From 69db5da7fcbfd4ebd2975b9c53184e275890b58c Mon Sep 17 00:00:00 2001 From: mx <1289317512@qq.com> Date: Thu, 12 Sep 2024 14:06:34 +0800 Subject: [PATCH] init --- .gitignore | 47 + LICENSE | 20 + bin/clean.bat | 12 + bin/package.bat | 12 + bin/run.bat | 14 + doc/若依环境使用手册.docx | Bin 0 -> 428430 bytes package-lock.json | 6 + pom.xml | 239 +++ ry.bat | 67 + ry.sh | 86 + sql/install.sql | 818 ++++++++ sql/quartz.sql | 174 ++ staffing-admin/pom.xml | 96 + .../com/staffing/StaffingApplication.java | 20 + .../staffing/StaffingServletInitializer.java | 18 + .../controller/common/CaptchaController.java | 94 + .../controller/common/CommonController.java | 163 ++ .../custom/StEmployeeController.java | 111 + .../StEmployeeFundRecordController.java | 163 ++ .../controller/custom/StTaskController.java | 135 ++ .../custom/StTaskSignController.java | 112 + .../employee/EmployeeFundController.java | 61 + .../employee/EmployeeTaskController.java | 107 + .../employee/EmployeeUserController.java | 223 ++ .../merchant/MerchantFundController.java | 117 ++ .../merchant/MerchantTaskController.java | 96 + .../merchant/MerchantUserController.java | 210 ++ .../controller/monitor/CacheController.java | 121 ++ .../controller/monitor/ServerController.java | 27 + .../monitor/SysLogininforController.java | 82 + .../monitor/SysOperlogController.java | 69 + .../monitor/SysUserOnlineController.java | 83 + .../system/SysConfigController.java | 133 ++ .../controller/system/SysDeptController.java | 132 ++ .../system/SysDictDataController.java | 121 ++ .../system/SysDictTypeController.java | 131 ++ .../controller/system/SysIndexController.java | 29 + .../controller/system/SysLoginController.java | 87 + .../controller/system/SysMenuController.java | 142 ++ .../system/SysNoticeController.java | 91 + .../controller/system/SysPostController.java | 129 ++ .../system/SysProfileController.java | 137 ++ .../system/SysRegisterController.java | 38 + .../controller/system/SysRoleController.java | 262 +++ .../controller/system/SysUserController.java | 256 +++ .../web/controller/tool/TestController.java | 183 ++ .../web/core/config/SwaggerConfig.java | 125 ++ .../META-INF/spring-devtools.properties | 1 + .../src/main/resources/application-druid.yml | 61 + .../src/main/resources/application.yml | 135 ++ staffing-admin/src/main/resources/banner.txt | 24 + .../main/resources/i18n/messages.properties | 38 + staffing-admin/src/main/resources/logback.xml | 93 + .../main/resources/mybatis/mybatis-config.xml | 20 + staffing-common/pom.xml | 143 ++ .../staffing/common/annotation/Anonymous.java | 19 + .../staffing/common/annotation/DataScope.java | 33 + .../common/annotation/DataSource.java | 28 + .../com/staffing/common/annotation/Excel.java | 192 ++ .../staffing/common/annotation/Excels.java | 18 + .../com/staffing/common/annotation/Log.java | 51 + .../common/annotation/RateLimiter.java | 40 + .../common/annotation/RepeatSubmit.java | 31 + .../staffing/common/annotation/Sensitive.java | 24 + .../staffing/common/config/MinioConfig.java | 30 + .../common/config/StaffingConfig.java | 122 ++ .../serializer/SensitiveJsonSerializer.java | 67 + .../common/constant/CacheConstants.java | 44 + .../staffing/common/constant/Constants.java | 173 ++ .../common/constant/GenConstants.java | 117 ++ .../staffing/common/constant/HttpStatus.java | 94 + .../common/constant/ScheduleConstants.java | 50 + .../common/constant/UserConstants.java | 78 + .../core/controller/BaseController.java | 202 ++ .../common/core/domain/AjaxResult.java | 216 ++ .../common/core/domain/BaseEntity.java | 119 ++ .../com/staffing/common/core/domain/R.java | 115 ++ .../common/core/domain/TreeEntity.java | 79 + .../common/core/domain/TreeSelect.java | 77 + .../staffing/common/core/domain/WxLogin.java | 49 + .../staffing/common/core/domain/WxPhone.java | 118 ++ .../staffing/common/core/domain/WxToken.java | 32 + .../common/core/domain/entity/SysDept.java | 203 ++ .../core/domain/entity/SysDictData.java | 176 ++ .../core/domain/entity/SysDictType.java | 96 + .../common/core/domain/entity/SysMenu.java | 274 +++ .../common/core/domain/entity/SysRole.java | 241 +++ .../common/core/domain/entity/SysUser.java | 344 ++++ .../common/core/domain/model/LoginBody.java | 89 + .../common/core/domain/model/LoginUser.java | 266 +++ .../core/domain/model/RegisterBody.java | 11 + .../staffing/common/core/page/PageDomain.java | 101 + .../common/core/page/TableDataInfo.java | 85 + .../common/core/page/TableSupport.java | 56 + .../common/core/redis/RedisCache.java | 268 +++ .../staffing/common/core/text/CharsetKit.java | 86 + .../staffing/common/core/text/Convert.java | 1010 +++++++++ .../common/core/text/StrFormatter.java | 92 + .../staffing/common/enums/BusinessStatus.java | 20 + .../staffing/common/enums/BusinessType.java | 59 + .../staffing/common/enums/DataSourceType.java | 19 + .../common/enums/DesensitizedType.java | 59 + .../com/staffing/common/enums/HttpMethod.java | 36 + .../com/staffing/common/enums/LimitType.java | 20 + .../staffing/common/enums/OperatorType.java | 24 + .../com/staffing/common/enums/UserStatus.java | 30 + .../common/exception/DemoModeException.java | 15 + .../common/exception/GlobalException.java | 58 + .../common/exception/ServiceException.java | 74 + .../common/exception/UtilException.java | 26 + .../common/exception/base/BaseException.java | 97 + .../common/exception/file/FileException.java | 19 + .../FileNameLengthLimitExceededException.java | 16 + .../file/FileSizeLimitExceededException.java | 16 + .../exception/file/FileUploadException.java | 61 + .../file/InvalidExtensionException.java | 80 + .../common/exception/job/TaskException.java | 34 + .../exception/user/BlackListException.java | 16 + .../exception/user/CaptchaException.java | 16 + .../user/CaptchaExpireException.java | 16 + .../common/exception/user/UserException.java | 18 + .../user/UserNotExistsException.java | 16 + .../user/UserPasswordNotMatchException.java | 16 + ...UserPasswordRetryLimitExceedException.java | 16 + .../filter/PropertyPreExcludeFilter.java | 24 + .../common/filter/RepeatableFilter.java | 52 + .../filter/RepeatedlyRequestWrapper.java | 76 + .../com/staffing/common/filter/XssFilter.java | 75 + .../filter/XssHttpServletRequestWrapper.java | 111 + .../java/com/staffing/common/utils/Arith.java | 114 ++ .../com/staffing/common/utils/DateUtils.java | 191 ++ .../common/utils/DesensitizedUtil.java | 49 + .../com/staffing/common/utils/DictUtils.java | 239 +++ .../staffing/common/utils/ExceptionUtil.java | 39 + .../com/staffing/common/utils/LogUtils.java | 18 + .../staffing/common/utils/MessageUtils.java | 26 + .../com/staffing/common/utils/MinioUtil.java | 190 ++ .../com/staffing/common/utils/OrderUtils.java | 14 + .../com/staffing/common/utils/PageUtils.java | 35 + .../common/utils/QRCodeGenerator.java | 111 + .../staffing/common/utils/SecurityUtils.java | 178 ++ .../staffing/common/utils/ServletUtils.java | 218 ++ .../staffing/common/utils/StringUtils.java | 684 +++++++ .../com/staffing/common/utils/Threads.java | 99 + .../com/staffing/common/utils/WxUtil.java | 63 + .../staffing/common/utils/bean/BeanUtils.java | 110 + .../common/utils/bean/BeanValidators.java | 24 + .../common/utils/file/FileTypeUtils.java | 76 + .../common/utils/file/FileUploadUtils.java | 232 +++ .../staffing/common/utils/file/FileUtils.java | 291 +++ .../common/utils/file/ImageUtils.java | 98 + .../common/utils/file/MimeTypeUtils.java | 59 + .../common/utils/html/EscapeUtil.java | 167 ++ .../common/utils/html/HTMLFilter.java | 570 ++++++ .../common/utils/http/HttpHelper.java | 55 + .../staffing/common/utils/http/HttpUtils.java | 286 +++ .../common/utils/ip/AddressUtils.java | 56 + .../com/staffing/common/utils/ip/IpUtils.java | 382 ++++ .../common/utils/poi/ExcelHandlerAdapter.java | 24 + .../staffing/common/utils/poi/ExcelUtil.java | 1812 +++++++++++++++++ .../common/utils/reflect/ReflectUtils.java | 410 ++++ .../staffing/common/utils/sign/Base64.java | 291 +++ .../staffing/common/utils/sign/Md5Utils.java | 67 + .../common/utils/spring/SpringUtils.java | 158 ++ .../staffing/common/utils/sql/SqlUtil.java | 70 + .../staffing/common/utils/uuid/IdUtils.java | 49 + .../com/staffing/common/utils/uuid/Seq.java | 86 + .../com/staffing/common/utils/uuid/UUID.java | 484 +++++ .../java/com/staffing/common/xss/Xss.java | 27 + .../com/staffing/common/xss/XssValidator.java | 39 + staffing-framework/pom.xml | 64 + .../framework/aspectj/DataScopeAspect.java | 184 ++ .../framework/aspectj/DataSourceAspect.java | 72 + .../staffing/framework/aspectj/LogAspect.java | 255 +++ .../framework/aspectj/RateLimiterAspect.java | 89 + .../framework/config/ApplicationConfig.java | 30 + .../framework/config/CaptchaConfig.java | 83 + .../framework/config/DruidConfig.java | 126 ++ .../config/FastJson2JsonRedisSerializer.java | 52 + .../framework/config/FilterConfig.java | 58 + .../staffing/framework/config/I18nConfig.java | 43 + .../framework/config/KaptchaTextCreator.java | 68 + .../framework/config/MyBatisConfig.java | 132 ++ .../framework/config/RedisConfig.java | 69 + .../framework/config/ResourcesConfig.java | 73 + .../framework/config/SecurityConfig.java | 143 ++ .../framework/config/ServerConfig.java | 32 + .../framework/config/ThreadPoolConfig.java | 63 + .../config/properties/DruidProperties.java | 89 + .../properties/PermitAllUrlProperties.java | 73 + .../datasource/DynamicDataSource.java | 26 + .../DynamicDataSourceContextHolder.java | 45 + .../interceptor/RepeatSubmitInterceptor.java | 56 + .../impl/SameUrlDataInterceptor.java | 110 + .../framework/manager/AsyncManager.java | 55 + .../framework/manager/ShutdownManager.java | 39 + .../manager/factory/AsyncFactory.java | 102 + .../context/AuthenticationContextHolder.java | 28 + .../context/PermissionContextHolder.java | 27 + .../filter/JwtAuthenticationTokenFilter.java | 44 + .../handle/AuthenticationEntryPointImpl.java | 34 + .../handle/LogoutSuccessHandlerImpl.java | 53 + .../staffing/framework/web/domain/Server.java | 240 +++ .../framework/web/domain/server/Cpu.java | 101 + .../framework/web/domain/server/Jvm.java | 130 ++ .../framework/web/domain/server/Mem.java | 61 + .../framework/web/domain/server/Sys.java | 84 + .../framework/web/domain/server/SysFile.java | 114 ++ .../web/exception/GlobalExceptionHandler.java | 145 ++ .../web/service/PermissionService.java | 159 ++ .../web/service/SysLoginService.java | 295 +++ .../web/service/SysPasswordService.java | 86 + .../web/service/SysPermissionService.java | 83 + .../web/service/SysRegisterService.java | 115 ++ .../framework/web/service/TokenService.java | 231 +++ .../web/service/UserDetailsServiceImpl.java | 66 + staffing-generator/pom.xml | 40 + .../staffing/generator/config/GenConfig.java | 73 + .../generator/controller/GenController.java | 258 +++ .../staffing/generator/domain/GenTable.java | 385 ++++ .../generator/domain/GenTableColumn.java | 373 ++++ .../mapper/GenTableColumnMapper.java | 60 + .../generator/mapper/GenTableMapper.java | 91 + .../service/GenTableColumnServiceImpl.java | 68 + .../service/GenTableServiceImpl.java | 531 +++++ .../service/IGenTableColumnService.java | 44 + .../generator/service/IGenTableService.java | 130 ++ .../com/staffing/generator/util/GenUtils.java | 257 +++ .../generator/util/VelocityInitializer.java | 34 + .../generator/util/VelocityUtils.java | 408 ++++ .../src/main/resources/generator.yml | 10 + .../mapper/generator/GenTableColumnMapper.xml | 127 ++ .../mapper/generator/GenTableMapper.xml | 210 ++ .../main/resources/vm/java/controller.java.vm | 115 ++ .../src/main/resources/vm/java/domain.java.vm | 101 + .../src/main/resources/vm/java/mapper.java.vm | 91 + .../main/resources/vm/java/service.java.vm | 61 + .../resources/vm/java/serviceImpl.java.vm | 169 ++ .../main/resources/vm/java/sub-domain.java.vm | 73 + .../src/main/resources/vm/js/api.js.vm | 44 + .../src/main/resources/vm/sql/sql.vm | 22 + .../main/resources/vm/vue/index-tree.vue.vm | 505 +++++ .../src/main/resources/vm/vue/index.vue.vm | 602 ++++++ .../resources/vm/vue/v3/index-tree.vue.vm | 474 +++++ .../src/main/resources/vm/vue/v3/index.vue.vm | 590 ++++++ .../src/main/resources/vm/xml/mapper.xml.vm | 140 ++ staffing-quartz/pom.xml | 40 + .../quartz/config/ScheduleConfig.java | 57 + .../quartz/controller/SysJobController.java | 185 ++ .../controller/SysJobLogController.java | 92 + .../com/staffing/quartz/domain/SysJob.java | 171 ++ .../com/staffing/quartz/domain/SysJobLog.java | 155 ++ .../quartz/mapper/SysJobLogMapper.java | 64 + .../staffing/quartz/mapper/SysJobMapper.java | 67 + .../quartz/service/ISysJobLogService.java | 56 + .../quartz/service/ISysJobService.java | 102 + .../service/impl/SysJobLogServiceImpl.java | 87 + .../service/impl/SysJobServiceImpl.java | 261 +++ .../java/com/staffing/quartz/task/RyTask.java | 28 + .../quartz/util/AbstractQuartzJob.java | 107 + .../com/staffing/quartz/util/CronUtils.java | 63 + .../staffing/quartz/util/JobInvokeUtil.java | 182 ++ .../QuartzDisallowConcurrentExecution.java | 21 + .../quartz/util/QuartzJobExecution.java | 19 + .../staffing/quartz/util/ScheduleUtils.java | 141 ++ .../mapper/quartz/SysJobLogMapper.xml | 94 + .../resources/mapper/quartz/SysJobMapper.xml | 111 + staffing-system/pom.xml | 34 + .../staffing/custom/domain/StEmployee.java | 234 +++ .../custom/domain/StEmployeeFundRecord.java | 303 +++ .../com/staffing/custom/domain/StTask.java | 287 +++ .../staffing/custom/domain/StTaskSign.java | 198 ++ .../custom/domain/StTransferRecord.java | 123 ++ .../mapper/StEmployeeFundRecordMapper.java | 68 + .../custom/mapper/StEmployeeMapper.java | 69 + .../staffing/custom/mapper/StTaskMapper.java | 63 + .../custom/mapper/StTaskSignMapper.java | 68 + .../custom/mapper/StTransferRecordMapper.java | 61 + .../com/staffing/custom/param/FxParam.java | 24 + .../service/IStEmployeeFundRecordService.java | 67 + .../custom/service/IStEmployeeService.java | 64 + .../custom/service/IStTaskService.java | 77 + .../custom/service/IStTaskSignService.java | 66 + .../service/IStTransferRecordService.java | 61 + .../custom/service/TransferBatchService.java | 150 ++ .../impl/StEmployeeFundRecordServiceImpl.java | 251 +++ .../service/impl/StEmployeeServiceImpl.java | 106 + .../service/impl/StTaskServiceImpl.java | 349 ++++ .../service/impl/StTaskSignServiceImpl.java | 187 ++ .../impl/StTransferRecordServiceImpl.java | 96 + .../com/staffing/system/domain/SysCache.java | 81 + .../com/staffing/system/domain/SysConfig.java | 111 + .../staffing/system/domain/SysLogininfor.java | 144 ++ .../com/staffing/system/domain/SysNotice.java | 102 + .../staffing/system/domain/SysOperLog.java | 269 +++ .../com/staffing/system/domain/SysPost.java | 124 ++ .../staffing/system/domain/SysRoleDept.java | 46 + .../staffing/system/domain/SysRoleMenu.java | 46 + .../staffing/system/domain/SysUserOnline.java | 113 + .../staffing/system/domain/SysUserPost.java | 46 + .../staffing/system/domain/SysUserRole.java | 46 + .../com/staffing/system/domain/vo/MetaVo.java | 106 + .../staffing/system/domain/vo/RouterVo.java | 148 ++ .../system/mapper/SysConfigMapper.java | 76 + .../staffing/system/mapper/SysDeptMapper.java | 118 ++ .../system/mapper/SysDictDataMapper.java | 95 + .../system/mapper/SysDictTypeMapper.java | 83 + .../system/mapper/SysLogininforMapper.java | 42 + .../staffing/system/mapper/SysMenuMapper.java | 125 ++ .../system/mapper/SysNoticeMapper.java | 60 + .../system/mapper/SysOperLogMapper.java | 48 + .../staffing/system/mapper/SysPostMapper.java | 99 + .../system/mapper/SysRoleDeptMapper.java | 44 + .../staffing/system/mapper/SysRoleMapper.java | 107 + .../system/mapper/SysRoleMenuMapper.java | 44 + .../staffing/system/mapper/SysUserMapper.java | 128 ++ .../system/mapper/SysUserPostMapper.java | 44 + .../system/mapper/SysUserRoleMapper.java | 62 + .../system/service/ISysConfigService.java | 89 + .../system/service/ISysDeptService.java | 124 ++ .../system/service/ISysDictDataService.java | 60 + .../system/service/ISysDictTypeService.java | 98 + .../system/service/ISysLogininforService.java | 40 + .../system/service/ISysMenuService.java | 144 ++ .../system/service/ISysNoticeService.java | 60 + .../system/service/ISysOperLogService.java | 48 + .../system/service/ISysPostService.java | 99 + .../system/service/ISysRoleService.java | 173 ++ .../system/service/ISysUserOnlineService.java | 48 + .../system/service/ISysUserService.java | 206 ++ .../service/impl/SysConfigServiceImpl.java | 232 +++ .../service/impl/SysDeptServiceImpl.java | 338 +++ .../service/impl/SysDictDataServiceImpl.java | 111 + .../service/impl/SysDictTypeServiceImpl.java | 223 ++ .../impl/SysLogininforServiceImpl.java | 65 + .../service/impl/SysMenuServiceImpl.java | 543 +++++ .../service/impl/SysNoticeServiceImpl.java | 92 + .../service/impl/SysOperLogServiceImpl.java | 76 + .../service/impl/SysPostServiceImpl.java | 178 ++ .../service/impl/SysRoleServiceImpl.java | 427 ++++ .../impl/SysUserOnlineServiceImpl.java | 96 + .../service/impl/SysUserServiceImpl.java | 555 +++++ .../src/main/resources/apiclient_key.pem | 28 + .../custom/StEmployeeFundRecordMapper.xml | 173 ++ .../mapper/custom/StEmployeeMapper.xml | 159 ++ .../resources/mapper/custom/StTaskMapper.xml | 109 + .../mapper/custom/StTaskSignMapper.xml | 128 ++ .../mapper/custom/StTransferRecordMapper.xml | 89 + .../mapper/system/SysConfigMapper.xml | 117 ++ .../resources/mapper/system/SysDeptMapper.xml | 159 ++ .../mapper/system/SysDictDataMapper.xml | 124 ++ .../mapper/system/SysDictTypeMapper.xml | 105 + .../mapper/system/SysLogininforMapper.xml | 57 + .../resources/mapper/system/SysMenuMapper.xml | 206 ++ .../mapper/system/SysNoticeMapper.xml | 89 + .../mapper/system/SysOperLogMapper.xml | 87 + .../resources/mapper/system/SysPostMapper.xml | 122 ++ .../mapper/system/SysRoleDeptMapper.xml | 34 + .../resources/mapper/system/SysRoleMapper.xml | 152 ++ .../mapper/system/SysRoleMenuMapper.xml | 34 + .../resources/mapper/system/SysUserMapper.xml | 228 +++ .../mapper/system/SysUserPostMapper.xml | 34 + .../mapper/system/SysUserRoleMapper.xml | 44 + staffing-ui/.editorconfig | 22 + staffing-ui/.env.development | 11 + staffing-ui/.env.production | 8 + staffing-ui/.env.staging | 10 + staffing-ui/.eslintignore | 10 + staffing-ui/.eslintrc.js | 199 ++ staffing-ui/.gitignore | 23 + staffing-ui/README.md | 30 + staffing-ui/babel.config.js | 13 + staffing-ui/bin/build.bat | 12 + staffing-ui/bin/package.bat | 12 + staffing-ui/bin/run-web.bat | 12 + staffing-ui/build/index.js | 35 + staffing-ui/package.json | 91 + staffing-ui/public/favicon.ico | Bin 0 -> 5663 bytes staffing-ui/public/html/ie.html | 46 + staffing-ui/public/index.html | 208 ++ staffing-ui/public/robots.txt | 2 + staffing-ui/src/App.vue | 28 + staffing-ui/src/api/employee/employee.js | 44 + staffing-ui/src/api/fund/fund.js | 44 + staffing-ui/src/api/login.js | 60 + staffing-ui/src/api/menu.js | 9 + staffing-ui/src/api/monitor/cache.js | 57 + staffing-ui/src/api/monitor/job.js | 71 + staffing-ui/src/api/monitor/jobLog.js | 26 + staffing-ui/src/api/monitor/logininfor.js | 34 + staffing-ui/src/api/monitor/online.js | 18 + staffing-ui/src/api/monitor/operlog.js | 26 + staffing-ui/src/api/monitor/server.js | 9 + staffing-ui/src/api/system/config.js | 60 + staffing-ui/src/api/system/dept.js | 52 + staffing-ui/src/api/system/dict/data.js | 52 + staffing-ui/src/api/system/dict/type.js | 60 + staffing-ui/src/api/system/menu.js | 60 + staffing-ui/src/api/system/notice.js | 44 + staffing-ui/src/api/system/post.js | 44 + staffing-ui/src/api/system/role.js | 119 ++ staffing-ui/src/api/system/user.js | 136 ++ staffing-ui/src/api/task/task.js | 44 + staffing-ui/src/api/taskSign/sign.js | 44 + staffing-ui/src/api/tool/gen.js | 85 + staffing-ui/src/assets/401_images/401.gif | Bin 0 -> 164227 bytes staffing-ui/src/assets/404_images/404.png | Bin 0 -> 98071 bytes .../src/assets/404_images/404_cloud.png | Bin 0 -> 4766 bytes staffing-ui/src/assets/icons/index.js | 9 + staffing-ui/src/assets/icons/svg/404.svg | 1 + staffing-ui/src/assets/icons/svg/bug.svg | 1 + staffing-ui/src/assets/icons/svg/build.svg | 1 + staffing-ui/src/assets/icons/svg/button.svg | 1 + staffing-ui/src/assets/icons/svg/cascader.svg | 1 + staffing-ui/src/assets/icons/svg/chart.svg | 1 + staffing-ui/src/assets/icons/svg/checkbox.svg | 1 + .../src/assets/icons/svg/clipboard.svg | 1 + staffing-ui/src/assets/icons/svg/code.svg | 1 + staffing-ui/src/assets/icons/svg/color.svg | 1 + .../src/assets/icons/svg/component.svg | 1 + .../src/assets/icons/svg/dashboard.svg | 1 + .../src/assets/icons/svg/date-range.svg | 1 + staffing-ui/src/assets/icons/svg/date.svg | 1 + staffing-ui/src/assets/icons/svg/dict.svg | 1 + .../src/assets/icons/svg/documentation.svg | 1 + staffing-ui/src/assets/icons/svg/download.svg | 1 + staffing-ui/src/assets/icons/svg/drag.svg | 1 + staffing-ui/src/assets/icons/svg/druid.svg | 1 + staffing-ui/src/assets/icons/svg/edit.svg | 1 + .../src/assets/icons/svg/education.svg | 1 + staffing-ui/src/assets/icons/svg/email.svg | 1 + staffing-ui/src/assets/icons/svg/example.svg | 1 + staffing-ui/src/assets/icons/svg/excel.svg | 1 + .../src/assets/icons/svg/exit-fullscreen.svg | 1 + staffing-ui/src/assets/icons/svg/eye-open.svg | 1 + staffing-ui/src/assets/icons/svg/eye.svg | 1 + staffing-ui/src/assets/icons/svg/form.svg | 1 + .../src/assets/icons/svg/fullscreen.svg | 1 + staffing-ui/src/assets/icons/svg/github.svg | 1 + staffing-ui/src/assets/icons/svg/guide.svg | 1 + staffing-ui/src/assets/icons/svg/icon.svg | 1 + staffing-ui/src/assets/icons/svg/input.svg | 1 + .../src/assets/icons/svg/international.svg | 1 + staffing-ui/src/assets/icons/svg/job.svg | 1 + staffing-ui/src/assets/icons/svg/language.svg | 1 + staffing-ui/src/assets/icons/svg/link.svg | 1 + staffing-ui/src/assets/icons/svg/list.svg | 1 + staffing-ui/src/assets/icons/svg/lock.svg | 1 + staffing-ui/src/assets/icons/svg/log.svg | 1 + .../src/assets/icons/svg/logininfor.svg | 1 + staffing-ui/src/assets/icons/svg/message.svg | 1 + staffing-ui/src/assets/icons/svg/money.svg | 1 + staffing-ui/src/assets/icons/svg/monitor.svg | 2 + staffing-ui/src/assets/icons/svg/nested.svg | 1 + staffing-ui/src/assets/icons/svg/number.svg | 1 + staffing-ui/src/assets/icons/svg/online.svg | 1 + staffing-ui/src/assets/icons/svg/password.svg | 1 + staffing-ui/src/assets/icons/svg/pdf.svg | 1 + staffing-ui/src/assets/icons/svg/people.svg | 1 + staffing-ui/src/assets/icons/svg/peoples.svg | 1 + staffing-ui/src/assets/icons/svg/phone.svg | 1 + staffing-ui/src/assets/icons/svg/post.svg | 1 + staffing-ui/src/assets/icons/svg/qq.svg | 1 + staffing-ui/src/assets/icons/svg/question.svg | 1 + staffing-ui/src/assets/icons/svg/radio.svg | 1 + staffing-ui/src/assets/icons/svg/rate.svg | 1 + .../src/assets/icons/svg/redis-list.svg | 2 + staffing-ui/src/assets/icons/svg/redis.svg | 1 + staffing-ui/src/assets/icons/svg/row.svg | 1 + staffing-ui/src/assets/icons/svg/search.svg | 1 + staffing-ui/src/assets/icons/svg/select.svg | 1 + staffing-ui/src/assets/icons/svg/server.svg | 1 + staffing-ui/src/assets/icons/svg/shopping.svg | 1 + staffing-ui/src/assets/icons/svg/size.svg | 1 + staffing-ui/src/assets/icons/svg/skill.svg | 1 + staffing-ui/src/assets/icons/svg/slider.svg | 1 + staffing-ui/src/assets/icons/svg/star.svg | 1 + staffing-ui/src/assets/icons/svg/swagger.svg | 1 + staffing-ui/src/assets/icons/svg/switch.svg | 1 + staffing-ui/src/assets/icons/svg/system.svg | 2 + staffing-ui/src/assets/icons/svg/tab.svg | 1 + staffing-ui/src/assets/icons/svg/table.svg | 1 + staffing-ui/src/assets/icons/svg/textarea.svg | 1 + staffing-ui/src/assets/icons/svg/theme.svg | 1 + .../src/assets/icons/svg/time-range.svg | 1 + staffing-ui/src/assets/icons/svg/time.svg | 1 + staffing-ui/src/assets/icons/svg/tool.svg | 1 + .../src/assets/icons/svg/tree-table.svg | 1 + staffing-ui/src/assets/icons/svg/tree.svg | 1 + staffing-ui/src/assets/icons/svg/upload.svg | 1 + staffing-ui/src/assets/icons/svg/user.svg | 1 + .../src/assets/icons/svg/validCode.svg | 1 + staffing-ui/src/assets/icons/svg/wechat.svg | 1 + staffing-ui/src/assets/icons/svg/zip.svg | 1 + staffing-ui/src/assets/icons/svgo.yml | 22 + staffing-ui/src/assets/images/bg.jpg | Bin 0 -> 986646 bytes staffing-ui/src/assets/images/dark.svg | 39 + staffing-ui/src/assets/images/light.svg | 39 + .../src/assets/images/login-background.jpg | Bin 0 -> 521275 bytes staffing-ui/src/assets/images/pay.png | Bin 0 -> 140720 bytes staffing-ui/src/assets/images/profile.jpg | Bin 0 -> 81131 bytes staffing-ui/src/assets/logo/logo.png | Bin 0 -> 5663 bytes staffing-ui/src/assets/styles/btn.scss | 99 + staffing-ui/src/assets/styles/element-ui.scss | 92 + .../src/assets/styles/element-variables.scss | 31 + staffing-ui/src/assets/styles/index.scss | 182 ++ staffing-ui/src/assets/styles/mixin.scss | 66 + staffing-ui/src/assets/styles/sidebar.scss | 227 +++ staffing-ui/src/assets/styles/staffing.scss | 291 +++ staffing-ui/src/assets/styles/transition.scss | 49 + staffing-ui/src/assets/styles/variables.scss | 54 + .../src/components/Breadcrumb/index.vue | 74 + staffing-ui/src/components/Crontab/day.vue | 161 ++ staffing-ui/src/components/Crontab/hour.vue | 120 ++ staffing-ui/src/components/Crontab/index.vue | 430 ++++ staffing-ui/src/components/Crontab/min.vue | 116 ++ staffing-ui/src/components/Crontab/month.vue | 114 ++ staffing-ui/src/components/Crontab/result.vue | 559 +++++ staffing-ui/src/components/Crontab/second.vue | 117 ++ staffing-ui/src/components/Crontab/week.vue | 202 ++ staffing-ui/src/components/Crontab/year.vue | 131 ++ staffing-ui/src/components/DictData/index.js | 49 + staffing-ui/src/components/DictTag/index.vue | 89 + staffing-ui/src/components/Editor/index.vue | 274 +++ .../src/components/FileUpload/index.vue | 216 ++ .../src/components/Hamburger/index.vue | 44 + .../src/components/HeaderSearch/index.vue | 198 ++ .../src/components/IconSelect/index.vue | 104 + .../src/components/IconSelect/requireIcons.js | 11 + .../src/components/ImagePreview/index.vue | 90 + .../src/components/ImageUpload/index.vue | 226 ++ .../src/components/Pagination/index.vue | 114 ++ staffing-ui/src/components/PanThumb/index.vue | 142 ++ .../src/components/ParentView/index.vue | 3 + .../src/components/RightPanel/index.vue | 106 + .../src/components/RightToolbar/index.vue | 129 ++ .../src/components/Screenfull/index.vue | 57 + .../src/components/SizeSelect/index.vue | 56 + staffing-ui/src/components/SvgIcon/index.vue | 61 + .../src/components/ThemePicker/index.vue | 173 ++ staffing-ui/src/components/TopNav/index.vue | 195 ++ staffing-ui/src/components/iFrame/index.vue | 36 + .../src/components/staffing/Doc/index.vue | 21 + .../src/components/staffing/Git/index.vue | 21 + staffing-ui/src/directive/dialog/drag.js | 64 + .../src/directive/dialog/dragHeight.js | 34 + staffing-ui/src/directive/dialog/dragWidth.js | 30 + staffing-ui/src/directive/index.js | 23 + staffing-ui/src/directive/module/clipboard.js | 54 + .../src/directive/permission/hasPermi.js | 28 + .../src/directive/permission/hasRole.js | 28 + staffing-ui/src/layout/components/AppMain.vue | 75 + .../layout/components/IframeToggle/index.vue | 33 + .../src/layout/components/InnerLink/index.vue | 47 + staffing-ui/src/layout/components/Navbar.vue | 200 ++ .../src/layout/components/Settings/index.vue | 260 +++ .../layout/components/Sidebar/FixiOSBug.js | 25 + .../src/layout/components/Sidebar/Item.vue | 33 + .../src/layout/components/Sidebar/Link.vue | 43 + .../src/layout/components/Sidebar/Logo.vue | 93 + .../layout/components/Sidebar/SidebarItem.vue | 100 + .../src/layout/components/Sidebar/index.vue | 57 + .../layout/components/TagsView/ScrollPane.vue | 94 + .../src/layout/components/TagsView/index.vue | 332 +++ staffing-ui/src/layout/components/index.js | 5 + staffing-ui/src/layout/index.vue | 111 + staffing-ui/src/layout/mixin/ResizeHandler.js | 45 + staffing-ui/src/main.js | 86 + staffing-ui/src/permission.js | 130 ++ staffing-ui/src/plugins/auth.js | 60 + staffing-ui/src/plugins/cache.js | 77 + staffing-ui/src/plugins/download.js | 79 + staffing-ui/src/plugins/index.js | 20 + staffing-ui/src/plugins/modal.js | 83 + staffing-ui/src/plugins/tab.js | 71 + staffing-ui/src/router/index.js | 183 ++ staffing-ui/src/settings.js | 44 + staffing-ui/src/store/getters.js | 19 + staffing-ui/src/store/index.js | 25 + staffing-ui/src/store/modules/app.js | 66 + staffing-ui/src/store/modules/dict.js | 50 + staffing-ui/src/store/modules/permission.js | 147 ++ staffing-ui/src/store/modules/settings.js | 42 + staffing-ui/src/store/modules/tagsView.js | 228 +++ staffing-ui/src/store/modules/user.js | 101 + staffing-ui/src/utils/auth.js | 15 + staffing-ui/src/utils/dict/Dict.js | 82 + staffing-ui/src/utils/dict/DictConverter.js | 17 + staffing-ui/src/utils/dict/DictData.js | 13 + staffing-ui/src/utils/dict/DictMeta.js | 38 + staffing-ui/src/utils/dict/DictOptions.js | 51 + staffing-ui/src/utils/dict/index.js | 33 + staffing-ui/src/utils/errorCode.js | 6 + staffing-ui/src/utils/generator/config.js | 438 ++++ staffing-ui/src/utils/generator/css.js | 18 + .../src/utils/generator/drawingDefault.js | 29 + staffing-ui/src/utils/generator/html.js | 359 ++++ staffing-ui/src/utils/generator/icon.json | 1 + staffing-ui/src/utils/generator/js.js | 235 +++ staffing-ui/src/utils/generator/render.js | 126 ++ staffing-ui/src/utils/index.js | 390 ++++ staffing-ui/src/utils/jsencrypt.js | 30 + staffing-ui/src/utils/permission.js | 47 + staffing-ui/src/utils/request.js | 152 ++ staffing-ui/src/utils/scroll-to.js | 58 + staffing-ui/src/utils/staffing.js | 233 +++ staffing-ui/src/utils/validate.js | 80 + staffing-ui/src/views/dashboard/BarChart.vue | 102 + staffing-ui/src/views/dashboard/LineChart.vue | 135 ++ .../src/views/dashboard/PanelGroup.vue | 181 ++ staffing-ui/src/views/dashboard/PieChart.vue | 79 + .../src/views/dashboard/RaddarChart.vue | 116 ++ .../src/views/dashboard/mixins/resize.js | 56 + .../src/views/employee/employee/index.vue | 408 ++++ staffing-ui/src/views/error/401.vue | 88 + staffing-ui/src/views/error/404.vue | 233 +++ staffing-ui/src/views/fund/fund/index.vue | 495 +++++ staffing-ui/src/views/index.vue | 87 + staffing-ui/src/views/index_v1.vue | 98 + staffing-ui/src/views/login.vue | 240 +++ staffing-ui/src/views/monitor/cache/index.vue | 148 ++ staffing-ui/src/views/monitor/cache/list.vue | 241 +++ staffing-ui/src/views/monitor/druid/index.vue | 15 + staffing-ui/src/views/monitor/job/index.vue | 513 +++++ staffing-ui/src/views/monitor/job/log.vue | 295 +++ .../src/views/monitor/logininfor/index.vue | 246 +++ .../src/views/monitor/online/index.vue | 122 ++ .../src/views/monitor/operlog/index.vue | 323 +++ .../src/views/monitor/server/index.vue | 207 ++ staffing-ui/src/views/redirect.vue | 12 + staffing-ui/src/views/register.vue | 210 ++ staffing-ui/src/views/system/config/index.vue | 343 ++++ staffing-ui/src/views/system/dept/index.vue | 340 ++++ staffing-ui/src/views/system/dict/data.vue | 402 ++++ staffing-ui/src/views/system/dict/index.vue | 347 ++++ staffing-ui/src/views/system/menu/index.vue | 452 ++++ staffing-ui/src/views/system/notice/index.vue | 312 +++ staffing-ui/src/views/system/post/index.vue | 309 +++ .../src/views/system/role/authUser.vue | 199 ++ staffing-ui/src/views/system/role/index.vue | 605 ++++++ .../src/views/system/role/selectUser.vue | 136 ++ .../src/views/system/user/authRole.vue | 117 ++ staffing-ui/src/views/system/user/index.vue | 676 ++++++ .../src/views/system/user/profile/index.vue | 91 + .../views/system/user/profile/resetPwd.vue | 69 + .../views/system/user/profile/userAvatar.vue | 184 ++ .../views/system/user/profile/userInfo.vue | 88 + staffing-ui/src/views/task/task/index.vue | 832 ++++++++ staffing-ui/src/views/taskSign/sign/index.vue | 311 +++ .../src/views/tool/build/CodeTypeDialog.vue | 106 + .../src/views/tool/build/DraggableItem.vue | 100 + .../src/views/tool/build/IconsDialog.vue | 123 ++ .../src/views/tool/build/RightPanel.vue | 946 +++++++++ .../src/views/tool/build/TreeNodeDialog.vue | 149 ++ staffing-ui/src/views/tool/build/index.vue | 768 +++++++ .../src/views/tool/gen/basicInfoForm.vue | 60 + .../src/views/tool/gen/createTable.vue | 45 + staffing-ui/src/views/tool/gen/editTable.vue | 234 +++ .../src/views/tool/gen/genInfoForm.vue | 312 +++ .../src/views/tool/gen/importTable.vue | 120 ++ staffing-ui/src/views/tool/gen/index.vue | 354 ++++ staffing-ui/src/views/tool/swagger/index.vue | 15 + staffing-ui/vue.config.js | 130 ++ wx-pay/pom.xml | 101 + .../pay/java/core/AbstractRSAConfig.java | 97 + .../java/core/AbstractRSAConfigBuilder.java | 40 + .../java/com/wechat/pay/java/core/Config.java | 46 + .../java/core/RSAAutoCertificateConfig.java | 123 ++ .../com/wechat/pay/java/core/RSAConfig.java | 64 + .../pay/java/core/RSAPublicKeyConfig.java | 121 ++ .../wechat/pay/java/core/auth/Credential.java | 31 + .../wechat/pay/java/core/auth/Validator.java | 17 + .../java/core/auth/WechatPay2Credential.java | 89 + .../java/core/auth/WechatPay2Validator.java | 60 + .../certificate/AutoCertificateService.java | 159 ++ .../certificate/CertificateDownloader.java | 113 + .../core/certificate/CertificateHandler.java | 23 + .../core/certificate/CertificateProvider.java | 22 + .../InMemoryCertificateProvider.java | 53 + .../RSAAutoCertificateProvider.java | 138 ++ .../certificate/RSACertificateHandler.java | 18 + .../pay/java/core/certificate/model/Data.java | 49 + .../model/DownloadCertificateResponse.java | 25 + .../certificate/model/EncryptCertificate.java | 48 + .../java/core/cipher/AbstractAeadCipher.java | 89 + .../core/cipher/AbstractPrivacyDecryptor.java | 50 + .../core/cipher/AbstractPrivacyEncryptor.java | 50 + .../pay/java/core/cipher/AbstractSigner.java | 60 + .../java/core/cipher/AbstractVerifier.java | 126 ++ .../pay/java/core/cipher/AeadAesCipher.java | 14 + .../pay/java/core/cipher/AeadCipher.java | 24 + .../wechat/pay/java/core/cipher/Constant.java | 11 + .../pay/java/core/cipher/Encryption.java | 10 + .../java/core/cipher/PrivacyDecryptor.java | 13 + .../java/core/cipher/PrivacyEncryptor.java | 19 + .../core/cipher/RSAPkcs1v15Decryptor.java | 11 + .../core/cipher/RSAPkcs1v15Encryptor.java | 11 + .../java/core/cipher/RSAPrivacyDecryptor.java | 16 + .../java/core/cipher/RSAPrivacyEncryptor.java | 17 + .../pay/java/core/cipher/RSASigner.java | 11 + .../pay/java/core/cipher/RSAVerifier.java | 23 + .../pay/java/core/cipher/SignatureResult.java | 41 + .../wechat/pay/java/core/cipher/Signer.java | 20 + .../wechat/pay/java/core/cipher/Verifier.java | 15 + .../core/exception/DecryptionException.java | 9 + .../java/core/exception/HttpException.java | 49 + .../exception/MalformedMessageException.java | 15 + .../java/core/exception/ServiceException.java | 86 + .../core/exception/ValidationException.java | 15 + .../core/exception/WechatPayException.java | 15 + .../java/core/http/AbstractHttpClient.java | 139 ++ .../core/http/AbstractHttpClientBuilder.java | 37 + .../wechat/pay/java/core/http/Constant.java | 36 + .../core/http/DefaultHttpClientBuilder.java | 189 ++ .../pay/java/core/http/FileRequestBody.java | 90 + .../wechat/pay/java/core/http/HostName.java | 23 + .../wechat/pay/java/core/http/HttpClient.java | 150 ++ .../pay/java/core/http/HttpHeaders.java | 61 + .../wechat/pay/java/core/http/HttpMethod.java | 14 + .../pay/java/core/http/HttpRequest.java | 179 ++ .../pay/java/core/http/HttpResponse.java | 111 + .../pay/java/core/http/JsonRequestBody.java | 48 + .../pay/java/core/http/JsonResponseBody.java | 46 + .../wechat/pay/java/core/http/MediaType.java | 26 + .../pay/java/core/http/OriginalResponse.java | 133 ++ .../pay/java/core/http/QueryParameter.java | 28 + .../pay/java/core/http/RequestBody.java | 12 + .../pay/java/core/http/ResponseBody.java | 12 + .../wechat/pay/java/core/http/UrlEncoder.java | 22 + .../core/http/okhttp/OkHttpClientAdapter.java | 164 ++ .../okhttp/OkHttpMultiDomainInterceptor.java | 60 + .../AbstractNotificationConfig.java | 86 + .../AutoCertificateNotificationConfig.java | 63 + .../pay/java/core/notification/Constant.java | 9 + .../java/core/notification/Notification.java | 89 + .../core/notification/NotificationConfig.java | 36 + .../core/notification/NotificationParser.java | 160 ++ .../RSACombinedNotificationConfig.java | 95 + .../notification/RSANotificationConfig.java | 71 + .../RSAPublicKeyNotificationConfig.java | 61 + .../java/core/notification/RequestParam.java | 99 + .../pay/java/core/notification/Resource.java | 62 + .../wechat/pay/java/core/util/GsonUtil.java | 65 + .../com/wechat/pay/java/core/util/IOUtil.java | 59 + .../wechat/pay/java/core/util/NonceUtil.java | 27 + .../wechat/pay/java/core/util/PemUtil.java | 236 +++ .../wechat/pay/java/core/util/ShaUtil.java | 107 + .../wechat/pay/java/core/util/StringUtil.java | 19 + .../TransferBatchServiceBase.java | 303 +++ .../transferbatch/model/CloseReasonType.java | 24 + .../transferbatch/model/FailReasonType.java | 96 + .../model/GetTransferBatchByNoRequest.java | 104 + .../model/GetTransferBatchByOutNoRequest.java | 104 + .../model/GetTransferDetailByNoRequest.java | 57 + .../GetTransferDetailByOutNoRequest.java | 57 + .../model/InitiateBatchTransferRequest.java | 173 ++ .../model/InitiateBatchTransferResponse.java | 84 + .../model/TransferBatchEntity.java | 56 + .../transferbatch/model/TransferBatchGet.java | 266 +++ .../model/TransferDetailCompact.java | 70 + .../model/TransferDetailEntity.java | 238 +++ .../model/TransferDetailInput.java | 113 + .../service/transferbatch/package-info.java | 2 + wx-pay/src/main/resources/apiclient_key.pem | 28 + 764 files changed, 79972 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 bin/clean.bat create mode 100644 bin/package.bat create mode 100644 bin/run.bat create mode 100644 doc/若依环境使用手册.docx create mode 100644 package-lock.json create mode 100644 pom.xml create mode 100644 ry.bat create mode 100644 ry.sh create mode 100644 sql/install.sql create mode 100644 sql/quartz.sql create mode 100644 staffing-admin/pom.xml create mode 100644 staffing-admin/src/main/java/com/staffing/StaffingApplication.java create mode 100644 staffing-admin/src/main/java/com/staffing/StaffingServletInitializer.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/common/CaptchaController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/common/CommonController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/custom/StEmployeeController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/custom/StEmployeeFundRecordController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/custom/StTaskController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/custom/StTaskSignController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/employee/EmployeeFundController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/employee/EmployeeTaskController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/employee/EmployeeUserController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/merchant/MerchantFundController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/merchant/MerchantTaskController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/merchant/MerchantUserController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/monitor/CacheController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/monitor/ServerController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/monitor/SysLogininforController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/monitor/SysOperlogController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/monitor/SysUserOnlineController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/system/SysConfigController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/system/SysDeptController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/system/SysDictDataController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/system/SysDictTypeController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/system/SysIndexController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/system/SysLoginController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/system/SysMenuController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/system/SysNoticeController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/system/SysPostController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/system/SysProfileController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/system/SysRegisterController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/system/SysRoleController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/system/SysUserController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/controller/tool/TestController.java create mode 100644 staffing-admin/src/main/java/com/staffing/web/core/config/SwaggerConfig.java create mode 100644 staffing-admin/src/main/resources/META-INF/spring-devtools.properties create mode 100644 staffing-admin/src/main/resources/application-druid.yml create mode 100644 staffing-admin/src/main/resources/application.yml create mode 100644 staffing-admin/src/main/resources/banner.txt create mode 100644 staffing-admin/src/main/resources/i18n/messages.properties create mode 100644 staffing-admin/src/main/resources/logback.xml create mode 100644 staffing-admin/src/main/resources/mybatis/mybatis-config.xml create mode 100644 staffing-common/pom.xml create mode 100644 staffing-common/src/main/java/com/staffing/common/annotation/Anonymous.java create mode 100644 staffing-common/src/main/java/com/staffing/common/annotation/DataScope.java create mode 100644 staffing-common/src/main/java/com/staffing/common/annotation/DataSource.java create mode 100644 staffing-common/src/main/java/com/staffing/common/annotation/Excel.java create mode 100644 staffing-common/src/main/java/com/staffing/common/annotation/Excels.java create mode 100644 staffing-common/src/main/java/com/staffing/common/annotation/Log.java create mode 100644 staffing-common/src/main/java/com/staffing/common/annotation/RateLimiter.java create mode 100644 staffing-common/src/main/java/com/staffing/common/annotation/RepeatSubmit.java create mode 100644 staffing-common/src/main/java/com/staffing/common/annotation/Sensitive.java create mode 100644 staffing-common/src/main/java/com/staffing/common/config/MinioConfig.java create mode 100644 staffing-common/src/main/java/com/staffing/common/config/StaffingConfig.java create mode 100644 staffing-common/src/main/java/com/staffing/common/config/serializer/SensitiveJsonSerializer.java create mode 100644 staffing-common/src/main/java/com/staffing/common/constant/CacheConstants.java create mode 100644 staffing-common/src/main/java/com/staffing/common/constant/Constants.java create mode 100644 staffing-common/src/main/java/com/staffing/common/constant/GenConstants.java create mode 100644 staffing-common/src/main/java/com/staffing/common/constant/HttpStatus.java create mode 100644 staffing-common/src/main/java/com/staffing/common/constant/ScheduleConstants.java create mode 100644 staffing-common/src/main/java/com/staffing/common/constant/UserConstants.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/controller/BaseController.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/domain/AjaxResult.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/domain/BaseEntity.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/domain/R.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/domain/TreeEntity.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/domain/TreeSelect.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/domain/WxLogin.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/domain/WxPhone.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/domain/WxToken.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysDept.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysDictData.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysDictType.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysMenu.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysRole.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysUser.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/domain/model/LoginBody.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/domain/model/LoginUser.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/domain/model/RegisterBody.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/page/PageDomain.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/page/TableDataInfo.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/page/TableSupport.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/redis/RedisCache.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/text/CharsetKit.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/text/Convert.java create mode 100644 staffing-common/src/main/java/com/staffing/common/core/text/StrFormatter.java create mode 100644 staffing-common/src/main/java/com/staffing/common/enums/BusinessStatus.java create mode 100644 staffing-common/src/main/java/com/staffing/common/enums/BusinessType.java create mode 100644 staffing-common/src/main/java/com/staffing/common/enums/DataSourceType.java create mode 100644 staffing-common/src/main/java/com/staffing/common/enums/DesensitizedType.java create mode 100644 staffing-common/src/main/java/com/staffing/common/enums/HttpMethod.java create mode 100644 staffing-common/src/main/java/com/staffing/common/enums/LimitType.java create mode 100644 staffing-common/src/main/java/com/staffing/common/enums/OperatorType.java create mode 100644 staffing-common/src/main/java/com/staffing/common/enums/UserStatus.java create mode 100644 staffing-common/src/main/java/com/staffing/common/exception/DemoModeException.java create mode 100644 staffing-common/src/main/java/com/staffing/common/exception/GlobalException.java create mode 100644 staffing-common/src/main/java/com/staffing/common/exception/ServiceException.java create mode 100644 staffing-common/src/main/java/com/staffing/common/exception/UtilException.java create mode 100644 staffing-common/src/main/java/com/staffing/common/exception/base/BaseException.java create mode 100644 staffing-common/src/main/java/com/staffing/common/exception/file/FileException.java create mode 100644 staffing-common/src/main/java/com/staffing/common/exception/file/FileNameLengthLimitExceededException.java create mode 100644 staffing-common/src/main/java/com/staffing/common/exception/file/FileSizeLimitExceededException.java create mode 100644 staffing-common/src/main/java/com/staffing/common/exception/file/FileUploadException.java create mode 100644 staffing-common/src/main/java/com/staffing/common/exception/file/InvalidExtensionException.java create mode 100644 staffing-common/src/main/java/com/staffing/common/exception/job/TaskException.java create mode 100644 staffing-common/src/main/java/com/staffing/common/exception/user/BlackListException.java create mode 100644 staffing-common/src/main/java/com/staffing/common/exception/user/CaptchaException.java create mode 100644 staffing-common/src/main/java/com/staffing/common/exception/user/CaptchaExpireException.java create mode 100644 staffing-common/src/main/java/com/staffing/common/exception/user/UserException.java create mode 100644 staffing-common/src/main/java/com/staffing/common/exception/user/UserNotExistsException.java create mode 100644 staffing-common/src/main/java/com/staffing/common/exception/user/UserPasswordNotMatchException.java create mode 100644 staffing-common/src/main/java/com/staffing/common/exception/user/UserPasswordRetryLimitExceedException.java create mode 100644 staffing-common/src/main/java/com/staffing/common/filter/PropertyPreExcludeFilter.java create mode 100644 staffing-common/src/main/java/com/staffing/common/filter/RepeatableFilter.java create mode 100644 staffing-common/src/main/java/com/staffing/common/filter/RepeatedlyRequestWrapper.java create mode 100644 staffing-common/src/main/java/com/staffing/common/filter/XssFilter.java create mode 100644 staffing-common/src/main/java/com/staffing/common/filter/XssHttpServletRequestWrapper.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/Arith.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/DateUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/DesensitizedUtil.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/DictUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/ExceptionUtil.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/LogUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/MessageUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/MinioUtil.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/OrderUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/PageUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/QRCodeGenerator.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/SecurityUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/ServletUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/StringUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/Threads.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/WxUtil.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/bean/BeanUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/bean/BeanValidators.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/file/FileTypeUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/file/FileUploadUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/file/FileUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/file/ImageUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/file/MimeTypeUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/html/EscapeUtil.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/html/HTMLFilter.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/http/HttpHelper.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/http/HttpUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/ip/AddressUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/ip/IpUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/poi/ExcelHandlerAdapter.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/poi/ExcelUtil.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/reflect/ReflectUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/sign/Base64.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/sign/Md5Utils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/spring/SpringUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/sql/SqlUtil.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/uuid/IdUtils.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/uuid/Seq.java create mode 100644 staffing-common/src/main/java/com/staffing/common/utils/uuid/UUID.java create mode 100644 staffing-common/src/main/java/com/staffing/common/xss/Xss.java create mode 100644 staffing-common/src/main/java/com/staffing/common/xss/XssValidator.java create mode 100644 staffing-framework/pom.xml create mode 100644 staffing-framework/src/main/java/com/staffing/framework/aspectj/DataScopeAspect.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/aspectj/DataSourceAspect.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/aspectj/LogAspect.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/aspectj/RateLimiterAspect.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/config/ApplicationConfig.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/config/CaptchaConfig.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/config/DruidConfig.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/config/FastJson2JsonRedisSerializer.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/config/FilterConfig.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/config/I18nConfig.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/config/KaptchaTextCreator.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/config/MyBatisConfig.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/config/RedisConfig.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/config/ResourcesConfig.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/config/SecurityConfig.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/config/ServerConfig.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/config/ThreadPoolConfig.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/config/properties/DruidProperties.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/config/properties/PermitAllUrlProperties.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/datasource/DynamicDataSource.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/datasource/DynamicDataSourceContextHolder.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/interceptor/RepeatSubmitInterceptor.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/interceptor/impl/SameUrlDataInterceptor.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/manager/AsyncManager.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/manager/ShutdownManager.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/manager/factory/AsyncFactory.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/security/context/AuthenticationContextHolder.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/security/context/PermissionContextHolder.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/security/filter/JwtAuthenticationTokenFilter.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/security/handle/AuthenticationEntryPointImpl.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/security/handle/LogoutSuccessHandlerImpl.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/web/domain/Server.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/web/domain/server/Cpu.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/web/domain/server/Jvm.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/web/domain/server/Mem.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/web/domain/server/Sys.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/web/domain/server/SysFile.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/web/exception/GlobalExceptionHandler.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/web/service/PermissionService.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/web/service/SysLoginService.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/web/service/SysPasswordService.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/web/service/SysPermissionService.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/web/service/SysRegisterService.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/web/service/TokenService.java create mode 100644 staffing-framework/src/main/java/com/staffing/framework/web/service/UserDetailsServiceImpl.java create mode 100644 staffing-generator/pom.xml create mode 100644 staffing-generator/src/main/java/com/staffing/generator/config/GenConfig.java create mode 100644 staffing-generator/src/main/java/com/staffing/generator/controller/GenController.java create mode 100644 staffing-generator/src/main/java/com/staffing/generator/domain/GenTable.java create mode 100644 staffing-generator/src/main/java/com/staffing/generator/domain/GenTableColumn.java create mode 100644 staffing-generator/src/main/java/com/staffing/generator/mapper/GenTableColumnMapper.java create mode 100644 staffing-generator/src/main/java/com/staffing/generator/mapper/GenTableMapper.java create mode 100644 staffing-generator/src/main/java/com/staffing/generator/service/GenTableColumnServiceImpl.java create mode 100644 staffing-generator/src/main/java/com/staffing/generator/service/GenTableServiceImpl.java create mode 100644 staffing-generator/src/main/java/com/staffing/generator/service/IGenTableColumnService.java create mode 100644 staffing-generator/src/main/java/com/staffing/generator/service/IGenTableService.java create mode 100644 staffing-generator/src/main/java/com/staffing/generator/util/GenUtils.java create mode 100644 staffing-generator/src/main/java/com/staffing/generator/util/VelocityInitializer.java create mode 100644 staffing-generator/src/main/java/com/staffing/generator/util/VelocityUtils.java create mode 100644 staffing-generator/src/main/resources/generator.yml create mode 100644 staffing-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml create mode 100644 staffing-generator/src/main/resources/mapper/generator/GenTableMapper.xml create mode 100644 staffing-generator/src/main/resources/vm/java/controller.java.vm create mode 100644 staffing-generator/src/main/resources/vm/java/domain.java.vm create mode 100644 staffing-generator/src/main/resources/vm/java/mapper.java.vm create mode 100644 staffing-generator/src/main/resources/vm/java/service.java.vm create mode 100644 staffing-generator/src/main/resources/vm/java/serviceImpl.java.vm create mode 100644 staffing-generator/src/main/resources/vm/java/sub-domain.java.vm create mode 100644 staffing-generator/src/main/resources/vm/js/api.js.vm create mode 100644 staffing-generator/src/main/resources/vm/sql/sql.vm create mode 100644 staffing-generator/src/main/resources/vm/vue/index-tree.vue.vm create mode 100644 staffing-generator/src/main/resources/vm/vue/index.vue.vm create mode 100644 staffing-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm create mode 100644 staffing-generator/src/main/resources/vm/vue/v3/index.vue.vm create mode 100644 staffing-generator/src/main/resources/vm/xml/mapper.xml.vm create mode 100644 staffing-quartz/pom.xml create mode 100644 staffing-quartz/src/main/java/com/staffing/quartz/config/ScheduleConfig.java create mode 100644 staffing-quartz/src/main/java/com/staffing/quartz/controller/SysJobController.java create mode 100644 staffing-quartz/src/main/java/com/staffing/quartz/controller/SysJobLogController.java create mode 100644 staffing-quartz/src/main/java/com/staffing/quartz/domain/SysJob.java create mode 100644 staffing-quartz/src/main/java/com/staffing/quartz/domain/SysJobLog.java create mode 100644 staffing-quartz/src/main/java/com/staffing/quartz/mapper/SysJobLogMapper.java create mode 100644 staffing-quartz/src/main/java/com/staffing/quartz/mapper/SysJobMapper.java create mode 100644 staffing-quartz/src/main/java/com/staffing/quartz/service/ISysJobLogService.java create mode 100644 staffing-quartz/src/main/java/com/staffing/quartz/service/ISysJobService.java create mode 100644 staffing-quartz/src/main/java/com/staffing/quartz/service/impl/SysJobLogServiceImpl.java create mode 100644 staffing-quartz/src/main/java/com/staffing/quartz/service/impl/SysJobServiceImpl.java create mode 100644 staffing-quartz/src/main/java/com/staffing/quartz/task/RyTask.java create mode 100644 staffing-quartz/src/main/java/com/staffing/quartz/util/AbstractQuartzJob.java create mode 100644 staffing-quartz/src/main/java/com/staffing/quartz/util/CronUtils.java create mode 100644 staffing-quartz/src/main/java/com/staffing/quartz/util/JobInvokeUtil.java create mode 100644 staffing-quartz/src/main/java/com/staffing/quartz/util/QuartzDisallowConcurrentExecution.java create mode 100644 staffing-quartz/src/main/java/com/staffing/quartz/util/QuartzJobExecution.java create mode 100644 staffing-quartz/src/main/java/com/staffing/quartz/util/ScheduleUtils.java create mode 100644 staffing-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml create mode 100644 staffing-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml create mode 100644 staffing-system/pom.xml create mode 100644 staffing-system/src/main/java/com/staffing/custom/domain/StEmployee.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/domain/StEmployeeFundRecord.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/domain/StTask.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/domain/StTaskSign.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/domain/StTransferRecord.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/mapper/StEmployeeFundRecordMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/mapper/StEmployeeMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/mapper/StTaskMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/mapper/StTaskSignMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/mapper/StTransferRecordMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/param/FxParam.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/service/IStEmployeeFundRecordService.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/service/IStEmployeeService.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/service/IStTaskService.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/service/IStTaskSignService.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/service/IStTransferRecordService.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/service/TransferBatchService.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/service/impl/StEmployeeFundRecordServiceImpl.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/service/impl/StEmployeeServiceImpl.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/service/impl/StTaskServiceImpl.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/service/impl/StTaskSignServiceImpl.java create mode 100644 staffing-system/src/main/java/com/staffing/custom/service/impl/StTransferRecordServiceImpl.java create mode 100644 staffing-system/src/main/java/com/staffing/system/domain/SysCache.java create mode 100644 staffing-system/src/main/java/com/staffing/system/domain/SysConfig.java create mode 100644 staffing-system/src/main/java/com/staffing/system/domain/SysLogininfor.java create mode 100644 staffing-system/src/main/java/com/staffing/system/domain/SysNotice.java create mode 100644 staffing-system/src/main/java/com/staffing/system/domain/SysOperLog.java create mode 100644 staffing-system/src/main/java/com/staffing/system/domain/SysPost.java create mode 100644 staffing-system/src/main/java/com/staffing/system/domain/SysRoleDept.java create mode 100644 staffing-system/src/main/java/com/staffing/system/domain/SysRoleMenu.java create mode 100644 staffing-system/src/main/java/com/staffing/system/domain/SysUserOnline.java create mode 100644 staffing-system/src/main/java/com/staffing/system/domain/SysUserPost.java create mode 100644 staffing-system/src/main/java/com/staffing/system/domain/SysUserRole.java create mode 100644 staffing-system/src/main/java/com/staffing/system/domain/vo/MetaVo.java create mode 100644 staffing-system/src/main/java/com/staffing/system/domain/vo/RouterVo.java create mode 100644 staffing-system/src/main/java/com/staffing/system/mapper/SysConfigMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/system/mapper/SysDeptMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/system/mapper/SysDictDataMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/system/mapper/SysDictTypeMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/system/mapper/SysLogininforMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/system/mapper/SysMenuMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/system/mapper/SysNoticeMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/system/mapper/SysOperLogMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/system/mapper/SysPostMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/system/mapper/SysRoleDeptMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/system/mapper/SysRoleMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/system/mapper/SysRoleMenuMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/system/mapper/SysUserMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/system/mapper/SysUserPostMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/system/mapper/SysUserRoleMapper.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/ISysConfigService.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/ISysDeptService.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/ISysDictDataService.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/ISysDictTypeService.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/ISysLogininforService.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/ISysMenuService.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/ISysNoticeService.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/ISysOperLogService.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/ISysPostService.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/ISysRoleService.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/ISysUserOnlineService.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/ISysUserService.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/impl/SysConfigServiceImpl.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/impl/SysDeptServiceImpl.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/impl/SysDictDataServiceImpl.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/impl/SysDictTypeServiceImpl.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/impl/SysLogininforServiceImpl.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/impl/SysMenuServiceImpl.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/impl/SysNoticeServiceImpl.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/impl/SysOperLogServiceImpl.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/impl/SysPostServiceImpl.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/impl/SysRoleServiceImpl.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/impl/SysUserOnlineServiceImpl.java create mode 100644 staffing-system/src/main/java/com/staffing/system/service/impl/SysUserServiceImpl.java create mode 100644 staffing-system/src/main/resources/apiclient_key.pem create mode 100644 staffing-system/src/main/resources/mapper/custom/StEmployeeFundRecordMapper.xml create mode 100644 staffing-system/src/main/resources/mapper/custom/StEmployeeMapper.xml create mode 100644 staffing-system/src/main/resources/mapper/custom/StTaskMapper.xml create mode 100644 staffing-system/src/main/resources/mapper/custom/StTaskSignMapper.xml create mode 100644 staffing-system/src/main/resources/mapper/custom/StTransferRecordMapper.xml create mode 100644 staffing-system/src/main/resources/mapper/system/SysConfigMapper.xml create mode 100644 staffing-system/src/main/resources/mapper/system/SysDeptMapper.xml create mode 100644 staffing-system/src/main/resources/mapper/system/SysDictDataMapper.xml create mode 100644 staffing-system/src/main/resources/mapper/system/SysDictTypeMapper.xml create mode 100644 staffing-system/src/main/resources/mapper/system/SysLogininforMapper.xml create mode 100644 staffing-system/src/main/resources/mapper/system/SysMenuMapper.xml create mode 100644 staffing-system/src/main/resources/mapper/system/SysNoticeMapper.xml create mode 100644 staffing-system/src/main/resources/mapper/system/SysOperLogMapper.xml create mode 100644 staffing-system/src/main/resources/mapper/system/SysPostMapper.xml create mode 100644 staffing-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml create mode 100644 staffing-system/src/main/resources/mapper/system/SysRoleMapper.xml create mode 100644 staffing-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml create mode 100644 staffing-system/src/main/resources/mapper/system/SysUserMapper.xml create mode 100644 staffing-system/src/main/resources/mapper/system/SysUserPostMapper.xml create mode 100644 staffing-system/src/main/resources/mapper/system/SysUserRoleMapper.xml create mode 100644 staffing-ui/.editorconfig create mode 100644 staffing-ui/.env.development create mode 100644 staffing-ui/.env.production create mode 100644 staffing-ui/.env.staging create mode 100644 staffing-ui/.eslintignore create mode 100644 staffing-ui/.eslintrc.js create mode 100644 staffing-ui/.gitignore create mode 100644 staffing-ui/README.md create mode 100644 staffing-ui/babel.config.js create mode 100644 staffing-ui/bin/build.bat create mode 100644 staffing-ui/bin/package.bat create mode 100644 staffing-ui/bin/run-web.bat create mode 100644 staffing-ui/build/index.js create mode 100644 staffing-ui/package.json create mode 100644 staffing-ui/public/favicon.ico create mode 100644 staffing-ui/public/html/ie.html create mode 100644 staffing-ui/public/index.html create mode 100644 staffing-ui/public/robots.txt create mode 100644 staffing-ui/src/App.vue create mode 100644 staffing-ui/src/api/employee/employee.js create mode 100644 staffing-ui/src/api/fund/fund.js create mode 100644 staffing-ui/src/api/login.js create mode 100644 staffing-ui/src/api/menu.js create mode 100644 staffing-ui/src/api/monitor/cache.js create mode 100644 staffing-ui/src/api/monitor/job.js create mode 100644 staffing-ui/src/api/monitor/jobLog.js create mode 100644 staffing-ui/src/api/monitor/logininfor.js create mode 100644 staffing-ui/src/api/monitor/online.js create mode 100644 staffing-ui/src/api/monitor/operlog.js create mode 100644 staffing-ui/src/api/monitor/server.js create mode 100644 staffing-ui/src/api/system/config.js create mode 100644 staffing-ui/src/api/system/dept.js create mode 100644 staffing-ui/src/api/system/dict/data.js create mode 100644 staffing-ui/src/api/system/dict/type.js create mode 100644 staffing-ui/src/api/system/menu.js create mode 100644 staffing-ui/src/api/system/notice.js create mode 100644 staffing-ui/src/api/system/post.js create mode 100644 staffing-ui/src/api/system/role.js create mode 100644 staffing-ui/src/api/system/user.js create mode 100644 staffing-ui/src/api/task/task.js create mode 100644 staffing-ui/src/api/taskSign/sign.js create mode 100644 staffing-ui/src/api/tool/gen.js create mode 100644 staffing-ui/src/assets/401_images/401.gif create mode 100644 staffing-ui/src/assets/404_images/404.png create mode 100644 staffing-ui/src/assets/404_images/404_cloud.png create mode 100644 staffing-ui/src/assets/icons/index.js create mode 100644 staffing-ui/src/assets/icons/svg/404.svg create mode 100644 staffing-ui/src/assets/icons/svg/bug.svg create mode 100644 staffing-ui/src/assets/icons/svg/build.svg create mode 100644 staffing-ui/src/assets/icons/svg/button.svg create mode 100644 staffing-ui/src/assets/icons/svg/cascader.svg create mode 100644 staffing-ui/src/assets/icons/svg/chart.svg create mode 100644 staffing-ui/src/assets/icons/svg/checkbox.svg create mode 100644 staffing-ui/src/assets/icons/svg/clipboard.svg create mode 100644 staffing-ui/src/assets/icons/svg/code.svg create mode 100644 staffing-ui/src/assets/icons/svg/color.svg create mode 100644 staffing-ui/src/assets/icons/svg/component.svg create mode 100644 staffing-ui/src/assets/icons/svg/dashboard.svg create mode 100644 staffing-ui/src/assets/icons/svg/date-range.svg create mode 100644 staffing-ui/src/assets/icons/svg/date.svg create mode 100644 staffing-ui/src/assets/icons/svg/dict.svg create mode 100644 staffing-ui/src/assets/icons/svg/documentation.svg create mode 100644 staffing-ui/src/assets/icons/svg/download.svg create mode 100644 staffing-ui/src/assets/icons/svg/drag.svg create mode 100644 staffing-ui/src/assets/icons/svg/druid.svg create mode 100644 staffing-ui/src/assets/icons/svg/edit.svg create mode 100644 staffing-ui/src/assets/icons/svg/education.svg create mode 100644 staffing-ui/src/assets/icons/svg/email.svg create mode 100644 staffing-ui/src/assets/icons/svg/example.svg create mode 100644 staffing-ui/src/assets/icons/svg/excel.svg create mode 100644 staffing-ui/src/assets/icons/svg/exit-fullscreen.svg create mode 100644 staffing-ui/src/assets/icons/svg/eye-open.svg create mode 100644 staffing-ui/src/assets/icons/svg/eye.svg create mode 100644 staffing-ui/src/assets/icons/svg/form.svg create mode 100644 staffing-ui/src/assets/icons/svg/fullscreen.svg create mode 100644 staffing-ui/src/assets/icons/svg/github.svg create mode 100644 staffing-ui/src/assets/icons/svg/guide.svg create mode 100644 staffing-ui/src/assets/icons/svg/icon.svg create mode 100644 staffing-ui/src/assets/icons/svg/input.svg create mode 100644 staffing-ui/src/assets/icons/svg/international.svg create mode 100644 staffing-ui/src/assets/icons/svg/job.svg create mode 100644 staffing-ui/src/assets/icons/svg/language.svg create mode 100644 staffing-ui/src/assets/icons/svg/link.svg create mode 100644 staffing-ui/src/assets/icons/svg/list.svg create mode 100644 staffing-ui/src/assets/icons/svg/lock.svg create mode 100644 staffing-ui/src/assets/icons/svg/log.svg create mode 100644 staffing-ui/src/assets/icons/svg/logininfor.svg create mode 100644 staffing-ui/src/assets/icons/svg/message.svg create mode 100644 staffing-ui/src/assets/icons/svg/money.svg create mode 100644 staffing-ui/src/assets/icons/svg/monitor.svg create mode 100644 staffing-ui/src/assets/icons/svg/nested.svg create mode 100644 staffing-ui/src/assets/icons/svg/number.svg create mode 100644 staffing-ui/src/assets/icons/svg/online.svg create mode 100644 staffing-ui/src/assets/icons/svg/password.svg create mode 100644 staffing-ui/src/assets/icons/svg/pdf.svg create mode 100644 staffing-ui/src/assets/icons/svg/people.svg create mode 100644 staffing-ui/src/assets/icons/svg/peoples.svg create mode 100644 staffing-ui/src/assets/icons/svg/phone.svg create mode 100644 staffing-ui/src/assets/icons/svg/post.svg create mode 100644 staffing-ui/src/assets/icons/svg/qq.svg create mode 100644 staffing-ui/src/assets/icons/svg/question.svg create mode 100644 staffing-ui/src/assets/icons/svg/radio.svg create mode 100644 staffing-ui/src/assets/icons/svg/rate.svg create mode 100644 staffing-ui/src/assets/icons/svg/redis-list.svg create mode 100644 staffing-ui/src/assets/icons/svg/redis.svg create mode 100644 staffing-ui/src/assets/icons/svg/row.svg create mode 100644 staffing-ui/src/assets/icons/svg/search.svg create mode 100644 staffing-ui/src/assets/icons/svg/select.svg create mode 100644 staffing-ui/src/assets/icons/svg/server.svg create mode 100644 staffing-ui/src/assets/icons/svg/shopping.svg create mode 100644 staffing-ui/src/assets/icons/svg/size.svg create mode 100644 staffing-ui/src/assets/icons/svg/skill.svg create mode 100644 staffing-ui/src/assets/icons/svg/slider.svg create mode 100644 staffing-ui/src/assets/icons/svg/star.svg create mode 100644 staffing-ui/src/assets/icons/svg/swagger.svg create mode 100644 staffing-ui/src/assets/icons/svg/switch.svg create mode 100644 staffing-ui/src/assets/icons/svg/system.svg create mode 100644 staffing-ui/src/assets/icons/svg/tab.svg create mode 100644 staffing-ui/src/assets/icons/svg/table.svg create mode 100644 staffing-ui/src/assets/icons/svg/textarea.svg create mode 100644 staffing-ui/src/assets/icons/svg/theme.svg create mode 100644 staffing-ui/src/assets/icons/svg/time-range.svg create mode 100644 staffing-ui/src/assets/icons/svg/time.svg create mode 100644 staffing-ui/src/assets/icons/svg/tool.svg create mode 100644 staffing-ui/src/assets/icons/svg/tree-table.svg create mode 100644 staffing-ui/src/assets/icons/svg/tree.svg create mode 100644 staffing-ui/src/assets/icons/svg/upload.svg create mode 100644 staffing-ui/src/assets/icons/svg/user.svg create mode 100644 staffing-ui/src/assets/icons/svg/validCode.svg create mode 100644 staffing-ui/src/assets/icons/svg/wechat.svg create mode 100644 staffing-ui/src/assets/icons/svg/zip.svg create mode 100644 staffing-ui/src/assets/icons/svgo.yml create mode 100644 staffing-ui/src/assets/images/bg.jpg create mode 100644 staffing-ui/src/assets/images/dark.svg create mode 100644 staffing-ui/src/assets/images/light.svg create mode 100644 staffing-ui/src/assets/images/login-background.jpg create mode 100644 staffing-ui/src/assets/images/pay.png create mode 100644 staffing-ui/src/assets/images/profile.jpg create mode 100644 staffing-ui/src/assets/logo/logo.png create mode 100644 staffing-ui/src/assets/styles/btn.scss create mode 100644 staffing-ui/src/assets/styles/element-ui.scss create mode 100644 staffing-ui/src/assets/styles/element-variables.scss create mode 100644 staffing-ui/src/assets/styles/index.scss create mode 100644 staffing-ui/src/assets/styles/mixin.scss create mode 100644 staffing-ui/src/assets/styles/sidebar.scss create mode 100644 staffing-ui/src/assets/styles/staffing.scss create mode 100644 staffing-ui/src/assets/styles/transition.scss create mode 100644 staffing-ui/src/assets/styles/variables.scss create mode 100644 staffing-ui/src/components/Breadcrumb/index.vue create mode 100644 staffing-ui/src/components/Crontab/day.vue create mode 100644 staffing-ui/src/components/Crontab/hour.vue create mode 100644 staffing-ui/src/components/Crontab/index.vue create mode 100644 staffing-ui/src/components/Crontab/min.vue create mode 100644 staffing-ui/src/components/Crontab/month.vue create mode 100644 staffing-ui/src/components/Crontab/result.vue create mode 100644 staffing-ui/src/components/Crontab/second.vue create mode 100644 staffing-ui/src/components/Crontab/week.vue create mode 100644 staffing-ui/src/components/Crontab/year.vue create mode 100644 staffing-ui/src/components/DictData/index.js create mode 100644 staffing-ui/src/components/DictTag/index.vue create mode 100644 staffing-ui/src/components/Editor/index.vue create mode 100644 staffing-ui/src/components/FileUpload/index.vue create mode 100644 staffing-ui/src/components/Hamburger/index.vue create mode 100644 staffing-ui/src/components/HeaderSearch/index.vue create mode 100644 staffing-ui/src/components/IconSelect/index.vue create mode 100644 staffing-ui/src/components/IconSelect/requireIcons.js create mode 100644 staffing-ui/src/components/ImagePreview/index.vue create mode 100644 staffing-ui/src/components/ImageUpload/index.vue create mode 100644 staffing-ui/src/components/Pagination/index.vue create mode 100644 staffing-ui/src/components/PanThumb/index.vue create mode 100644 staffing-ui/src/components/ParentView/index.vue create mode 100644 staffing-ui/src/components/RightPanel/index.vue create mode 100644 staffing-ui/src/components/RightToolbar/index.vue create mode 100644 staffing-ui/src/components/Screenfull/index.vue create mode 100644 staffing-ui/src/components/SizeSelect/index.vue create mode 100644 staffing-ui/src/components/SvgIcon/index.vue create mode 100644 staffing-ui/src/components/ThemePicker/index.vue create mode 100644 staffing-ui/src/components/TopNav/index.vue create mode 100644 staffing-ui/src/components/iFrame/index.vue create mode 100644 staffing-ui/src/components/staffing/Doc/index.vue create mode 100644 staffing-ui/src/components/staffing/Git/index.vue create mode 100644 staffing-ui/src/directive/dialog/drag.js create mode 100644 staffing-ui/src/directive/dialog/dragHeight.js create mode 100644 staffing-ui/src/directive/dialog/dragWidth.js create mode 100644 staffing-ui/src/directive/index.js create mode 100644 staffing-ui/src/directive/module/clipboard.js create mode 100644 staffing-ui/src/directive/permission/hasPermi.js create mode 100644 staffing-ui/src/directive/permission/hasRole.js create mode 100644 staffing-ui/src/layout/components/AppMain.vue create mode 100644 staffing-ui/src/layout/components/IframeToggle/index.vue create mode 100644 staffing-ui/src/layout/components/InnerLink/index.vue create mode 100644 staffing-ui/src/layout/components/Navbar.vue create mode 100644 staffing-ui/src/layout/components/Settings/index.vue create mode 100644 staffing-ui/src/layout/components/Sidebar/FixiOSBug.js create mode 100644 staffing-ui/src/layout/components/Sidebar/Item.vue create mode 100644 staffing-ui/src/layout/components/Sidebar/Link.vue create mode 100644 staffing-ui/src/layout/components/Sidebar/Logo.vue create mode 100644 staffing-ui/src/layout/components/Sidebar/SidebarItem.vue create mode 100644 staffing-ui/src/layout/components/Sidebar/index.vue create mode 100644 staffing-ui/src/layout/components/TagsView/ScrollPane.vue create mode 100644 staffing-ui/src/layout/components/TagsView/index.vue create mode 100644 staffing-ui/src/layout/components/index.js create mode 100644 staffing-ui/src/layout/index.vue create mode 100644 staffing-ui/src/layout/mixin/ResizeHandler.js create mode 100644 staffing-ui/src/main.js create mode 100644 staffing-ui/src/permission.js create mode 100644 staffing-ui/src/plugins/auth.js create mode 100644 staffing-ui/src/plugins/cache.js create mode 100644 staffing-ui/src/plugins/download.js create mode 100644 staffing-ui/src/plugins/index.js create mode 100644 staffing-ui/src/plugins/modal.js create mode 100644 staffing-ui/src/plugins/tab.js create mode 100644 staffing-ui/src/router/index.js create mode 100644 staffing-ui/src/settings.js create mode 100644 staffing-ui/src/store/getters.js create mode 100644 staffing-ui/src/store/index.js create mode 100644 staffing-ui/src/store/modules/app.js create mode 100644 staffing-ui/src/store/modules/dict.js create mode 100644 staffing-ui/src/store/modules/permission.js create mode 100644 staffing-ui/src/store/modules/settings.js create mode 100644 staffing-ui/src/store/modules/tagsView.js create mode 100644 staffing-ui/src/store/modules/user.js create mode 100644 staffing-ui/src/utils/auth.js create mode 100644 staffing-ui/src/utils/dict/Dict.js create mode 100644 staffing-ui/src/utils/dict/DictConverter.js create mode 100644 staffing-ui/src/utils/dict/DictData.js create mode 100644 staffing-ui/src/utils/dict/DictMeta.js create mode 100644 staffing-ui/src/utils/dict/DictOptions.js create mode 100644 staffing-ui/src/utils/dict/index.js create mode 100644 staffing-ui/src/utils/errorCode.js create mode 100644 staffing-ui/src/utils/generator/config.js create mode 100644 staffing-ui/src/utils/generator/css.js create mode 100644 staffing-ui/src/utils/generator/drawingDefault.js create mode 100644 staffing-ui/src/utils/generator/html.js create mode 100644 staffing-ui/src/utils/generator/icon.json create mode 100644 staffing-ui/src/utils/generator/js.js create mode 100644 staffing-ui/src/utils/generator/render.js create mode 100644 staffing-ui/src/utils/index.js create mode 100644 staffing-ui/src/utils/jsencrypt.js create mode 100644 staffing-ui/src/utils/permission.js create mode 100644 staffing-ui/src/utils/request.js create mode 100644 staffing-ui/src/utils/scroll-to.js create mode 100644 staffing-ui/src/utils/staffing.js create mode 100644 staffing-ui/src/utils/validate.js create mode 100644 staffing-ui/src/views/dashboard/BarChart.vue create mode 100644 staffing-ui/src/views/dashboard/LineChart.vue create mode 100644 staffing-ui/src/views/dashboard/PanelGroup.vue create mode 100644 staffing-ui/src/views/dashboard/PieChart.vue create mode 100644 staffing-ui/src/views/dashboard/RaddarChart.vue create mode 100644 staffing-ui/src/views/dashboard/mixins/resize.js create mode 100644 staffing-ui/src/views/employee/employee/index.vue create mode 100644 staffing-ui/src/views/error/401.vue create mode 100644 staffing-ui/src/views/error/404.vue create mode 100644 staffing-ui/src/views/fund/fund/index.vue create mode 100644 staffing-ui/src/views/index.vue create mode 100644 staffing-ui/src/views/index_v1.vue create mode 100644 staffing-ui/src/views/login.vue create mode 100644 staffing-ui/src/views/monitor/cache/index.vue create mode 100644 staffing-ui/src/views/monitor/cache/list.vue create mode 100644 staffing-ui/src/views/monitor/druid/index.vue create mode 100644 staffing-ui/src/views/monitor/job/index.vue create mode 100644 staffing-ui/src/views/monitor/job/log.vue create mode 100644 staffing-ui/src/views/monitor/logininfor/index.vue create mode 100644 staffing-ui/src/views/monitor/online/index.vue create mode 100644 staffing-ui/src/views/monitor/operlog/index.vue create mode 100644 staffing-ui/src/views/monitor/server/index.vue create mode 100644 staffing-ui/src/views/redirect.vue create mode 100644 staffing-ui/src/views/register.vue create mode 100644 staffing-ui/src/views/system/config/index.vue create mode 100644 staffing-ui/src/views/system/dept/index.vue create mode 100644 staffing-ui/src/views/system/dict/data.vue create mode 100644 staffing-ui/src/views/system/dict/index.vue create mode 100644 staffing-ui/src/views/system/menu/index.vue create mode 100644 staffing-ui/src/views/system/notice/index.vue create mode 100644 staffing-ui/src/views/system/post/index.vue create mode 100644 staffing-ui/src/views/system/role/authUser.vue create mode 100644 staffing-ui/src/views/system/role/index.vue create mode 100644 staffing-ui/src/views/system/role/selectUser.vue create mode 100644 staffing-ui/src/views/system/user/authRole.vue create mode 100644 staffing-ui/src/views/system/user/index.vue create mode 100644 staffing-ui/src/views/system/user/profile/index.vue create mode 100644 staffing-ui/src/views/system/user/profile/resetPwd.vue create mode 100644 staffing-ui/src/views/system/user/profile/userAvatar.vue create mode 100644 staffing-ui/src/views/system/user/profile/userInfo.vue create mode 100644 staffing-ui/src/views/task/task/index.vue create mode 100644 staffing-ui/src/views/taskSign/sign/index.vue create mode 100644 staffing-ui/src/views/tool/build/CodeTypeDialog.vue create mode 100644 staffing-ui/src/views/tool/build/DraggableItem.vue create mode 100644 staffing-ui/src/views/tool/build/IconsDialog.vue create mode 100644 staffing-ui/src/views/tool/build/RightPanel.vue create mode 100644 staffing-ui/src/views/tool/build/TreeNodeDialog.vue create mode 100644 staffing-ui/src/views/tool/build/index.vue create mode 100644 staffing-ui/src/views/tool/gen/basicInfoForm.vue create mode 100644 staffing-ui/src/views/tool/gen/createTable.vue create mode 100644 staffing-ui/src/views/tool/gen/editTable.vue create mode 100644 staffing-ui/src/views/tool/gen/genInfoForm.vue create mode 100644 staffing-ui/src/views/tool/gen/importTable.vue create mode 100644 staffing-ui/src/views/tool/gen/index.vue create mode 100644 staffing-ui/src/views/tool/swagger/index.vue create mode 100644 staffing-ui/vue.config.js create mode 100644 wx-pay/pom.xml create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/AbstractRSAConfig.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/AbstractRSAConfigBuilder.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/Config.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/RSAAutoCertificateConfig.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/RSAConfig.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/RSAPublicKeyConfig.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/auth/Credential.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/auth/Validator.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/auth/WechatPay2Credential.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/auth/WechatPay2Validator.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/certificate/AutoCertificateService.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/certificate/CertificateDownloader.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/certificate/CertificateHandler.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/certificate/CertificateProvider.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/certificate/InMemoryCertificateProvider.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/certificate/RSAAutoCertificateProvider.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/certificate/RSACertificateHandler.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/certificate/model/Data.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/certificate/model/DownloadCertificateResponse.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/certificate/model/EncryptCertificate.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractAeadCipher.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractPrivacyDecryptor.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractPrivacyEncryptor.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractSigner.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractVerifier.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AeadAesCipher.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AeadCipher.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/Constant.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/Encryption.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/PrivacyDecryptor.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/PrivacyEncryptor.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAPkcs1v15Decryptor.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAPkcs1v15Encryptor.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAPrivacyDecryptor.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAPrivacyEncryptor.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSASigner.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAVerifier.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/SignatureResult.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/Signer.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/cipher/Verifier.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/exception/DecryptionException.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/exception/HttpException.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/exception/MalformedMessageException.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/exception/ServiceException.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/exception/ValidationException.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/exception/WechatPayException.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/AbstractHttpClient.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/AbstractHttpClientBuilder.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/Constant.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/DefaultHttpClientBuilder.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/FileRequestBody.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/HostName.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpClient.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpHeaders.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpMethod.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpRequest.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpResponse.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/JsonRequestBody.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/JsonResponseBody.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/MediaType.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/OriginalResponse.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/QueryParameter.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/RequestBody.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/ResponseBody.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/UrlEncoder.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/okhttp/OkHttpClientAdapter.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/http/okhttp/OkHttpMultiDomainInterceptor.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/notification/AbstractNotificationConfig.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/notification/AutoCertificateNotificationConfig.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/notification/Constant.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/notification/Notification.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/notification/NotificationConfig.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/notification/NotificationParser.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/notification/RSACombinedNotificationConfig.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/notification/RSANotificationConfig.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/notification/RSAPublicKeyNotificationConfig.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/notification/RequestParam.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/notification/Resource.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/util/GsonUtil.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/util/IOUtil.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/util/NonceUtil.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/util/PemUtil.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/util/ShaUtil.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/core/util/StringUtil.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/TransferBatchServiceBase.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/CloseReasonType.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/FailReasonType.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/GetTransferBatchByNoRequest.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/GetTransferBatchByOutNoRequest.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/GetTransferDetailByNoRequest.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/GetTransferDetailByOutNoRequest.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/InitiateBatchTransferRequest.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/InitiateBatchTransferResponse.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferBatchEntity.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferBatchGet.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferDetailCompact.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferDetailEntity.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferDetailInput.java create mode 100644 wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/package-info.java create mode 100644 wx-pay/src/main/resources/apiclient_key.pem diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ed8368a --- /dev/null +++ b/.gitignore @@ -0,0 +1,47 @@ +###################################################################### +# 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 + +### JRebel ### +rebel.xml + +### NetBeans ### +nbproject/private/ +build/* +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +###################################################################### +# Others +*.log +*.xml.versionsBackup +*.swp + +!*/build/*.java +!*/build/*.html +!*/build/*.xml diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0bd3198 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2018 staffing + +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/bin/clean.bat b/bin/clean.bat new file mode 100644 index 0000000..24c0974 --- /dev/null +++ b/bin/clean.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] target· +echo. + +%~d0 +cd %~dp0 + +cd .. +call mvn clean + +pause \ No newline at end of file diff --git a/bin/package.bat b/bin/package.bat new file mode 100644 index 0000000..c693ec0 --- /dev/null +++ b/bin/package.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] Weḅ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/bin/run.bat b/bin/run.bat new file mode 100644 index 0000000..41efbd0 --- /dev/null +++ b/bin/run.bat @@ -0,0 +1,14 @@ +@echo off +echo. +echo [Ϣ] ʹJarWeb̡ +echo. + +cd %~dp0 +cd ../ruoyi-admin/target + +set JAVA_OPTS=-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m + +java -jar %JAVA_OPTS% ruoyi-admin.jar + +cd bin +pause \ No newline at end of file diff --git a/doc/若依环境使用手册.docx b/doc/若依环境使用手册.docx new file mode 100644 index 0000000000000000000000000000000000000000..9e4daef4d9be2e445419109a02eaf321cd4d537e GIT binary patch literal 428430 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 +HtCx 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 Rli)_iWGz7fMupr%QDEgRC> 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%0DfC-!Au^tv1-R|XemvERC8O1`5!u;Z5%iD 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

K#u)l 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

)q;tSdIrAwYxlSM|Hl};Y` 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 literal 0 HcmV?d00001 diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..ed7f340 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "staffing", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..fb9f19a --- /dev/null +++ b/pom.xml @@ -0,0 +1,239 @@ + + + 4.0.0 + + com.staffing + staffing + 3.8.8 + + staffing + http://www.staffing.vip + 管理系统 + + + 3.8.8 + UTF-8 + UTF-8 + 1.8 + 3.1.1 + 5.3.33 + 5.7.12 + 1.2.23 + 1.21 + 3.0.0 + 2.3.3 + 1.4.7 + 2.0.43 + 6.6.1 + 2.13.0 + 4.1.2 + 2.3 + 0.9.1 + + + + + + + + + org.springframework + spring-framework-bom + ${spring-framework.version} + pom + import + + + + + org.springframework.security + spring-security-bom + ${spring-security.version} + pom + import + + + + + org.springframework.boot + spring-boot-dependencies + 2.5.15 + pom + import + + + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + + + eu.bitwalker + UserAgentUtils + ${bitwalker.version} + + + + + com.github.pagehelper + pagehelper-spring-boot-starter + ${pagehelper.boot.version} + + + + + com.github.oshi + oshi-core + ${oshi.version} + + + + + io.springfox + springfox-boot-starter + ${swagger.version} + + + io.swagger + swagger-models + + + + + + + commons-io + commons-io + ${commons.io.version} + + + + + org.apache.poi + poi-ooxml + ${poi.version} + + + + + org.apache.velocity + velocity-engine-core + ${velocity.version} + + + + + com.alibaba.fastjson2 + fastjson2 + ${fastjson.version} + + + + + io.jsonwebtoken + jjwt + ${jwt.version} + + + + + pro.fessional + kaptcha + ${kaptcha.version} + + + + + com.staffing + staffing-quartz + ${staffing.version} + + + + + com.staffing + staffing-generator + ${staffing.version} + + + + + com.staffing + staffing-framework + ${staffing.version} + + + + + com.staffing + staffing-system + ${staffing.version} + + + + + com.staffing + staffing-common + ${staffing.version} + + + + + + + staffing-admin + staffing-framework + staffing-system + staffing-quartz + staffing-generator + staffing-common + wx-pay + + pom + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + ${java.version} + ${java.version} + ${project.build.sourceEncoding} + + + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public + + true + + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public + + true + + + false + + + + + \ No newline at end of file diff --git a/ry.bat b/ry.bat new file mode 100644 index 0000000..ac1e437 --- /dev/null +++ b/ry.bat @@ -0,0 +1,67 @@ +@echo off + +rem jarƽĿ¼ +set AppName=ruoyi-admin.jar + +rem JVM +set JVM_OPTS="-Dname=%AppName% -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC" + + +ECHO. + ECHO. [1] %AppName% + ECHO. [2] ر%AppName% + ECHO. [3] %AppName% + ECHO. [4] ״̬ %AppName% + ECHO. [5] +ECHO. + +ECHO.ѡĿ: +set /p ID= + IF "%id%"=="1" GOTO start + IF "%id%"=="2" GOTO stop + IF "%id%"=="3" GOTO restart + IF "%id%"=="4" GOTO status + IF "%id%"=="5" EXIT +PAUSE +:start + for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do ( + set pid=%%a + set image_name=%%b + ) + if defined pid ( + echo %%is running + PAUSE + ) + +start javaw %JVM_OPTS% -jar %AppName% + +echo starting +echo Start %AppName% success... +goto:eof + +rem stopͨjpspid +:stop + for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do ( + set pid=%%a + set image_name=%%b + ) + if not defined pid (echo process %AppName% does not exists) else ( + echo prepare to kill %image_name% + echo start kill %pid% ... + rem ݽIDkill + taskkill /f /pid %pid% + ) +goto:eof +:restart + call :stop + call :start +goto:eof +:status + for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do ( + set pid=%%a + set image_name=%%b + ) + if not defined pid (echo process %AppName% is dead ) else ( + echo %image_name% is running + ) +goto:eof diff --git a/ry.sh b/ry.sh new file mode 100644 index 0000000..ecc476b --- /dev/null +++ b/ry.sh @@ -0,0 +1,86 @@ +#!/bin/sh +# ./ry.sh start 启动 stop 停止 restart 重启 status 状态 +AppName=staffing-admin.jar + +# JVM参数 +JVM_OPTS="-Dname=$AppName -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=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 $JVM_OPTS -jar $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/sql/install.sql b/sql/install.sql new file mode 100644 index 0000000..5a50f5f --- /dev/null +++ b/sql/install.sql @@ -0,0 +1,818 @@ +-- ---------------------------- +-- 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 '父部门id', + 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正常 1停用)', + del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', + 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', 'xx科技', 0, 'xx', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(101, 100, '0,100', '深圳总公司', 1, 'xx', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(102, 100, '0,100', '长沙分公司', 2, 'xx', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(103, 101, '0,100,101', '研发部门', 1, 'xx', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(104, 101, '0,100,101', '市场部门', 2, 'xx', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(105, 101, '0,100,101', '测试部门', 3, 'xx', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(106, 101, '0,100,101', '财务部门', 4, 'xx', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(107, 101, '0,100,101', '运维部门', 5, 'xx', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(108, 102, '0,100,102', '市场部门', 1, 'xx', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(109, 102, '0,100,102', '财务部门', 2, 'xx', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); + + +-- ---------------------------- +-- 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正常 1停用)', + del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', + login_ip varchar(128) default '' comment '最后登录IP', + 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', 'xx', '00', 'ry@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), 'admin', sysdate(), '', null, '管理员'); +insert into sys_user values(2, 105, 'ry', 'xx', '00', 'ry@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), 'admin', sysdate(), '', null, '测试员'); + + +-- ---------------------------- +-- 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正常 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', '董事长', 1, '0', 'admin', sysdate(), '', null, ''); +insert into sys_post values(2, 'se', '项目经理', 2, '0', 'admin', sysdate(), '', null, ''); +insert into sys_post values(3, 'hr', '人力资源', 3, '0', 'admin', sysdate(), '', null, ''); +insert into sys_post values(4, 'user', '普通员工', 4, '0', 'admin', sysdate(), '', null, ''); + + +-- ---------------------------- +-- 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:本部门及以下数据权限)', + menu_check_strictly tinyint(1) default 1 comment '菜单树选择项是否关联显示', + dept_check_strictly tinyint(1) default 1 comment '部门树选择项是否关联显示', + status char(1) not null comment '角色状态(0正常 1停用)', + del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', + 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, 1, 1, '0', '0', 'admin', sysdate(), '', null, '超级管理员'); +insert into sys_role values('2', '普通角色', 'common', 2, 2, 1, 1, '0', '0', 'admin', sysdate(), '', null, '普通角色'); + + +-- ---------------------------- +-- 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 '父菜单ID', + order_num int(4) default 0 comment '显示顺序', + path varchar(200) default '' comment '路由地址', + component varchar(255) default null comment '组件路径', + query varchar(255) default null comment '路由参数', + route_name varchar(50) default '' comment '路由名称', + is_frame int(1) default 1 comment '是否为外链(0是 1否)', + is_cache int(1) default 0 comment '是否缓存(0缓存 1不缓存)', + menu_type char(1) default '' comment '菜单类型(M目录 C菜单 F按钮)', + visible char(1) default 0 comment '菜单状态(0显示 1隐藏)', + status 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, 0, 'M', '0', '0', '', 'system', 'admin', sysdate(), '', null, '系统管理目录'); +insert into sys_menu values('2', '系统监控', '0', '2', 'monitor', null, '', '', 1, 0, 'M', '0', '0', '', 'monitor', 'admin', sysdate(), '', null, '系统监控目录'); +insert into sys_menu values('3', '系统工具', '0', '3', 'tool', null, '', '', 1, 0, 'M', '0', '0', '', 'tool', 'admin', sysdate(), '', null, '系统工具目录'); +insert into sys_menu values('4', 'xx官网', '0', '4', 'http://staffing.vip', null, '', '', 0, 0, 'M', '0', '0', '', 'guide', 'admin', sysdate(), '', null, 'xx官网地址'); +-- 二级菜单 +insert into sys_menu values('100', '用户管理', '1', '1', 'user', 'system/user/index', '', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', sysdate(), '', null, '用户管理菜单'); +insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', '', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', sysdate(), '', null, '角色管理菜单'); +insert into sys_menu values('102', '菜单管理', '1', '3', 'menu', 'system/menu/index', '', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', sysdate(), '', null, '菜单管理菜单'); +insert into sys_menu values('103', '部门管理', '1', '4', 'dept', 'system/dept/index', '', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 'admin', sysdate(), '', null, '部门管理菜单'); +insert into sys_menu values('104', '岗位管理', '1', '5', 'post', 'system/post/index', '', '', 1, 0, 'C', '0', '0', 'system:post:list', 'post', 'admin', sysdate(), '', null, '岗位管理菜单'); +insert into sys_menu values('105', '字典管理', '1', '6', 'dict', 'system/dict/index', '', '', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', sysdate(), '', null, '字典管理菜单'); +insert into sys_menu values('106', '参数设置', '1', '7', 'config', 'system/config/index', '', '', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', sysdate(), '', null, '参数设置菜单'); +insert into sys_menu values('107', '通知公告', '1', '8', 'notice', 'system/notice/index', '', '', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', sysdate(), '', null, '通知公告菜单'); +insert into sys_menu values('108', '日志管理', '1', '9', 'log', '', '', '', 1, 0, 'M', '0', '0', '', 'log', 'admin', sysdate(), '', null, '日志管理菜单'); +insert into sys_menu values('109', '在线用户', '2', '1', 'online', 'monitor/online/index', '', '', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', sysdate(), '', null, '在线用户菜单'); +insert into sys_menu values('110', '定时任务', '2', '2', 'job', 'monitor/job/index', '', '', 1, 0, 'C', '0', '0', 'monitor:job:list', 'job', 'admin', sysdate(), '', null, '定时任务菜单'); +insert into sys_menu values('111', '数据监控', '2', '3', 'druid', 'monitor/druid/index', '', '', 1, 0, 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', sysdate(), '', null, '数据监控菜单'); +insert into sys_menu values('112', '服务监控', '2', '4', 'server', 'monitor/server/index', '', '', 1, 0, 'C', '0', '0', 'monitor:server:list', 'server', 'admin', sysdate(), '', null, '服务监控菜单'); +insert into sys_menu values('113', '缓存监控', '2', '5', 'cache', 'monitor/cache/index', '', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis', 'admin', sysdate(), '', null, '缓存监控菜单'); +insert into sys_menu values('114', '缓存列表', '2', '6', 'cacheList', 'monitor/cache/list', '', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis-list', 'admin', sysdate(), '', null, '缓存列表菜单'); +insert into sys_menu values('115', '表单构建', '3', '1', 'build', 'tool/build/index', '', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', sysdate(), '', null, '表单构建菜单'); +insert into sys_menu values('116', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', sysdate(), '', null, '代码生成菜单'); +insert into sys_menu values('117', '系统接口', '3', '3', 'swagger', 'tool/swagger/index', '', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', sysdate(), '', null, '系统接口菜单'); +-- 三级菜单 +insert into sys_menu values('500', '操作日志', '108', '1', 'operlog', 'monitor/operlog/index', '', '', 1, 0, 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', sysdate(), '', null, '操作日志菜单'); +insert into sys_menu values('501', '登录日志', '108', '2', 'logininfor', 'monitor/logininfor/index', '', '', 1, 0, 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', sysdate(), '', null, '登录日志菜单'); +-- 用户管理按钮 +insert into sys_menu values('1000', '用户查询', '100', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1001', '用户新增', '100', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1002', '用户修改', '100', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1003', '用户删除', '100', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1004', '用户导出', '100', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:export', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1005', '用户导入', '100', '6', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:import', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1006', '重置密码', '100', '7', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', sysdate(), '', null, ''); +-- 角色管理按钮 +insert into sys_menu values('1007', '角色查询', '101', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1008', '角色新增', '101', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1009', '角色修改', '101', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1010', '角色删除', '101', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1011', '角色导出', '101', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:export', '#', 'admin', sysdate(), '', null, ''); +-- 菜单管理按钮 +insert into sys_menu values('1012', '菜单查询', '102', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1013', '菜单新增', '102', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1014', '菜单修改', '102', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1015', '菜单删除', '102', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:remove', '#', 'admin', sysdate(), '', null, ''); +-- 部门管理按钮 +insert into sys_menu values('1016', '部门查询', '103', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1017', '部门新增', '103', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1018', '部门修改', '103', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1019', '部门删除', '103', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:remove', '#', 'admin', sysdate(), '', null, ''); +-- 岗位管理按钮 +insert into sys_menu values('1020', '岗位查询', '104', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1021', '岗位新增', '104', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1022', '岗位修改', '104', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1023', '岗位删除', '104', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1024', '岗位导出', '104', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:export', '#', 'admin', sysdate(), '', null, ''); +-- 字典管理按钮 +insert into sys_menu values('1025', '字典查询', '105', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1026', '字典新增', '105', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1027', '字典修改', '105', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1028', '字典删除', '105', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1029', '字典导出', '105', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:export', '#', 'admin', sysdate(), '', null, ''); +-- 参数设置按钮 +insert into sys_menu values('1030', '参数查询', '106', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1031', '参数新增', '106', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1032', '参数修改', '106', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1033', '参数删除', '106', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1034', '参数导出', '106', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:export', '#', 'admin', sysdate(), '', null, ''); +-- 通知公告按钮 +insert into sys_menu values('1035', '公告查询', '107', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1036', '公告新增', '107', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1037', '公告修改', '107', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1038', '公告删除', '107', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:remove', '#', 'admin', sysdate(), '', null, ''); +-- 操作日志按钮 +insert into sys_menu values('1039', '操作查询', '500', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1040', '操作删除', '500', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1041', '日志导出', '500', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', sysdate(), '', null, ''); +-- 登录日志按钮 +insert into sys_menu values('1042', '登录查询', '501', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1043', '登录删除', '501', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1044', '日志导出', '501', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1045', '账户解锁', '501', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', sysdate(), '', null, ''); +-- 在线用户按钮 +insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1048', '单条强退', '109', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', sysdate(), '', null, ''); +-- 定时任务按钮 +insert into sys_menu values('1049', '任务查询', '110', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1050', '任务新增', '110', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1051', '任务修改', '110', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1052', '任务删除', '110', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1053', '状态修改', '110', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:changeStatus', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1054', '任务导出', '110', '6', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:export', '#', 'admin', sysdate(), '', null, ''); +-- 代码生成按钮 +insert into sys_menu values('1055', '生成查询', '116', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1056', '生成修改', '116', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1057', '生成删除', '116', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1058', '导入代码', '116', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1059', '预览代码', '116', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1060', '生成代码', '116', '6', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', sysdate(), '', null, ''); + + +-- ---------------------------- +-- 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', '116'); +insert into sys_role_menu values ('2', '117'); +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(200) 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(128) 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正常 1异常)', + error_msg varchar(2000) default '' comment '错误消息', + oper_time datetime comment '操作时间', + cost_time bigint(20) default 0 comment '消耗时间', + primary key (oper_id), + key idx_sys_oper_log_bt (business_type), + key idx_sys_oper_log_s (status), + key idx_sys_oper_log_ot (oper_time) +) 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正常 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', sysdate(), '', null, '用户性别列表'); +insert into sys_dict_type values(2, '菜单状态', 'sys_show_hide', '0', 'admin', sysdate(), '', null, '菜单状态列表'); +insert into sys_dict_type values(3, '系统开关', 'sys_normal_disable', '0', 'admin', sysdate(), '', null, '系统开关列表'); +insert into sys_dict_type values(4, '任务状态', 'sys_job_status', '0', 'admin', sysdate(), '', null, '任务状态列表'); +insert into sys_dict_type values(5, '任务分组', 'sys_job_group', '0', 'admin', sysdate(), '', null, '任务分组列表'); +insert into sys_dict_type values(6, '系统是否', 'sys_yes_no', '0', 'admin', sysdate(), '', null, '系统是否列表'); +insert into sys_dict_type values(7, '通知类型', 'sys_notice_type', '0', 'admin', sysdate(), '', null, '通知类型列表'); +insert into sys_dict_type values(8, '通知状态', 'sys_notice_status', '0', 'admin', sysdate(), '', null, '通知状态列表'); +insert into sys_dict_type values(9, '操作类型', 'sys_oper_type', '0', 'admin', sysdate(), '', null, '操作类型列表'); +insert into sys_dict_type values(10, '系统状态', 'sys_common_status', '0', 'admin', sysdate(), '', null, '登录状态列表'); + + +-- ---------------------------- +-- 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 '是否默认(Y是 N否)', + status char(1) default '0' comment '状态(0正常 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', sysdate(), '', null, '性别男'); +insert into sys_dict_data values(2, 2, '女', '1', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate(), '', null, '性别女'); +insert into sys_dict_data values(3, 3, '未知', '2', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate(), '', null, '性别未知'); +insert into sys_dict_data values(4, 1, '显示', '0', 'sys_show_hide', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '显示菜单'); +insert into sys_dict_data values(5, 2, '隐藏', '1', 'sys_show_hide', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '隐藏菜单'); +insert into sys_dict_data values(6, 1, '正常', '0', 'sys_normal_disable', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(7, 2, '停用', '1', 'sys_normal_disable', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态'); +insert into sys_dict_data values(8, 1, '正常', '0', 'sys_job_status', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(9, 2, '暂停', '1', 'sys_job_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态'); +insert into sys_dict_data values(10, 1, '默认', 'DEFAULT', 'sys_job_group', '', '', 'Y', '0', 'admin', sysdate(), '', null, '默认分组'); +insert into sys_dict_data values(11, 2, '系统', 'SYSTEM', 'sys_job_group', '', '', 'N', '0', 'admin', sysdate(), '', null, '系统分组'); +insert into sys_dict_data values(12, 1, '是', 'Y', 'sys_yes_no', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '系统默认是'); +insert into sys_dict_data values(13, 2, '否', 'N', 'sys_yes_no', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '系统默认否'); +insert into sys_dict_data values(14, 1, '通知', '1', 'sys_notice_type', '', 'warning', 'Y', '0', 'admin', sysdate(), '', null, '通知'); +insert into sys_dict_data values(15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', sysdate(), '', null, '公告'); +insert into sys_dict_data values(16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '关闭状态'); +insert into sys_dict_data values(18, 99, '其他', '0', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '其他操作'); +insert into sys_dict_data values(19, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '新增操作'); +insert into sys_dict_data values(20, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '修改操作'); +insert into sys_dict_data values(21, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '删除操作'); +insert into sys_dict_data values(22, 4, '授权', '4', 'sys_oper_type', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '授权操作'); +insert into sys_dict_data values(23, 5, '导出', '5', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '导出操作'); +insert into sys_dict_data values(24, 6, '导入', '6', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '导入操作'); +insert into sys_dict_data values(25, 7, '强退', '7', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '强退操作'); +insert into sys_dict_data values(26, 8, '生成代码', '8', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '生成操作'); +insert into sys_dict_data values(27, 9, '清空数据', '9', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '清空操作'); +insert into sys_dict_data values(28, 1, '成功', '0', 'sys_common_status', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(29, 2, '失败', '1', 'sys_common_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态'); + + +-- ---------------------------- +-- 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 '系统内置(Y是 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', sysdate(), '', null, '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow' ); +insert into sys_config values(2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', sysdate(), '', null, '初始化密码 123456' ); +insert into sys_config values(3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', sysdate(), '', null, '深色主题theme-dark,浅色主题theme-light' ); +insert into sys_config values(4, '账号自助-验证码开关', 'sys.account.captchaEnabled', 'true', 'Y', 'admin', sysdate(), '', null, '是否开启验证码功能(true开启,false关闭)'); +insert into sys_config values(5, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', sysdate(), '', null, '是否开启注册用户功能(true开启,false关闭)'); +insert into sys_config values(6, '用户登录-黑名单列表', 'sys.login.blackIPList', '', 'Y', 'admin', sysdate(), '', null, '设置登录IP黑名单限制,多个匹配项以;分隔,支持匹配(*通配、网段)'); + + +-- ---------------------------- +-- 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(128) 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), + key idx_sys_logininfor_s (status), + key idx_sys_logininfor_lt (login_time) +) 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正常 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', sysdate(), '', null, ''); +insert into sys_job values(2, '系统默认(有参)', 'DEFAULT', 'ryTask.ryParams(\'ry\')', '0/15 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, ''); +insert into sys_job values(3, '系统默认(多参)', 'DEFAULT', 'ryTask.ryMultipleParams(\'ry\', true, 2000L, 316.50D, 100)', '0/20 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, ''); + + +-- ---------------------------- +-- 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正常 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 longblob default null comment '公告内容', + status char(1) default '0' comment '公告状态(0正常 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 xx新版本发布啦', '2', '新版本内容', '0', 'admin', sysdate(), '', null, '管理员'); +insert into sys_notice values('2', '维护通知:2018-07-01 xx系统凌晨维护', '1', '维护内容', '0', 'admin', sysdate(), '', null, '管理员'); + + +-- ---------------------------- +-- 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 '表描述', + sub_table_name varchar(64) default null comment '关联子表的表名', + sub_table_fk_name varchar(64) default null comment '子表关联的外键名', + class_name varchar(100) default '' comment '实体类名称', + tpl_category varchar(200) default 'crud' comment '使用的模板(crud单表操作 tree树表操作)', + tpl_web_type varchar(30) default '' comment '前端模板类型(element-ui模版 element-plus模版)', + 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 '生成功能作者', + gen_type char(1) default '0' comment '生成代码方式(0zip压缩包 1自定义路径)', + gen_path varchar(200) default '/' 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 = '代码生成业务表'; + + +-- ---------------------------- +-- 19、代码生成业务表字段 +-- ---------------------------- +drop table if exists gen_table_column; +create table gen_table_column ( + column_id bigint(20) not null auto_increment comment '编号', + table_id bigint(20) 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 = '代码生成业务表字段'; + + + + +drop table if exists st_employee; +create table st_employee ( + id bigint(20) not null auto_increment comment 'id', + real_name varchar(20) comment '名字', + phone varchar(30) comment '手机', + id_card varchar(30) comment '身份证', + open_id varchar(50) comment '微信openId', + sex int(1) comment '性别', + nation varchar(20) comment '民族', + age int(3) comment '年龄', + use_unit varchar(50) comment '用工单位', + interview_date datetime comment '面试日期', + entry_date datetime comment '入职日期', + supplier varchar(50) comment '供应商', + employee_price varchar(30) comment '员工单价', + supplier_price varchar(30) comment '供应商单价', + employee_type int(1) comment '0灵活用工,1固定长期用工', + update_time datetime comment '更新时间', + create_time datetime comment '注册时间', + primary key (id), + UNIQUE INDEX `phone`(`phone`) USING BTREE +) engine=innodb auto_increment=1 comment = '员工表'; + + + +drop table if exists st_task; +create table st_task ( + id bigint(20) not null auto_increment comment 'id', + task_name varchar(100) comment '任务名称', + task_date datetime comment '任务时间', + day_price varchar(30) comment '日结单价', + use_num int(10) comment '用工数量', + code_pic varchar(500) comment '二维码', + status int(1) comment '0已下架 1已上架', + update_time datetime comment '更新时间', + create_time datetime comment '创建时间', + primary key (id) +) engine=innodb auto_increment=1 comment = '任务表'; + + +-- drop table if exists st_task_sign; +-- create table st_task_sign ( +-- id bigint(20) not null auto_increment comment 'id', +-- task_id bigint(20) comment '任务id', +-- task_name varchar(100) comment '任务名称', +-- day_price varchar(30) comment '日结单价', +-- sign_time datetime comment '签到时间', +-- employee_id bigint(20) comment '员工id', +-- employee_name varchar(20) comment '名字', +-- phone varchar(30) comment '手机', +-- id_card varchar(30) comment '身份证', +-- status int(1) comment '0已下架 1已上架', +-- remark varchar(500) comment '备注', +-- primary key (id) +-- ) engine=innodb auto_increment=1 comment = '签到表'; + + +drop table if exists st_task_sign; +create table st_task_sign ( + id bigint(20) not null auto_increment comment 'id', + task_id bigint(20) comment '任务id', + task_name varchar(100) comment '任务名称', + day_price varchar(30) comment '日结单价', + sign_time datetime comment '签到时间', + employee_id bigint(20) comment '员工id', + employee_name varchar(20) comment '名字', + phone varchar(30) comment '手机', + id_card varchar(30) comment '身份证', + status int(1) comment '0未签到 1已签到', + remark varchar(500) comment '备注', + primary key (id), + UNIQUE INDEX `taskIdEmId`(`task_id`, `employee_id`) USING BTREE +) engine=innodb auto_increment=1 comment = '签到表'; + + +drop table if exists st_employee_fund_record; +create table st_employee_fund_record ( + id bigint(20) not null auto_increment comment 'id', + task_id bigint(20) comment '任务id', + task_name varchar(100) comment '任务名称', + task_date datetime comment '任务时间', + employee_id bigint(20) comment '员工id', + employee_name varchar(20) comment '名字', + phone varchar(30) comment '手机', + id_card varchar(30) comment '身份证', + day_price varchar(30) comment '日结单价', + should_price varchar(30) comment '应发金额', + real_price varchar(30) comment '实发金额', + pay_way int(1) comment '发薪方式0微信转账', + pay_account int(1) comment '签到账户0微信钱包', + pay_time datetime comment '发薪时间', + transfer_no varchar(100) comment '转账订单号', + update_time datetime comment '更新时间', + pay_status int(1) comment '0未发放,1已发放 2发放失败', + primary key (id), + UNIQUE INDEX `taskId_emId`(`task_id`, `employee_id`) USING BTREE +) engine=innodb auto_increment=1 comment = '员工资金流水'; + + + +drop table if exists st_transfer_record; +create table st_transfer_record ( + id bigint(20) not null auto_increment comment 'id', + task_id bigint(20) comment '任务id', + task_name varchar(100) comment '任务名称', + transfer_no varchar(100) comment '转账订单号', + count_price varchar(30) comment '总金额', + employee_ids varchar(500) comment '发薪职工', + create_time datetime comment '发起转账时间', + update_time datetime comment '更新状态时间', + pay_status int(1) comment '待商户确认、已受理、转账中、已完成、已关闭', + primary key (id) +) engine=innodb auto_increment=1 comment = '微信转账记录'; \ No newline at end of file diff --git a/sql/quartz.sql b/sql/quartz.sql new file mode 100644 index 0000000..cee613b --- /dev/null +++ b/sql/quartz.sql @@ -0,0 +1,174 @@ +DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS; +DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE; +DROP TABLE IF EXISTS QRTZ_LOCKS; +DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_JOB_DETAILS; +DROP TABLE IF EXISTS QRTZ_CALENDARS; + +-- ---------------------------- +-- 1、存储每一个已配置的 jobDetail 的详细信息 +-- ---------------------------- +create table QRTZ_JOB_DETAILS ( + sched_name varchar(120) not null comment '调度名称', + job_name varchar(200) not null comment '任务名称', + job_group varchar(200) not null comment '任务组名', + description varchar(250) null comment '相关介绍', + job_class_name varchar(250) not null comment '执行任务类名称', + is_durable varchar(1) not null comment '是否持久化', + is_nonconcurrent varchar(1) not null comment '是否并发', + is_update_data varchar(1) not null comment '是否更新数据', + requests_recovery varchar(1) not null comment '是否接受恢复执行', + job_data blob null comment '存放持久化job对象', + primary key (sched_name, job_name, job_group) +) engine=innodb comment = '任务详细信息表'; + +-- ---------------------------- +-- 2、 存储已配置的 Trigger 的信息 +-- ---------------------------- +create table QRTZ_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment '触发器的名字', + trigger_group varchar(200) not null comment '触发器所属组的名字', + job_name varchar(200) not null comment 'qrtz_job_details表job_name的外键', + job_group varchar(200) not null comment 'qrtz_job_details表job_group的外键', + description varchar(250) null comment '相关介绍', + next_fire_time bigint(13) null comment '上一次触发时间(毫秒)', + prev_fire_time bigint(13) null comment '下一次触发时间(默认为-1表示不触发)', + priority integer null comment '优先级', + trigger_state varchar(16) not null comment '触发器状态', + trigger_type varchar(8) not null comment '触发器的类型', + start_time bigint(13) not null comment '开始时间', + end_time bigint(13) null comment '结束时间', + calendar_name varchar(200) null comment '日程表名称', + misfire_instr smallint(2) null comment '补偿执行的策略', + job_data blob null comment '存放持久化job对象', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, job_name, job_group) references QRTZ_JOB_DETAILS(sched_name, job_name, job_group) +) engine=innodb comment = '触发器详细信息表'; + +-- ---------------------------- +-- 3、 存储简单的 Trigger,包括重复次数,间隔,以及已触发的次数 +-- ---------------------------- +create table QRTZ_SIMPLE_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + repeat_count bigint(7) not null comment '重复的次数统计', + repeat_interval bigint(12) not null comment '重复的间隔时间', + times_triggered bigint(10) not null comment '已经触发的次数', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +) engine=innodb comment = '简单触发器的信息表'; + +-- ---------------------------- +-- 4、 存储 Cron Trigger,包括 Cron 表达式和时区信息 +-- ---------------------------- +create table QRTZ_CRON_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + cron_expression varchar(200) not null comment 'cron表达式', + time_zone_id varchar(80) comment '时区', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +) engine=innodb comment = 'Cron类型的触发器表'; + +-- ---------------------------- +-- 5、 Trigger 作为 Blob 类型存储(用于 Quartz 用户用 JDBC 创建他们自己定制的 Trigger 类型,JobStore 并不知道如何存储实例的时候) +-- ---------------------------- +create table QRTZ_BLOB_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + blob_data blob null comment '存放持久化Trigger对象', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +) engine=innodb comment = 'Blob类型的触发器表'; + +-- ---------------------------- +-- 6、 以 Blob 类型存储存放日历信息, quartz可配置一个日历来指定一个时间范围 +-- ---------------------------- +create table QRTZ_CALENDARS ( + sched_name varchar(120) not null comment '调度名称', + calendar_name varchar(200) not null comment '日历名称', + calendar blob not null comment '存放持久化calendar对象', + primary key (sched_name, calendar_name) +) engine=innodb comment = '日历信息表'; + +-- ---------------------------- +-- 7、 存储已暂停的 Trigger 组的信息 +-- ---------------------------- +create table QRTZ_PAUSED_TRIGGER_GRPS ( + sched_name varchar(120) not null comment '调度名称', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + primary key (sched_name, trigger_group) +) engine=innodb comment = '暂停的触发器表'; + +-- ---------------------------- +-- 8、 存储与已触发的 Trigger 相关的状态信息,以及相联 Job 的执行信息 +-- ---------------------------- +create table QRTZ_FIRED_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + entry_id varchar(95) not null comment '调度器实例id', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + instance_name varchar(200) not null comment '调度器实例名', + fired_time bigint(13) not null comment '触发的时间', + sched_time bigint(13) not null comment '定时器制定的时间', + priority integer not null comment '优先级', + state varchar(16) not null comment '状态', + job_name varchar(200) null comment '任务名称', + job_group varchar(200) null comment '任务组名', + is_nonconcurrent varchar(1) null comment '是否并发', + requests_recovery varchar(1) null comment '是否接受恢复执行', + primary key (sched_name, entry_id) +) engine=innodb comment = '已触发的触发器表'; + +-- ---------------------------- +-- 9、 存储少量的有关 Scheduler 的状态信息,假如是用于集群中,可以看到其他的 Scheduler 实例 +-- ---------------------------- +create table QRTZ_SCHEDULER_STATE ( + sched_name varchar(120) not null comment '调度名称', + instance_name varchar(200) not null comment '实例名称', + last_checkin_time bigint(13) not null comment '上次检查时间', + checkin_interval bigint(13) not null comment '检查间隔时间', + primary key (sched_name, instance_name) +) engine=innodb comment = '调度器状态表'; + +-- ---------------------------- +-- 10、 存储程序的悲观锁的信息(假如使用了悲观锁) +-- ---------------------------- +create table QRTZ_LOCKS ( + sched_name varchar(120) not null comment '调度名称', + lock_name varchar(40) not null comment '悲观锁名称', + primary key (sched_name, lock_name) +) engine=innodb comment = '存储的悲观锁信息表'; + +-- ---------------------------- +-- 11、 Quartz集群实现同步机制的行锁表 +-- ---------------------------- +create table QRTZ_SIMPROP_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + str_prop_1 varchar(512) null comment 'String类型的trigger的第一个参数', + str_prop_2 varchar(512) null comment 'String类型的trigger的第二个参数', + str_prop_3 varchar(512) null comment 'String类型的trigger的第三个参数', + int_prop_1 int null comment 'int类型的trigger的第一个参数', + int_prop_2 int null comment 'int类型的trigger的第二个参数', + long_prop_1 bigint null comment 'long类型的trigger的第一个参数', + long_prop_2 bigint null comment 'long类型的trigger的第二个参数', + dec_prop_1 numeric(13,4) null comment 'decimal类型的trigger的第一个参数', + dec_prop_2 numeric(13,4) null comment 'decimal类型的trigger的第二个参数', + bool_prop_1 varchar(1) null comment 'Boolean类型的trigger的第一个参数', + bool_prop_2 varchar(1) null comment 'Boolean类型的trigger的第二个参数', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +) engine=innodb comment = '同步机制的行锁表'; + +commit; \ No newline at end of file diff --git a/staffing-admin/pom.xml b/staffing-admin/pom.xml new file mode 100644 index 0000000..48520e5 --- /dev/null +++ b/staffing-admin/pom.xml @@ -0,0 +1,96 @@ + + + + staffing + com.staffing + 3.8.8 + + 4.0.0 + jar + staffing-admin + + + web服务入口 + + + + + + + org.springframework.boot + spring-boot-devtools + true + + + + + io.springfox + springfox-boot-starter + + + + + io.swagger + swagger-models + 1.6.2 + + + + + mysql + mysql-connector-java + + + + + com.staffing + staffing-framework + + + + + com.staffing + staffing-quartz + + + + + com.staffing + staffing-generator + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.5.15 + + true + + + + + repackage + + + + + + org.apache.maven.plugins + maven-war-plugin + 3.1.0 + + false + ${project.artifactId} + + + + ${project.artifactId} + + + \ No newline at end of file diff --git a/staffing-admin/src/main/java/com/staffing/StaffingApplication.java b/staffing-admin/src/main/java/com/staffing/StaffingApplication.java new file mode 100644 index 0000000..3208019 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/StaffingApplication.java @@ -0,0 +1,20 @@ +package com.staffing; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; + +/** + * 启动程序 + * + * @author staffing + */ +@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) +public class StaffingApplication +{ + public static void main(String[] args) + { + // System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(StaffingApplication.class, args); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/StaffingServletInitializer.java b/staffing-admin/src/main/java/com/staffing/StaffingServletInitializer.java new file mode 100644 index 0000000..792eb47 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/StaffingServletInitializer.java @@ -0,0 +1,18 @@ +package com.staffing; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * web容器中进行部署 + * + * @author staffing + */ +public class StaffingServletInitializer extends SpringBootServletInitializer +{ + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) + { + return application.sources(StaffingApplication.class); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/common/CaptchaController.java b/staffing-admin/src/main/java/com/staffing/web/controller/common/CaptchaController.java new file mode 100644 index 0000000..3eb1cba --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/common/CaptchaController.java @@ -0,0 +1,94 @@ +package com.staffing.web.controller.common; + +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import javax.annotation.Resource; +import javax.imageio.ImageIO; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.FastByteArrayOutputStream; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import com.google.code.kaptcha.Producer; +import com.staffing.common.config.StaffingConfig; +import com.staffing.common.constant.CacheConstants; +import com.staffing.common.constant.Constants; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.redis.RedisCache; +import com.staffing.common.utils.sign.Base64; +import com.staffing.common.utils.uuid.IdUtils; +import com.staffing.system.service.ISysConfigService; + +/** + * 验证码操作处理 + * + * @author staffing + */ +@RestController +public class CaptchaController +{ + @Resource(name = "captchaProducer") + private Producer captchaProducer; + + @Resource(name = "captchaProducerMath") + private Producer captchaProducerMath; + + @Autowired + private RedisCache redisCache; + + @Autowired + private ISysConfigService configService; + /** + * 生成验证码 + */ + @GetMapping("/captchaImage") + public AjaxResult getCode(HttpServletResponse response) throws IOException + { + AjaxResult ajax = AjaxResult.success(); + boolean captchaEnabled = configService.selectCaptchaEnabled(); + ajax.put("captchaEnabled", captchaEnabled); + if (!captchaEnabled) + { + return ajax; + } + + // 保存验证码信息 + String uuid = IdUtils.simpleUUID(); + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; + + String capStr = null, code = null; + BufferedImage image = null; + + // 生成验证码 + String captchaType = StaffingConfig.getCaptchaType(); + if ("math".equals(captchaType)) + { + String capText = captchaProducerMath.createText(); + capStr = capText.substring(0, capText.lastIndexOf("@")); + code = capText.substring(capText.lastIndexOf("@") + 1); + image = captchaProducerMath.createImage(capStr); + } + else if ("char".equals(captchaType)) + { + capStr = code = captchaProducer.createText(); + image = captchaProducer.createImage(capStr); + } + + redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); + // 转换流信息写出 + FastByteArrayOutputStream os = new FastByteArrayOutputStream(); + try + { + ImageIO.write(image, "jpg", os); + } + catch (IOException e) + { + return AjaxResult.error(e.getMessage()); + } + + ajax.put("uuid", uuid); + ajax.put("img", Base64.encode(os.toByteArray())); + return ajax; + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/common/CommonController.java b/staffing-admin/src/main/java/com/staffing/web/controller/common/CommonController.java new file mode 100644 index 0000000..9140d2c --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/common/CommonController.java @@ -0,0 +1,163 @@ +package com.staffing.web.controller.common; + +import java.util.ArrayList; +import java.util.List; +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.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import com.staffing.common.config.StaffingConfig; +import com.staffing.common.constant.Constants; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.file.FileUploadUtils; +import com.staffing.common.utils.file.FileUtils; +import com.staffing.framework.config.ServerConfig; + +/** + * 通用请求处理 + * + * @author staffing + */ +@RestController +@RequestMapping("/common") +public class CommonController +{ + private static final Logger log = LoggerFactory.getLogger(CommonController.class); + + @Autowired + private ServerConfig serverConfig; + + private static final String FILE_DELIMETER = ","; + + /** + * 通用下载请求 + * + * @param fileName 文件名称 + * @param delete 是否删除 + */ + @GetMapping("/download") + public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) + { + try + { + if (!FileUtils.checkAllowDownload(fileName)) + { + throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName)); + } + String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1); + String filePath = StaffingConfig.getDownloadPath() + fileName; + + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + FileUtils.setAttachmentResponseHeader(response, realFileName); + FileUtils.writeBytes(filePath, response.getOutputStream()); + if (delete) + { + FileUtils.deleteFile(filePath); + } + } + catch (Exception e) + { + log.error("下载文件失败", e); + } + } + + /** + * 通用上传请求(单个) + */ + @PostMapping("/upload") + public AjaxResult uploadFile(MultipartFile file) throws Exception + { + try + { + // 上传文件路径 + String filePath = StaffingConfig.getUploadPath(); + // 上传并返回新文件名称 + String fileName = FileUploadUtils.upload(filePath, file); + String url = serverConfig.getUrl() + fileName; + AjaxResult ajax = AjaxResult.success(); + ajax.put("url", url); + ajax.put("fileName", fileName); + ajax.put("newFileName", FileUtils.getName(fileName)); + ajax.put("originalFilename", file.getOriginalFilename()); + return ajax; + } + catch (Exception e) + { + return AjaxResult.error(e.getMessage()); + } + } + + /** + * 通用上传请求(多个) + */ + @PostMapping("/uploads") + public AjaxResult uploadFiles(List files) throws Exception + { + try + { + // 上传文件路径 + String filePath = StaffingConfig.getUploadPath(); + List urls = new ArrayList(); + List fileNames = new ArrayList(); + List newFileNames = new ArrayList(); + List originalFilenames = new ArrayList(); + for (MultipartFile file : files) + { + // 上传并返回新文件名称 + String fileName = FileUploadUtils.upload(filePath, file); + String url = serverConfig.getUrl() + fileName; + urls.add(url); + fileNames.add(fileName); + newFileNames.add(FileUtils.getName(fileName)); + originalFilenames.add(file.getOriginalFilename()); + } + AjaxResult ajax = AjaxResult.success(); + ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER)); + ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER)); + ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER)); + ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER)); + return ajax; + } + catch (Exception e) + { + return AjaxResult.error(e.getMessage()); + } + } + + /** + * 本地资源通用下载 + */ + @GetMapping("/download/resource") + public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response) + throws Exception + { + try + { + if (!FileUtils.checkAllowDownload(resource)) + { + throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource)); + } + // 本地资源路径 + String localPath = StaffingConfig.getProfile(); + // 数据库资源地址 + String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX); + // 下载名称 + String downloadName = StringUtils.substringAfterLast(downloadPath, "/"); + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + FileUtils.setAttachmentResponseHeader(response, downloadName); + FileUtils.writeBytes(downloadPath, response.getOutputStream()); + } + catch (Exception e) + { + log.error("下载文件失败", e); + } + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/custom/StEmployeeController.java b/staffing-admin/src/main/java/com/staffing/web/controller/custom/StEmployeeController.java new file mode 100644 index 0000000..c846b4e --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/custom/StEmployeeController.java @@ -0,0 +1,111 @@ +package com.staffing.web.controller.custom; + +import java.util.Date; +import java.util.List; +import javax.servlet.http.HttpServletResponse; +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.staffing.common.annotation.Log; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.enums.BusinessType; +import com.staffing.custom.domain.StEmployee; +import com.staffing.custom.service.IStEmployeeService; +import com.staffing.common.utils.poi.ExcelUtil; +import com.staffing.common.core.page.TableDataInfo; + +/** + * 员工Controller + * + * @author staffing + * @date 2024-08-27 + */ +@RestController +@RequestMapping("/employee/employee") +public class StEmployeeController extends BaseController +{ + @Autowired + private IStEmployeeService stEmployeeService; + + /** + * 查询员工列表 + */ + @PreAuthorize("@ss.hasPermi('employee:employee:list')") + @GetMapping("/list") + public TableDataInfo list(StEmployee stEmployee) + { + startPage(); + List list = stEmployeeService.selectStEmployeeList(stEmployee); + return getDataTable(list); + } + + /** + * 导出员工列表 + */ + @PreAuthorize("@ss.hasPermi('employee:employee:export')") + @Log(title = "员工", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, StEmployee stEmployee) + { + List list = stEmployeeService.selectStEmployeeList(stEmployee); + ExcelUtil util = new ExcelUtil(StEmployee.class); + util.exportExcel(response, list, "员工数据"); + } + + /** + * 获取员工详细信息 + */ + @PreAuthorize("@ss.hasPermi('employee:employee:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(stEmployeeService.selectStEmployeeById(id)); + } + + /** + * 新增员工 + */ + @PreAuthorize("@ss.hasPermi('employee:employee:add')") + @Log(title = "员工", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody StEmployee stEmployee) + { + StEmployee stEmployee1 = stEmployeeService.selectStEmployeeByPhone(stEmployee.getPhone()); + if (stEmployee1 != null){ + return error("手机号已存在"); + } + stEmployee.setUpdateTime(new Date()); + return toAjax(stEmployeeService.insertStEmployee(stEmployee)); + } + + /** + * 修改员工 + */ + @PreAuthorize("@ss.hasPermi('employee:employee:edit')") + @Log(title = "员工", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody StEmployee stEmployee) + { + stEmployee.setUpdateTime(new Date()); + return toAjax(stEmployeeService.updateStEmployeeOrNull(stEmployee)); + } + + /** + * 删除员工 + */ + @PreAuthorize("@ss.hasPermi('employee:employee:remove')") + @Log(title = "员工", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(stEmployeeService.deleteStEmployeeByIds(ids)); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/custom/StEmployeeFundRecordController.java b/staffing-admin/src/main/java/com/staffing/web/controller/custom/StEmployeeFundRecordController.java new file mode 100644 index 0000000..8848171 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/custom/StEmployeeFundRecordController.java @@ -0,0 +1,163 @@ +package com.staffing.web.controller.custom; + +import java.util.Date; +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.staffing.custom.domain.StTaskSign; +import com.staffing.custom.service.IStTaskSignService; +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.staffing.common.annotation.Log; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.enums.BusinessType; +import com.staffing.custom.domain.StEmployeeFundRecord; +import com.staffing.custom.service.IStEmployeeFundRecordService; +import com.staffing.common.utils.poi.ExcelUtil; +import com.staffing.common.core.page.TableDataInfo; +import org.springframework.web.multipart.MultipartFile; + +/** + * 员工资金流水Controller + * + * @author staffing + * @date 2024-08-27 + */ +@RestController +@RequestMapping("/fund/fund") +public class StEmployeeFundRecordController extends BaseController +{ + @Autowired + private IStEmployeeFundRecordService stEmployeeFundRecordService; + + @Autowired + private IStTaskSignService taskSignService; + + /** + * 查询员工资金流水列表 + */ + @PreAuthorize("@ss.hasPermi('fund:fund:list')") + @GetMapping("/list") + public TableDataInfo list(StEmployeeFundRecord stEmployeeFundRecord) + { + startPage(); + List list = stEmployeeFundRecordService.selectStEmployeeFundRecordList(stEmployeeFundRecord); + return getDataTable(list); + } + + /** + * 导出员工资金流水列表 + */ + @PreAuthorize("@ss.hasPermi('fund:fund:export')") + @Log(title = "员工资金流水", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, StEmployeeFundRecord stEmployeeFundRecord) + { + List list = stEmployeeFundRecordService.selectStEmployeeFundRecordList(stEmployeeFundRecord); + for (StEmployeeFundRecord employeeFundRecord : list) { + if (employeeFundRecord.getPayStatus() == 0){ + employeeFundRecord.setPayStatusStr("未发"); + }else if (employeeFundRecord.getPayStatus() == 1){ + employeeFundRecord.setPayStatusStr("已发"); + }else if (employeeFundRecord.getPayStatus() == 2){ + employeeFundRecord.setPayStatusStr("发放失败"); + } + + employeeFundRecord.setPayWayStr("微信转账"); + employeeFundRecord.setPayAccountStr("微信钱包"); + + if (employeeFundRecord.getStTaskSign() != null){ + employeeFundRecord.setRemark(employeeFundRecord.getStTaskSign().getRemark()); + } + + } + ExcelUtil util = new ExcelUtil(StEmployeeFundRecord.class); + + util.exportExcel(response, list, "员工资金流水数据"); + } + + /** + * 获取员工资金流水详细信息 + */ + @PreAuthorize("@ss.hasPermi('fund:fund:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(stEmployeeFundRecordService.selectStEmployeeFundRecordById(id)); + } + + /** + * 新增员工资金流水 + */ + @PreAuthorize("@ss.hasPermi('fund:fund:add')") + @Log(title = "员工资金流水", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody StEmployeeFundRecord stEmployeeFundRecord) + { + stEmployeeFundRecord.setUpdateTime(new Date()); + return toAjax(stEmployeeFundRecordService.insertStEmployeeFundRecord(stEmployeeFundRecord)); + } + + /** + * 修改员工资金流水 + */ + @PreAuthorize("@ss.hasPermi('fund:fund:edit')") + @Log(title = "员工资金流水", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody StEmployeeFundRecord stEmployeeFundRecord) + { + stEmployeeFundRecord.setUpdateTime(new Date()); + return toAjax(stEmployeeFundRecordService.updateStEmployeeFundRecord(stEmployeeFundRecord)); + } + + /** + * 删除员工资金流水 + */ + @PreAuthorize("@ss.hasPermi('fund:fund:remove')") + @Log(title = "员工资金流水", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(stEmployeeFundRecordService.deleteStEmployeeFundRecordByIds(ids)); + } + + @Log(title = "流水导入", businessType = BusinessType.IMPORT) + @PreAuthorize("@ss.hasPermi('fund:fund:export')") + @PostMapping("/importData") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception + { + ExcelUtil util = new ExcelUtil<>(StEmployeeFundRecord.class); + List records = util.importExcel(file.getInputStream()); + for (StEmployeeFundRecord employeeFundRecord : records) { + if (employeeFundRecord.getPayStatusStr().equals("未发")){ + employeeFundRecord.setPayStatus(0l); + }else if (employeeFundRecord.getPayStatusStr().equals("已发")){ + employeeFundRecord.setPayStatus(1l); + }else if (employeeFundRecord.getPayStatusStr().equals("发放失败")){ + employeeFundRecord.setPayStatus(2l); + } + employeeFundRecord.setPayWay(0l); + employeeFundRecord.setPayAccount(0l); + + + StTaskSign stTaskSign = new StTaskSign(); + stTaskSign.setTaskId(employeeFundRecord.getTaskId()); + stTaskSign.setEmployeeId(employeeFundRecord.getEmployeeId()); + stTaskSign.setRemark(employeeFundRecord.getRemark()); + taskSignService.updateStTaskSignByTaskIdAndEmId(stTaskSign); + } + + String message = stEmployeeFundRecordService.importRecord(records); + return success(message); + } + +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/custom/StTaskController.java b/staffing-admin/src/main/java/com/staffing/web/controller/custom/StTaskController.java new file mode 100644 index 0000000..bad9f9c --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/custom/StTaskController.java @@ -0,0 +1,135 @@ +package com.staffing.web.controller.custom; + +import java.io.File; +import java.io.InputStream; +import java.util.Date; +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.staffing.common.utils.MinioUtil; +import com.staffing.common.utils.QRCodeGenerator; +import io.minio.ObjectWriteResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import com.staffing.common.annotation.Log; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.enums.BusinessType; +import com.staffing.custom.domain.StTask; +import com.staffing.custom.service.IStTaskService; +import com.staffing.common.utils.poi.ExcelUtil; +import com.staffing.common.core.page.TableDataInfo; +import org.springframework.web.multipart.MultipartFile; + +/** + * 任务Controller + * + * @author staffing + * @date 2024-08-27 + */ +@RestController +@RequestMapping("/task/task") +public class StTaskController extends BaseController +{ + @Autowired + private IStTaskService stTaskService; + + @Autowired + private MinioUtil minioUtil; + /** + * 查询任务列表 + */ + @PreAuthorize("@ss.hasPermi('task:list')") + @GetMapping("/list") + public TableDataInfo list(StTask stTask) + { + startPage(); + List list = stTaskService.selectStTaskList(stTask, 0); + for (StTask task : list) { + if (task.getCodePic() == null){ + continue; + } + task.setCodePic(minioUtil.getObjectURL( "yonggong", task.getCodePic())); + } + return getDataTable(list); + } + + /** + * 导出任务列表 + */ + @PreAuthorize("@ss.hasPermi('task:export')") + @Log(title = "任务", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, StTask stTask) + { + List list = stTaskService.selectStTaskList(stTask, 0); + ExcelUtil util = new ExcelUtil(StTask.class); + util.exportExcel(response, list, "任务数据"); + } + + + + /** + * 获取任务详细信息 + */ + @PreAuthorize("@ss.hasPermi('task:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(stTaskService.selectStTaskById(id)); + } + + /** + * 新增任务 + */ + @PreAuthorize("@ss.hasPermi('task:add')") + @Log(title = "任务", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody StTask stTask) + { + stTask.setStatus(0); + stTask.setCreateTime(new Date()); + stTask.setUpdateTime(new Date()); + stTaskService.insertStTask(stTask); + + String url = "http://yg.pusonggroup.com:81/index.html?id=" + stTask.getId(); + InputStream inputStream = QRCodeGenerator.generateQRCodeImage(url, 500, 500); + String fileName = System.currentTimeMillis() + stTask.getId() + ".png"; + try { + ObjectWriteResponse objectWriteResponse = minioUtil.putObject("yonggong" + , fileName, inputStream, inputStream.available(), "image/png"); + } catch (Exception e) { + logger.error("minioUtil.putObject error", e); + } + + stTask.setCodePic(fileName); + + return toAjax(stTaskService.updateStTask(stTask)); + } + + + + /** + * 修改任务 + */ + @PreAuthorize("@ss.hasPermi('task:edit')") + @Log(title = "任务", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody StTask stTask) + { + stTask.setUpdateTime(new Date()); + return toAjax(stTaskService.updateStTask(stTask)); + } + + /** + * 删除任务 + */ + @PreAuthorize("@ss.hasPermi('task:remove')") + @Log(title = "任务", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(stTaskService.deleteStTaskByIds(ids)); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/custom/StTaskSignController.java b/staffing-admin/src/main/java/com/staffing/web/controller/custom/StTaskSignController.java new file mode 100644 index 0000000..faf3951 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/custom/StTaskSignController.java @@ -0,0 +1,112 @@ +package com.staffing.web.controller.custom; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +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.staffing.common.annotation.Log; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.enums.BusinessType; +import com.staffing.custom.domain.StTaskSign; +import com.staffing.custom.service.IStTaskSignService; +import com.staffing.common.utils.poi.ExcelUtil; +import com.staffing.common.core.page.TableDataInfo; + +/** + * 签到Controller + * + * @author staffing + * @date 2024-08-27 + */ +@RestController +@RequestMapping("/taskSign/sign") +public class StTaskSignController extends BaseController +{ + @Autowired + private IStTaskSignService stTaskSignService; + + /** + * 查询签到列表 + */ + @PreAuthorize("@ss.hasPermi('taskSign:sign:list')") + @GetMapping("/list") + public TableDataInfo list(StTaskSign stTaskSign) + { + startPage(); + List list = stTaskSignService.selectStTaskSignList(stTaskSign); + return getDataTable(list); + } + + /** + * 导出签到列表 + */ + @PreAuthorize("@ss.hasPermi('taskSign:sign:export')") + @Log(title = "签到", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, StTaskSign stTaskSign) + { + List list = stTaskSignService.selectStTaskSignList(stTaskSign); + for (StTaskSign taskSign : list) { + if (taskSign.getStatus() == 0){ + taskSign.setStatusStr("未签到"); + }else{ + taskSign.setStatusStr("已签到"); + } + + } + ExcelUtil util = new ExcelUtil(StTaskSign.class); + util.exportExcel(response, list, "签到数据"); + } + + /** + * 获取签到详细信息 + */ + @PreAuthorize("@ss.hasPermi('taskSign:sign:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(stTaskSignService.selectStTaskSignById(id)); + } + + /** + * 新增签到 + */ + @PreAuthorize("@ss.hasPermi('taskSign:sign:add')") + @Log(title = "签到", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody StTaskSign stTaskSign) + { + return toAjax(stTaskSignService.insertStTaskSign(stTaskSign)); + } + + /** + * 修改签到 + */ + @PreAuthorize("@ss.hasPermi('taskSign:sign:edit')") + @Log(title = "签到", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody StTaskSign stTaskSign) + { + return toAjax(stTaskSignService.updateStTaskSign(stTaskSign)); + } + + /** + * 删除签到 + */ + @PreAuthorize("@ss.hasPermi('taskSign:sign:remove')") + @Log(title = "签到", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(stTaskSignService.deleteStTaskSignByIds(ids)); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/employee/EmployeeFundController.java b/staffing-admin/src/main/java/com/staffing/web/controller/employee/EmployeeFundController.java new file mode 100644 index 0000000..73bd5b8 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/employee/EmployeeFundController.java @@ -0,0 +1,61 @@ +package com.staffing.web.controller.employee; + +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.page.TableDataInfo; +import com.staffing.custom.domain.StEmployeeFundRecord; +import com.staffing.custom.domain.StTaskSign; +import com.staffing.custom.service.IStEmployeeFundRecordService; +import com.staffing.custom.service.IStTaskService; +import com.staffing.custom.service.IStTaskSignService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 任务Controller + * + * @author staffing + * @date 2024-08-27 + */ +@RestController +@RequestMapping("/employee/fund") +public class EmployeeFundController extends BaseController +{ + @Autowired + private IStTaskService stTaskService; + @Autowired + private IStTaskSignService stTaskSignService; + + @Autowired + private IStEmployeeFundRecordService stEmployeeFundRecordService; + + @GetMapping("/list") + public TableDataInfo list(StEmployeeFundRecord stEmployeeFundRecord) + { + startPage(); + List list = stEmployeeFundRecordService.selectStEmployeeFundRecordList(stEmployeeFundRecord); + return getDataTable(list); + } + + /** + * 获取任务详细信息 + */ + @GetMapping(value = "/details/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(stTaskService.selectStTaskById(id)); + } + + /** + * 修改签到 + */ + @PutMapping("/editSign") + public AjaxResult edit(@RequestBody StTaskSign stTaskSign) + { + return toAjax(stTaskSignService.updateStTaskSign(stTaskSign)); + } + + +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/employee/EmployeeTaskController.java b/staffing-admin/src/main/java/com/staffing/web/controller/employee/EmployeeTaskController.java new file mode 100644 index 0000000..e672527 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/employee/EmployeeTaskController.java @@ -0,0 +1,107 @@ +package com.staffing.web.controller.employee; + +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.domain.entity.SysUser; +import com.staffing.common.core.page.TableDataInfo; +import com.staffing.common.utils.SecurityUtils; +import com.staffing.custom.domain.StEmployee; +import com.staffing.custom.domain.StTask; +import com.staffing.custom.domain.StTaskSign; +import com.staffing.custom.service.IStEmployeeService; +import com.staffing.custom.service.IStTaskService; +import com.staffing.custom.service.IStTaskSignService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Date; +import java.util.List; + +/** + * 任务Controller + * + * @author staffing + * @date 2024-08-27 + */ +@RestController +@RequestMapping("/employee/task") +public class EmployeeTaskController extends BaseController +{ + @Autowired + private IStTaskService stTaskService; + @Autowired + private IStTaskSignService stTaskSignService; + + @Autowired + private IStEmployeeService stEmployeeService; + /** + * 查询任务列表 + */ + @GetMapping("/list") + public TableDataInfo list(StTask stTask, @RequestParam(required = false) boolean self, @RequestParam(required = false) boolean xinchou) + { + + if (!xinchou){ + stTask.setDateStatus(1); + }else{ + stTask.setDateStatus(0); + } + stTask.setStatus(1); + // 获取当前时间 + ZonedDateTime now = ZonedDateTime.now(); + // 将当前时间加上一天,‌然后设置为0点0分 + ZonedDateTime nextDayStart = now.plusDays(1).truncatedTo(ChronoUnit.DAYS); + Date nextDayZero = Date.from(nextDayStart.toInstant()); + + if (stTask.getDateStatus() != 0){ + stTask.setTaskDateCompare(nextDayZero); + } + SysUser user = SecurityUtils.getLoginUser().getUser(); + long userId = user.getUserId(); + List list; + stTask.getParams().put("order", nextDayZero); + if (!self){ + list = stTaskService.selectStTaskList(stTask, userId); + }else{ + stTask.setDateStatus(0); + list = stTaskService.selectStTaskListByUserId(stTask, userId, xinchou); + } + return getDataTable(list); + } + + + + @GetMapping("/baoming") + public AjaxResult baoming(StTaskSign taskSign) + { + return stTaskSignService.baoming(taskSign); + } + /** + * 修改签到 + */ + @GetMapping("/cancelBaoming") + public AjaxResult cancelBaoming(StTaskSign taskSign) + { + return toAjax(stTaskSignService.deleteStTaskSignById(taskSign.getId())); + } + + + /** + * 获取任务详细信息 + */ + @GetMapping(value = "/getTask") + public AjaxResult getInfo(@RequestParam("taskId") Long id) + { + return success(stTaskService.selectStTaskById(id)); + } + + + + private long getUid(){ + return 1l; + } + +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/employee/EmployeeUserController.java b/staffing-admin/src/main/java/com/staffing/web/controller/employee/EmployeeUserController.java new file mode 100644 index 0000000..d287984 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/employee/EmployeeUserController.java @@ -0,0 +1,223 @@ +package com.staffing.web.controller.employee; + +import com.google.code.kaptcha.Producer; +import com.staffing.common.annotation.Log; +import com.staffing.common.config.StaffingConfig; +import com.staffing.common.constant.CacheConstants; +import com.staffing.common.constant.Constants; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.domain.entity.SysDept; +import com.staffing.common.core.domain.entity.SysMenu; +import com.staffing.common.core.domain.entity.SysRole; +import com.staffing.common.core.domain.entity.SysUser; +import com.staffing.common.core.domain.model.LoginBody; +import com.staffing.common.core.page.TableDataInfo; +import com.staffing.common.core.redis.RedisCache; +import com.staffing.common.enums.BusinessType; +import com.staffing.common.utils.SecurityUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.poi.ExcelUtil; +import com.staffing.common.utils.sign.Base64; +import com.staffing.common.utils.uuid.IdUtils; +import com.staffing.custom.domain.StEmployee; +import com.staffing.custom.service.IStEmployeeService; +import com.staffing.custom.service.impl.StEmployeeServiceImpl; +import com.staffing.framework.web.service.SysLoginService; +import com.staffing.framework.web.service.SysPermissionService; +import com.staffing.framework.web.service.TokenService; +import com.staffing.system.service.*; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.util.FastByteArrayOutputStream; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.imageio.ImageIO; +import javax.servlet.http.HttpServletResponse; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * 用户信息 + * + * @author staffing + */ +@RestController +@RequestMapping("/employee/user") +public class EmployeeUserController extends BaseController +{ + @Autowired + private IStEmployeeService stEmployeeService; + @Autowired + private TokenService tokenService; + /** + * 修改用户 + */ + @PutMapping("profile") + public AjaxResult edit(@RequestBody StEmployee stEmployeeParam) + { + StEmployee employee = new StEmployee(); + employee.setRealName(stEmployeeParam.getRealName()); + employee.setPhone(stEmployeeParam.getPhone()); + employee.setIdCard(stEmployeeParam.getIdCard()); + + SysUser user = SecurityUtils.getLoginUser().getUser(); + user.setNickName(stEmployeeParam.getRealName()); + user.setPhonenumber(stEmployeeParam.getPhone()); + user.setIdCard(stEmployeeParam.getIdCard()); + tokenService.refreshToken( SecurityUtils.getLoginUser()); + + employee.setId(user.getUserId()); + return toAjax(stEmployeeService.updateStEmployee(employee)); + } + + @Resource(name = "captchaProducer") + private Producer captchaProducer; + + @Resource(name = "captchaProducerMath") + private Producer captchaProducerMath; + + @Autowired + private RedisCache redisCache; + + @Autowired + private ISysConfigService configService; + /** + * 生成验证码 + */ + @GetMapping("/captchaImage") + public AjaxResult getCode(HttpServletResponse response) throws IOException + { + AjaxResult ajax = AjaxResult.success(); + boolean captchaEnabled = configService.selectCaptchaEnabled(); + ajax.put("captchaEnabled", captchaEnabled); + if (!captchaEnabled) + { + return ajax; + } + + // 保存验证码信息 + String uuid = IdUtils.simpleUUID(); + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; + + String capStr = null, code = null; + BufferedImage image = null; + + // 生成验证码 + String captchaType = StaffingConfig.getCaptchaType(); + if ("math".equals(captchaType)) + { + String capText = captchaProducerMath.createText(); + capStr = capText.substring(0, capText.lastIndexOf("@")); + code = capText.substring(capText.lastIndexOf("@") + 1); + image = captchaProducerMath.createImage(capStr); + } + else if ("char".equals(captchaType)) + { + capStr = code = captchaProducer.createText(); + image = captchaProducer.createImage(capStr); + } + + redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); + // 转换流信息写出 + FastByteArrayOutputStream os = new FastByteArrayOutputStream(); + try + { + ImageIO.write(image, "jpg", os); + } + catch (IOException e) + { + return AjaxResult.error(e.getMessage()); + } + + ajax.put("uuid", uuid); + ajax.put("img", Base64.encode(os.toByteArray())); + return ajax; + } + + + @Autowired + private SysLoginService loginService; + + @Autowired + private ISysMenuService menuService; + + @Autowired + private SysPermissionService permissionService; + + /** + * 登录方法 + * + * @param loginBody 登录信息 + * @return 结果 + */ + @PostMapping("/login") + public AjaxResult login(@RequestBody LoginBody loginBody) + { + AjaxResult ajax = AjaxResult.success(); + // 生成令牌 + String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), + loginBody.getUuid()); + ajax.put(Constants.TOKEN, token); + return ajax; + } + + + /** + * wx登录方法 + * + * @param loginBody 登录信息 + * @return 结果 + */ + @PostMapping("/wxlogin") + public AjaxResult wxlogin(@RequestBody LoginBody loginBody) + { + AjaxResult ajax = AjaxResult.success(); + // 生成令牌 + String token = loginService.wxLogin(loginBody.getLoginCode(), loginBody.getPhoneCode()); + ajax.put(Constants.TOKEN, token); + return ajax; + } + + /** + * 获取用户信息 + * + * @return 用户信息 + */ + @GetMapping("getInfo") + public AjaxResult getInfo() + { + SysUser user = SecurityUtils.getLoginUser().getUser(); + // 角色集合 + Set roles = permissionService.getRolePermission(user); + // 权限集合 + Set 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() + { + Long userId = SecurityUtils.getUserId(); + List menus = menuService.selectMenuTreeByUserId(userId); + return AjaxResult.success(menuService.buildMenus(menus)); + } + +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/merchant/MerchantFundController.java b/staffing-admin/src/main/java/com/staffing/web/controller/merchant/MerchantFundController.java new file mode 100644 index 0000000..99168ea --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/merchant/MerchantFundController.java @@ -0,0 +1,117 @@ +package com.staffing.web.controller.merchant; + +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.page.TableDataInfo; +import com.staffing.custom.domain.StEmployeeFundRecord; +import com.staffing.custom.domain.StTask; +import com.staffing.custom.domain.StTaskSign; +import com.staffing.custom.param.FxParam; +import com.staffing.custom.service.IStEmployeeFundRecordService; +import com.staffing.custom.service.IStTaskService; +import com.staffing.custom.service.IStTaskSignService; +import com.staffing.custom.service.TransferBatchService; +import com.wechat.pay.java.core.notification.RequestParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Date; +import java.util.Enumeration; +import java.util.List; + +/** + * 任务Controller + * + * @author staffing + * @date 2024-08-27 + */ +@RestController +@RequestMapping("/merchant/fund") +public class MerchantFundController extends BaseController +{ + @Autowired + private IStTaskService stTaskService; + @Autowired + private IStTaskSignService stTaskSignService; + + @Autowired + private IStEmployeeFundRecordService stEmployeeFundRecordService; + + @Autowired + private TransferBatchService transferBatchService; + +// @GetMapping("/list") +// @PreAuthorize("@ss.hasPermi('task:edit')") +// public TableDataInfo list(StTask stTask) +// { +// startPage(); +// stTask.setStatus(1); +// // 获取当前时间 +// ZonedDateTime now = ZonedDateTime.now(); +// // 将当前时间加上一天,‌然后设置为0点0分 +// ZonedDateTime nextDayStart = now.plusDays(1).truncatedTo(ChronoUnit.DAYS); +// Date nextDayZero = Date.from(nextDayStart.toInstant()); +// if (stTask.getDateStatus() != 0){ +// stTask.setTaskDateCompare(nextDayZero); +// } +// stTask.getParams().put("order", nextDayZero); +// List list = stTaskService.selectStTaskList(stTask, 0); +// return getDataTable(list); +// } + + /** + * 获取任务详细信息 + */ + @GetMapping(value = "/details/{id}") + @PreAuthorize("@ss.hasPermi('task:edit')") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(stTaskService.selectStTaskById(id)); + } + + /** + * 修改签到 + */ + @PutMapping("/editSign") + @PreAuthorize("@ss.hasPermi('task:edit')") + public AjaxResult edit(@RequestBody StTaskSign stTaskSign) + { + return toAjax(stTaskSignService.updateStTaskSign(stTaskSign)); + } + + @PutMapping("/fx") + @PreAuthorize("@ss.hasPermi('task:edit')") + public AjaxResult fx(@RequestBody FxParam fxParam) + { + return success(stEmployeeFundRecordService.faxin(fxParam)); + } + + @PostMapping("/fxResult") + public ResponseEntity.BodyBuilder fxResult(HttpServletRequest request, @RequestBody String body) + { + + StringBuilder headers = new StringBuilder(); + Enumeration headerNames = request.getHeaderNames(); + while (headerNames.hasMoreElements()) { + String headerName = headerNames.nextElement(); + String headerValue = request.getHeader(headerName); + headers.append(headerName).append(": ").append(headerValue).append("\n"); + } + + logger.info("fxResult=====Headers:\n" + headers.toString() + "\nBody:\n" + body); + + RequestParam requestParam = new RequestParam.Builder() + .serialNumber("123") + .nonce("aaaa") + .signature("aaaa") + .timestamp("1234") + .body(body) + .build(); + return transferBatchService.parse(requestParam); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/merchant/MerchantTaskController.java b/staffing-admin/src/main/java/com/staffing/web/controller/merchant/MerchantTaskController.java new file mode 100644 index 0000000..b3ed983 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/merchant/MerchantTaskController.java @@ -0,0 +1,96 @@ +package com.staffing.web.controller.merchant; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.staffing.common.annotation.Excel; +import com.staffing.common.annotation.Log; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.page.TableDataInfo; +import com.staffing.common.enums.BusinessType; +import com.staffing.common.utils.poi.ExcelUtil; +import com.staffing.custom.domain.StEmployeeFundRecord; +import com.staffing.custom.domain.StTask; +import com.staffing.custom.domain.StTaskSign; +import com.staffing.custom.service.IStEmployeeFundRecordService; +import com.staffing.custom.service.IStTaskService; +import com.staffing.custom.service.IStTaskSignService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Date; +import java.util.List; + +/** + * 任务Controller + * + * @author staffing + * @date 2024-08-27 + */ +@RestController +@RequestMapping("/merchant/task") +public class MerchantTaskController extends BaseController +{ + @Autowired + private IStTaskService stTaskService; + @Autowired + private IStTaskSignService stTaskSignService; + @Autowired + private IStEmployeeFundRecordService employeeFundRecordService; + /** + * 查询任务列表 + */ + @GetMapping("/list") + @PreAuthorize("@ss.hasPermi('task:edit')") + public TableDataInfo list(StTask stTask) + { + startPage(); + stTask.setStatus(1); + // 获取当前时间 + ZonedDateTime now = ZonedDateTime.now(); + // 将当前时间加上一天,‌然后设置为0点0分 + ZonedDateTime nextDayStart = now.plusDays(1).truncatedTo(ChronoUnit.DAYS); + Date nextDayZero = Date.from(nextDayStart.toInstant()); + if (stTask.getDateStatus() != 0){ + stTask.setTaskDateCompare(nextDayZero); + } + stTask.getParams().put("order", nextDayZero); + List list = stTaskService.selectStTaskList(stTask, 0); + return getDataTable(list); + } + + /** + * 获取任务详细信息 + */ + @GetMapping(value = "/details/{id}") + @PreAuthorize("@ss.hasPermi('task:edit')") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(stTaskService.selectStTaskById(id)); + } + + /** + * 获取任务详细信息 + */ + @GetMapping(value = "/fxInfo/{id}") + @PreAuthorize("@ss.hasPermi('task:edit')") + public AjaxResult fxInfo(@PathVariable("id") Long id) + { + return success(stTaskService.selectStTaskById(id, true)); + } + + /** + * 修改签到 + */ + @PutMapping("/editSign") + @PreAuthorize("@ss.hasPermi('task:edit')") + public AjaxResult edit(@RequestBody StTaskSign updateStTaskSign) + { + return toAjax(stTaskSignService.signUp(updateStTaskSign)); + } + + +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/merchant/MerchantUserController.java b/staffing-admin/src/main/java/com/staffing/web/controller/merchant/MerchantUserController.java new file mode 100644 index 0000000..cb77de5 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/merchant/MerchantUserController.java @@ -0,0 +1,210 @@ +package com.staffing.web.controller.merchant; + +import com.google.code.kaptcha.Producer; +import com.staffing.common.config.StaffingConfig; +import com.staffing.common.constant.CacheConstants; +import com.staffing.common.constant.Constants; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.domain.entity.SysMenu; +import com.staffing.common.core.domain.entity.SysUser; +import com.staffing.common.core.domain.model.LoginBody; +import com.staffing.common.core.redis.RedisCache; +import com.staffing.common.utils.SecurityUtils; +import com.staffing.common.utils.sign.Base64; +import com.staffing.common.utils.uuid.IdUtils; +import com.staffing.custom.domain.StEmployee; +import com.staffing.custom.service.IStEmployeeService; +import com.staffing.framework.web.service.SysLoginService; +import com.staffing.framework.web.service.SysPermissionService; +import com.staffing.framework.web.service.TokenService; +import com.staffing.system.service.ISysConfigService; +import com.staffing.system.service.ISysMenuService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.FastByteArrayOutputStream; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.imageio.ImageIO; +import javax.servlet.http.HttpServletResponse; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * 用户信息 + * + * @author staffing + */ +@RestController +@RequestMapping("/merchant/user") +public class MerchantUserController extends BaseController +{ + @Autowired + private IStEmployeeService stEmployeeService; + @Autowired + private TokenService tokenService; + /** + * 修改用户 + */ + @PutMapping("profile") + public AjaxResult edit(@RequestBody StEmployee stEmployeeParam) + { + StEmployee employee = new StEmployee(); + employee.setRealName(stEmployeeParam.getRealName()); + employee.setPhone(stEmployeeParam.getPhone()); + employee.setIdCard(stEmployeeParam.getIdCard()); + + + SysUser user = SecurityUtils.getLoginUser().getUser(); + user.setNickName(stEmployeeParam.getRealName()); + user.setPhonenumber(stEmployeeParam.getPhone()); + user.setIdCard(stEmployeeParam.getIdCard()); + tokenService.refreshToken( SecurityUtils.getLoginUser()); + + employee.setId(user.getUserId()); + return toAjax(stEmployeeService.updateStEmployee(employee)); + } + + @Resource(name = "captchaProducer") + private Producer captchaProducer; + + @Resource(name = "captchaProducerMath") + private Producer captchaProducerMath; + + @Autowired + private RedisCache redisCache; + + @Autowired + private ISysConfigService configService; + /** + * 生成验证码 + */ + @GetMapping("/captchaImage") + public AjaxResult getCode(HttpServletResponse response) throws IOException + { + AjaxResult ajax = AjaxResult.success(); + boolean captchaEnabled = configService.selectCaptchaEnabled(); + ajax.put("captchaEnabled", captchaEnabled); + if (!captchaEnabled) + { + return ajax; + } + + // 保存验证码信息 + String uuid = IdUtils.simpleUUID(); + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; + + String capStr = null, code = null; + BufferedImage image = null; + + // 生成验证码 + String captchaType = StaffingConfig.getCaptchaType(); + if ("math".equals(captchaType)) + { + String capText = captchaProducerMath.createText(); + capStr = capText.substring(0, capText.lastIndexOf("@")); + code = capText.substring(capText.lastIndexOf("@") + 1); + image = captchaProducerMath.createImage(capStr); + } + else if ("char".equals(captchaType)) + { + capStr = code = captchaProducer.createText(); + image = captchaProducer.createImage(capStr); + } + + redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); + // 转换流信息写出 + FastByteArrayOutputStream os = new FastByteArrayOutputStream(); + try + { + ImageIO.write(image, "jpg", os); + } + catch (IOException e) + { + return AjaxResult.error(e.getMessage()); + } + + ajax.put("uuid", uuid); + ajax.put("img", Base64.encode(os.toByteArray())); + return ajax; + } + + + @Autowired + private SysLoginService loginService; + + @Autowired + private ISysMenuService menuService; + + @Autowired + private SysPermissionService permissionService; + + /** + * 登录方法 + * + * @param loginBody 登录信息 + * @return 结果 + */ + @PostMapping("/login") + public AjaxResult login(@RequestBody LoginBody loginBody) + { + AjaxResult ajax = AjaxResult.success(); + // 生成令牌 + String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), + loginBody.getUuid()); + ajax.put(Constants.TOKEN, token); + return ajax; + } + + /** + * wx登录方法 + * + * @param loginBody 登录信息 + * @return 结果 + */ + @PostMapping("/wxlogin") + public AjaxResult wxlogin(@RequestBody LoginBody loginBody) + { + AjaxResult ajax = AjaxResult.success(); + // 生成令牌 + String token = loginService.wxMerchantLogin(loginBody.getLoginCode(), loginBody.getPhoneCode()); + ajax.put(Constants.TOKEN, token); + return ajax; + } + /** + * 获取用户信息 + * + * @return 用户信息 + */ + @GetMapping("getInfo") + public AjaxResult getInfo() + { + SysUser user = SecurityUtils.getLoginUser().getUser(); + // 角色集合 + Set roles = permissionService.getRolePermission(user); + // 权限集合 + Set 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() + { + Long userId = SecurityUtils.getUserId(); + List menus = menuService.selectMenuTreeByUserId(userId); + return AjaxResult.success(menuService.buildMenus(menus)); + } + +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/monitor/CacheController.java b/staffing-admin/src/main/java/com/staffing/web/controller/monitor/CacheController.java new file mode 100644 index 0000000..73ea5c3 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/monitor/CacheController.java @@ -0,0 +1,121 @@ +package com.staffing.web.controller.monitor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.TreeSet; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisCallback; +import org.springframework.data.redis.core.RedisTemplate; +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.staffing.common.constant.CacheConstants; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.utils.StringUtils; +import com.staffing.system.domain.SysCache; + +/** + * 缓存监控 + * + * @author staffing + */ +@RestController +@RequestMapping("/monitor/cache") +public class CacheController +{ + @Autowired + private RedisTemplate redisTemplate; + + private final static List caches = new ArrayList(); + { + caches.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "用户信息")); + caches.add(new SysCache(CacheConstants.SYS_CONFIG_KEY, "配置信息")); + caches.add(new SysCache(CacheConstants.SYS_DICT_KEY, "数据字典")); + caches.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码")); + caches.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交")); + caches.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理")); + caches.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数")); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping() + public AjaxResult getInfo() throws Exception + { + Properties info = (Properties) redisTemplate.execute((RedisCallback) connection -> connection.info()); + Properties commandStats = (Properties) redisTemplate.execute((RedisCallback) connection -> connection.info("commandstats")); + Object dbSize = redisTemplate.execute((RedisCallback) connection -> connection.dbSize()); + + Map result = new HashMap<>(3); + result.put("info", info); + result.put("dbSize", dbSize); + + List> pieList = new ArrayList<>(); + commandStats.stringPropertyNames().forEach(key -> { + Map data = new HashMap<>(2); + String property = commandStats.getProperty(key); + data.put("name", StringUtils.removeStart(key, "cmdstat_")); + data.put("value", StringUtils.substringBetween(property, "calls=", ",usec")); + pieList.add(data); + }); + result.put("commandStats", pieList); + return AjaxResult.success(result); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping("/getNames") + public AjaxResult cache() + { + return AjaxResult.success(caches); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping("/getKeys/{cacheName}") + public AjaxResult getCacheKeys(@PathVariable String cacheName) + { + Set cacheKeys = redisTemplate.keys(cacheName + "*"); + return AjaxResult.success(new TreeSet<>(cacheKeys)); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping("/getValue/{cacheName}/{cacheKey}") + public AjaxResult getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey) + { + String cacheValue = redisTemplate.opsForValue().get(cacheKey); + SysCache sysCache = new SysCache(cacheName, cacheKey, cacheValue); + return AjaxResult.success(sysCache); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @DeleteMapping("/clearCacheName/{cacheName}") + public AjaxResult clearCacheName(@PathVariable String cacheName) + { + Collection cacheKeys = redisTemplate.keys(cacheName + "*"); + redisTemplate.delete(cacheKeys); + return AjaxResult.success(); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @DeleteMapping("/clearCacheKey/{cacheKey}") + public AjaxResult clearCacheKey(@PathVariable String cacheKey) + { + redisTemplate.delete(cacheKey); + return AjaxResult.success(); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @DeleteMapping("/clearCacheAll") + public AjaxResult clearCacheAll() + { + Collection cacheKeys = redisTemplate.keys("*"); + redisTemplate.delete(cacheKeys); + return AjaxResult.success(); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/monitor/ServerController.java b/staffing-admin/src/main/java/com/staffing/web/controller/monitor/ServerController.java new file mode 100644 index 0000000..33713f4 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/monitor/ServerController.java @@ -0,0 +1,27 @@ +package com.staffing.web.controller.monitor; + +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.staffing.common.core.domain.AjaxResult; +import com.staffing.framework.web.domain.Server; + +/** + * 服务器监控 + * + * @author staffing + */ +@RestController +@RequestMapping("/monitor/server") +public class ServerController +{ + @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/staffing-admin/src/main/java/com/staffing/web/controller/monitor/SysLogininforController.java b/staffing-admin/src/main/java/com/staffing/web/controller/monitor/SysLogininforController.java new file mode 100644 index 0000000..8a30cca --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/monitor/SysLogininforController.java @@ -0,0 +1,82 @@ +package com.staffing.web.controller.monitor; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +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.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.staffing.common.annotation.Log; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.page.TableDataInfo; +import com.staffing.common.enums.BusinessType; +import com.staffing.common.utils.poi.ExcelUtil; +import com.staffing.framework.web.service.SysPasswordService; +import com.staffing.system.domain.SysLogininfor; +import com.staffing.system.service.ISysLogininforService; + +/** + * 系统访问记录 + * + * @author staffing + */ +@RestController +@RequestMapping("/monitor/logininfor") +public class SysLogininforController extends BaseController +{ + @Autowired + private ISysLogininforService logininforService; + + @Autowired + private SysPasswordService passwordService; + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:list')") + @GetMapping("/list") + public TableDataInfo list(SysLogininfor logininfor) + { + startPage(); + List list = logininforService.selectLogininforList(logininfor); + return getDataTable(list); + } + + @Log(title = "登录日志", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('monitor:logininfor:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysLogininfor logininfor) + { + List list = logininforService.selectLogininforList(logininfor); + ExcelUtil util = new ExcelUtil(SysLogininfor.class); + util.exportExcel(response, 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 success(); + } + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:unlock')") + @Log(title = "账户解锁", businessType = BusinessType.OTHER) + @GetMapping("/unlock/{userName}") + public AjaxResult unlock(@PathVariable("userName") String userName) + { + passwordService.clearLoginRecordCache(userName); + return success(); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/monitor/SysOperlogController.java b/staffing-admin/src/main/java/com/staffing/web/controller/monitor/SysOperlogController.java new file mode 100644 index 0000000..dd41646 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/monitor/SysOperlogController.java @@ -0,0 +1,69 @@ +package com.staffing.web.controller.monitor; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +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.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.staffing.common.annotation.Log; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.page.TableDataInfo; +import com.staffing.common.enums.BusinessType; +import com.staffing.common.utils.poi.ExcelUtil; +import com.staffing.system.domain.SysOperLog; +import com.staffing.system.service.ISysOperLogService; + +/** + * 操作日志记录 + * + * @author staffing + */ +@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 list = operLogService.selectOperLogList(operLog); + return getDataTable(list); + } + + @Log(title = "操作日志", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('monitor:operlog:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysOperLog operLog) + { + List list = operLogService.selectOperLogList(operLog); + ExcelUtil util = new ExcelUtil(SysOperLog.class); + util.exportExcel(response, list, "操作日志"); + } + + @Log(title = "操作日志", businessType = BusinessType.DELETE) + @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 success(); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/monitor/SysUserOnlineController.java b/staffing-admin/src/main/java/com/staffing/web/controller/monitor/SysUserOnlineController.java new file mode 100644 index 0000000..5292325 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/monitor/SysUserOnlineController.java @@ -0,0 +1,83 @@ +package com.staffing.web.controller.monitor; + +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.staffing.common.annotation.Log; +import com.staffing.common.constant.CacheConstants; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.domain.model.LoginUser; +import com.staffing.common.core.page.TableDataInfo; +import com.staffing.common.core.redis.RedisCache; +import com.staffing.common.enums.BusinessType; +import com.staffing.common.utils.StringUtils; +import com.staffing.system.domain.SysUserOnline; +import com.staffing.system.service.ISysUserOnlineService; + +/** + * 在线用户监控 + * + * @author staffing + */ +@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 keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*"); + List userOnlineList = new ArrayList(); + for (String key : keys) + { + LoginUser user = redisCache.getCacheObject(key); + if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) + { + userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user)); + } + else if (StringUtils.isNotEmpty(ipaddr)) + { + userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user)); + } + else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser())) + { + 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.FORCE) + @DeleteMapping("/{tokenId}") + public AjaxResult forceLogout(@PathVariable String tokenId) + { + redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId); + return success(); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/system/SysConfigController.java b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysConfigController.java new file mode 100644 index 0000000..4357fb5 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysConfigController.java @@ -0,0 +1,133 @@ +package com.staffing.web.controller.system; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +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.staffing.common.annotation.Log; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.page.TableDataInfo; +import com.staffing.common.enums.BusinessType; +import com.staffing.common.utils.poi.ExcelUtil; +import com.staffing.system.domain.SysConfig; +import com.staffing.system.service.ISysConfigService; + +/** + * 参数配置 信息操作处理 + * + * @author staffing + */ +@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 list = configService.selectConfigList(config); + return getDataTable(list); + } + + @Log(title = "参数管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:config:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysConfig config) + { + List list = configService.selectConfigList(config); + ExcelUtil util = new ExcelUtil(SysConfig.class); + util.exportExcel(response, list, "参数数据"); + } + + /** + * 根据参数编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:config:query')") + @GetMapping(value = "/{configId}") + public AjaxResult getInfo(@PathVariable Long configId) + { + return success(configService.selectConfigById(configId)); + } + + /** + * 根据参数键名查询参数值 + */ + @GetMapping(value = "/configKey/{configKey}") + public AjaxResult getConfigKey(@PathVariable String configKey) + { + return success(configService.selectConfigByKey(configKey)); + } + + /** + * 新增参数配置 + */ + @PreAuthorize("@ss.hasPermi('system:config:add')") + @Log(title = "参数管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysConfig config) + { + if (!configService.checkConfigKeyUnique(config)) + { + return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在"); + } + config.setCreateBy(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 (!configService.checkConfigKeyUnique(config)) + { + return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在"); + } + config.setUpdateBy(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) + { + configService.deleteConfigByIds(configIds); + return success(); + } + + /** + * 刷新参数缓存 + */ + @PreAuthorize("@ss.hasPermi('system:config:remove')") + @Log(title = "参数管理", businessType = BusinessType.CLEAN) + @DeleteMapping("/refreshCache") + public AjaxResult refreshCache() + { + configService.resetConfigCache(); + return success(); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/system/SysDeptController.java b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysDeptController.java new file mode 100644 index 0000000..b695b9d --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysDeptController.java @@ -0,0 +1,132 @@ +package com.staffing.web.controller.system; + +import java.util.List; +import org.apache.commons.lang3.ArrayUtils; +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.staffing.common.annotation.Log; +import com.staffing.common.constant.UserConstants; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.domain.entity.SysDept; +import com.staffing.common.enums.BusinessType; +import com.staffing.common.utils.StringUtils; +import com.staffing.system.service.ISysDeptService; + +/** + * 部门信息 + * + * @author staffing + */ +@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 depts = deptService.selectDeptList(dept); + return success(depts); + } + + /** + * 查询部门列表(排除节点) + */ + @PreAuthorize("@ss.hasPermi('system:dept:list')") + @GetMapping("/list/exclude/{deptId}") + public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) + { + List depts = deptService.selectDeptList(new SysDept()); + depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + "")); + return success(depts); + } + + /** + * 根据部门编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:dept:query')") + @GetMapping(value = "/{deptId}") + public AjaxResult getInfo(@PathVariable Long deptId) + { + deptService.checkDeptDataScope(deptId); + return success(deptService.selectDeptById(deptId)); + } + + /** + * 新增部门 + */ + @PreAuthorize("@ss.hasPermi('system:dept:add')") + @Log(title = "部门管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDept dept) + { + if (!deptService.checkDeptNameUnique(dept)) + { + return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在"); + } + dept.setCreateBy(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) + { + Long deptId = dept.getDeptId(); + deptService.checkDeptDataScope(deptId); + if (!deptService.checkDeptNameUnique(dept)) + { + return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在"); + } + else if (dept.getParentId().equals(deptId)) + { + return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己"); + } + else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0) + { + return error("该部门包含未停用的子部门!"); + } + dept.setUpdateBy(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 warn("存在下级部门,不允许删除"); + } + if (deptService.checkDeptExistUser(deptId)) + { + return warn("部门存在用户,不允许删除"); + } + deptService.checkDeptDataScope(deptId); + return toAjax(deptService.deleteDeptById(deptId)); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/system/SysDictDataController.java b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysDictDataController.java new file mode 100644 index 0000000..866dab8 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysDictDataController.java @@ -0,0 +1,121 @@ +package com.staffing.web.controller.system; + +import java.util.ArrayList; +import java.util.List; +import javax.servlet.http.HttpServletResponse; +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.staffing.common.annotation.Log; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.domain.entity.SysDictData; +import com.staffing.common.core.page.TableDataInfo; +import com.staffing.common.enums.BusinessType; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.poi.ExcelUtil; +import com.staffing.system.service.ISysDictDataService; +import com.staffing.system.service.ISysDictTypeService; + +/** + * 数据字典信息 + * + * @author staffing + */ +@RestController +@RequestMapping("/system/dict/data") +public class SysDictDataController extends BaseController +{ + @Autowired + private ISysDictDataService dictDataService; + + @Autowired + private ISysDictTypeService dictTypeService; + + @PreAuthorize("@ss.hasPermi('system:dict:list')") + @GetMapping("/list") + public TableDataInfo list(SysDictData dictData) + { + startPage(); + List list = dictDataService.selectDictDataList(dictData); + return getDataTable(list); + } + + @Log(title = "字典数据", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:dict:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysDictData dictData) + { + List list = dictDataService.selectDictDataList(dictData); + ExcelUtil util = new ExcelUtil(SysDictData.class); + util.exportExcel(response, list, "字典数据"); + } + + /** + * 查询字典数据详细 + */ + @PreAuthorize("@ss.hasPermi('system:dict:query')") + @GetMapping(value = "/{dictCode}") + public AjaxResult getInfo(@PathVariable Long dictCode) + { + return success(dictDataService.selectDictDataById(dictCode)); + } + + /** + * 根据字典类型查询字典数据信息 + */ + @GetMapping(value = "/type/{dictType}") + public AjaxResult dictType(@PathVariable String dictType) + { + List data = dictTypeService.selectDictDataByType(dictType); + if (StringUtils.isNull(data)) + { + data = new ArrayList(); + } + return success(data); + } + + /** + * 新增字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:add')") + @Log(title = "字典数据", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDictData dict) + { + dict.setCreateBy(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(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) + { + dictDataService.deleteDictDataByIds(dictCodes); + return success(); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/system/SysDictTypeController.java b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysDictTypeController.java new file mode 100644 index 0000000..4471f19 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysDictTypeController.java @@ -0,0 +1,131 @@ +package com.staffing.web.controller.system; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +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.staffing.common.annotation.Log; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.domain.entity.SysDictType; +import com.staffing.common.core.page.TableDataInfo; +import com.staffing.common.enums.BusinessType; +import com.staffing.common.utils.poi.ExcelUtil; +import com.staffing.system.service.ISysDictTypeService; + +/** + * 数据字典信息 + * + * @author staffing + */ +@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 list = dictTypeService.selectDictTypeList(dictType); + return getDataTable(list); + } + + @Log(title = "字典类型", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:dict:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysDictType dictType) + { + List list = dictTypeService.selectDictTypeList(dictType); + ExcelUtil util = new ExcelUtil(SysDictType.class); + util.exportExcel(response, list, "字典类型"); + } + + /** + * 查询字典类型详细 + */ + @PreAuthorize("@ss.hasPermi('system:dict:query')") + @GetMapping(value = "/{dictId}") + public AjaxResult getInfo(@PathVariable Long dictId) + { + return success(dictTypeService.selectDictTypeById(dictId)); + } + + /** + * 新增字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:add')") + @Log(title = "字典类型", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDictType dict) + { + if (!dictTypeService.checkDictTypeUnique(dict)) + { + return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在"); + } + dict.setCreateBy(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 (!dictTypeService.checkDictTypeUnique(dict)) + { + return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在"); + } + dict.setUpdateBy(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) + { + dictTypeService.deleteDictTypeByIds(dictIds); + return success(); + } + + /** + * 刷新字典缓存 + */ + @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @Log(title = "字典类型", businessType = BusinessType.CLEAN) + @DeleteMapping("/refreshCache") + public AjaxResult refreshCache() + { + dictTypeService.resetDictCache(); + return success(); + } + + /** + * 获取字典选择框列表 + */ + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + List dictTypes = dictTypeService.selectDictTypeAll(); + return success(dictTypes); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/system/SysIndexController.java b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysIndexController.java new file mode 100644 index 0000000..ecc9b99 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysIndexController.java @@ -0,0 +1,29 @@ +package com.staffing.web.controller.system; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.staffing.common.config.StaffingConfig; +import com.staffing.common.utils.StringUtils; + +/** + * 首页 + * + * @author staffing + */ +@RestController +public class SysIndexController +{ + /** 系统基础配置 */ + @Autowired + private StaffingConfig staffingConfig; + + /** + * 访问首页,提示语 + */ + @RequestMapping("/") + public String index() + { + return StringUtils.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。", staffingConfig.getName(), staffingConfig.getVersion()); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/system/SysLoginController.java b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysLoginController.java new file mode 100644 index 0000000..53bd3ae --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysLoginController.java @@ -0,0 +1,87 @@ +package com.staffing.web.controller.system; + +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.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import com.staffing.common.constant.Constants; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.domain.entity.SysMenu; +import com.staffing.common.core.domain.entity.SysUser; +import com.staffing.common.core.domain.model.LoginBody; +import com.staffing.common.utils.SecurityUtils; +import com.staffing.framework.web.service.SysLoginService; +import com.staffing.framework.web.service.SysPermissionService; +import com.staffing.system.service.ISysMenuService; + +/** + * 登录验证 + * + * @author staffing + */ +@RestController +public class SysLoginController +{ + @Autowired + private SysLoginService loginService; + + @Autowired + private ISysMenuService menuService; + + @Autowired + private SysPermissionService permissionService; + + /** + * 登录方法 + * + * @param loginBody 登录信息 + * @return 结果 + */ + @PostMapping("/login") + public AjaxResult login(@RequestBody LoginBody loginBody) + { + AjaxResult ajax = AjaxResult.success(); + // 生成令牌 + String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), + loginBody.getUuid()); + ajax.put(Constants.TOKEN, token); + return ajax; + } + + + /** + * 获取用户信息 + * + * @return 用户信息 + */ + @GetMapping("getInfo") + public AjaxResult getInfo() + { + SysUser user = SecurityUtils.getLoginUser().getUser(); + // 角色集合 + Set roles = permissionService.getRolePermission(user); + // 权限集合 + Set 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() + { + Long userId = SecurityUtils.getUserId(); + List menus = menuService.selectMenuTreeByUserId(userId); + return AjaxResult.success(menuService.buildMenus(menus)); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/system/SysMenuController.java b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysMenuController.java new file mode 100644 index 0000000..affe5d9 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysMenuController.java @@ -0,0 +1,142 @@ +package com.staffing.web.controller.system; + +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.staffing.common.annotation.Log; +import com.staffing.common.constant.UserConstants; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.domain.entity.SysMenu; +import com.staffing.common.enums.BusinessType; +import com.staffing.common.utils.StringUtils; +import com.staffing.system.service.ISysMenuService; + +/** + * 菜单信息 + * + * @author staffing + */ +@RestController +@RequestMapping("/system/menu") +public class SysMenuController extends BaseController +{ + @Autowired + private ISysMenuService menuService; + + /** + * 获取菜单列表 + */ + @PreAuthorize("@ss.hasPermi('system:menu:list')") + @GetMapping("/list") + public AjaxResult list(SysMenu menu) + { + List menus = menuService.selectMenuList(menu, getUserId()); + return success(menus); + } + + /** + * 根据菜单编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:menu:query')") + @GetMapping(value = "/{menuId}") + public AjaxResult getInfo(@PathVariable Long menuId) + { + return success(menuService.selectMenuById(menuId)); + } + + /** + * 获取菜单下拉树列表 + */ + @GetMapping("/treeselect") + public AjaxResult treeselect(SysMenu menu) + { + List menus = menuService.selectMenuList(menu, getUserId()); + return success(menuService.buildMenuTreeSelect(menus)); + } + + /** + * 加载对应角色菜单列表树 + */ + @GetMapping(value = "/roleMenuTreeselect/{roleId}") + public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId) + { + List menus = menuService.selectMenuList(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 (!menuService.checkMenuNameUnique(menu)) + { + return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } + else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) + { + return error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); + } + menu.setCreateBy(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 (!menuService.checkMenuNameUnique(menu)) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } + else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); + } + else if (menu.getMenuId().equals(menu.getParentId())) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己"); + } + menu.setUpdateBy(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 warn("存在子菜单,不允许删除"); + } + if (menuService.checkMenuExistRole(menuId)) + { + return warn("菜单已分配,不允许删除"); + } + return toAjax(menuService.deleteMenuById(menuId)); + } +} \ No newline at end of file diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/system/SysNoticeController.java b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysNoticeController.java new file mode 100644 index 0000000..f6742d8 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysNoticeController.java @@ -0,0 +1,91 @@ +package com.staffing.web.controller.system; + +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.staffing.common.annotation.Log; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.page.TableDataInfo; +import com.staffing.common.enums.BusinessType; +import com.staffing.system.domain.SysNotice; +import com.staffing.system.service.ISysNoticeService; + +/** + * 公告 信息操作处理 + * + * @author staffing + */ +@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 list = noticeService.selectNoticeList(notice); + return getDataTable(list); + } + + /** + * 根据通知公告编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:notice:query')") + @GetMapping(value = "/{noticeId}") + public AjaxResult getInfo(@PathVariable Long noticeId) + { + return 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(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(getUsername()); + return toAjax(noticeService.updateNotice(notice)); + } + + /** + * 删除通知公告 + */ + @PreAuthorize("@ss.hasPermi('system:notice:remove')") + @Log(title = "通知公告", businessType = BusinessType.DELETE) + @DeleteMapping("/{noticeIds}") + public AjaxResult remove(@PathVariable Long[] noticeIds) + { + return toAjax(noticeService.deleteNoticeByIds(noticeIds)); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/system/SysPostController.java b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysPostController.java new file mode 100644 index 0000000..c98b939 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysPostController.java @@ -0,0 +1,129 @@ +package com.staffing.web.controller.system; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +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.staffing.common.annotation.Log; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.page.TableDataInfo; +import com.staffing.common.enums.BusinessType; +import com.staffing.common.utils.poi.ExcelUtil; +import com.staffing.system.domain.SysPost; +import com.staffing.system.service.ISysPostService; + +/** + * 岗位信息操作处理 + * + * @author staffing + */ +@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 list = postService.selectPostList(post); + return getDataTable(list); + } + + @Log(title = "岗位管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:post:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysPost post) + { + List list = postService.selectPostList(post); + ExcelUtil util = new ExcelUtil(SysPost.class); + util.exportExcel(response, list, "岗位数据"); + } + + /** + * 根据岗位编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:post:query')") + @GetMapping(value = "/{postId}") + public AjaxResult getInfo(@PathVariable Long postId) + { + return success(postService.selectPostById(postId)); + } + + /** + * 新增岗位 + */ + @PreAuthorize("@ss.hasPermi('system:post:add')") + @Log(title = "岗位管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysPost post) + { + if (!postService.checkPostNameUnique(post)) + { + return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在"); + } + else if (!postService.checkPostCodeUnique(post)) + { + return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在"); + } + post.setCreateBy(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 (!postService.checkPostNameUnique(post)) + { + return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在"); + } + else if (!postService.checkPostCodeUnique(post)) + { + return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在"); + } + post.setUpdateBy(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 posts = postService.selectPostAll(); + return success(posts); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/system/SysProfileController.java b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysProfileController.java new file mode 100644 index 0000000..8be25b9 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysProfileController.java @@ -0,0 +1,137 @@ +package com.staffing.web.controller.system; + +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.staffing.common.annotation.Log; +import com.staffing.common.config.StaffingConfig; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.domain.entity.SysUser; +import com.staffing.common.core.domain.model.LoginUser; +import com.staffing.common.enums.BusinessType; +import com.staffing.common.utils.SecurityUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.file.FileUploadUtils; +import com.staffing.common.utils.file.MimeTypeUtils; +import com.staffing.framework.web.service.TokenService; +import com.staffing.system.service.ISysUserService; + +/** + * 个人信息 业务处理 + * + * @author staffing + */ +@RestController +@RequestMapping("/system/user/profile") +public class SysProfileController extends BaseController +{ + @Autowired + private ISysUserService userService; + + @Autowired + private TokenService tokenService; + + /** + * 个人信息 + */ + @GetMapping + public AjaxResult profile() + { + LoginUser loginUser = getLoginUser(); + 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) + { + LoginUser loginUser = getLoginUser(); + SysUser currentUser = loginUser.getUser(); + currentUser.setNickName(user.getNickName()); + currentUser.setEmail(user.getEmail()); + currentUser.setPhonenumber(user.getPhonenumber()); + currentUser.setSex(user.getSex()); + if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser)) + { + return error("修改用户'" + loginUser.getUsername() + "'失败,手机号码已存在"); + } + if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser)) + { + return error("修改用户'" + loginUser.getUsername() + "'失败,邮箱账号已存在"); + } + if (userService.updateUserProfile(currentUser) > 0) + { + // 更新缓存用户信息 + tokenService.setLoginUser(loginUser); + return success(); + } + return error("修改个人信息异常,请联系管理员"); + } + + /** + * 重置密码 + */ + @Log(title = "个人信息", businessType = BusinessType.UPDATE) + @PutMapping("/updatePwd") + public AjaxResult updatePwd(String oldPassword, String newPassword) + { + LoginUser loginUser = getLoginUser(); + String userName = loginUser.getUsername(); + String password = loginUser.getPassword(); + if (!SecurityUtils.matchesPassword(oldPassword, password)) + { + return error("修改密码失败,旧密码错误"); + } + if (SecurityUtils.matchesPassword(newPassword, password)) + { + return error("新密码不能与旧密码相同"); + } + newPassword = SecurityUtils.encryptPassword(newPassword); + if (userService.resetUserPwd(userName, newPassword) > 0) + { + // 更新缓存用户密码 + loginUser.getUser().setPassword(newPassword); + tokenService.setLoginUser(loginUser); + return success(); + } + return error("修改密码异常,请联系管理员"); + } + + /** + * 头像上传 + */ + @Log(title = "用户头像", businessType = BusinessType.UPDATE) + @PostMapping("/avatar") + public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception + { + if (!file.isEmpty()) + { + LoginUser loginUser = getLoginUser(); + String avatar = FileUploadUtils.upload(StaffingConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION); + if (userService.updateUserAvatar(loginUser.getUsername(), avatar)) + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("imgUrl", avatar); + // 更新缓存用户头像 + loginUser.getUser().setAvatar(avatar); + tokenService.setLoginUser(loginUser); + return ajax; + } + } + return error("上传图片异常,请联系管理员"); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/system/SysRegisterController.java b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysRegisterController.java new file mode 100644 index 0000000..15de781 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysRegisterController.java @@ -0,0 +1,38 @@ +package com.staffing.web.controller.system; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.domain.model.RegisterBody; +import com.staffing.common.utils.StringUtils; +import com.staffing.framework.web.service.SysRegisterService; +import com.staffing.system.service.ISysConfigService; + +/** + * 注册验证 + * + * @author staffing + */ +@RestController +public class SysRegisterController extends BaseController +{ + @Autowired + private SysRegisterService registerService; + + @Autowired + private ISysConfigService configService; + + @PostMapping("/register") + public AjaxResult register(@RequestBody RegisterBody user) + { + if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) + { + return error("当前系统没有开启注册功能!"); + } + String msg = registerService.register(user); + return StringUtils.isEmpty(msg) ? success() : error(msg); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/system/SysRoleController.java b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysRoleController.java new file mode 100644 index 0000000..1065e43 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysRoleController.java @@ -0,0 +1,262 @@ +package com.staffing.web.controller.system; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +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.staffing.common.annotation.Log; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.domain.entity.SysDept; +import com.staffing.common.core.domain.entity.SysRole; +import com.staffing.common.core.domain.entity.SysUser; +import com.staffing.common.core.domain.model.LoginUser; +import com.staffing.common.core.page.TableDataInfo; +import com.staffing.common.enums.BusinessType; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.poi.ExcelUtil; +import com.staffing.framework.web.service.SysPermissionService; +import com.staffing.framework.web.service.TokenService; +import com.staffing.system.domain.SysUserRole; +import com.staffing.system.service.ISysDeptService; +import com.staffing.system.service.ISysRoleService; +import com.staffing.system.service.ISysUserService; + +/** + * 角色信息 + * + * @author staffing + */ +@RestController +@RequestMapping("/system/role") +public class SysRoleController extends BaseController +{ + @Autowired + private ISysRoleService roleService; + + @Autowired + private TokenService tokenService; + + @Autowired + private SysPermissionService permissionService; + + @Autowired + private ISysUserService userService; + + @Autowired + private ISysDeptService deptService; + + @PreAuthorize("@ss.hasPermi('system:role:list')") + @GetMapping("/list") + public TableDataInfo list(SysRole role) + { + startPage(); + List list = roleService.selectRoleList(role); + return getDataTable(list); + } + + @Log(title = "角色管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:role:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysRole role) + { + List list = roleService.selectRoleList(role); + ExcelUtil util = new ExcelUtil(SysRole.class); + util.exportExcel(response, list, "角色数据"); + } + + /** + * 根据角色编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:role:query')") + @GetMapping(value = "/{roleId}") + public AjaxResult getInfo(@PathVariable Long roleId) + { + roleService.checkRoleDataScope(roleId); + return success(roleService.selectRoleById(roleId)); + } + + /** + * 新增角色 + */ + @PreAuthorize("@ss.hasPermi('system:role:add')") + @Log(title = "角色管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysRole role) + { + if (!roleService.checkRoleNameUnique(role)) + { + return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在"); + } + else if (!roleService.checkRoleKeyUnique(role)) + { + return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在"); + } + role.setCreateBy(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); + roleService.checkRoleDataScope(role.getRoleId()); + if (!roleService.checkRoleNameUnique(role)) + { + return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在"); + } + else if (!roleService.checkRoleKeyUnique(role)) + { + return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在"); + } + role.setUpdateBy(getUsername()); + + if (roleService.updateRole(role) > 0) + { + // 更新缓存用户权限 + LoginUser loginUser = getLoginUser(); + if (StringUtils.isNotNull(loginUser.getUser()) && !loginUser.getUser().isAdmin()) + { + loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser())); + loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName())); + tokenService.setLoginUser(loginUser); + } + return success(); + } + return error("修改角色'" + role.getRoleName() + "'失败,请联系管理员"); + } + + /** + * 修改保存数据权限 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping("/dataScope") + public AjaxResult dataScope(@RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + 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); + roleService.checkRoleDataScope(role.getRoleId()); + role.setUpdateBy(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 success(roleService.selectRoleAll()); + } + + /** + * 查询已分配用户角色列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:list')") + @GetMapping("/authUser/allocatedList") + public TableDataInfo allocatedList(SysUser user) + { + startPage(); + List list = userService.selectAllocatedList(user); + return getDataTable(list); + } + + /** + * 查询未分配用户角色列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:list')") + @GetMapping("/authUser/unallocatedList") + public TableDataInfo unallocatedList(SysUser user) + { + startPage(); + List list = userService.selectUnallocatedList(user); + return getDataTable(list); + } + + /** + * 取消授权用户 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/cancel") + public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole) + { + return toAjax(roleService.deleteAuthUser(userRole)); + } + + /** + * 批量取消授权用户 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/cancelAll") + public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds) + { + return toAjax(roleService.deleteAuthUsers(roleId, userIds)); + } + + /** + * 批量选择用户授权 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/selectAll") + public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds) + { + roleService.checkRoleDataScope(roleId); + return toAjax(roleService.insertAuthUsers(roleId, userIds)); + } + + /** + * 获取对应角色部门树列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:query')") + @GetMapping(value = "/deptTree/{roleId}") + public AjaxResult deptTree(@PathVariable("roleId") Long roleId) + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId)); + ajax.put("depts", deptService.selectDeptTreeList(new SysDept())); + return ajax; + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/system/SysUserController.java b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysUserController.java new file mode 100644 index 0000000..6baf1c7 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/system/SysUserController.java @@ -0,0 +1,256 @@ +package com.staffing.web.controller.system; + +import java.util.List; +import java.util.stream.Collectors; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.ArrayUtils; +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.staffing.common.annotation.Log; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.domain.entity.SysDept; +import com.staffing.common.core.domain.entity.SysRole; +import com.staffing.common.core.domain.entity.SysUser; +import com.staffing.common.core.page.TableDataInfo; +import com.staffing.common.enums.BusinessType; +import com.staffing.common.utils.SecurityUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.poi.ExcelUtil; +import com.staffing.system.service.ISysDeptService; +import com.staffing.system.service.ISysPostService; +import com.staffing.system.service.ISysRoleService; +import com.staffing.system.service.ISysUserService; + +/** + * 用户信息 + * + * @author staffing + */ +@RestController +@RequestMapping("/system/user") +public class SysUserController extends BaseController +{ + @Autowired + private ISysUserService userService; + + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysDeptService deptService; + + @Autowired + private ISysPostService postService; + + /** + * 获取用户列表 + */ + @PreAuthorize("@ss.hasPermi('system:user:list')") + @GetMapping("/list") + public TableDataInfo list(SysUser user) + { + startPage(); + List list = userService.selectUserList(user); + return getDataTable(list); + } + + @Log(title = "用户管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:user:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysUser user) + { + List list = userService.selectUserList(user); + ExcelUtil util = new ExcelUtil(SysUser.class); + util.exportExcel(response, list, "用户数据"); + } + + @Log(title = "用户管理", businessType = BusinessType.IMPORT) + @PreAuthorize("@ss.hasPermi('system:user:import')") + @PostMapping("/importData") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception + { + ExcelUtil util = new ExcelUtil(SysUser.class); + List userList = util.importExcel(file.getInputStream()); + String operName = getUsername(); + String message = userService.importUser(userList, updateSupport, operName); + return success(message); + } + + @PostMapping("/importTemplate") + public void importTemplate(HttpServletResponse response) + { + ExcelUtil util = new ExcelUtil(SysUser.class); + util.importTemplateExcel(response, "用户数据"); + } + + /** + * 根据用户编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:user:query')") + @GetMapping(value = { "/", "/{userId}" }) + public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) + { + userService.checkUserDataScope(userId); + AjaxResult ajax = AjaxResult.success(); + List roles = roleService.selectRoleAll(); + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + ajax.put("posts", postService.selectPostAll()); + if (StringUtils.isNotNull(userId)) + { + SysUser sysUser = userService.selectUserById(userId); + ajax.put(AjaxResult.DATA_TAG, sysUser); + ajax.put("postIds", postService.selectPostListByUserId(userId)); + ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList())); + } + return ajax; + } + + /** + * 新增用户 + */ + @PreAuthorize("@ss.hasPermi('system:user:add')") + @Log(title = "用户管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysUser user) + { + deptService.checkDeptDataScope(user.getDeptId()); + roleService.checkRoleDataScope(user.getRoleIds()); + if (!userService.checkUserNameUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); + } + else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setCreateBy(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); + userService.checkUserDataScope(user.getUserId()); + deptService.checkDeptDataScope(user.getDeptId()); + roleService.checkRoleDataScope(user.getRoleIds()); + if (!userService.checkUserNameUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在"); + } + else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setUpdateBy(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) + { + if (ArrayUtils.contains(userIds, getUserId())) + { + return error("当前用户不能删除"); + } + return toAjax(userService.deleteUserByIds(userIds)); + } + + /** + * 重置密码 + */ + @PreAuthorize("@ss.hasPermi('system:user:resetPwd')") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping("/resetPwd") + public AjaxResult resetPwd(@RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + user.setUpdateBy(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); + userService.checkUserDataScope(user.getUserId()); + user.setUpdateBy(getUsername()); + return toAjax(userService.updateUserStatus(user)); + } + + /** + * 根据用户编号获取授权角色 + */ + @PreAuthorize("@ss.hasPermi('system:user:query')") + @GetMapping("/authRole/{userId}") + public AjaxResult authRole(@PathVariable("userId") Long userId) + { + AjaxResult ajax = AjaxResult.success(); + SysUser user = userService.selectUserById(userId); + List roles = roleService.selectRolesByUserId(userId); + ajax.put("user", user); + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + return ajax; + } + + /** + * 用户授权角色 + */ + @PreAuthorize("@ss.hasPermi('system:user:edit')") + @Log(title = "用户管理", businessType = BusinessType.GRANT) + @PutMapping("/authRole") + public AjaxResult insertAuthRole(Long userId, Long[] roleIds) + { + userService.checkUserDataScope(userId); + roleService.checkRoleDataScope(roleIds); + userService.insertUserAuth(userId, roleIds); + return success(); + } + + /** + * 获取部门树列表 + */ + @PreAuthorize("@ss.hasPermi('system:user:list')") + @GetMapping("/deptTree") + public AjaxResult deptTree(SysDept dept) + { + return success(deptService.selectDeptTreeList(dept)); + } +} diff --git a/staffing-admin/src/main/java/com/staffing/web/controller/tool/TestController.java b/staffing-admin/src/main/java/com/staffing/web/controller/tool/TestController.java new file mode 100644 index 0000000..bfe20d8 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/controller/tool/TestController.java @@ -0,0 +1,183 @@ +package com.staffing.web.controller.tool; + +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.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.R; +import com.staffing.common.utils.StringUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import io.swagger.annotations.ApiOperation; + +/** + * swagger 用户测试方法 + * + * @author staffing + */ +@Api("用户信息管理") +@RestController +@RequestMapping("/test/user") +public class TestController extends BaseController +{ + private final static Map users = new LinkedHashMap(); + { + users.put(1, new UserEntity(1, "admin", "admin123", "15888888888")); + users.put(2, new UserEntity(2, "ry", "admin123", "15666666666")); + } + + @ApiOperation("获取用户列表") + @GetMapping("/list") + public R> userList() + { + List userList = new ArrayList(users.values()); + return R.ok(userList); + } + + @ApiOperation("获取用户详细") + @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class) + @GetMapping("/{userId}") + public R getUser(@PathVariable Integer userId) + { + if (!users.isEmpty() && users.containsKey(userId)) + { + return R.ok(users.get(userId)); + } + else + { + return R.fail("用户不存在"); + } + } + + @ApiOperation("新增用户") + @ApiImplicitParams({ + @ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", dataTypeClass = Integer.class), + @ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class), + @ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class), + @ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String", dataTypeClass = String.class) + }) + @PostMapping("/save") + public R save(UserEntity user) + { + if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) + { + return R.fail("用户ID不能为空"); + } + users.put(user.getUserId(), user); + return R.ok(); + } + + @ApiOperation("更新用户") + @PutMapping("/update") + public R update(@RequestBody UserEntity user) + { + if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) + { + return R.fail("用户ID不能为空"); + } + if (users.isEmpty() || !users.containsKey(user.getUserId())) + { + return R.fail("用户不存在"); + } + users.remove(user.getUserId()); + users.put(user.getUserId(), user); + return R.ok(); + } + + @ApiOperation("删除用户信息") + @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class) + @DeleteMapping("/{userId}") + public R delete(@PathVariable Integer userId) + { + if (!users.isEmpty() && users.containsKey(userId)) + { + users.remove(userId); + return R.ok(); + } + else + { + return R.fail("用户不存在"); + } + } +} + +@ApiModel(value = "UserEntity", description = "用户实体") +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/staffing-admin/src/main/java/com/staffing/web/core/config/SwaggerConfig.java b/staffing-admin/src/main/java/com/staffing/web/core/config/SwaggerConfig.java new file mode 100644 index 0000000..ccf3a23 --- /dev/null +++ b/staffing-admin/src/main/java/com/staffing/web/core/config/SwaggerConfig.java @@ -0,0 +1,125 @@ +package com.staffing.web.core.config; + +import java.util.ArrayList; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import com.staffing.common.config.StaffingConfig; +import io.swagger.annotations.ApiOperation; +import io.swagger.models.auth.In; +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.service.SecurityScheme; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.Docket; + +/** + * Swagger2的接口配置 + * + * @author staffing + */ +@Configuration +public class SwaggerConfig +{ + /** 系统基础配置 */ + @Autowired + private StaffingConfig staffingConfig; + + /** 是否开启swagger */ + @Value("${swagger.enabled}") + private boolean enabled; + + /** 设置请求的统一前缀 */ + @Value("${swagger.pathMapping}") + private String pathMapping; + + /** + * 创建API + */ + @Bean + public Docket createRestApi() + { + return new Docket(DocumentationType.OAS_30) + // 是否启用Swagger + .enable(enabled) + // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息) + .apiInfo(apiInfo()) + // 设置哪些接口暴露给Swagger展示 + .select() + // 扫描所有有注解的api,用这种方式更灵活 + .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) + // 扫描指定包中的swagger注解 + // .apis(RequestHandlerSelectors.basePackage("com.staffing.project.tool.swagger")) + // 扫描所有 .apis(RequestHandlerSelectors.any()) + .paths(PathSelectors.any()) + .build() + /* 设置安全模式,swagger可以设置访问token */ + .securitySchemes(securitySchemes()) + .securityContexts(securityContexts()) + .pathMapping(pathMapping); + } + + /** + * 安全模式,这里指定token通过Authorization头请求头传递 + */ + private List securitySchemes() + { + List apiKeyList = new ArrayList(); + apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue())); + return apiKeyList; + } + + /** + * 安全上下文 + */ + private List securityContexts() + { + List securityContexts = new ArrayList<>(); + securityContexts.add( + SecurityContext.builder() + .securityReferences(defaultAuth()) + .operationSelector(o -> o.requestMappingPattern().matches("/.*")) + .build()); + return securityContexts; + } + + /** + * 默认的安全上引用 + */ + private List defaultAuth() + { + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; + authorizationScopes[0] = authorizationScope; + List securityReferences = new ArrayList<>(); + securityReferences.add(new SecurityReference("Authorization", authorizationScopes)); + return securityReferences; + } + + /** + * 添加摘要信息 + */ + private ApiInfo apiInfo() + { + // 用ApiInfoBuilder进行定制 + return new ApiInfoBuilder() + // 设置标题 + .title("标题:管理系统_接口文档") + // 描述 + .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...") + // 作者信息 + .contact(new Contact(staffingConfig.getName(), null, null)) + // 版本 + .version("版本号:" + staffingConfig.getVersion()) + .build(); + } +} diff --git a/staffing-admin/src/main/resources/META-INF/spring-devtools.properties b/staffing-admin/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 0000000..37e7b58 --- /dev/null +++ b/staffing-admin/src/main/resources/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.json=/com.alibaba.fastjson2.*.jar \ No newline at end of file diff --git a/staffing-admin/src/main/resources/application-druid.yml b/staffing-admin/src/main/resources/application-druid.yml new file mode 100644 index 0000000..8aeeea0 --- /dev/null +++ b/staffing-admin/src/main/resources/application-druid.yml @@ -0,0 +1,61 @@ +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 主库数据源 + master: + url: jdbc:mysql://192.168.18.119:3307/staffing?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: root + password: Ps123456@ + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置连接超时时间 + connectTimeout: 30000 + # 配置网络超时时间 + socketTimeout: 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: staffing + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + 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/staffing-admin/src/main/resources/application.yml b/staffing-admin/src/main/resources/application.yml new file mode 100644 index 0000000..797e3cf --- /dev/null +++ b/staffing-admin/src/main/resources/application.yml @@ -0,0 +1,135 @@ +# 项目相关配置 +staffing: + # 名称 + name: staffing + # 版本 + version: 3.8.8 + # 版权年份 + copyrightYear: 2024 + # 文件路径 示例( Windows配置D:/staffing/uploadPath,Linux配置 /home/staffing/uploadPath) + profile: D:/staffing/uploadPath + # 获取ip地址开关 + addressEnabled: false + # 验证码类型 math 数字计算 char 字符验证 + captchaType: math + +# 开发环境配置 +server: + # 服务器的HTTP端口,默认为8080 + port: 8080 + servlet: + # 应用的访问路径 + context-path: / + tomcat: + # tomcat的URI编码 + uri-encoding: UTF-8 + # 连接数满后的排队数,默认为100 + accept-count: 1000 + threads: + # tomcat最大线程数,默认为200 + max: 800 + # Tomcat启动初始化的线程数,默认值10 + min-spare: 100 + +# 日志配置 +logging: + level: + com.staffing: debug + org.springframework: warn + +# 用户配置 +user: + password: + # 密码最大错误次数 + maxRetryCount: 5 + # 密码锁定时间(默认10分钟) + lockTime: 10 + +# 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: 192.168.18.119 + # 端口,默认为6379 + port: 6378 + # 数据库索引 + database: 0 + # 密码 + password: 12345 + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + +# token配置 +token: + # 令牌自定义标识 + header: Authorization + # 令牌密钥 + secret: abcdefghijklmnopqrstuvwxyz + # 令牌有效期(默认30分钟) + expireTime: 2880 + +# MyBatis配置 +mybatis: + # 搜索指定包别名 + typeAliasesPackage: com.staffing.**.domain + # 配置mapper的扫描,找到所有的mapper.xml映射文件 + mapperLocations: classpath*:mapper/**/*Mapper.xml + # 加载全局的配置文件 + configLocation: classpath:mybatis/mybatis-config.xml + +# PageHelper分页插件 +pagehelper: + helperDialect: mysql + supportMethodsArguments: true + params: count=countSql + +# Swagger配置 +swagger: + # 是否开启swagger + enabled: true + # 请求前缀 + pathMapping: /dev-api + +# 防止XSS攻击 +xss: + # 过滤开关 + enabled: true + # 排除链接(多个用逗号分隔) + excludes: /system/notice + # 匹配链接 + urlPatterns: /system/*,/monitor/*,/tool/* + +minio: + ip: 120.55.69.166 + port: 9000 + access-key: root + secret-key: root_1234 \ No newline at end of file diff --git a/staffing-admin/src/main/resources/banner.txt b/staffing-admin/src/main/resources/banner.txt new file mode 100644 index 0000000..d9eaacc --- /dev/null +++ b/staffing-admin/src/main/resources/banner.txt @@ -0,0 +1,24 @@ +Application Version: ${staffing.version} +Spring Boot Version: ${spring-boot.version} +//////////////////////////////////////////////////////////////////// +// _ooOoo_ // +// o8888888o // +// 88" . "88 // +// (| ^_^ |) // +// O\ = /O // +// ____/`---'\____ // +// .' \\| |// `. // +// / \\||| : |||// \ // +// / _||||| -:- |||||- \ // +// | | \\\ - /// | | // +// | \_| ''\---/'' | | // +// \ .-\__ `-` ___/-. / // +// ___`. .' /--.--\ `. . ___ // +// ."" '< `.___\_<|>_/___.' >'"". // +// | | : `- \`.;`\ _ /`;.`/ - ` : | | // +// \ \ `-. \_ __\ /__ _/ .-` / / // +// ========`-.____`-.___\_____/___.-`____.-'======== // +// `=---=' // +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // +// 佛祖保佑 永不宕机 永无BUG // +//////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/staffing-admin/src/main/resources/i18n/messages.properties b/staffing-admin/src/main/resources/i18n/messages.properties new file mode 100644 index 0000000..93de005 --- /dev/null +++ b/staffing-admin/src/main/resources/i18n/messages.properties @@ -0,0 +1,38 @@ +#错误消息 +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}次,帐户锁定{1}分钟 +user.password.delete=对不起,您的账号已被删除 +user.blocked=用户已封禁,请联系管理员 +role.blocked=角色已封禁,请联系管理员 +login.blocked=很遗憾,访问IP已被列入系统黑名单 +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.register.success=注册成功 +user.notfound=请重新登录 +user.forcelogout=管理员强制退出,请重新登录 +user.unknown.error=未知错误,请重新登录 + +##文件上传消息 +upload.exceed.maxSize=上传的文件大小超出限制的文件大小!
允许的文件最大大小是:{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/staffing-admin/src/main/resources/logback.xml b/staffing-admin/src/main/resources/logback.xml new file mode 100644 index 0000000..fbab991 --- /dev/null +++ b/staffing-admin/src/main/resources/logback.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/sys-info.log + + + + ${log.path}/sys-info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/sys-error.log + + + + ${log.path}/sys-error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + ${log.path}/sys-user.log + + + ${log.path}/sys-user.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/staffing-admin/src/main/resources/mybatis/mybatis-config.xml b/staffing-admin/src/main/resources/mybatis/mybatis-config.xml new file mode 100644 index 0000000..ac47c03 --- /dev/null +++ b/staffing-admin/src/main/resources/mybatis/mybatis-config.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/staffing-common/pom.xml b/staffing-common/pom.xml new file mode 100644 index 0000000..b13b9e0 --- /dev/null +++ b/staffing-common/pom.xml @@ -0,0 +1,143 @@ + + + + staffing + com.staffing + 3.8.8 + + 4.0.0 + + staffing-common + + + common通用工具 + + + + + + + org.springframework + spring-context-support + + + + + org.springframework + spring-web + + + + + org.springframework.boot + spring-boot-starter-security + + + + + com.github.pagehelper + pagehelper-spring-boot-starter + + + + + org.springframework.boot + spring-boot-starter-validation + + + + + org.apache.commons + commons-lang3 + + + + + com.fasterxml.jackson.core + jackson-databind + + + + + com.alibaba.fastjson2 + fastjson2 + + + + + commons-io + commons-io + + + + + org.apache.poi + poi-ooxml + + + + + org.yaml + snakeyaml + + + + + io.jsonwebtoken + jjwt + + + + + javax.xml.bind + jaxb-api + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + + org.apache.commons + commons-pool2 + + + + + eu.bitwalker + UserAgentUtils + + + + + javax.servlet + javax.servlet-api + + + + com.google.zxing + core + 3.4.1 + + + com.google.zxing + javase + 3.4.1 + + + + io.minio + minio + 7.1.0 + + + + + + + \ No newline at end of file diff --git a/staffing-common/src/main/java/com/staffing/common/annotation/Anonymous.java b/staffing-common/src/main/java/com/staffing/common/annotation/Anonymous.java new file mode 100644 index 0000000..779b3db --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/annotation/Anonymous.java @@ -0,0 +1,19 @@ +package com.staffing.common.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 staffing + */ +@Target({ ElementType.METHOD, ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Anonymous +{ +} diff --git a/staffing-common/src/main/java/com/staffing/common/annotation/DataScope.java b/staffing-common/src/main/java/com/staffing/common/annotation/DataScope.java new file mode 100644 index 0000000..7646ae5 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/annotation/DataScope.java @@ -0,0 +1,33 @@ +package com.staffing.common.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 staffing + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface DataScope +{ + /** + * 部门表的别名 + */ + public String deptAlias() default ""; + + /** + * 用户表的别名 + */ + public String userAlias() default ""; + + /** + * 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@ss获取,多个权限用逗号分隔开来 + */ + public String permission() default ""; +} diff --git a/staffing-common/src/main/java/com/staffing/common/annotation/DataSource.java b/staffing-common/src/main/java/com/staffing/common/annotation/DataSource.java new file mode 100644 index 0000000..38cbae8 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/annotation/DataSource.java @@ -0,0 +1,28 @@ +package com.staffing.common.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.staffing.common.enums.DataSourceType; + +/** + * 自定义多数据源切换注解 + * + * 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准 + * + * @author staffing + */ +@Target({ ElementType.METHOD, ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +public @interface DataSource +{ + /** + * 切换数据源名称 + */ + public DataSourceType value() default DataSourceType.MASTER; +} diff --git a/staffing-common/src/main/java/com/staffing/common/annotation/Excel.java b/staffing-common/src/main/java/com/staffing/common/annotation/Excel.java new file mode 100644 index 0000000..05c919c --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/annotation/Excel.java @@ -0,0 +1,192 @@ +package com.staffing.common.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.math.BigDecimal; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; +import com.staffing.common.utils.poi.ExcelHandlerAdapter; + +/** + * 自定义导出Excel数据注解 + * + * @author staffing + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Excel +{ + /** + * 导出时在excel中排序 + */ + public int sort() default Integer.MAX_VALUE; + + /** + * 导出到Excel中的名字. + */ + public String name() default ""; + + /** + * 日期格式, 如: yyyy-MM-dd + */ + public String dateFormat() default ""; + + /** + * 如果是字典类型,请设置字典的type值 (如: sys_user_sex) + */ + public String dictType() default ""; + + /** + * 读取内容转表达式 (如: 0=男,1=女,2=未知) + */ + public String readConverterExp() default ""; + + /** + * 分隔符,读取字符串组内容 + */ + public String separator() default ","; + + /** + * BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化) + */ + public int scale() default -1; + + /** + * BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN + */ + public int roundingMode() default BigDecimal.ROUND_HALF_EVEN; + + /** + * 导出时在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 {}; + + /** + * 是否从字典读数据到combo,默认不读取,如读取需要设置dictType注解. + */ + public boolean comboReadDict() default false; + + /** + * 是否需要纵向合并单元格,应对需求:含有list集合单元格) + */ + public boolean needMerge() default false; + + /** + * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写. + */ + public boolean isExport() default true; + + /** + * 另一个类中的属性名称,支持多级获取,以小数点隔开 + */ + public String targetAttr() default ""; + + /** + * 是否自动统计数据,在最后追加一行统计数据总和 + */ + public boolean isStatistics() default false; + + /** + * 导出类型(0数字 1字符串 2图片) + */ + public ColumnType cellType() default ColumnType.STRING; + + /** + * 导出列头背景颜色 + */ + public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT; + + /** + * 导出列头字体颜色 + */ + public IndexedColors headerColor() default IndexedColors.WHITE; + + /** + * 导出单元格背景颜色 + */ + public IndexedColors backgroundColor() default IndexedColors.WHITE; + + /** + * 导出单元格字体颜色 + */ + public IndexedColors color() default IndexedColors.BLACK; + + /** + * 导出字段对齐方式 + */ + public HorizontalAlignment align() default HorizontalAlignment.CENTER; + + /** + * 自定义数据处理器 + */ + public Class handler() default ExcelHandlerAdapter.class; + + /** + * 自定义数据处理器参数 + */ + public String[] args() 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), IMAGE(2), TEXT(3); + 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/staffing-common/src/main/java/com/staffing/common/annotation/Excels.java b/staffing-common/src/main/java/com/staffing/common/annotation/Excels.java new file mode 100644 index 0000000..5deff12 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/annotation/Excels.java @@ -0,0 +1,18 @@ +package com.staffing.common.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Excel注解集 + * + * @author staffing + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Excels +{ + public Excel[] value(); +} diff --git a/staffing-common/src/main/java/com/staffing/common/annotation/Log.java b/staffing-common/src/main/java/com/staffing/common/annotation/Log.java new file mode 100644 index 0000000..cf6c9df --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/annotation/Log.java @@ -0,0 +1,51 @@ +package com.staffing.common.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.staffing.common.enums.BusinessType; +import com.staffing.common.enums.OperatorType; + +/** + * 自定义操作日志记录注解 + * + * @author staffing + * + */ +@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; + + /** + * 是否保存响应的参数 + */ + public boolean isSaveResponseData() default true; + + /** + * 排除指定的请求参数 + */ + public String[] excludeParamNames() default {}; +} diff --git a/staffing-common/src/main/java/com/staffing/common/annotation/RateLimiter.java b/staffing-common/src/main/java/com/staffing/common/annotation/RateLimiter.java new file mode 100644 index 0000000..32f548f --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/annotation/RateLimiter.java @@ -0,0 +1,40 @@ +package com.staffing.common.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.staffing.common.constant.CacheConstants; +import com.staffing.common.enums.LimitType; + +/** + * 限流注解 + * + * @author staffing + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RateLimiter +{ + /** + * 限流key + */ + public String key() default CacheConstants.RATE_LIMIT_KEY; + + /** + * 限流时间,单位秒 + */ + public int time() default 60; + + /** + * 限流次数 + */ + public int count() default 100; + + /** + * 限流类型 + */ + public LimitType limitType() default LimitType.DEFAULT; +} diff --git a/staffing-common/src/main/java/com/staffing/common/annotation/RepeatSubmit.java b/staffing-common/src/main/java/com/staffing/common/annotation/RepeatSubmit.java new file mode 100644 index 0000000..26720b7 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/annotation/RepeatSubmit.java @@ -0,0 +1,31 @@ +package com.staffing.common.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; + +/** + * 自定义注解防止表单重复提交 + * + * @author staffing + * + */ +@Inherited +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RepeatSubmit +{ + /** + * 间隔时间(ms),小于此时间视为重复提交 + */ + public int interval() default 5000; + + /** + * 提示消息 + */ + public String message() default "不允许重复提交,请稍候再试"; +} diff --git a/staffing-common/src/main/java/com/staffing/common/annotation/Sensitive.java b/staffing-common/src/main/java/com/staffing/common/annotation/Sensitive.java new file mode 100644 index 0000000..48658b9 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/annotation/Sensitive.java @@ -0,0 +1,24 @@ +package com.staffing.common.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.staffing.common.config.serializer.SensitiveJsonSerializer; +import com.staffing.common.enums.DesensitizedType; + +/** + * 数据脱敏注解 + * + * @author staffing + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +@JacksonAnnotationsInside +@JsonSerialize(using = SensitiveJsonSerializer.class) +public @interface Sensitive +{ + DesensitizedType desensitizedType(); +} diff --git a/staffing-common/src/main/java/com/staffing/common/config/MinioConfig.java b/staffing-common/src/main/java/com/staffing/common/config/MinioConfig.java new file mode 100644 index 0000000..f44c8c8 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/config/MinioConfig.java @@ -0,0 +1,30 @@ +package com.staffing.common.config; + +import io.minio.MinioClient; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class MinioConfig { + + @Value("${minio.ip}") + private String ip; + + @Value("${minio.port}") + private int port; + + @Value("${minio.access-key}") + private String accessKey; + + @Value("${minio.secret-key}") + private String secretKey; + + @Bean + public MinioClient minioClient() { + return MinioClient.builder() + .endpoint(ip, port, false) //https or not + .credentials(accessKey, secretKey) + .build(); + } +} \ No newline at end of file diff --git a/staffing-common/src/main/java/com/staffing/common/config/StaffingConfig.java b/staffing-common/src/main/java/com/staffing/common/config/StaffingConfig.java new file mode 100644 index 0000000..e340ccf --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/config/StaffingConfig.java @@ -0,0 +1,122 @@ +package com.staffing.common.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * 读取项目相关配置 + * + * @author staffing + */ +@Component +@ConfigurationProperties(prefix = "staffing") +public class StaffingConfig +{ + /** 项目名称 */ + private String name; + + /** 版本 */ + private String version; + + /** 版权年份 */ + private String copyrightYear; + + /** 上传路径 */ + private static String profile; + + /** 获取地址开关 */ + private static boolean addressEnabled; + + /** 验证码类型 */ + private static String captchaType; + + 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 static String getProfile() + { + return profile; + } + + public void setProfile(String profile) + { + StaffingConfig.profile = profile; + } + + public static boolean isAddressEnabled() + { + return addressEnabled; + } + + public void setAddressEnabled(boolean addressEnabled) + { + StaffingConfig.addressEnabled = addressEnabled; + } + + public static String getCaptchaType() { + return captchaType; + } + + public void setCaptchaType(String captchaType) { + StaffingConfig.captchaType = captchaType; + } + + /** + * 获取导入上传路径 + */ + public static String getImportPath() + { + return getProfile() + "/import"; + } + + /** + * 获取头像上传路径 + */ + public static String getAvatarPath() + { + return getProfile() + "/avatar"; + } + + /** + * 获取下载路径 + */ + public static String getDownloadPath() + { + return getProfile() + "/download/"; + } + + /** + * 获取上传路径 + */ + public static String getUploadPath() + { + return getProfile() + "/upload"; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/config/serializer/SensitiveJsonSerializer.java b/staffing-common/src/main/java/com/staffing/common/config/serializer/SensitiveJsonSerializer.java new file mode 100644 index 0000000..035b707 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/config/serializer/SensitiveJsonSerializer.java @@ -0,0 +1,67 @@ +package com.staffing.common.config.serializer; + +import java.io.IOException; +import java.util.Objects; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.BeanProperty; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.ContextualSerializer; +import com.staffing.common.annotation.Sensitive; +import com.staffing.common.core.domain.model.LoginUser; +import com.staffing.common.enums.DesensitizedType; +import com.staffing.common.utils.SecurityUtils; + +/** + * 数据脱敏序列化过滤 + * + * @author staffing + */ +public class SensitiveJsonSerializer extends JsonSerializer implements ContextualSerializer +{ + private DesensitizedType desensitizedType; + + @Override + public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException + { + if (desensitization()) + { + gen.writeString(desensitizedType.desensitizer().apply(value)); + } + else + { + gen.writeString(value); + } + } + + @Override + public JsonSerializer createContextual(SerializerProvider prov, BeanProperty property) + throws JsonMappingException + { + Sensitive annotation = property.getAnnotation(Sensitive.class); + if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) + { + this.desensitizedType = annotation.desensitizedType(); + return this; + } + return prov.findValueSerializer(property.getType(), property); + } + + /** + * 是否需要脱敏处理 + */ + private boolean desensitization() + { + try + { + LoginUser securityUser = SecurityUtils.getLoginUser(); + // 管理员不脱敏 + return !securityUser.getUser().isAdmin(); + } + catch (Exception e) + { + return true; + } + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/constant/CacheConstants.java b/staffing-common/src/main/java/com/staffing/common/constant/CacheConstants.java new file mode 100644 index 0000000..5696a05 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/constant/CacheConstants.java @@ -0,0 +1,44 @@ +package com.staffing.common.constant; + +/** + * 缓存的key 常量 + * + * @author staffing + */ +public class CacheConstants +{ + /** + * 登录用户 redis key + */ + public static final String LOGIN_TOKEN_KEY = "login_tokens:"; + + /** + * 验证码 redis key + */ + public static final String CAPTCHA_CODE_KEY = "captcha_codes:"; + + /** + * 参数管理 cache key + */ + public static final String SYS_CONFIG_KEY = "sys_config:"; + + /** + * 字典管理 cache key + */ + public static final String SYS_DICT_KEY = "sys_dict:"; + + /** + * 防重提交 redis key + */ + public static final String REPEAT_SUBMIT_KEY = "repeat_submit:"; + + /** + * 限流 redis key + */ + public static final String RATE_LIMIT_KEY = "rate_limit:"; + + /** + * 登录账户密码错误次数 redis key + */ + public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:"; +} diff --git a/staffing-common/src/main/java/com/staffing/common/constant/Constants.java b/staffing-common/src/main/java/com/staffing/common/constant/Constants.java new file mode 100644 index 0000000..085697b --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/constant/Constants.java @@ -0,0 +1,173 @@ +package com.staffing.common.constant; + +import java.util.Locale; +import io.jsonwebtoken.Claims; + +/** + * 通用常量信息 + * + * @author staffing + */ +public class Constants +{ + /** + * UTF-8 字符集 + */ + public static final String UTF8 = "UTF-8"; + + /** + * GBK 字符集 + */ + public static final String GBK = "GBK"; + + /** + * 系统语言 + */ + public static final Locale DEFAULT_LOCALE = Locale.SIMPLIFIED_CHINESE; + + /** + * www主域 + */ + public static final String WWW = "www."; + + /** + * http请求 + */ + public static final String HTTP = "http://"; + + /** + * https请求 + */ + public static final String HTTPS = "https://"; + + /** + * 通用成功标识 + */ + 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 REGISTER = "Register"; + + /** + * 登录失败 + */ + public static final String LOGIN_FAIL = "Error"; + + /** + * 所有权限标识 + */ + public static final String ALL_PERMISSION = "*:*:*"; + + /** + * 管理员角色权限标识 + */ + public static final String SUPER_ADMIN = "admin"; + + /** + * 角色权限分隔符 + */ + public static final String ROLE_DELIMETER = ","; + + /** + * 权限标识分隔符 + */ + public static final String PERMISSION_DELIMETER = ","; + + /** + * 验证码有效期(分钟) + */ + 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"; + + /** + * RMI 远程方法调用 + */ + public static final String LOOKUP_RMI = "rmi:"; + + /** + * LDAP 远程方法调用 + */ + public static final String LOOKUP_LDAP = "ldap:"; + + /** + * LDAPS 远程方法调用 + */ + public static final String LOOKUP_LDAPS = "ldaps:"; + + /** + * 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全) + */ + public static final String[] JSON_WHITELIST_STR = { "org.springframework", "com.staffing" }; + + /** + * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加) + */ + public static final String[] JOB_WHITELIST_STR = { "com.staffing.quartz.task" }; + + /** + * 定时任务违规的字符 + */ + public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", + "org.springframework", "org.apache", "com.staffing.common.utils.file", "com.staffing.common.config", "com.staffing.generator" }; +} diff --git a/staffing-common/src/main/java/com/staffing/common/constant/GenConstants.java b/staffing-common/src/main/java/com/staffing/common/constant/GenConstants.java new file mode 100644 index 0000000..e9afdbe --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/constant/GenConstants.java @@ -0,0 +1,117 @@ +package com.staffing.common.constant; + +/** + * 代码生成通用常量 + * + * @author staffing + */ +public class GenConstants +{ + /** 单表(增删改查) */ + public static final String TPL_CRUD = "crud"; + + /** 树表(增删改查) */ + public static final String TPL_TREE = "tree"; + + /** 主子表(增删改查) */ + public static final String TPL_SUB = "sub"; + + /** 树编码字段 */ + public static final String TREE_CODE = "treeCode"; + + /** 树父编码字段 */ + public static final String TREE_PARENT_CODE = "treeParentCode"; + + /** 树名称字段 */ + public static final String TREE_NAME = "treeName"; + + /** 上级菜单ID字段 */ + public static final String PARENT_MENU_ID = "parentMenuId"; + + /** 上级菜单名称字段 */ + public static final String PARENT_MENU_NAME = "parentMenuName"; + + /** 数据库字符串类型 */ + public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" }; + + /** 数据库文本类型 */ + public static final String[] COLUMNTYPE_TEXT = { "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", + "bit", "bigint", "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", "children" }; + + /** 文本框 */ + 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 HTML_IMAGE_UPLOAD = "imageUpload"; + + /** 文件上传控件 */ + public static final String HTML_FILE_UPLOAD = "fileUpload"; + + /** 富文本控件 */ + public static final String HTML_EDITOR = "editor"; + + /** 字符串类型 */ + 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 QUERY_EQ = "EQ"; + + /** 需要 */ + public static final String REQUIRE = "1"; +} diff --git a/staffing-common/src/main/java/com/staffing/common/constant/HttpStatus.java b/staffing-common/src/main/java/com/staffing/common/constant/HttpStatus.java new file mode 100644 index 0000000..b2246b7 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/constant/HttpStatus.java @@ -0,0 +1,94 @@ +package com.staffing.common.constant; + +/** + * 返回状态码 + * + * @author staffing + */ +public class 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; + + /** + * 系统警告消息 + */ + public static final int WARN = 601; +} diff --git a/staffing-common/src/main/java/com/staffing/common/constant/ScheduleConstants.java b/staffing-common/src/main/java/com/staffing/common/constant/ScheduleConstants.java new file mode 100644 index 0000000..4406d87 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/constant/ScheduleConstants.java @@ -0,0 +1,50 @@ +package com.staffing.common.constant; + +/** + * 任务调度通用常量 + * + * @author staffing + */ +public class ScheduleConstants +{ + public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME"; + + /** 执行目标key */ + public static final String TASK_PROPERTIES = "TASK_PROPERTIES"; + + /** 默认 */ + public static final String MISFIRE_DEFAULT = "0"; + + /** 立即触发执行 */ + public static final String MISFIRE_IGNORE_MISFIRES = "1"; + + /** 触发一次执行 */ + public static final String MISFIRE_FIRE_AND_PROCEED = "2"; + + /** 不触发立即执行 */ + public static final String MISFIRE_DO_NOTHING = "3"; + + public enum Status + { + /** + * 正常 + */ + NORMAL("0"), + /** + * 暂停 + */ + PAUSE("1"); + + private String value; + + private Status(String value) + { + this.value = value; + } + + public String getValue() + { + return value; + } + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/constant/UserConstants.java b/staffing-common/src/main/java/com/staffing/common/constant/UserConstants.java new file mode 100644 index 0000000..4c80085 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/constant/UserConstants.java @@ -0,0 +1,78 @@ +package com.staffing.common.constant; + +/** + * 用户常量信息 + * + * @author staffing + */ +public class UserConstants +{ + /** + * 平台内系统用户的唯一标志 + */ + public static final String SYS_USER = "SYS_USER"; + + /** 正常状态 */ + public static final String NORMAL = "0"; + + /** 异常状态 */ + public static final String EXCEPTION = "1"; + + /** 用户封禁状态 */ + public static final String USER_DISABLE = "1"; + + /** 角色封禁状态 */ + public static final String ROLE_DISABLE = "1"; + + /** 部门正常状态 */ + public static final String DEPT_NORMAL = "0"; + + /** 部门停用状态 */ + public static final String DEPT_DISABLE = "1"; + + /** 字典正常状态 */ + public static final String DICT_NORMAL = "0"; + + /** 是否为系统默认(是) */ + public static final String YES = "Y"; + + /** 是否菜单外链(是) */ + public static final String YES_FRAME = "0"; + + /** 是否菜单外链(否) */ + public static final String NO_FRAME = "1"; + + /** 菜单类型(目录) */ + public static final String TYPE_DIR = "M"; + + /** 菜单类型(菜单) */ + public static final String TYPE_MENU = "C"; + + /** 菜单类型(按钮) */ + public static final String TYPE_BUTTON = "F"; + + /** Layout组件标识 */ + public final static String LAYOUT = "Layout"; + + /** ParentView组件标识 */ + public final static String PARENT_VIEW = "ParentView"; + + /** InnerLink组件标识 */ + public final static String INNER_LINK = "InnerLink"; + + /** 校验是否唯一的返回标识 */ + public final static boolean UNIQUE = true; + public final static boolean NOT_UNIQUE = false; + + /** + * 用户名长度限制 + */ + public static final int USERNAME_MIN_LENGTH = 2; + public static final int USERNAME_MAX_LENGTH = 20; + + /** + * 密码长度限制 + */ + public static final int PASSWORD_MIN_LENGTH = 5; + public static final int PASSWORD_MAX_LENGTH = 20; +} diff --git a/staffing-common/src/main/java/com/staffing/common/core/controller/BaseController.java b/staffing-common/src/main/java/com/staffing/common/core/controller/BaseController.java new file mode 100644 index 0000000..69520c1 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/controller/BaseController.java @@ -0,0 +1,202 @@ +package com.staffing.common.core.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.staffing.common.constant.HttpStatus; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.domain.model.LoginUser; +import com.staffing.common.core.page.PageDomain; +import com.staffing.common.core.page.TableDataInfo; +import com.staffing.common.core.page.TableSupport; +import com.staffing.common.utils.DateUtils; +import com.staffing.common.utils.PageUtils; +import com.staffing.common.utils.SecurityUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.sql.SqlUtil; + +/** + * web层通用数据处理 + * + * @author staffing + */ +public class BaseController +{ + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + + /** + * 将前台传递过来的日期格式的字符串,自动转化为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() + { + PageUtils.startPage(); + } + + /** + * 设置请求排序数据 + */ + protected void startOrderBy() + { + PageDomain pageDomain = TableSupport.buildPageRequest(); + if (StringUtils.isNotEmpty(pageDomain.getOrderBy())) + { + String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy()); + PageHelper.orderBy(orderBy); + } + } + + /** + * 清理分页的线程变量 + */ + protected void clearPage() + { + PageUtils.clearPage(); + } + + /** + * 响应请求分页数据 + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected TableDataInfo getDataTable(List list) + { + TableDataInfo rspData = new TableDataInfo(); + rspData.setCode(HttpStatus.SUCCESS); + rspData.setMsg("查询成功"); + rspData.setRows(list); + rspData.setTotal(new PageInfo(list).getTotal()); + return rspData; + } + + /** + * 返回成功 + */ + public AjaxResult success() + { + return AjaxResult.success(); + } + + /** + * 返回失败消息 + */ + public AjaxResult error() + { + return AjaxResult.error(); + } + + /** + * 返回成功消息 + */ + public AjaxResult success(String message) + { + return AjaxResult.success(message); + } + + /** + * 返回成功消息 + */ + public AjaxResult success(Object data) + { + return AjaxResult.success(data); + } + + /** + * 返回失败消息 + */ + public AjaxResult error(String message) + { + return AjaxResult.error(message); + } + + /** + * 返回警告消息 + */ + public AjaxResult warn(String message) + { + return AjaxResult.warn(message); + } + + /** + * 响应返回结果 + * + * @param rows 影响行数 + * @return 操作结果 + */ + protected AjaxResult toAjax(int rows) + { + return rows > 0 ? AjaxResult.success() : AjaxResult.error(); + } + + /** + * 响应返回结果 + * + * @param result 结果 + * @return 操作结果 + */ + protected AjaxResult toAjax(boolean result) + { + return result ? success() : error(); + } + + /** + * 页面跳转 + */ + public String redirect(String url) + { + return StringUtils.format("redirect:{}", url); + } + + /** + * 获取用户缓存信息 + */ + public LoginUser getLoginUser() + { + return SecurityUtils.getLoginUser(); + } + + /** + * 获取登录用户id + */ + public Long getUserId() + { + return getLoginUser().getUserId(); + } + + /** + * 获取登录部门id + */ + public Long getDeptId() + { + return getLoginUser().getDeptId(); + } + + /** + * 获取登录用户名 + */ + public String getUsername() + { + return getLoginUser().getUsername(); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/core/domain/AjaxResult.java b/staffing-common/src/main/java/com/staffing/common/core/domain/AjaxResult.java new file mode 100644 index 0000000..84b9cea --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/domain/AjaxResult.java @@ -0,0 +1,216 @@ +package com.staffing.common.core.domain; + +import java.util.HashMap; +import java.util.Objects; +import com.staffing.common.constant.HttpStatus; +import com.staffing.common.utils.StringUtils; + +/** + * 操作消息提醒 + * + * @author staffing + */ +public class AjaxResult extends HashMap +{ + 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); + } + + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @return 警告消息 + */ + public static AjaxResult warn(String msg) + { + return AjaxResult.warn(msg, null); + } + + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 警告消息 + */ + public static AjaxResult warn(String msg, Object data) + { + return new AjaxResult(HttpStatus.WARN, 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); + } + + /** + * 是否为成功消息 + * + * @return 结果 + */ + public boolean isSuccess() + { + return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG)); + } + + /** + * 是否为警告消息 + * + * @return 结果 + */ + public boolean isWarn() + { + return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG)); + } + + /** + * 是否为错误消息 + * + * @return 结果 + */ + public boolean isError() + { + return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG)); + } + + /** + * 方便链式调用 + * + * @param key 键 + * @param value 值 + * @return 数据对象 + */ + @Override + public AjaxResult put(String key, Object value) + { + super.put(key, value); + return this; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/core/domain/BaseEntity.java b/staffing-common/src/main/java/com/staffing/common/core/domain/BaseEntity.java new file mode 100644 index 0000000..bc798cd --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/domain/BaseEntity.java @@ -0,0 +1,119 @@ +package com.staffing.common.core.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; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.staffing.common.annotation.Excel; + +/** + * Entity基类 + * + * @author staffing + */ +public class BaseEntity implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 搜索值 */ + @JsonIgnore + 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; + + /** 请求参数 */ + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private Map 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 Map getParams() + { + if (params == null) + { + params = new HashMap<>(); + } + return params; + } + + public void setParams(Map params) + { + this.params = params; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/core/domain/R.java b/staffing-common/src/main/java/com/staffing/common/core/domain/R.java new file mode 100644 index 0000000..3ddcba1 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/domain/R.java @@ -0,0 +1,115 @@ +package com.staffing.common.core.domain; + +import java.io.Serializable; +import com.staffing.common.constant.HttpStatus; + +/** + * 响应信息主体 + * + * @author staffing + */ +public class R implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 成功 */ + public static final int SUCCESS = HttpStatus.SUCCESS; + + /** 失败 */ + public static final int FAIL = HttpStatus.ERROR; + + private int code; + + private String msg; + + private T data; + + public static R ok() + { + return restResult(null, SUCCESS, "操作成功"); + } + + public static R ok(T data) + { + return restResult(data, SUCCESS, "操作成功"); + } + + public static R ok(T data, String msg) + { + return restResult(data, SUCCESS, msg); + } + + public static R fail() + { + return restResult(null, FAIL, "操作失败"); + } + + public static R fail(String msg) + { + return restResult(null, FAIL, msg); + } + + public static R fail(T data) + { + return restResult(data, FAIL, "操作失败"); + } + + public static R fail(T data, String msg) + { + return restResult(data, FAIL, msg); + } + + public static R fail(int code, String msg) + { + return restResult(null, code, msg); + } + + private static R restResult(T data, int code, String msg) + { + R apiResult = new R<>(); + apiResult.setCode(code); + apiResult.setData(data); + apiResult.setMsg(msg); + return apiResult; + } + + public int getCode() + { + return code; + } + + public void setCode(int code) + { + this.code = code; + } + + public String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } + + public T getData() + { + return data; + } + + public void setData(T data) + { + this.data = data; + } + + public static Boolean isError(R ret) + { + return !isSuccess(ret); + } + + public static Boolean isSuccess(R ret) + { + return R.SUCCESS == ret.getCode(); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/core/domain/TreeEntity.java b/staffing-common/src/main/java/com/staffing/common/core/domain/TreeEntity.java new file mode 100644 index 0000000..2c52a06 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/domain/TreeEntity.java @@ -0,0 +1,79 @@ +package com.staffing.common.core.domain; + +import java.util.ArrayList; +import java.util.List; + +/** + * Tree基类 + * + * @author staffing + */ +public class TreeEntity extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 父菜单名称 */ + private String parentName; + + /** 父菜单ID */ + private Long parentId; + + /** 显示顺序 */ + private Integer orderNum; + + /** 祖级列表 */ + private String ancestors; + + /** 子部门 */ + private List children = new ArrayList<>(); + + 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; + } + + public Integer getOrderNum() + { + return orderNum; + } + + public void setOrderNum(Integer orderNum) + { + this.orderNum = orderNum; + } + + public String getAncestors() + { + return ancestors; + } + + public void setAncestors(String ancestors) + { + this.ancestors = ancestors; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/core/domain/TreeSelect.java b/staffing-common/src/main/java/com/staffing/common/core/domain/TreeSelect.java new file mode 100644 index 0000000..e7d79f1 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/domain/TreeSelect.java @@ -0,0 +1,77 @@ +package com.staffing.common.core.domain; + +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.staffing.common.core.domain.entity.SysDept; +import com.staffing.common.core.domain.entity.SysMenu; + +/** + * Treeselect树结构实体类 + * + * @author staffing + */ +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 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 getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/core/domain/WxLogin.java b/staffing-common/src/main/java/com/staffing/common/core/domain/WxLogin.java new file mode 100644 index 0000000..128224f --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/domain/WxLogin.java @@ -0,0 +1,49 @@ +package com.staffing.common.core.domain; + +public class WxLogin { + private String session_key; + private String unionid;//用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台账号下会返回,详见 UnionID 机制说明。 + private String errmsg; + private String openid; + private int errcode; + + public String getSession_key() { + return session_key; + } + + public void setSession_key(String session_key) { + this.session_key = session_key; + } + + public String getUnionid() { + return unionid; + } + + public void setUnionid(String unionid) { + this.unionid = unionid; + } + + public String getErrmsg() { + return errmsg; + } + + public void setErrmsg(String errmsg) { + this.errmsg = errmsg; + } + + public String getOpenid() { + return openid; + } + + public void setOpenid(String openid) { + this.openid = openid; + } + + public int getErrcode() { + return errcode; + } + + public void setErrcode(int errcode) { + this.errcode = errcode; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/core/domain/WxPhone.java b/staffing-common/src/main/java/com/staffing/common/core/domain/WxPhone.java new file mode 100644 index 0000000..5f2de86 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/domain/WxPhone.java @@ -0,0 +1,118 @@ +package com.staffing.common.core.domain; + +public class WxPhone { + private int errcode;//有效期 秒 + private String errmsg;//有效期 秒 + private PhoneInfo phone_info;//有效期 秒 + + + static class PhoneInfo{ + String phoneNumber; + String purePhoneNumber; + int countryCode; + Watermark watermark; + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getPurePhoneNumber() { + return purePhoneNumber; + } + + public void setPurePhoneNumber(String purePhoneNumber) { + this.purePhoneNumber = purePhoneNumber; + } + + public int getCountryCode() { + return countryCode; + } + + public void setCountryCode(int countryCode) { + this.countryCode = countryCode; + } + + public Watermark getWatermark() { + return watermark; + } + + public void setWatermark(Watermark watermark) { + this.watermark = watermark; + } + } + + static class Watermark{ + int timestamp; + String appid; + } + + private String access_token; + private int expires_in;//有效期 秒 + + private long expiresTime;//到期时间 + + + public int getErrcode() { + return errcode; + } + + public void setErrcode(int errcode) { + this.errcode = errcode; + } + + public String getErrmsg() { + return errmsg; + } + + public void setErrmsg(String errmsg) { + this.errmsg = errmsg; + } + + public PhoneInfo getPhone_info() { + return phone_info; + } + + public void setPhone_info(PhoneInfo phone_info) { + this.phone_info = phone_info; + } + + public String getAccess_token() { + return access_token; + } + + public void setAccess_token(String access_token) { + this.access_token = access_token; + } + + public int getExpires_in() { + return expires_in; + } + + public void setExpires_in(int expires_in) { + this.expires_in = expires_in; + } + + public long getExpiresTime() { + return expiresTime; + } + + public void setExpiresTime(long expiresTime) { + this.expiresTime = expiresTime; + } + + public String getPhoneNumber() { + return this.phone_info.phoneNumber; + } + + + public String getPurePhoneNumber() { + return this.phone_info.purePhoneNumber; + } + + + +} diff --git a/staffing-common/src/main/java/com/staffing/common/core/domain/WxToken.java b/staffing-common/src/main/java/com/staffing/common/core/domain/WxToken.java new file mode 100644 index 0000000..a041341 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/domain/WxToken.java @@ -0,0 +1,32 @@ +package com.staffing.common.core.domain; + +public class WxToken { + private String access_token; + private int expires_in;//有效期 秒 + + private long expiresTime;//到期时间 + + public String getAccess_token() { + return access_token; + } + + public void setAccess_token(String access_token) { + this.access_token = access_token; + } + + public int getExpires_in() { + return expires_in; + } + + public void setExpires_in(int expires_in) { + this.expires_in = expires_in; + } + + public long getExpiresTime() { + return expiresTime; + } + + public void setExpiresTime(long expiresTime) { + this.expiresTime = expiresTime; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysDept.java b/staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysDept.java new file mode 100644 index 0000000..195cb47 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysDept.java @@ -0,0 +1,203 @@ +package com.staffing.common.core.domain.entity; + +import java.util.ArrayList; +import java.util.List; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.staffing.common.core.domain.BaseEntity; + +/** + * 部门表 sys_dept + * + * @author staffing + */ +public class SysDept extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 部门ID */ + private Long deptId; + + /** 父部门ID */ + private Long parentId; + + /** 祖级列表 */ + private String ancestors; + + /** 部门名称 */ + private String deptName; + + /** 显示顺序 */ + private Integer orderNum; + + /** 负责人 */ + private String leader; + + /** 联系电话 */ + private String phone; + + /** 邮箱 */ + private String email; + + /** 部门状态:0正常,1停用 */ + private String status; + + /** 删除标志(0代表存在 2代表删除) */ + private String delFlag; + + /** 父部门名称 */ + private String parentName; + + /** 子部门 */ + private List children = new ArrayList(); + + 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; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getOrderNum() + { + return orderNum; + } + + public void setOrderNum(Integer 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 getChildren() + { + return children; + } + + public void setChildren(List 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/staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysDictData.java b/staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysDictData.java new file mode 100644 index 0000000..7e5e017 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysDictData.java @@ -0,0 +1,176 @@ +package com.staffing.common.core.domain.entity; + +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.staffing.common.annotation.Excel; +import com.staffing.common.annotation.Excel.ColumnType; +import com.staffing.common.constant.UserConstants; +import com.staffing.common.core.domain.BaseEntity; + +/** + * 字典数据表 sys_dict_data + * + * @author staffing + */ +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; + + /** 是否默认(Y是 N否) */ + @Excel(name = "是否默认", readConverterExp = "Y=是,N=否") + private String isDefault; + + /** 状态(0正常 1停用) */ + @Excel(name = "状态", readConverterExp = "0=正常,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); + } + + 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/staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysDictType.java b/staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysDictType.java new file mode 100644 index 0000000..d0f7cf9 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysDictType.java @@ -0,0 +1,96 @@ +package com.staffing.common.core.domain.entity; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.staffing.common.annotation.Excel; +import com.staffing.common.annotation.Excel.ColumnType; +import com.staffing.common.core.domain.BaseEntity; + +/** + * 字典类型表 sys_dict_type + * + * @author staffing + */ +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正常 1停用) */ + @Excel(name = "状态", readConverterExp = "0=正常,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个字符") + @Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)") + 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/staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysMenu.java b/staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysMenu.java new file mode 100644 index 0000000..7a29cbc --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysMenu.java @@ -0,0 +1,274 @@ +package com.staffing.common.core.domain.entity; + +import java.util.ArrayList; +import java.util.List; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.staffing.common.core.domain.BaseEntity; + +/** + * 菜单权限表 sys_menu + * + * @author staffing + */ +public class SysMenu extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 菜单ID */ + private Long menuId; + + /** 菜单名称 */ + private String menuName; + + /** 父菜单名称 */ + private String parentName; + + /** 父菜单ID */ + private Long parentId; + + /** 显示顺序 */ + private Integer orderNum; + + /** 路由地址 */ + private String path; + + /** 组件路径 */ + private String component; + + /** 路由参数 */ + private String query; + + /** 路由名称,默认和路由地址相同的驼峰格式(注意:因为vue3版本的router会删除名称相同路由,为避免名字的冲突,特殊情况可以自定义) */ + private String routeName; + + /** 是否为外链(0是 1否) */ + private String isFrame; + + /** 是否缓存(0缓存 1不缓存) */ + private String isCache; + + /** 类型(M目录 C菜单 F按钮) */ + private String menuType; + + /** 显示状态(0显示 1隐藏) */ + private String visible; + + /** 菜单状态(0正常 1停用) */ + private String status; + + /** 权限字符串 */ + private String perms; + + /** 菜单图标 */ + private String icon; + + /** 子菜单 */ + private List children = new ArrayList(); + + 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; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getOrderNum() + { + return orderNum; + } + + public void setOrderNum(Integer 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 getQuery() + { + return query; + } + + public void setQuery(String query) + { + this.query = query; + } + + public String getRouteName() + { + return routeName; + } + + public void setRouteName(String routeName) + { + this.routeName = routeName; + } + + public String getIsFrame() + { + return isFrame; + } + + public void setIsFrame(String isFrame) + { + this.isFrame = isFrame; + } + + public String getIsCache() + { + return isCache; + } + + public void setIsCache(String isCache) + { + this.isCache = isCache; + } + + @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; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @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 getChildren() + { + return children; + } + + public void setChildren(List 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("query", getQuery()) + .append("routeName", getRouteName()) + .append("isFrame", getIsFrame()) + .append("IsCache", getIsCache()) + .append("menuType", getMenuType()) + .append("visible", getVisible()) + .append("status ", getStatus()) + .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/staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysRole.java b/staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysRole.java new file mode 100644 index 0000000..51f1aa3 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysRole.java @@ -0,0 +1,241 @@ +package com.staffing.common.core.domain.entity; + +import java.util.Set; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.staffing.common.annotation.Excel; +import com.staffing.common.annotation.Excel.ColumnType; +import com.staffing.common.core.domain.BaseEntity; + +/** + * 角色表 sys_role + * + * @author staffing + */ +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 Integer roleSort; + + /** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */ + @Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限") + private String dataScope; + + /** 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示) */ + private boolean menuCheckStrictly; + + /** 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 ) */ + private boolean deptCheckStrictly; + + /** 角色状态(0正常 1停用) */ + @Excel(name = "角色状态", readConverterExp = "0=正常,1=停用") + private String status; + + /** 删除标志(0代表存在 2代表删除) */ + private String delFlag; + + /** 用户是否存在此角色标识 默认不存在 */ + private boolean flag = false; + + /** 菜单组 */ + private Long[] menuIds; + + /** 部门组(数据权限) */ + private Long[] deptIds; + + /** 角色菜单权限 */ + private Set permissions; + + 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; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getRoleSort() + { + return roleSort; + } + + public void setRoleSort(Integer roleSort) + { + this.roleSort = roleSort; + } + + public String getDataScope() + { + return dataScope; + } + + public void setDataScope(String dataScope) + { + this.dataScope = dataScope; + } + + public boolean isMenuCheckStrictly() + { + return menuCheckStrictly; + } + + public void setMenuCheckStrictly(boolean menuCheckStrictly) + { + this.menuCheckStrictly = menuCheckStrictly; + } + + public boolean isDeptCheckStrictly() + { + return deptCheckStrictly; + } + + public void setDeptCheckStrictly(boolean deptCheckStrictly) + { + this.deptCheckStrictly = deptCheckStrictly; + } + + 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 Set getPermissions() + { + return permissions; + } + + public void setPermissions(Set permissions) + { + this.permissions = permissions; + } + + @Override + 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("menuCheckStrictly", isMenuCheckStrictly()) + .append("deptCheckStrictly", isDeptCheckStrictly()) + .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/staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysUser.java b/staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysUser.java new file mode 100644 index 0000000..c285909 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/domain/entity/SysUser.java @@ -0,0 +1,344 @@ +package com.staffing.common.core.domain.entity; + +import java.util.Date; +import java.util.List; +import javax.validation.constraints.*; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.staffing.common.annotation.Excel; +import com.staffing.common.annotation.Excel.ColumnType; +import com.staffing.common.annotation.Excel.Type; +import com.staffing.common.annotation.Excels; +import com.staffing.common.core.domain.BaseEntity; +import com.staffing.common.xss.Xss; + +/** + * 用户对象 sys_user + * + * @author staffing + */ +public class SysUser extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 用户ID */ + @Excel(name = "用户序号", type = Type.EXPORT, 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 = "手机号码", cellType = ColumnType.TEXT) + private String phonenumber; + + /** 用户性别 */ + @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知") + private String sex; + + /** 用户头像 */ + private String avatar; + + /** 密码 */ + private String password; + + /** 帐号状态(0正常 1停用) */ + @Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用") + private String status; + + /** 删除标志(0代表存在 2代表删除) */ + private String delFlag; + + /** 最后登录IP */ + @Excel(name = "最后登录IP", 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 roles; + + /** 角色组 */ + private Long[] roleIds; + + /** 岗位组 */ + private Long[] postIds; + + /** 角色ID */ + private Long roleId; + + private String idCard; + + private String openId; + + public SysUser() + { + + } + + public String getOpenId() { + return openId; + } + + public void setOpenId(String openId) { + this.openId = openId; + } + + public String getIdCard() { + return idCard; + } + + public void setIdCard(String idCard) { + this.idCard = idCard; + } + + 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; + } + + @Xss(message = "用户昵称不能包含脚本字符") + @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符") + public String getNickName() + { + return nickName; + } + + public void setNickName(String nickName) + { + this.nickName = nickName; + } + + @Xss(message = "用户账号不能包含脚本字符") + @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 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 getRoles() + { + return roles; + } + + public void setRoles(List 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; + } + + 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("deptId", getDeptId()) + .append("userName", getUserName()) + .append("nickName", getNickName()) + .append("email", getEmail()) + .append("phonenumber", getPhonenumber()) + .append("sex", getSex()) + .append("avatar", getAvatar()) + .append("password", getPassword()) + .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/staffing-common/src/main/java/com/staffing/common/core/domain/model/LoginBody.java b/staffing-common/src/main/java/com/staffing/common/core/domain/model/LoginBody.java new file mode 100644 index 0000000..f895053 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/domain/model/LoginBody.java @@ -0,0 +1,89 @@ +package com.staffing.common.core.domain.model; + +/** + * 用户登录对象 + * + * @author staffing + */ +public class LoginBody +{ + /** + * 用户名 + */ + private String username; + + /** + * 用户密码 + */ + private String password; + + /** + * 验证码 + */ + private String code; + + /** + * 唯一标识 + */ + private String uuid; + + + private String loginCode; + private String phoneCode; + + public String getLoginCode() { + return loginCode; + } + + public void setLoginCode(String loginCode) { + this.loginCode = loginCode; + } + + public String getPhoneCode() { + return phoneCode; + } + + public void setPhoneCode(String phoneCode) { + this.phoneCode = phoneCode; + } + + 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 getCode() + { + return code; + } + + public void setCode(String code) + { + this.code = code; + } + + public String getUuid() + { + return uuid; + } + + public void setUuid(String uuid) + { + this.uuid = uuid; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/core/domain/model/LoginUser.java b/staffing-common/src/main/java/com/staffing/common/core/domain/model/LoginUser.java new file mode 100644 index 0000000..c5bb0d5 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/domain/model/LoginUser.java @@ -0,0 +1,266 @@ +package com.staffing.common.core.domain.model; + +import com.alibaba.fastjson2.annotation.JSONField; +import com.staffing.common.core.domain.entity.SysUser; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import java.util.Collection; +import java.util.Set; + +/** + * 登录用户身份权限 + * + * @author staffing + */ +public class LoginUser implements UserDetails +{ + private static final long serialVersionUID = 1L; + + /** + * 用户ID + */ + private Long userId; + + /** + * 部门ID + */ + private Long deptId; + + /** + * 用户唯一标识 + */ + private String token; + + /** + * 登录时间 + */ + private Long loginTime; + + /** + * 过期时间 + */ + private Long expireTime; + + /** + * 登录IP地址 + */ + private String ipaddr; + + /** + * 登录地点 + */ + private String loginLocation; + + /** + * 浏览器类型 + */ + private String browser; + + /** + * 操作系统 + */ + private String os; + + /** + * 权限列表 + */ + private Set permissions; + + /** + * 用户信息 + */ + private SysUser user; + + public LoginUser() + { + } + + public LoginUser(SysUser user, Set permissions) + { + this.user = user; + this.permissions = permissions; + } + + public LoginUser(Long userId, Long deptId, SysUser user, Set permissions) + { + this.userId = userId; + this.deptId = deptId; + this.user = user; + this.permissions = permissions; + } + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + public String getToken() + { + return token; + } + + public void setToken(String token) + { + this.token = token; + } + + @JSONField(serialize = false) + @Override + public String getPassword() + { + return user.getPassword(); + } + + @Override + public String getUsername() + { + return user.getUserName(); + } + + /** + * 账户是否未过期,过期无法验证 + */ + @JSONField(serialize = false) + @Override + public boolean isAccountNonExpired() + { + return true; + } + + /** + * 指定用户是否解锁,锁定的用户无法进行身份验证 + * + * @return + */ + @JSONField(serialize = false) + @Override + public boolean isAccountNonLocked() + { + return true; + } + + /** + * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证 + * + * @return + */ + @JSONField(serialize = false) + @Override + public boolean isCredentialsNonExpired() + { + return true; + } + + /** + * 是否可用 ,禁用的用户不能身份验证 + * + * @return + */ + @JSONField(serialize = false) + @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 getPermissions() + { + return permissions; + } + + public void setPermissions(Set permissions) + { + this.permissions = permissions; + } + + public SysUser getUser() + { + return user; + } + + public void setUser(SysUser user) + { + this.user = user; + } + + @Override + public Collection getAuthorities() + { + return null; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/core/domain/model/RegisterBody.java b/staffing-common/src/main/java/com/staffing/common/core/domain/model/RegisterBody.java new file mode 100644 index 0000000..61ed464 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/domain/model/RegisterBody.java @@ -0,0 +1,11 @@ +package com.staffing.common.core.domain.model; + +/** + * 用户注册对象 + * + * @author staffing + */ +public class RegisterBody extends LoginBody +{ + +} diff --git a/staffing-common/src/main/java/com/staffing/common/core/page/PageDomain.java b/staffing-common/src/main/java/com/staffing/common/core/page/PageDomain.java new file mode 100644 index 0000000..2dfb4ab --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/page/PageDomain.java @@ -0,0 +1,101 @@ +package com.staffing.common.core.page; + +import com.staffing.common.utils.StringUtils; + +/** + * 分页数据 + * + * @author staffing + */ +public class PageDomain +{ + /** 当前记录起始索引 */ + private Integer pageNum; + + /** 每页显示记录数 */ + private Integer pageSize; + + /** 排序列 */ + private String orderByColumn; + + /** 排序的方向desc或者asc */ + private String isAsc = "asc"; + + /** 分页参数合理化 */ + private Boolean reasonable = false; + + 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) + { + if (StringUtils.isNotEmpty(isAsc)) + { + // 兼容前端排序类型 + if ("ascending".equals(isAsc)) + { + isAsc = "asc"; + } + else if ("descending".equals(isAsc)) + { + isAsc = "desc"; + } + this.isAsc = isAsc; + } + } + + public Boolean getReasonable() + { + if (StringUtils.isNull(reasonable)) + { + return Boolean.FALSE; + } + return reasonable; + } + + public void setReasonable(Boolean reasonable) + { + this.reasonable = reasonable; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/core/page/TableDataInfo.java b/staffing-common/src/main/java/com/staffing/common/core/page/TableDataInfo.java new file mode 100644 index 0000000..5198240 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/page/TableDataInfo.java @@ -0,0 +1,85 @@ +package com.staffing.common.core.page; + +import java.io.Serializable; +import java.util.List; + +/** + * 表格分页数据对象 + * + * @author staffing + */ +public class TableDataInfo implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 总记录数 */ + private long total; + + /** 列表数据 */ + private List rows; + + /** 消息状态码 */ + private int code; + + /** 消息内容 */ + private String 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 String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/core/page/TableSupport.java b/staffing-common/src/main/java/com/staffing/common/core/page/TableSupport.java new file mode 100644 index 0000000..7018e84 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/page/TableSupport.java @@ -0,0 +1,56 @@ +package com.staffing.common.core.page; + +import com.staffing.common.core.text.Convert; +import com.staffing.common.utils.ServletUtils; + +/** + * 表格数据处理 + * + * @author staffing + */ +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 final String REASONABLE = "reasonable"; + + /** + * 封装分页对象 + */ + public static PageDomain getPageDomain() + { + PageDomain pageDomain = new PageDomain(); + pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1)); + pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10)); + pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN)); + pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC)); + pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE)); + return pageDomain; + } + + public static PageDomain buildPageRequest() + { + return getPageDomain(); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/core/redis/RedisCache.java b/staffing-common/src/main/java/com/staffing/common/core/redis/RedisCache.java new file mode 100644 index 0000000..d043f0f --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/redis/RedisCache.java @@ -0,0 +1,268 @@ +package com.staffing.common.core.redis; + +import java.util.Collection; +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.RedisTemplate; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.stereotype.Component; + +/** + * spring redis 工具类 + * + * @author staffing + **/ +@SuppressWarnings(value = { "unchecked", "rawtypes" }) +@Component +public class RedisCache +{ + @Autowired + public RedisTemplate redisTemplate; + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + */ + public void setCacheObject(final String key, final T value) + { + redisTemplate.opsForValue().set(key, value); + } + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + * @param timeout 时间 + * @param timeUnit 时间颗粒度 + */ + public void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) + { + redisTemplate.opsForValue().set(key, value, timeout, timeUnit); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @return true=设置成功;false=设置失败 + */ + public boolean expire(final String key, final long timeout) + { + return expire(key, timeout, TimeUnit.SECONDS); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @param unit 时间单位 + * @return true=设置成功;false=设置失败 + */ + public boolean expire(final String key, final long timeout, final TimeUnit unit) + { + return redisTemplate.expire(key, timeout, unit); + } + + /** + * 获取有效时间 + * + * @param key Redis键 + * @return 有效时间 + */ + public long getExpire(final String key) + { + return redisTemplate.getExpire(key); + } + + /** + * 判断 key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public Boolean hasKey(String key) + { + return redisTemplate.hasKey(key); + } + + /** + * 获得缓存的基本对象。 + * + * @param key 缓存键值 + * @return 缓存键值对应的数据 + */ + public T getCacheObject(final String key) + { + ValueOperations operation = redisTemplate.opsForValue(); + return operation.get(key); + } + + /** + * 删除单个对象 + * + * @param key + */ + public boolean deleteObject(final String key) + { + return redisTemplate.delete(key); + } + + /** + * 删除集合对象 + * + * @param collection 多个对象 + * @return + */ + public boolean deleteObject(final Collection collection) + { + return redisTemplate.delete(collection) > 0; + } + + /** + * 缓存List数据 + * + * @param key 缓存的键值 + * @param dataList 待缓存的List数据 + * @return 缓存的对象 + */ + public long setCacheList(final String key, final List dataList) + { + Long count = redisTemplate.opsForList().rightPushAll(key, dataList); + return count == null ? 0 : count; + } + + /** + * 获得缓存的list对象 + * + * @param key 缓存的键值 + * @return 缓存键值对应的数据 + */ + public List getCacheList(final String key) + { + return redisTemplate.opsForList().range(key, 0, -1); + } + + /** + * 缓存Set + * + * @param key 缓存键值 + * @param dataSet 缓存的数据 + * @return 缓存数据的对象 + */ + public BoundSetOperations setCacheSet(final String key, final Set dataSet) + { + BoundSetOperations setOperation = redisTemplate.boundSetOps(key); + Iterator it = dataSet.iterator(); + while (it.hasNext()) + { + setOperation.add(it.next()); + } + return setOperation; + } + + /** + * 获得缓存的set + * + * @param key + * @return + */ + public Set getCacheSet(final String key) + { + return redisTemplate.opsForSet().members(key); + } + + /** + * 缓存Map + * + * @param key + * @param dataMap + */ + public void setCacheMap(final String key, final Map dataMap) + { + if (dataMap != null) { + redisTemplate.opsForHash().putAll(key, dataMap); + } + } + + /** + * 获得缓存的Map + * + * @param key + * @return + */ + public Map getCacheMap(final String key) + { + return redisTemplate.opsForHash().entries(key); + } + + /** + * 往Hash中存入数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @param value 值 + */ + public void setCacheMapValue(final String key, final String hKey, final T value) + { + redisTemplate.opsForHash().put(key, hKey, value); + } + + /** + * 获取Hash中的数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return Hash中的对象 + */ + public T getCacheMapValue(final String key, final String hKey) + { + HashOperations opsForHash = redisTemplate.opsForHash(); + return opsForHash.get(key, hKey); + } + + /** + * 获取多个Hash中的数据 + * + * @param key Redis键 + * @param hKeys Hash键集合 + * @return Hash对象集合 + */ + public List getMultiCacheMapValue(final String key, final Collection hKeys) + { + return redisTemplate.opsForHash().multiGet(key, hKeys); + } + + /** + * 删除Hash中的某条数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return 是否成功 + */ + public boolean deleteCacheMapValue(final String key, final String hKey) + { + return redisTemplate.opsForHash().delete(key, hKey) > 0; + } + + /** + * 获得缓存的基本对象列表 + * + * @param pattern 字符串前缀 + * @return 对象列表 + */ + public Collection keys(final String pattern) + { + return redisTemplate.keys(pattern); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/core/text/CharsetKit.java b/staffing-common/src/main/java/com/staffing/common/core/text/CharsetKit.java new file mode 100644 index 0000000..5a12ca1 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/text/CharsetKit.java @@ -0,0 +1,86 @@ +package com.staffing.common.core.text; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import com.staffing.common.utils.StringUtils; + +/** + * 字符集工具类 + * + * @author staffing + */ +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); + + /** + * 转换为Charset对象 + * + * @param charset 字符集,为空则返回默认字符集 + * @return Charset + */ + public static Charset charset(String charset) + { + return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset); + } + + /** + * 转换字符串的字符集编码 + * + * @param source 字符串 + * @param srcCharset 源字符集,默认ISO-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 源字符集,默认ISO-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) + { + destCharset = 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/staffing-common/src/main/java/com/staffing/common/core/text/Convert.java b/staffing-common/src/main/java/com/staffing/common/core/text/Convert.java new file mode 100644 index 0000000..442d6c9 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/text/Convert.java @@ -0,0 +1,1010 @@ +package com.staffing.common.core.text; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.math.RoundingMode; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.text.NumberFormat; +import java.util.Set; +import com.staffing.common.utils.StringUtils; +import org.apache.commons.lang3.ArrayUtils; + +/** + * 类型转换器 + * + * @author staffing + */ +public class Convert +{ + /** + * 转换为字符串
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @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(); + } + + /** + * 转换为字符串
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static String toStr(Object value) + { + return toStr(value, null); + } + + /** + * 转换为字符
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @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); + } + + /** + * 转换为字符
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Character toChar(Object value) + { + return toChar(value, null); + } + + /** + * 转换为byte
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @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; + } + } + + /** + * 转换为byte
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Byte toByte(Object value) + { + return toByte(value, null); + } + + /** + * 转换为Short
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @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; + } + } + + /** + * 转换为Short
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Short toShort(Object value) + { + return toShort(value, null); + } + + /** + * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @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; + } + } + + /** + * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Number toNumber(Object value) + { + return toNumber(value, null); + } + + /** + * 转换为int
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @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; + } + } + + /** + * 转换为int
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Integer toInt(Object value) + { + return toInt(value, null); + } + + /** + * 转换为Integer数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static Integer[] toIntArray(String str) + { + return toIntArray(",", str); + } + + /** + * 转换为Long数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static Long[] toLongArray(String str) + { + return toLongArray(",", str); + } + + /** + * 转换为Integer数组
+ * + * @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; + } + + /** + * 转换为Long数组
+ * + * @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; + } + + /** + * 转换为String数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String str) + { + if (StringUtils.isEmpty(str)) + { + return new String[] {}; + } + return toStrArray(",", str); + } + + /** + * 转换为String数组
+ * + * @param split 分隔符 + * @param split 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String split, String str) + { + return str.split(split); + } + + /** + * 转换为long
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @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; + } + } + + /** + * 转换为long
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Long toLong(Object value) + { + return toLong(value, null); + } + + /** + * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @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; + } + } + + /** + * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Double toDouble(Object value) + { + return toDouble(value, null); + } + + /** + * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @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; + } + } + + /** + * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Float toFloat(Object value) + { + return toFloat(value, null); + } + + /** + * 转换为boolean
+ * String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @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": + case "yes": + case "ok": + case "1": + return true; + case "false": + case "no": + case "0": + return false; + default: + return defaultValue; + } + } + + /** + * 转换为boolean
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Boolean toBool(Object value) + { + return toBool(value, null); + } + + /** + * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * + * @param clazz Enum的Class + * @param value 值 + * @param defaultValue 默认值 + * @return Enum + */ + public static > E toEnum(Class 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; + } + } + + /** + * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * + * @param clazz Enum的Class + * @param value 值 + * @return Enum + */ + public static > E toEnum(Class clazz, Object value) + { + return toEnum(clazz, value, null); + } + + /** + * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @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; + } + } + + /** + * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static BigInteger toBigInteger(Object value) + { + return toBigInteger(value, null); + } + + /** + * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @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 BigDecimal.valueOf((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; + } + } + + /** + * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static BigDecimal toBigDecimal(Object value) + { + return toBigDecimal(value, null); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @return 字符串 + */ + public static String utf8Str(Object obj) + { + return str(obj, CharsetKit.CHARSET_UTF_8); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @param charsetName 字符集 + * @return 字符串 + */ + public static String str(Object obj, String charsetName) + { + return str(obj, Charset.forName(charsetName)); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 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[]) + { + return str((byte[]) obj, charset); + } + else if (obj instanceof Byte[]) + { + byte[] bytes = ArrayUtils.toPrimitive((Byte[]) obj); + return str(bytes, charset); + } + else if (obj instanceof ByteBuffer) + { + return str((ByteBuffer) obj, charset); + } + return obj.toString(); + } + + /** + * 将byte数组转为字符串 + * + * @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)); + } + + /** + * 解码字节码 + * + * @param data 字符串 + * @param charset 字符集,如果此字段为空,则解码的结果取决于平台 + * @return 解码后的字符串 + */ + 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 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 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++) + { + // 优化double计算精度丢失问题 + BigDecimal nNum = new BigDecimal(n); + BigDecimal decimal = new BigDecimal(10); + BigDecimal scale = nNum.multiply(decimal).setScale(2, RoundingMode.HALF_EVEN); + double d = scale.doubleValue(); + s += (digit[(int) (Math.floor(d * 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/staffing-common/src/main/java/com/staffing/common/core/text/StrFormatter.java b/staffing-common/src/main/java/com/staffing/common/core/text/StrFormatter.java new file mode 100644 index 0000000..0cf7b3b --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/core/text/StrFormatter.java @@ -0,0 +1,92 @@ +package com.staffing.common.core.text; + +import com.staffing.common.utils.StringUtils; + +/** + * 字符串格式化 + * + * @author staffing + */ +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 = '}'; + + /** + * 格式化字符串
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b
+ * + * @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 + { + // 正常占位符 + 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/staffing-common/src/main/java/com/staffing/common/enums/BusinessStatus.java b/staffing-common/src/main/java/com/staffing/common/enums/BusinessStatus.java new file mode 100644 index 0000000..1db516c --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/enums/BusinessStatus.java @@ -0,0 +1,20 @@ +package com.staffing.common.enums; + +/** + * 操作状态 + * + * @author staffing + * + */ +public enum BusinessStatus +{ + /** + * 成功 + */ + SUCCESS, + + /** + * 失败 + */ + FAIL, +} diff --git a/staffing-common/src/main/java/com/staffing/common/enums/BusinessType.java b/staffing-common/src/main/java/com/staffing/common/enums/BusinessType.java new file mode 100644 index 0000000..6bc4998 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/enums/BusinessType.java @@ -0,0 +1,59 @@ +package com.staffing.common.enums; + +/** + * 业务操作类型 + * + * @author staffing + */ +public enum BusinessType +{ + /** + * 其它 + */ + OTHER, + + /** + * 新增 + */ + INSERT, + + /** + * 修改 + */ + UPDATE, + + /** + * 删除 + */ + DELETE, + + /** + * 授权 + */ + GRANT, + + /** + * 导出 + */ + EXPORT, + + /** + * 导入 + */ + IMPORT, + + /** + * 强退 + */ + FORCE, + + /** + * 生成代码 + */ + GENCODE, + + /** + * 清空数据 + */ + CLEAN, +} diff --git a/staffing-common/src/main/java/com/staffing/common/enums/DataSourceType.java b/staffing-common/src/main/java/com/staffing/common/enums/DataSourceType.java new file mode 100644 index 0000000..c7d2e06 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/enums/DataSourceType.java @@ -0,0 +1,19 @@ +package com.staffing.common.enums; + +/** + * 数据源 + * + * @author staffing + */ +public enum DataSourceType +{ + /** + * 主库 + */ + MASTER, + + /** + * 从库 + */ + SLAVE +} diff --git a/staffing-common/src/main/java/com/staffing/common/enums/DesensitizedType.java b/staffing-common/src/main/java/com/staffing/common/enums/DesensitizedType.java new file mode 100644 index 0000000..b210888 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/enums/DesensitizedType.java @@ -0,0 +1,59 @@ +package com.staffing.common.enums; + +import java.util.function.Function; +import com.staffing.common.utils.DesensitizedUtil; + +/** + * 脱敏类型 + * + * @author staffing + */ +public enum DesensitizedType +{ + /** + * 姓名,第2位星号替换 + */ + USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")), + + /** + * 密码,全部字符都用*代替 + */ + PASSWORD(DesensitizedUtil::password), + + /** + * 身份证,中间10位星号替换 + */ + ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\d{4})", "$1** **** ****$2")), + + /** + * 手机号,中间4位星号替换 + */ + PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")), + + /** + * 电子邮箱,仅显示第一个字母和@后面的地址显示,其他星号替换 + */ + EMAIL(s -> s.replaceAll("(^.)[^@]*(@.*$)", "$1****$2")), + + /** + * 银行卡号,保留最后4位,其他星号替换 + */ + BANK_CARD(s -> s.replaceAll("\\d{15}(\\d{3})", "**** **** **** **** $1")), + + /** + * 车牌号码,包含普通车辆、新能源车辆 + */ + CAR_LICENSE(DesensitizedUtil::carLicense); + + private final Function desensitizer; + + DesensitizedType(Function desensitizer) + { + this.desensitizer = desensitizer; + } + + public Function desensitizer() + { + return desensitizer; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/enums/HttpMethod.java b/staffing-common/src/main/java/com/staffing/common/enums/HttpMethod.java new file mode 100644 index 0000000..07c7c60 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/enums/HttpMethod.java @@ -0,0 +1,36 @@ +package com.staffing.common.enums; + +import java.util.HashMap; +import java.util.Map; +import org.springframework.lang.Nullable; + +/** + * 请求方式 + * + * @author staffing + */ +public enum HttpMethod +{ + GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE; + + private static final Map 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/staffing-common/src/main/java/com/staffing/common/enums/LimitType.java b/staffing-common/src/main/java/com/staffing/common/enums/LimitType.java new file mode 100644 index 0000000..3feb168 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/enums/LimitType.java @@ -0,0 +1,20 @@ +package com.staffing.common.enums; + +/** + * 限流类型 + * + * @author staffing + */ + +public enum LimitType +{ + /** + * 默认策略全局限流 + */ + DEFAULT, + + /** + * 根据请求者IP进行限流 + */ + IP +} diff --git a/staffing-common/src/main/java/com/staffing/common/enums/OperatorType.java b/staffing-common/src/main/java/com/staffing/common/enums/OperatorType.java new file mode 100644 index 0000000..002fc1e --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/enums/OperatorType.java @@ -0,0 +1,24 @@ +package com.staffing.common.enums; + +/** + * 操作人类别 + * + * @author staffing + */ +public enum OperatorType +{ + /** + * 其它 + */ + OTHER, + + /** + * 后台用户 + */ + MANAGE, + + /** + * 手机端用户 + */ + MOBILE +} diff --git a/staffing-common/src/main/java/com/staffing/common/enums/UserStatus.java b/staffing-common/src/main/java/com/staffing/common/enums/UserStatus.java new file mode 100644 index 0000000..ab887c7 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/enums/UserStatus.java @@ -0,0 +1,30 @@ +package com.staffing.common.enums; + +/** + * 用户状态 + * + * @author staffing + */ +public enum UserStatus +{ + OK("0", "正常"), 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/staffing-common/src/main/java/com/staffing/common/exception/DemoModeException.java b/staffing-common/src/main/java/com/staffing/common/exception/DemoModeException.java new file mode 100644 index 0000000..3d5bfed --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/exception/DemoModeException.java @@ -0,0 +1,15 @@ +package com.staffing.common.exception; + +/** + * 演示模式异常 + * + * @author staffing + */ +public class DemoModeException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public DemoModeException() + { + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/exception/GlobalException.java b/staffing-common/src/main/java/com/staffing/common/exception/GlobalException.java new file mode 100644 index 0000000..b8461a2 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/exception/GlobalException.java @@ -0,0 +1,58 @@ +package com.staffing.common.exception; + +/** + * 全局异常 + * + * @author staffing + */ +public class GlobalException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + /** + * 错误提示 + */ + private String message; + + /** + * 错误明细,内部调试错误 + * + * 和 {@link CommonResult#getDetailMessage()} 一致的设计 + */ + private String detailMessage; + + /** + * 空构造方法,避免反序列化问题 + */ + public GlobalException() + { + } + + public GlobalException(String message) + { + this.message = message; + } + + public String getDetailMessage() + { + return detailMessage; + } + + public GlobalException setDetailMessage(String detailMessage) + { + this.detailMessage = detailMessage; + return this; + } + + @Override + public String getMessage() + { + return message; + } + + public GlobalException setMessage(String message) + { + this.message = message; + return this; + } +} \ No newline at end of file diff --git a/staffing-common/src/main/java/com/staffing/common/exception/ServiceException.java b/staffing-common/src/main/java/com/staffing/common/exception/ServiceException.java new file mode 100644 index 0000000..03bad1e --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/exception/ServiceException.java @@ -0,0 +1,74 @@ +package com.staffing.common.exception; + +/** + * 业务异常 + * + * @author staffing + */ +public final class ServiceException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + /** + * 错误码 + */ + private Integer code; + + /** + * 错误提示 + */ + private String message; + + /** + * 错误明细,内部调试错误 + * + * 和 {@link CommonResult#getDetailMessage()} 一致的设计 + */ + private String detailMessage; + + /** + * 空构造方法,避免反序列化问题 + */ + public ServiceException() + { + } + + public ServiceException(String message) + { + this.message = message; + } + + public ServiceException(String message, Integer code) + { + this.message = message; + this.code = code; + } + + public String getDetailMessage() + { + return detailMessage; + } + + @Override + public String getMessage() + { + return message; + } + + public Integer getCode() + { + return code; + } + + public ServiceException setMessage(String message) + { + this.message = message; + return this; + } + + public ServiceException setDetailMessage(String detailMessage) + { + this.detailMessage = detailMessage; + return this; + } +} \ No newline at end of file diff --git a/staffing-common/src/main/java/com/staffing/common/exception/UtilException.java b/staffing-common/src/main/java/com/staffing/common/exception/UtilException.java new file mode 100644 index 0000000..ee5cf49 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/exception/UtilException.java @@ -0,0 +1,26 @@ +package com.staffing.common.exception; + +/** + * 工具类异常 + * + * @author staffing + */ +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/staffing-common/src/main/java/com/staffing/common/exception/base/BaseException.java b/staffing-common/src/main/java/com/staffing/common/exception/base/BaseException.java new file mode 100644 index 0000000..a8a9179 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/exception/base/BaseException.java @@ -0,0 +1,97 @@ +package com.staffing.common.exception.base; + +import com.staffing.common.utils.MessageUtils; +import com.staffing.common.utils.StringUtils; + +/** + * 基础异常 + * + * @author staffing + */ +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/staffing-common/src/main/java/com/staffing/common/exception/file/FileException.java b/staffing-common/src/main/java/com/staffing/common/exception/file/FileException.java new file mode 100644 index 0000000..ab4c2c6 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/exception/file/FileException.java @@ -0,0 +1,19 @@ +package com.staffing.common.exception.file; + +import com.staffing.common.exception.base.BaseException; + +/** + * 文件信息异常类 + * + * @author staffing + */ +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/staffing-common/src/main/java/com/staffing/common/exception/file/FileNameLengthLimitExceededException.java b/staffing-common/src/main/java/com/staffing/common/exception/file/FileNameLengthLimitExceededException.java new file mode 100644 index 0000000..b855687 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/exception/file/FileNameLengthLimitExceededException.java @@ -0,0 +1,16 @@ +package com.staffing.common.exception.file; + +/** + * 文件名称超长限制异常类 + * + * @author staffing + */ +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/staffing-common/src/main/java/com/staffing/common/exception/file/FileSizeLimitExceededException.java b/staffing-common/src/main/java/com/staffing/common/exception/file/FileSizeLimitExceededException.java new file mode 100644 index 0000000..c216e6d --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/exception/file/FileSizeLimitExceededException.java @@ -0,0 +1,16 @@ +package com.staffing.common.exception.file; + +/** + * 文件名大小限制异常类 + * + * @author staffing + */ +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/staffing-common/src/main/java/com/staffing/common/exception/file/FileUploadException.java b/staffing-common/src/main/java/com/staffing/common/exception/file/FileUploadException.java new file mode 100644 index 0000000..2bf1470 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/exception/file/FileUploadException.java @@ -0,0 +1,61 @@ +package com.staffing.common.exception.file; + +import java.io.PrintStream; +import java.io.PrintWriter; + +/** + * 文件上传异常类 + * + * @author staffing + */ +public class FileUploadException extends Exception +{ + + private static final long serialVersionUID = 1L; + + private final Throwable cause; + + public FileUploadException() + { + this(null, null); + } + + public FileUploadException(final String msg) + { + this(msg, null); + } + + public FileUploadException(String msg, Throwable cause) + { + super(msg); + this.cause = cause; + } + + @Override + public void printStackTrace(PrintStream stream) + { + super.printStackTrace(stream); + if (cause != null) + { + stream.println("Caused by:"); + cause.printStackTrace(stream); + } + } + + @Override + public void printStackTrace(PrintWriter writer) + { + super.printStackTrace(writer); + if (cause != null) + { + writer.println("Caused by:"); + cause.printStackTrace(writer); + } + } + + @Override + public Throwable getCause() + { + return cause; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/exception/file/InvalidExtensionException.java b/staffing-common/src/main/java/com/staffing/common/exception/file/InvalidExtensionException.java new file mode 100644 index 0000000..2987cab --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/exception/file/InvalidExtensionException.java @@ -0,0 +1,80 @@ +package com.staffing.common.exception.file; + +import java.util.Arrays; + +/** + * 文件上传 误异常类 + * + * @author staffing + */ +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 + "]后缀[" + 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); + } + } + + public static class InvalidVideoExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/exception/job/TaskException.java b/staffing-common/src/main/java/com/staffing/common/exception/job/TaskException.java new file mode 100644 index 0000000..c2b2ee5 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/exception/job/TaskException.java @@ -0,0 +1,34 @@ +package com.staffing.common.exception.job; + +/** + * 计划策略异常 + * + * @author staffing + */ +public class TaskException extends Exception +{ + private static final long serialVersionUID = 1L; + + private Code code; + + public TaskException(String msg, Code code) + { + this(msg, code, null); + } + + public TaskException(String msg, Code code, Exception nestedEx) + { + super(msg, nestedEx); + this.code = code; + } + + public Code getCode() + { + return code; + } + + public enum Code + { + TASK_EXISTS, NO_TASK_EXISTS, TASK_ALREADY_STARTED, UNKNOWN, CONFIG_ERROR, TASK_NODE_NOT_AVAILABLE + } +} \ No newline at end of file diff --git a/staffing-common/src/main/java/com/staffing/common/exception/user/BlackListException.java b/staffing-common/src/main/java/com/staffing/common/exception/user/BlackListException.java new file mode 100644 index 0000000..3764bda --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/exception/user/BlackListException.java @@ -0,0 +1,16 @@ +package com.staffing.common.exception.user; + +/** + * 黑名单IP异常类 + * + * @author staffing + */ +public class BlackListException extends UserException +{ + private static final long serialVersionUID = 1L; + + public BlackListException() + { + super("login.blocked", null); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/exception/user/CaptchaException.java b/staffing-common/src/main/java/com/staffing/common/exception/user/CaptchaException.java new file mode 100644 index 0000000..5535685 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/exception/user/CaptchaException.java @@ -0,0 +1,16 @@ +package com.staffing.common.exception.user; + +/** + * 验证码错误异常类 + * + * @author staffing + */ +public class CaptchaException extends UserException +{ + private static final long serialVersionUID = 1L; + + public CaptchaException() + { + super("user.jcaptcha.error", null); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/exception/user/CaptchaExpireException.java b/staffing-common/src/main/java/com/staffing/common/exception/user/CaptchaExpireException.java new file mode 100644 index 0000000..cd7afea --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/exception/user/CaptchaExpireException.java @@ -0,0 +1,16 @@ +package com.staffing.common.exception.user; + +/** + * 验证码失效异常类 + * + * @author staffing + */ +public class CaptchaExpireException extends UserException +{ + private static final long serialVersionUID = 1L; + + public CaptchaExpireException() + { + super("user.jcaptcha.expire", null); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/exception/user/UserException.java b/staffing-common/src/main/java/com/staffing/common/exception/user/UserException.java new file mode 100644 index 0000000..0768d38 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/exception/user/UserException.java @@ -0,0 +1,18 @@ +package com.staffing.common.exception.user; + +import com.staffing.common.exception.base.BaseException; + +/** + * 用户信息异常类 + * + * @author staffing + */ +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/staffing-common/src/main/java/com/staffing/common/exception/user/UserNotExistsException.java b/staffing-common/src/main/java/com/staffing/common/exception/user/UserNotExistsException.java new file mode 100644 index 0000000..03d6190 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/exception/user/UserNotExistsException.java @@ -0,0 +1,16 @@ +package com.staffing.common.exception.user; + +/** + * 用户不存在异常类 + * + * @author staffing + */ +public class UserNotExistsException extends UserException +{ + private static final long serialVersionUID = 1L; + + public UserNotExistsException() + { + super("user.not.exists", null); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/exception/user/UserPasswordNotMatchException.java b/staffing-common/src/main/java/com/staffing/common/exception/user/UserPasswordNotMatchException.java new file mode 100644 index 0000000..0085194 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/exception/user/UserPasswordNotMatchException.java @@ -0,0 +1,16 @@ +package com.staffing.common.exception.user; + +/** + * 用户密码不正确或不符合规范异常类 + * + * @author staffing + */ +public class UserPasswordNotMatchException extends UserException +{ + private static final long serialVersionUID = 1L; + + public UserPasswordNotMatchException() + { + super("user.password.not.match", null); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/exception/user/UserPasswordRetryLimitExceedException.java b/staffing-common/src/main/java/com/staffing/common/exception/user/UserPasswordRetryLimitExceedException.java new file mode 100644 index 0000000..5370d19 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/exception/user/UserPasswordRetryLimitExceedException.java @@ -0,0 +1,16 @@ +package com.staffing.common.exception.user; + +/** + * 用户错误最大次数异常类 + * + * @author staffing + */ +public class UserPasswordRetryLimitExceedException extends UserException +{ + private static final long serialVersionUID = 1L; + + public UserPasswordRetryLimitExceedException(int retryLimitCount, int lockTime) + { + super("user.password.retry.limit.exceed", new Object[] { retryLimitCount, lockTime }); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/filter/PropertyPreExcludeFilter.java b/staffing-common/src/main/java/com/staffing/common/filter/PropertyPreExcludeFilter.java new file mode 100644 index 0000000..4739bc6 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/filter/PropertyPreExcludeFilter.java @@ -0,0 +1,24 @@ +package com.staffing.common.filter; + +import com.alibaba.fastjson2.filter.SimplePropertyPreFilter; + +/** + * 排除JSON敏感属性 + * + * @author staffing + */ +public class PropertyPreExcludeFilter extends SimplePropertyPreFilter +{ + public PropertyPreExcludeFilter() + { + } + + public PropertyPreExcludeFilter addExcludes(String... filters) + { + for (int i = 0; i < filters.length; i++) + { + this.getExcludes().add(filters[i]); + } + return this; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/filter/RepeatableFilter.java b/staffing-common/src/main/java/com/staffing/common/filter/RepeatableFilter.java new file mode 100644 index 0000000..2fa5c38 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/filter/RepeatableFilter.java @@ -0,0 +1,52 @@ +package com.staffing.common.filter; + +import java.io.IOException; +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 org.springframework.http.MediaType; +import com.staffing.common.utils.StringUtils; + +/** + * Repeatable 过滤器 + * + * @author staffing + */ +public class RepeatableFilter implements Filter +{ + @Override + public void init(FilterConfig filterConfig) throws ServletException + { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException + { + ServletRequest requestWrapper = null; + if (request instanceof HttpServletRequest + && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) + { + requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response); + } + if (null == requestWrapper) + { + chain.doFilter(request, response); + } + else + { + chain.doFilter(requestWrapper, response); + } + } + + @Override + public void destroy() + { + + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/filter/RepeatedlyRequestWrapper.java b/staffing-common/src/main/java/com/staffing/common/filter/RepeatedlyRequestWrapper.java new file mode 100644 index 0000000..8293c0f --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/filter/RepeatedlyRequestWrapper.java @@ -0,0 +1,76 @@ +package com.staffing.common.filter; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import com.staffing.common.utils.http.HttpHelper; +import com.staffing.common.constant.Constants; + +/** + * 构建可重复读取inputStream的request + * + * @author staffing + */ +public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper +{ + private final byte[] body; + + public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException + { + super(request); + request.setCharacterEncoding(Constants.UTF8); + response.setCharacterEncoding(Constants.UTF8); + + body = HttpHelper.getBodyString(request).getBytes(Constants.UTF8); + } + + @Override + public BufferedReader getReader() throws IOException + { + return new BufferedReader(new InputStreamReader(getInputStream())); + } + + @Override + public ServletInputStream getInputStream() throws IOException + { + final ByteArrayInputStream bais = new ByteArrayInputStream(body); + return new ServletInputStream() + { + @Override + public int read() throws IOException + { + return bais.read(); + } + + @Override + public int available() throws IOException + { + return body.length; + } + + @Override + public boolean isFinished() + { + return false; + } + + @Override + public boolean isReady() + { + return false; + } + + @Override + public void setReadListener(ReadListener readListener) + { + + } + }; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/filter/XssFilter.java b/staffing-common/src/main/java/com/staffing/common/filter/XssFilter.java new file mode 100644 index 0000000..97e1387 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/filter/XssFilter.java @@ -0,0 +1,75 @@ +package com.staffing.common.filter; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +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.staffing.common.utils.StringUtils; +import com.staffing.common.enums.HttpMethod; + +/** + * 防止XSS攻击的过滤器 + * + * @author staffing + */ +public class XssFilter implements Filter +{ + /** + * 排除链接 + */ + public List excludes = new ArrayList<>(); + + @Override + public void init(FilterConfig filterConfig) throws ServletException + { + String tempExcludes = filterConfig.getInitParameter("excludes"); + if (StringUtils.isNotEmpty(tempExcludes)) + { + String[] urls = tempExcludes.split(","); + for (String url : urls) + { + excludes.add(url); + } + } + } + + @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) + { + String url = request.getServletPath(); + String method = request.getMethod(); + // GET DELETE 不过滤 + if (method == null || HttpMethod.GET.matches(method) || HttpMethod.DELETE.matches(method)) + { + return true; + } + return StringUtils.matches(url, excludes); + } + + @Override + public void destroy() + { + + } +} \ No newline at end of file diff --git a/staffing-common/src/main/java/com/staffing/common/filter/XssHttpServletRequestWrapper.java b/staffing-common/src/main/java/com/staffing/common/filter/XssHttpServletRequestWrapper.java new file mode 100644 index 0000000..211322a --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/filter/XssHttpServletRequestWrapper.java @@ -0,0 +1,111 @@ +package com.staffing.common.filter; + +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.staffing.common.utils.StringUtils; +import com.staffing.common.utils.html.EscapeUtil; + +/** + * XSS过滤处理 + * + * @author staffing + */ +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[] escapesValues = new String[length]; + for (int i = 0; i < length; i++) + { + // 防xss攻击和过滤前后空格 + escapesValues[i] = EscapeUtil.clean(values[i]).trim(); + } + return escapesValues; + } + return super.getParameterValues(name); + } + + @Override + public ServletInputStream getInputStream() throws IOException + { + // 非json类型,直接返回 + 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(); + byte[] jsonBytes = json.getBytes("utf-8"); + final ByteArrayInputStream bis = new ByteArrayInputStream(jsonBytes); + return new ServletInputStream() + { + @Override + public boolean isFinished() + { + return true; + } + + @Override + public boolean isReady() + { + return true; + } + + @Override + public int available() throws IOException + { + return jsonBytes.length; + } + + @Override + public void setReadListener(ReadListener readListener) + { + } + + @Override + public int read() throws IOException + { + return bis.read(); + } + }; + } + + /** + * 是否是Json请求 + * + * @param request + */ + public boolean isJsonRequest() + { + String header = super.getHeader(HttpHeaders.CONTENT_TYPE); + return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE); + } +} \ No newline at end of file diff --git a/staffing-common/src/main/java/com/staffing/common/utils/Arith.java b/staffing-common/src/main/java/com/staffing/common/utils/Arith.java new file mode 100644 index 0000000..03b1eca --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/Arith.java @@ -0,0 +1,114 @@ +package com.staffing.common.utils; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +/** + * 精确的浮点数运算 + * + * @author staffing + */ +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); + } + + /** + * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 + * 定精度,以后的数字四舍五入。 + * @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 = BigDecimal.ONE; + return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue(); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/DateUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/DateUtils.java new file mode 100644 index 0000000..f7c280d --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/DateUtils.java @@ -0,0 +1,191 @@ +package com.staffing.common.utils; + +import java.lang.management.ManagementFactory; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Date; +import org.apache.commons.lang3.time.DateFormatUtils; + +/** + * 时间工具类 + * + * @author staffing + */ +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(); + } + + /** + * 获取当前日期, 默认格式为yyyy-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 int differentDaysByMillisecond(Date date1, Date date2) + { + return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24))); + } + + /** + * 计算时间差 + * + * @param endDate 最后时间 + * @param startTime 开始时间 + * @return 时间差(天/小时/分钟) + */ + public static String timeDistance(Date endDate, Date startTime) + { + long nd = 1000 * 24 * 60 * 60; + long nh = 1000 * 60 * 60; + long nm = 1000 * 60; + // long ns = 1000; + // 获得两个时间的毫秒时间差异 + long diff = endDate.getTime() - startTime.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 + "分钟"; + } + + /** + * 增加 LocalDateTime ==> Date + */ + public static Date toDate(LocalDateTime temporalAccessor) + { + ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault()); + return Date.from(zdt.toInstant()); + } + + /** + * 增加 LocalDate ==> Date + */ + public static Date toDate(LocalDate temporalAccessor) + { + LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0)); + ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault()); + return Date.from(zdt.toInstant()); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/DesensitizedUtil.java b/staffing-common/src/main/java/com/staffing/common/utils/DesensitizedUtil.java new file mode 100644 index 0000000..cb535c2 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/DesensitizedUtil.java @@ -0,0 +1,49 @@ +package com.staffing.common.utils; + +/** + * 脱敏工具类 + * + * @author staffing + */ +public class DesensitizedUtil +{ + /** + * 密码的全部字符都用*代替,比如:****** + * + * @param password 密码 + * @return 脱敏后的密码 + */ + public static String password(String password) + { + if (StringUtils.isBlank(password)) + { + return StringUtils.EMPTY; + } + return StringUtils.repeat('*', password.length()); + } + + /** + * 车牌中间用*代替,如果是错误的车牌,不处理 + * + * @param carLicense 完整的车牌号 + * @return 脱敏后的车牌 + */ + public static String carLicense(String carLicense) + { + if (StringUtils.isBlank(carLicense)) + { + return StringUtils.EMPTY; + } + // 普通车牌 + if (carLicense.length() == 7) + { + carLicense = StringUtils.hide(carLicense, 3, 6); + } + else if (carLicense.length() == 8) + { + // 新能源车牌 + carLicense = StringUtils.hide(carLicense, 3, 7); + } + return carLicense; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/DictUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/DictUtils.java new file mode 100644 index 0000000..8a0498c --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/DictUtils.java @@ -0,0 +1,239 @@ +package com.staffing.common.utils; + +import java.util.Collection; +import java.util.List; +import com.alibaba.fastjson2.JSONArray; +import com.staffing.common.constant.CacheConstants; +import com.staffing.common.core.domain.entity.SysDictData; +import com.staffing.common.core.redis.RedisCache; +import com.staffing.common.utils.spring.SpringUtils; + +/** + * 字典工具类 + * + * @author staffing + */ +public class DictUtils +{ + /** + * 分隔符 + */ + public static final String SEPARATOR = ","; + + /** + * 设置字典缓存 + * + * @param key 参数键 + * @param dictDatas 字典数据列表 + */ + public static void setDictCache(String key, List dictDatas) + { + SpringUtils.getBean(RedisCache.class).setCacheObject(getCacheKey(key), dictDatas); + } + + /** + * 获取字典缓存 + * + * @param key 参数键 + * @return dictDatas 字典数据列表 + */ + public static List getDictCache(String key) + { + JSONArray arrayCache = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key)); + if (StringUtils.isNotNull(arrayCache)) + { + return arrayCache.toList(SysDictData.class); + } + return null; + } + + /** + * 根据字典类型和字典值获取字典标签 + * + * @param dictType 字典类型 + * @param dictValue 字典值 + * @return 字典标签 + */ + public static String getDictLabel(String dictType, String dictValue) + { + if (StringUtils.isEmpty(dictValue)) + { + return StringUtils.EMPTY; + } + return getDictLabel(dictType, dictValue, SEPARATOR); + } + + /** + * 根据字典类型和字典标签获取字典值 + * + * @param dictType 字典类型 + * @param dictLabel 字典标签 + * @return 字典值 + */ + public static String getDictValue(String dictType, String dictLabel) + { + if (StringUtils.isEmpty(dictLabel)) + { + return StringUtils.EMPTY; + } + return getDictValue(dictType, dictLabel, SEPARATOR); + } + + /** + * 根据字典类型和字典值获取字典标签 + * + * @param dictType 字典类型 + * @param dictValue 字典值 + * @param separator 分隔符 + * @return 字典标签 + */ + public static String getDictLabel(String dictType, String dictValue, String separator) + { + StringBuilder propertyString = new StringBuilder(); + List datas = getDictCache(dictType); + if (StringUtils.isNull(datas)) + { + return StringUtils.EMPTY; + } + if (StringUtils.containsAny(separator, dictValue)) + { + for (SysDictData dict : datas) + { + for (String value : dictValue.split(separator)) + { + if (value.equals(dict.getDictValue())) + { + propertyString.append(dict.getDictLabel()).append(separator); + break; + } + } + } + } + else + { + for (SysDictData dict : datas) + { + if (dictValue.equals(dict.getDictValue())) + { + return dict.getDictLabel(); + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 根据字典类型和字典标签获取字典值 + * + * @param dictType 字典类型 + * @param dictLabel 字典标签 + * @param separator 分隔符 + * @return 字典值 + */ + public static String getDictValue(String dictType, String dictLabel, String separator) + { + StringBuilder propertyString = new StringBuilder(); + List datas = getDictCache(dictType); + if (StringUtils.isNull(datas)) + { + return StringUtils.EMPTY; + } + if (StringUtils.containsAny(separator, dictLabel)) + { + for (SysDictData dict : datas) + { + for (String label : dictLabel.split(separator)) + { + if (label.equals(dict.getDictLabel())) + { + propertyString.append(dict.getDictValue()).append(separator); + break; + } + } + } + } + else + { + for (SysDictData dict : datas) + { + if (dictLabel.equals(dict.getDictLabel())) + { + return dict.getDictValue(); + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 根据字典类型获取字典所有值 + * + * @param dictType 字典类型 + * @return 字典值 + */ + public static String getDictValues(String dictType) + { + StringBuilder propertyString = new StringBuilder(); + List datas = getDictCache(dictType); + if (StringUtils.isNull(datas)) + { + return StringUtils.EMPTY; + } + for (SysDictData dict : datas) + { + propertyString.append(dict.getDictValue()).append(SEPARATOR); + } + return StringUtils.stripEnd(propertyString.toString(), SEPARATOR); + } + + /** + * 根据字典类型获取字典所有标签 + * + * @param dictType 字典类型 + * @return 字典值 + */ + public static String getDictLabels(String dictType) + { + StringBuilder propertyString = new StringBuilder(); + List datas = getDictCache(dictType); + if (StringUtils.isNull(datas)) + { + return StringUtils.EMPTY; + } + for (SysDictData dict : datas) + { + propertyString.append(dict.getDictLabel()).append(SEPARATOR); + } + return StringUtils.stripEnd(propertyString.toString(), SEPARATOR); + } + + /** + * 删除指定字典缓存 + * + * @param key 字典键 + */ + public static void removeDictCache(String key) + { + SpringUtils.getBean(RedisCache.class).deleteObject(getCacheKey(key)); + } + + /** + * 清空字典缓存 + */ + public static void clearDictCache() + { + Collection keys = SpringUtils.getBean(RedisCache.class).keys(CacheConstants.SYS_DICT_KEY + "*"); + SpringUtils.getBean(RedisCache.class).deleteObject(keys); + } + + /** + * 设置cache key + * + * @param configKey 参数键 + * @return 缓存键key + */ + public static String getCacheKey(String configKey) + { + return CacheConstants.SYS_DICT_KEY + configKey; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/ExceptionUtil.java b/staffing-common/src/main/java/com/staffing/common/utils/ExceptionUtil.java new file mode 100644 index 0000000..2d4147d --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/ExceptionUtil.java @@ -0,0 +1,39 @@ +package com.staffing.common.utils; + +import java.io.PrintWriter; +import java.io.StringWriter; +import org.apache.commons.lang3.exception.ExceptionUtils; + +/** + * 错误信息处理类。 + * + * @author staffing + */ +public class ExceptionUtil +{ + /** + * 获取exception的详细错误信息。 + */ + public static String getExceptionMessage(Throwable e) + { + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw, true)); + return sw.toString(); + } + + public static String getRootErrorMessage(Exception e) + { + Throwable root = ExceptionUtils.getRootCause(e); + root = (root == null ? e : root); + if (root == null) + { + return ""; + } + String msg = root.getMessage(); + if (msg == null) + { + return "null"; + } + return StringUtils.defaultString(msg); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/LogUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/LogUtils.java new file mode 100644 index 0000000..9031d7b --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/LogUtils.java @@ -0,0 +1,18 @@ +package com.staffing.common.utils; + +/** + * 处理并记录日志文件 + * + * @author staffing + */ +public class LogUtils +{ + public static String getBlock(Object msg) + { + if (msg == null) + { + msg = ""; + } + return "[" + msg.toString() + "]"; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/MessageUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/MessageUtils.java new file mode 100644 index 0000000..99c0171 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/MessageUtils.java @@ -0,0 +1,26 @@ +package com.staffing.common.utils; + +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; +import com.staffing.common.utils.spring.SpringUtils; + +/** + * 获取i18n资源文件 + * + * @author staffing + */ +public class MessageUtils +{ + /** + * 根据消息键和参数 获取消息 委托给spring 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/staffing-common/src/main/java/com/staffing/common/utils/MinioUtil.java b/staffing-common/src/main/java/com/staffing/common/utils/MinioUtil.java new file mode 100644 index 0000000..f1b7cbb --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/MinioUtil.java @@ -0,0 +1,190 @@ +package com.staffing.common.utils; + +import com.github.pagehelper.util.StringUtil; +import io.minio.*; +import io.minio.errors.*; +import io.minio.http.Method; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URLEncoder; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.concurrent.TimeUnit; + + +@Component +public class MinioUtil { + private Logger logger = LoggerFactory.getLogger(MinioUtil.class); + + @Autowired + private MinioClient minioClient; + + /** + * 创建bucket + * */ + private void createBucket(String bucketName) throws Exception { + BucketExistsArgs existsArgs = BucketExistsArgs.builder().bucket(bucketName).build(); + if(!minioClient.bucketExists(existsArgs)) { + MakeBucketArgs makeArgs = MakeBucketArgs.builder().bucket(bucketName).build(); + minioClient.makeBucket(makeArgs); + logger.info("bucket {} 不存在, 自动创建该bucket", bucketName); + } + } + + /** + * 从给定输入流中传输对象并放入bucket + * */ + public ObjectWriteResponse putObject(String bucketName, String objectName, InputStream stream, long objectSize, String contentType) throws Exception { + if (StringUtils.isEmpty(bucketName)) { + throw new RuntimeException("保存的bucketName为空"); + } + createBucket(bucketName); + //long objSize = -1; + long partSize = -1; //objectSize已知,partSize设为-1意为自动设置 + PutObjectArgs putArgs = PutObjectArgs.builder() + .bucket(bucketName) + .object(objectName) + .stream(stream, objectSize, partSize) + .contentType(contentType) + .build(); + ObjectWriteResponse response = minioClient.putObject(putArgs); + + return response; + } + public enum ViewContentType { + DEFAULT("default","application/octet-stream"), + JPG("jpg", "image/jpeg"), + TIFF("tiff", "image/tiff"), + GIF("gif", "image/gif"), + JFIF("jfif", "image/jpeg"), + PNG("png", "image/png"), + TIF("tif", "image/tiff"), + ICO("ico", "image/x-icon"), + JPEG("jpeg", "image/jpeg"), + WBMP("wbmp", "image/vnd.wap.wbmp"), + FAX("fax", "image/fax"), + NET("net", "image/pnetvue"), + JPE("jpe", "image/jpeg"), + RP("rp", "image/vnd.rn-realpix"); + + private String prefix; + + private String type; + + public static String getContentType(String prefix){ + if(StringUtil.isEmpty(prefix)){ + return DEFAULT.getType(); + } + prefix = prefix.substring(prefix.lastIndexOf(".") + 1); + for (ViewContentType value : ViewContentType.values()) { + if(prefix.equalsIgnoreCase(value.getPrefix())){ + return value.getType(); + } + } + return DEFAULT.getType(); + } + + ViewContentType(String prefix, String type) { + this.prefix = prefix; + this.type = type; + } + + public String getPrefix() { + return prefix; + } + + public String getType() { + return type; + } + } + /** + * 从bucket获取指定对象的输入流,后续可使用输入流读取对象 + * getObject与minio server连接默认保持5分钟, + * 每隔15s由minio server向客户端发送keep-alive check,5分钟后由客户端主动发起关闭连接 + * */ + public InputStream getObject(String bucketName, String objectName) throws Exception{ + GetObjectArgs args = GetObjectArgs.builder() + .bucket(bucketName) + .object(objectName) + .build(); + return minioClient.getObject(args); + } + + /** + * 获取对象的临时访问url,有效期5分钟 + * */ + public String getObjectURL(String bucketName, String objectName){ + GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder() + .bucket(bucketName) + .object(objectName) + .expiry(5, TimeUnit.MINUTES) + .method(Method.GET) + .build(); + try { + return minioClient.getPresignedObjectUrl(args); + } catch (Exception e) { + e.printStackTrace(); + } + return ""; + } + + /** + * 删除对象 + * */ + public void removeObject(String bucketName, String objectName) throws Exception { + RemoveObjectArgs args = RemoveObjectArgs.builder() + .bucket(bucketName) + .object(objectName) + .build(); + minioClient.removeObject(args); + logger.info("bucket:{}文件{}已删除", bucketName , objectName); + } + + /** + * 上传MultipartFile + * @param bucketName 文件存放的bucket + * @param filePath 文件在bucket里的全目录 + * */ + public ObjectWriteResponse uploadFile(String bucketName, String filePath, MultipartFile file) throws Exception{ + return putObject(bucketName, filePath, file.getInputStream(), file.getSize(), file.getContentType()); + } + + /** + * 从minio下载文件,直接通过response传输 + * */ + public void downloadFile(String bucketName, String filePath, HttpServletResponse response) throws Exception { + + try (InputStream is = getObject(bucketName, filePath); + BufferedInputStream bis = new BufferedInputStream(is); + OutputStream os = response.getOutputStream()) { + //try { + /*InputStream is = getObject(bucketName, filePath); + BufferedInputStream bis = new BufferedInputStream(is); + OutputStream os = response.getOutputStream();*/ + response.setContentType("application/force-download;charset=utf-8");// 设置强制下载而不是直接打开 + response.addHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(filePath, "UTF-8"));// 设置文件名 + + + byte[] buffer = new byte[1024*1024*1024]; //buffer 1M + int offset = bis.read(buffer); + while (offset != -1) { + os.write(buffer, 0, offset); + offset = bis.read(buffer); + } + os.flush(); + } catch (Exception e) { + logger.error("下载文件失败"+e.getMessage(), e); + throw new RuntimeException("下载文件失败" , e); + } + } +} \ No newline at end of file diff --git a/staffing-common/src/main/java/com/staffing/common/utils/OrderUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/OrderUtils.java new file mode 100644 index 0000000..5af0f64 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/OrderUtils.java @@ -0,0 +1,14 @@ +package com.staffing.common.utils; + +import java.util.concurrent.atomic.AtomicInteger; + +public class OrderUtils { + private static AtomicInteger nextId = new AtomicInteger(0); + private static int serverId = 1; + public static String genOrderId(String type){ + String id = type + System.currentTimeMillis() + serverId + nextId.addAndGet(1); + return id; + } + + +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/PageUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/PageUtils.java new file mode 100644 index 0000000..f979647 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/PageUtils.java @@ -0,0 +1,35 @@ +package com.staffing.common.utils; + +import com.github.pagehelper.PageHelper; +import com.staffing.common.core.page.PageDomain; +import com.staffing.common.core.page.TableSupport; +import com.staffing.common.utils.sql.SqlUtil; + +/** + * 分页工具类 + * + * @author staffing + */ +public class PageUtils extends PageHelper +{ + /** + * 设置请求分页数据 + */ + public static void startPage() + { + PageDomain pageDomain = TableSupport.buildPageRequest(); + Integer pageNum = pageDomain.getPageNum(); + Integer pageSize = pageDomain.getPageSize(); + String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy()); + Boolean reasonable = pageDomain.getReasonable(); + PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable); + } + + /** + * 清理分页的线程变量 + */ + public static void clearPage() + { + PageHelper.clearPage(); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/QRCodeGenerator.java b/staffing-common/src/main/java/com/staffing/common/utils/QRCodeGenerator.java new file mode 100644 index 0000000..6d18811 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/QRCodeGenerator.java @@ -0,0 +1,111 @@ +package com.staffing.common.utils; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.WriterException; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.WriterException; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.*; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.*; +import java.awt.Graphics2D; + +public class QRCodeGenerator { + private static Logger logger = LoggerFactory.getLogger(QRCodeGenerator.class); + + /** + * 永久二维码 + * @param text + * @param width + * @param height + * @param filePath + */ + public static InputStream generateQRCodeImage(String text, int width, int height) { + try { + QRCodeWriter qrCodeWriter = new QRCodeWriter(); + Map hints = new HashMap<>(); + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); + BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hints); + + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + bufferedImage.createGraphics(); + + Graphics2D graphics = (Graphics2D) bufferedImage.getGraphics(); + graphics.setColor(java.awt.Color.WHITE); + graphics.fillRect(0, 0, width, height); + graphics.setColor(java.awt.Color.BLACK); + + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { + if (bitMatrix.get(i, j)) { + graphics.fillRect(i, j, 1, 1); + } + } + } + + return bufferedImageToInputStream(bufferedImage, "png"); + } catch (WriterException | IOException e) { + logger.error("generateQRCodeImage error", e); + } + return null; + } + public static InputStream bufferedImageToInputStream(BufferedImage image, String formatName) throws IOException { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ImageIO.write(image, formatName, outputStream); + return new ByteArrayInputStream(outputStream.toByteArray()); + } + /** + * 永久二维码 + * @param text + * @param width + * @param height + * @param filePath + */ + public static void generateQRCodeImage(String text, int width, int height, String filePath) { + try { + QRCodeWriter qrCodeWriter = new QRCodeWriter(); + Map hints = new HashMap<>(); + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); + BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hints); + + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + bufferedImage.createGraphics(); + + Graphics2D graphics = (Graphics2D) bufferedImage.getGraphics(); + graphics.setColor(java.awt.Color.WHITE); + graphics.fillRect(0, 0, width, height); + graphics.setColor(java.awt.Color.BLACK); + + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { + if (bitMatrix.get(i, j)) { + graphics.fillRect(i, j, 1, 1); + } + } + } + + ImageIO.write(bufferedImage, "png", new File(filePath)); + } catch (WriterException | IOException e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { +// generateQRCodeImage("http://yg.pusonggroup.com:81/index.html?id=啦啦啦", 100, 100, "d://a.png"); + File file = new File("d://apng"); + } +} + diff --git a/staffing-common/src/main/java/com/staffing/common/utils/SecurityUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/SecurityUtils.java new file mode 100644 index 0000000..a631067 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/SecurityUtils.java @@ -0,0 +1,178 @@ +package com.staffing.common.utils; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.util.PatternMatchUtils; +import com.staffing.common.constant.Constants; +import com.staffing.common.constant.HttpStatus; +import com.staffing.common.core.domain.entity.SysRole; +import com.staffing.common.core.domain.model.LoginUser; +import com.staffing.common.exception.ServiceException; + +/** + * 安全服务工具类 + * + * @author staffing + */ +public class SecurityUtils +{ + + /** + * 用户ID + **/ + public static Long getUserId() + { + try + { + return getLoginUser().getUserId(); + } + catch (Exception e) + { + throw new ServiceException("获取用户ID异常", HttpStatus.UNAUTHORIZED); + } + } + + /** + * 获取部门ID + **/ + public static Long getDeptId() + { + try + { + return getLoginUser().getDeptId(); + } + catch (Exception e) + { + throw new ServiceException("获取部门ID异常", HttpStatus.UNAUTHORIZED); + } + } + + /** + * 获取用户账户 + **/ + public static String getUsername() + { + try + { + return getLoginUser().getUsername(); + } + catch (Exception e) + { + throw new ServiceException("获取用户账户异常", HttpStatus.UNAUTHORIZED); + } + } + + /** + * 获取用户 + **/ + public static LoginUser getLoginUser() + { + try + { + return (LoginUser) getAuthentication().getPrincipal(); + } + catch (Exception e) + { + throw new ServiceException("获取用户信息异常", 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; + } + + /** + * 验证用户是否具备某权限 + * + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + public static boolean hasPermi(String permission) + { + return hasPermi(getLoginUser().getPermissions(), permission); + } + + /** + * 判断是否包含权限 + * + * @param authorities 权限列表 + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + public static boolean hasPermi(Collection authorities, String permission) + { + return authorities.stream().filter(StringUtils::hasText) + .anyMatch(x -> Constants.ALL_PERMISSION.equals(x) || PatternMatchUtils.simpleMatch(x, permission)); + } + + /** + * 验证用户是否拥有某个角色 + * + * @param role 角色标识 + * @return 用户是否具备某角色 + */ + public static boolean hasRole(String role) + { + List roleList = getLoginUser().getUser().getRoles(); + Collection roles = roleList.stream().map(SysRole::getRoleKey).collect(Collectors.toSet()); + return hasRole(roles, role); + } + + /** + * 判断是否包含角色 + * + * @param roles 角色列表 + * @param role 角色 + * @return 用户是否具备某角色权限 + */ + public static boolean hasRole(Collection roles, String role) + { + return roles.stream().filter(StringUtils::hasText) + .anyMatch(x -> Constants.SUPER_ADMIN.equals(x) || PatternMatchUtils.simpleMatch(x, role)); + } + +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/ServletUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/ServletUtils.java new file mode 100644 index 0000000..ccfb4bf --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/ServletUtils.java @@ -0,0 +1,218 @@ +package com.staffing.common.utils; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import javax.servlet.ServletRequest; +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.staffing.common.constant.Constants; +import com.staffing.common.core.text.Convert; + +/** + * 客户端工具类 + * + * @author staffing + */ +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); + } + + /** + * 获取Boolean参数 + */ + public static Boolean getParameterToBool(String name) + { + return Convert.toBool(getRequest().getParameter(name)); + } + + /** + * 获取Boolean参数 + */ + public static Boolean getParameterToBool(String name, Boolean defaultValue) + { + return Convert.toBool(getRequest().getParameter(name), defaultValue); + } + + /** + * 获得所有请求参数 + * + * @param request 请求对象{@link ServletRequest} + * @return Map + */ + public static Map getParams(ServletRequest request) + { + final Map map = request.getParameterMap(); + return Collections.unmodifiableMap(map); + } + + /** + * 获得所有请求参数 + * + * @param request 请求对象{@link ServletRequest} + * @return Map + */ + public static Map getParamMap(ServletRequest request) + { + Map params = new HashMap<>(); + for (Map.Entry entry : getParams(request).entrySet()) + { + params.put(entry.getKey(), StringUtils.join(entry.getValue(), ",")); + } + return params; + } + + /** + * 获取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 待渲染的字符串 + */ + public static void 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(); + } + } + + /** + * 是否是Ajax异步请求 + * + * @param request + */ + public static boolean isAjaxRequest(HttpServletRequest request) + { + String accept = request.getHeader("accept"); + if (accept != null && accept.contains("application/json")) + { + return true; + } + + String xRequestedWith = request.getHeader("X-Requested-With"); + if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) + { + return true; + } + + String uri = request.getRequestURI(); + if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")) + { + return true; + } + + String ajax = request.getParameter("__ajax"); + return StringUtils.inStringIgnoreCase(ajax, "json", "xml"); + } + + /** + * 内容编码 + * + * @param str 内容 + * @return 编码后的内容 + */ + public static String urlEncode(String str) + { + try + { + return URLEncoder.encode(str, Constants.UTF8); + } + catch (UnsupportedEncodingException e) + { + return StringUtils.EMPTY; + } + } + + /** + * 内容解码 + * + * @param str 内容 + * @return 解码后的内容 + */ + public static String urlDecode(String str) + { + try + { + return URLDecoder.decode(str, Constants.UTF8); + } + catch (UnsupportedEncodingException e) + { + return StringUtils.EMPTY; + } + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/StringUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/StringUtils.java new file mode 100644 index 0000000..b67e09d --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/StringUtils.java @@ -0,0 +1,684 @@ +package com.staffing.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 org.springframework.util.AntPathMatcher; +import com.staffing.common.constant.Constants; +import com.staffing.common.core.text.StrFormatter; + +/** + * 字符串工具类 + * + * @author staffing + */ +public class StringUtils extends org.apache.commons.lang3.StringUtils +{ + /** 空字符串 */ + private static final String NULLSTR = ""; + + /** 下划线 */ + private static final char SEPARATOR = '_'; + + /** 星号 */ + private static final char ASTERISK = '*'; + + /** + * 获取参数不为空值 + * + * @param value defaultValue 要判断的value + * @return value 返回值 + */ + public static T nvl(T value, T defaultValue) + { + return value != null ? value : defaultValue; + } + + /** + * * 判断一个Collection是否为空, 包含List,Set,Queue + * + * @param coll 要判断的Collection + * @return true:为空 false:非空 + */ + public static boolean isEmpty(Collection coll) + { + return isNull(coll) || coll.isEmpty(); + } + + /** + * * 判断一个Collection是否非空,包含List,Set,Queue + * + * @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); + } + + /** + * * 判断一个Map是否为空 + * + * @param map 要判断的Map + * @return true:为空 false:非空 + */ + public static boolean isEmpty(Map map) + { + return isNull(map) || map.isEmpty(); + } + + /** + * * 判断一个Map是否为空 + * + * @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); + } + + /** + * * 判断一个对象是否是数组类型(Java基本型别的数组) + * + * @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 startInclude 开始位置(包含) + * @param endExclude 结束位置(不包含) + * @return 替换后的字符串 + */ + public static String hide(CharSequence str, int startInclude, int endExclude) + { + if (isEmpty(str)) + { + return NULLSTR; + } + final int strLength = str.length(); + if (startInclude > strLength) + { + return NULLSTR; + } + if (endExclude > strLength) + { + endExclude = strLength; + } + if (startInclude > endExclude) + { + // 如果起始位置大于结束位置,不替换 + return NULLSTR; + } + final char[] chars = new char[strLength]; + for (int i = 0; i < strLength; i++) + { + if (i >= startInclude && i < endExclude) + { + chars[i] = ASTERISK; + } + else + { + chars[i] = str.charAt(i); + } + } + return new String(chars); + } + + /** + * 截取字符串 + * + * @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); + } + + /** + * 判断是否为空,并且不是空白字符 + * + * @param str 要判断的value + * @return 结果 + */ + public static boolean hasText(String str) + { + return (str != null && !str.isEmpty() && containsText(str)); + } + + private static boolean containsText(CharSequence str) + { + int strLen = str.length(); + for (int i = 0; i < strLen; i++) + { + if (!Character.isWhitespace(str.charAt(i))) + { + return true; + } + } + return false; + } + + /** + * 格式化文本, {} 表示占位符
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b
+ * + * @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); + } + + /** + * 是否为http(s)://开头 + * + * @param link 链接 + * @return 结果 + */ + public static boolean ishttp(String link) + { + return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS); + } + + /** + * 字符串转set + * + * @param str 字符串 + * @param sep 分隔符 + * @return set集合 + */ + public static final Set str2Set(String str, String sep) + { + return new HashSet(str2List(str, sep, true, false)); + } + + /** + * 字符串转list + * + * @param str 字符串 + * @param sep 分隔符 + * @param filterBlank 过滤纯空白 + * @param trim 去掉首尾空白 + * @return list集合 + */ + public static final List str2List(String str, String sep, boolean filterBlank, boolean trim) + { + List list = new ArrayList(); + 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; + } + + /** + * 判断给定的collection列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value + * + * @param collection 给定的集合 + * @param array 给定的数组 + * @return boolean 结果 + */ + public static boolean containsAny(Collection collection, String... array) + { + if (isEmpty(collection) || isEmpty(array)) + { + return false; + } + else + { + for (String str : array) + { + if (collection.contains(str)) + { + return true; + } + } + return false; + } + } + + /** + * 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写 + * + * @param cs 指定字符串 + * @param searchCharSequences 需要检查的字符串数组 + * @return 是否包含任意一个字符串 + */ + public static boolean containsAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences) + { + if (isEmpty(cs) || isEmpty(searchCharSequences)) + { + return false; + } + for (CharSequence testStr : searchCharSequences) + { + if (containsIgnoreCase(cs, testStr)) + { + return true; + } + } + return false; + } + + /** + * 驼峰转下划线命名 + */ + 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; + } + + /** + * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_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(); + } + + /** + * 驼峰式命名法 + * 例如:user_name->userName + */ + public static String toCamelCase(String s) + { + if (s == null) + { + return null; + } + if (s.indexOf(SEPARATOR) == -1) + { + return s; + } + 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(); + } + + /** + * 查找指定字符串是否匹配指定字符串列表中的任意一个字符串 + * + * @param str 指定字符串 + * @param strs 需要检查的字符串数组 + * @return 是否匹配 + */ + public static boolean matches(String str, List strs) + { + if (isEmpty(str) || isEmpty(strs)) + { + return false; + } + for (String pattern : strs) + { + if (isMatch(pattern, str)) + { + return true; + } + } + return false; + } + + /** + * 判断url是否与规则配置: + * ? 表示单个字符; + * * 表示一层路径内的任意字符串,不可跨层级; + * ** 表示任意层路径; + * + * @param pattern 匹配规则 + * @param url 需要匹配的url + * @return + */ + public static boolean isMatch(String pattern, String url) + { + AntPathMatcher matcher = new AntPathMatcher(); + return matcher.match(pattern, url); + } + + @SuppressWarnings("unchecked") + public static T cast(Object obj) + { + return (T) obj; + } + + /** + * 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。 + * + * @param num 数字对象 + * @param size 字符串指定长度 + * @return 返回数字的字符串格式,该字符串为指定长度。 + */ + public static final String padl(final Number num, final int size) + { + return padl(num.toString(), size, '0'); + } + + /** + * 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。 + * + * @param s 原始字符串 + * @param size 字符串指定长度 + * @param c 用于补齐的字符 + * @return 返回指定长度的字符串,由原字符串左补齐或截取得到。 + */ + public static final String padl(final String s, final int size, final char c) + { + final StringBuilder sb = new StringBuilder(size); + if (s != null) + { + final int len = s.length(); + if (s.length() <= size) + { + for (int i = size - len; i > 0; i--) + { + sb.append(c); + } + sb.append(s); + } + else + { + return s.substring(len - size, len); + } + } + else + { + for (int i = size; i > 0; i--) + { + sb.append(c); + } + } + return sb.toString(); + } +} \ No newline at end of file diff --git a/staffing-common/src/main/java/com/staffing/common/utils/Threads.java b/staffing-common/src/main/java/com/staffing/common/utils/Threads.java new file mode 100644 index 0000000..1fa6c18 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/Threads.java @@ -0,0 +1,99 @@ +package com.staffing.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 staffing + */ +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; + } + } + + /** + * 停止线程池 + * 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务. + * 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数. + * 如果仍然超時,則強制退出. + * 另对在shutdown时线程本身被调用中断做了处理. + */ + 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/staffing-common/src/main/java/com/staffing/common/utils/WxUtil.java b/staffing-common/src/main/java/com/staffing/common/utils/WxUtil.java new file mode 100644 index 0000000..2fe3dad --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/WxUtil.java @@ -0,0 +1,63 @@ +package com.staffing.common.utils; + +import com.alibaba.fastjson2.JSONObject; +import com.staffing.common.core.domain.WxLogin; +import com.staffing.common.core.domain.WxPhone; +import com.staffing.common.core.domain.WxToken; +import com.staffing.common.utils.http.HttpUtils; + +import java.util.HashMap; +import java.util.Map; + +public class WxUtil { + public final static String appId = "wx7bc7df6eb945a84f"; + public final static String secret = "60dc8f7e8c850dfbe0170acefa48070a"; + + private static WxToken wxToken = null; + + public static synchronized WxToken getAccessToken(){ + if (wxToken == null || System.currentTimeMillis() > wxToken.getExpiresTime() - 60000){ + Map getParam = new HashMap<>(); + getParam.put("grant_type", "client_credential"); + getParam.put("appid", appId); + getParam.put("secret", secret); + String resJson = HttpUtils.sendGet("https://api.weixin.qq.com/cgi-bin/token", HttpUtils.getParam(getParam)); + wxToken = JSONObject.parseObject(resJson, WxToken.class); + wxToken.setExpiresTime(wxToken.getExpires_in() * 1000 + System.currentTimeMillis()); + } + return wxToken; + } + + /** + * 获取手机号码 + * @param code, 前端api获取后 传的 + * @param openId 微信用户唯一表示 + * @return + */ + public static WxPhone getPhoneNumber(String code, String openId){ + Map getParam = new HashMap<>(); + getParam.put("code", code); + getParam.put("openid", openId); + String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + getAccessToken().getAccess_token(); + String resJson = HttpUtils.sendPost(url, JSONObject.toJSONString(getParam)); + WxPhone wxPhone = JSONObject.parseObject(resJson, WxPhone.class); + + return wxPhone; + } + /** + * wx 登录 获取openId + * @return + */ + public static WxLogin login(String code){ + Map getParam = new HashMap<>(); + getParam.put("grant_type", "authorization_code"); + getParam.put("appid", appId); + getParam.put("secret", secret); + getParam.put("js_code", code); + String url = "https://api.weixin.qq.com/sns/jscode2session"; + String resJson = HttpUtils.sendGet(url, HttpUtils.getParam(getParam)); + WxLogin WxLogin = JSONObject.parseObject(resJson, WxLogin.class); + return WxLogin; + } + +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/bean/BeanUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/bean/BeanUtils.java new file mode 100644 index 0000000..9ac4430 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/bean/BeanUtils.java @@ -0,0 +1,110 @@ +package com.staffing.common.utils.bean; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Bean 工具类 + * + * @author staffing + */ +public class BeanUtils extends org.springframework.beans.BeanUtils +{ + /** Bean方法名中属性名开始的下标 */ + private static final int BEAN_METHOD_PROP_INDEX = 3; + + /** * 匹配getter方法的正则表达式 */ + private static final Pattern GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)"); + + /** * 匹配setter方法的正则表达式 */ + private static final Pattern SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)"); + + /** + * Bean属性复制工具方法。 + * + * @param dest 目标对象 + * @param src 源对象 + */ + public static void copyBeanProp(Object dest, Object src) + { + try + { + copyProperties(src, dest); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * 获取对象的setter方法。 + * + * @param obj 对象 + * @return 对象的setter方法列表 + */ + public static List getSetterMethods(Object obj) + { + // setter方法列表 + List setterMethods = new ArrayList(); + + // 获取所有方法 + Method[] methods = obj.getClass().getMethods(); + + // 查找setter方法 + + for (Method method : methods) + { + Matcher m = SET_PATTERN.matcher(method.getName()); + if (m.matches() && (method.getParameterTypes().length == 1)) + { + setterMethods.add(method); + } + } + // 返回setter方法列表 + return setterMethods; + } + + /** + * 获取对象的getter方法。 + * + * @param obj 对象 + * @return 对象的getter方法列表 + */ + + public static List getGetterMethods(Object obj) + { + // getter方法列表 + List getterMethods = new ArrayList(); + // 获取所有方法 + Method[] methods = obj.getClass().getMethods(); + // 查找getter方法 + for (Method method : methods) + { + Matcher m = GET_PATTERN.matcher(method.getName()); + if (m.matches() && (method.getParameterTypes().length == 0)) + { + getterMethods.add(method); + } + } + // 返回getter方法列表 + return getterMethods; + } + + /** + * 检查Bean方法名中的属性名是否相等。
+ * 如getName()和setName()属性名一样,getName()和setAge()属性名不一样。 + * + * @param m1 方法名1 + * @param m2 方法名2 + * @return 属性名一样返回true,否则返回false + */ + + public static boolean isMethodPropEquals(String m1, String m2) + { + return m1.substring(BEAN_METHOD_PROP_INDEX).equals(m2.substring(BEAN_METHOD_PROP_INDEX)); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/bean/BeanValidators.java b/staffing-common/src/main/java/com/staffing/common/utils/bean/BeanValidators.java new file mode 100644 index 0000000..c5fb4d8 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/bean/BeanValidators.java @@ -0,0 +1,24 @@ +package com.staffing.common.utils.bean; + +import java.util.Set; +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.validation.Validator; + +/** + * bean对象属性验证 + * + * @author staffing + */ +public class BeanValidators +{ + public static void validateWithException(Validator validator, Object object, Class... groups) + throws ConstraintViolationException + { + Set> constraintViolations = validator.validate(object, groups); + if (!constraintViolations.isEmpty()) + { + throw new ConstraintViolationException(constraintViolations); + } + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/file/FileTypeUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/file/FileTypeUtils.java new file mode 100644 index 0000000..e874deb --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/file/FileTypeUtils.java @@ -0,0 +1,76 @@ +package com.staffing.common.utils.file; + +import java.io.File; +import org.apache.commons.lang3.StringUtils; + +/** + * 文件类型工具类 + * + * @author staffing + */ +public class FileTypeUtils +{ + /** + * 获取文件类型 + *

+ * 例如: staffing.txt, 返回: txt + * + * @param file 文件名 + * @return 后缀(不含".") + */ + public static String getFileType(File file) + { + if (null == file) + { + return StringUtils.EMPTY; + } + return getFileType(file.getName()); + } + + /** + * 获取文件类型 + *

+ * 例如: staffing.txt, 返回: txt + * + * @param fileName 文件名 + * @return 后缀(不含".") + */ + public static String getFileType(String fileName) + { + int separatorIndex = fileName.lastIndexOf("."); + if (separatorIndex < 0) + { + return ""; + } + return fileName.substring(separatorIndex + 1).toLowerCase(); + } + + /** + * 获取文件类型 + * + * @param photoByte 文件字节码 + * @return 后缀(不含".") + */ + public static String getFileExtendName(byte[] photoByte) + { + String strFileExtendName = "JPG"; + if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56) + && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97)) + { + strFileExtendName = "GIF"; + } + else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70)) + { + strFileExtendName = "JPG"; + } + else if ((photoByte[0] == 66) && (photoByte[1] == 77)) + { + strFileExtendName = "BMP"; + } + else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71)) + { + strFileExtendName = "PNG"; + } + return strFileExtendName; + } +} \ No newline at end of file diff --git a/staffing-common/src/main/java/com/staffing/common/utils/file/FileUploadUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/file/FileUploadUtils.java new file mode 100644 index 0000000..ae1f471 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/file/FileUploadUtils.java @@ -0,0 +1,232 @@ +package com.staffing.common.utils.file; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.Objects; +import org.apache.commons.io.FilenameUtils; +import org.springframework.web.multipart.MultipartFile; +import com.staffing.common.config.StaffingConfig; +import com.staffing.common.constant.Constants; +import com.staffing.common.exception.file.FileNameLengthLimitExceededException; +import com.staffing.common.exception.file.FileSizeLimitExceededException; +import com.staffing.common.exception.file.InvalidExtensionException; +import com.staffing.common.utils.DateUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.uuid.Seq; + +/** + * 文件上传工具类 + * + * @author staffing + */ +public class FileUploadUtils +{ + /** + * 默认大小 50M + */ + public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024L; + + /** + * 默认的文件名最大长度 100 + */ + public static final int DEFAULT_FILE_NAME_LENGTH = 100; + + /** + * 默认上传的地址 + */ + private static String defaultBaseDir = StaffingConfig.getProfile(); + + 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 allowedExtension 上传文件类型 + * @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 = Objects.requireNonNull(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); + + String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath(); + file.transferTo(Paths.get(absPath)); + return getPathFileName(baseDir, fileName); + } + + /** + * 编码文件名 + */ + public static final String extractFilename(MultipartFile file) + { + return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(), + FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file)); + } + + public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException + { + File desc = new File(uploadDir + File.separator + fileName); + + if (!desc.exists()) + { + if (!desc.getParentFile().exists()) + { + desc.getParentFile().mkdirs(); + } + } + return desc; + } + + public static final String getPathFileName(String uploadDir, String fileName) throws IOException + { + int dirLastIndex = StaffingConfig.getProfile().length() + 1; + String currentDir = StringUtils.substring(uploadDir, dirLastIndex); + return Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + 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 (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 if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION) + { + throw new InvalidExtensionException.InvalidVideoExtensionException(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(Objects.requireNonNull(file.getContentType())); + } + return extension; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/file/FileUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/file/FileUtils.java new file mode 100644 index 0000000..969994d --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/file/FileUtils.java @@ -0,0 +1,291 @@ +package com.staffing.common.utils.file; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.ArrayUtils; +import com.staffing.common.config.StaffingConfig; +import com.staffing.common.utils.DateUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.uuid.IdUtils; +import org.apache.commons.io.FilenameUtils; + +/** + * 文件处理工具类 + * + * @author staffing + */ +public class FileUtils +{ + public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+"; + + /** + * 输出指定文件的byte数组 + * + * @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 + { + IOUtils.close(os); + IOUtils.close(fis); + } + } + + /** + * 写数据到文件中 + * + * @param data 数据 + * @return 目标文件 + * @throws IOException IO异常 + */ + public static String writeImportBytes(byte[] data) throws IOException + { + return writeBytes(data, StaffingConfig.getImportPath()); + } + + /** + * 写数据到文件中 + * + * @param data 数据 + * @param uploadDir 目标文件 + * @return 目标文件 + * @throws IOException IO异常 + */ + public static String writeBytes(byte[] data, String uploadDir) throws IOException + { + FileOutputStream fos = null; + String pathName = ""; + try + { + String extension = getFileExtendName(data); + pathName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension; + File file = FileUploadUtils.getAbsoluteFile(uploadDir, pathName); + fos = new FileOutputStream(file); + fos.write(data); + } + finally + { + IOUtils.close(fos); + } + return FileUploadUtils.getPathFileName(uploadDir, pathName); + } + + /** + * 删除文件 + * + * @param filePath 文件 + * @return + */ + public static boolean deleteFile(String filePath) + { + boolean flag = false; + File file = new File(filePath); + // 路径为文件且不为空则进行删除 + if (file.isFile() && file.exists()) + { + flag = file.delete(); + } + return flag; + } + + /** + * 文件名称验证 + * + * @param filename 文件名称 + * @return true 正常 false 非法 + */ + public static boolean isValidFilename(String filename) + { + return filename.matches(FILENAME_PATTERN); + } + + /** + * 检查文件是否可下载 + * + * @param resource 需要下载的文件 + * @return true 正常 false 非法 + */ + public static boolean checkAllowDownload(String resource) + { + // 禁止目录上跳级别 + if (StringUtils.contains(resource, "..")) + { + return false; + } + + // 检查允许下载的文件规则 + if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource))) + { + return true; + } + + // 不在允许下载的文件规则 + return false; + } + + /** + * 下载文件名重新编码 + * + * @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; + } + + /** + * 下载文件名重新编码 + * + * @param response 响应对象 + * @param realFileName 真实文件名 + */ + public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException + { + String percentEncodedFileName = percentEncode(realFileName); + + StringBuilder contentDispositionValue = new StringBuilder(); + contentDispositionValue.append("attachment; filename=") + .append(percentEncodedFileName) + .append(";") + .append("filename*=") + .append("utf-8''") + .append(percentEncodedFileName); + + response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename"); + response.setHeader("Content-disposition", contentDispositionValue.toString()); + response.setHeader("download-filename", percentEncodedFileName); + } + + /** + * 百分号编码工具方法 + * + * @param s 需要百分号编码的字符串 + * @return 百分号编码后的字符串 + */ + public static String percentEncode(String s) throws UnsupportedEncodingException + { + String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString()); + return encode.replaceAll("\\+", "%20"); + } + + /** + * 获取图像后缀 + * + * @param photoByte 图像数据 + * @return 后缀名 + */ + public static String getFileExtendName(byte[] photoByte) + { + String strFileExtendName = "jpg"; + if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56) + && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97)) + { + strFileExtendName = "gif"; + } + else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70)) + { + strFileExtendName = "jpg"; + } + else if ((photoByte[0] == 66) && (photoByte[1] == 77)) + { + strFileExtendName = "bmp"; + } + else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71)) + { + strFileExtendName = "png"; + } + return strFileExtendName; + } + + /** + * 获取文件名称 /profile/upload/2022/04/16/staffing.png -- staffing.png + * + * @param fileName 路径名称 + * @return 没有文件路径的名称 + */ + public static String getName(String fileName) + { + if (fileName == null) + { + return null; + } + int lastUnixPos = fileName.lastIndexOf('/'); + int lastWindowsPos = fileName.lastIndexOf('\\'); + int index = Math.max(lastUnixPos, lastWindowsPos); + return fileName.substring(index + 1); + } + + /** + * 获取不带后缀文件名称 /profile/upload/2022/04/16/staffing.png -- staffing + * + * @param fileName 路径名称 + * @return 没有文件路径和后缀的名称 + */ + public static String getNameNotSuffix(String fileName) + { + if (fileName == null) + { + return null; + } + String baseName = FilenameUtils.getBaseName(fileName); + return baseName; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/file/ImageUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/file/ImageUtils.java new file mode 100644 index 0000000..9a50379 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/file/ImageUtils.java @@ -0,0 +1,98 @@ +package com.staffing.common.utils.file; + +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.Arrays; +import org.apache.poi.util.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.staffing.common.config.StaffingConfig; +import com.staffing.common.constant.Constants; +import com.staffing.common.utils.StringUtils; + +/** + * 图片处理工具类 + * + * @author staffing + */ +public class ImageUtils +{ + private static final Logger log = LoggerFactory.getLogger(ImageUtils.class); + + public static byte[] getImage(String imagePath) + { + InputStream is = getFile(imagePath); + try + { + return IOUtils.toByteArray(is); + } + catch (Exception e) + { + log.error("图片加载异常 {}", e); + return null; + } + finally + { + IOUtils.closeQuietly(is); + } + } + + public static InputStream getFile(String imagePath) + { + try + { + byte[] result = readFile(imagePath); + result = Arrays.copyOf(result, result.length); + return new ByteArrayInputStream(result); + } + catch (Exception e) + { + log.error("获取图片异常 {}", e); + } + return null; + } + + /** + * 读取文件为字节数据 + * + * @param url 地址 + * @return 字节数据 + */ + public static byte[] readFile(String url) + { + InputStream in = null; + try + { + if (url.startsWith("http")) + { + // 网络地址 + URL urlObj = new URL(url); + URLConnection urlConnection = urlObj.openConnection(); + urlConnection.setConnectTimeout(30 * 1000); + urlConnection.setReadTimeout(60 * 1000); + urlConnection.setDoInput(true); + in = urlConnection.getInputStream(); + } + else + { + // 本机地址 + String localPath = StaffingConfig.getProfile(); + String downloadPath = localPath + StringUtils.substringAfter(url, Constants.RESOURCE_PREFIX); + in = new FileInputStream(downloadPath); + } + return IOUtils.toByteArray(in); + } + catch (Exception e) + { + log.error("获取文件路径异常 {}", e); + return null; + } + finally + { + IOUtils.closeQuietly(in); + } + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/file/MimeTypeUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/file/MimeTypeUtils.java new file mode 100644 index 0000000..4320da3 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/file/MimeTypeUtils.java @@ -0,0 +1,59 @@ +package com.staffing.common.utils.file; + +/** + * 媒体类型工具类 + * + * @author staffing + */ +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[] VIDEO_EXTENSION = { "mp4", "avi", "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", + // 视频格式 + "mp4", "avi", "rmvb", + // 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/staffing-common/src/main/java/com/staffing/common/utils/html/EscapeUtil.java b/staffing-common/src/main/java/com/staffing/common/utils/html/EscapeUtil.java new file mode 100644 index 0000000..74c5a9f --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/html/EscapeUtil.java @@ -0,0 +1,167 @@ +package com.staffing.common.utils.html; + +import com.staffing.common.utils.StringUtils; + +/** + * 转义和反转义工具类 + * + * @author staffing + */ +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); + } + + /** + * 清除所有HTML标签,但是不删除标签内的内容 + * + * @param content 文本 + * @return 清除标签后的文本 + */ + public static String clean(String content) + { + return new HTMLFilter().filter(content); + } + + /** + * Escape编码 + * + * @param text 被编码的文本 + * @return 编码后的字符 + */ + private static String encode(String text) + { + if (StringUtils.isEmpty(text)) + { + return StringUtils.EMPTY; + } + + final StringBuilder tmp = new StringBuilder(text.length() * 6); + char c; + for (int i = 0; i < text.length(); i++) + { + c = text.charAt(i); + if (c < 256) + { + tmp.append("%"); + if (c < 16) + { + tmp.append("0"); + } + tmp.append(Integer.toString(c, 16)); + } + else + { + tmp.append("%u"); + if (c <= 0xfff) + { + // issue#I49JU8@Gitee + tmp.append("0"); + } + tmp.append(Integer.toString(c, 16)); + } + } + return tmp.toString(); + } + + /** + * Escape解码 + * + * @param content 被转义的内容 + * @return 解码后的字符串 + */ + 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 = ""; + String escape = EscapeUtil.escape(html); + // String html = "ipt>alert(\"XSS\")ipt>"; + // String html = "<123"; + // String html = "123>"; + System.out.println("clean: " + EscapeUtil.clean(html)); + System.out.println("escape: " + escape); + System.out.println("unescape: " + EscapeUtil.unescape(escape)); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/html/HTMLFilter.java b/staffing-common/src/main/java/com/staffing/common/utils/html/HTMLFilter.java new file mode 100644 index 0000000..13a25f2 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/html/HTMLFilter.java @@ -0,0 +1,570 @@ +package com.staffing.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 staffing + */ +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 P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap<>(); + private static final ConcurrentMap P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<>(); + + /** + * set of allowed html elements, along with allowed attributes for each element + **/ + private final Map> vAllowed; + /** + * counts of open tags for each (allowable) html element + **/ + private final Map vTagCounts = new HashMap<>(); + + /** + * html elements which must always be self-closing (e.g. "") + **/ + private final String[] vSelfClosingTags; + /** + * html elements which must always have separate opening and closing tags (e.g. "") + **/ + 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. "" or "") + **/ + 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. "" + * becomes " text "). If set to false, unbalanced angle brackets will be html escaped. + */ + private final boolean alwaysMakeTags; + + /** + * Default constructor. + */ + public HTMLFilter() + { + vAllowed = new HashMap<>(); + + final ArrayList a_atts = new ArrayList<>(); + a_atts.add("href"); + a_atts.add("target"); + vAllowed.put("a", a_atts); + + final ArrayList 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 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 = false; + } + + /** + * Map-parameter configurable constructor. + * + * @param conf map containing configuration. keys match field names. + */ + @SuppressWarnings("unchecked") + public HTMLFilter(final Map 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>) 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("")); + } + 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(""); + } + } + 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[^>]*)?>")); + } + 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 (!inArray(name, vSelfClosingTags)) + { + if (vTagCounts.containsKey(name)) + { + vTagCounts.put(name, vTagCounts.get(name) - 1); + return ""; + } + } + } + } + + // 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 paramNames = new ArrayList<>(); + final List 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); // (<|$) + // 不替换双引号为",防止json格式无效 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/staffing-common/src/main/java/com/staffing/common/utils/http/HttpHelper.java b/staffing-common/src/main/java/com/staffing/common/utils/http/HttpHelper.java new file mode 100644 index 0000000..e1d0c04 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/http/HttpHelper.java @@ -0,0 +1,55 @@ +package com.staffing.common.utils.http; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import javax.servlet.ServletRequest; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 通用http工具封装 + * + * @author staffing + */ +public class HttpHelper +{ + private static final Logger LOGGER = LoggerFactory.getLogger(HttpHelper.class); + + public static String getBodyString(ServletRequest request) + { + StringBuilder sb = new StringBuilder(); + BufferedReader reader = null; + try (InputStream inputStream = request.getInputStream()) + { + reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); + String line = ""; + while ((line = reader.readLine()) != null) + { + sb.append(line); + } + } + catch (IOException e) + { + LOGGER.warn("getBodyString出现问题!"); + } + finally + { + if (reader != null) + { + try + { + reader.close(); + } + catch (IOException e) + { + LOGGER.error(ExceptionUtils.getMessage(e)); + } + } + } + return sb.toString(); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/http/HttpUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/http/HttpUtils.java new file mode 100644 index 0000000..983e58d --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/http/HttpUtils.java @@ -0,0 +1,286 @@ +package com.staffing.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.nio.charset.StandardCharsets; +import java.security.cert.X509Certificate; +import java.util.Map; +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; +import com.staffing.common.constant.Constants; +import com.staffing.common.utils.StringUtils; + +/** + * 通用http发送方法 + * + * @author staffing + */ +public class HttpUtils +{ + private static final Logger log = LoggerFactory.getLogger(HttpUtils.class); + + public static String getParam(Map param){ + StringBuilder stringBuilder = new StringBuilder(); + for (Map.Entry stringStringEntry : param.entrySet()) { + stringBuilder.append(stringStringEntry.getKey()).append("=").append(stringStringEntry.getValue()).append("&"); + } + if (stringBuilder.length() > 0){ + stringBuilder = stringBuilder.deleteCharAt(stringBuilder.length() - 1); + } + + return stringBuilder.toString(); + } + /** + * 向指定 URL 发送GET方法的请求 + * + * @param url 发送请求的 URL + * @return 所代表远程资源的响应结果 + */ + public static String sendGet(String url) + { + return sendGet(url, StringUtils.EMPTY); + } + + /** + * 向指定 URL 发送GET方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 + * @return 所代表远程资源的响应结果 + */ + public static String sendGet(String url, String param) + { + return sendGet(url, param, Constants.UTF8); + } + + /** + * 向指定 URL 发送GET方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 + * @param contentType 编码类型 + * @return 所代表远程资源的响应结果 + */ + public static String sendGet(String url, String param, String contentType) + { + StringBuilder result = new StringBuilder(); + BufferedReader in = null; + try + { + String urlNameString = StringUtils.isNotBlank(param) ? url + "?" + param : url; + 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/5.0 (Windows NT 10.0; Win64; x64)"); + connection.connect(); + in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType)); + 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 发送POST方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 + * @return 所代表远程资源的响应结果 + */ + public static String sendPost(String url, String param) + { + PrintWriter out = null; + BufferedReader in = null; + StringBuilder result = new StringBuilder(); + try + { + log.info("sendPost - {}", url); + URL realUrl = new URL(url); + URLConnection conn = realUrl.openConnection(); + conn.setRequestProperty("accept", "*/*"); + conn.setRequestProperty("connection", "Keep-Alive"); + conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"); + 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(), StandardCharsets.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/5.0 (Windows NT 10.0; Win64; x64)"); + 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 && !"".equals(ret.trim())) + { + result.append(new String(ret.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.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/staffing-common/src/main/java/com/staffing/common/utils/ip/AddressUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/ip/AddressUtils.java new file mode 100644 index 0000000..c898c5a --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/ip/AddressUtils.java @@ -0,0 +1,56 @@ +package com.staffing.common.utils.ip; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.staffing.common.config.StaffingConfig; +import com.staffing.common.constant.Constants; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.http.HttpUtils; + +/** + * 获取地址类 + * + * @author staffing + */ +public class AddressUtils +{ + private static final Logger log = LoggerFactory.getLogger(AddressUtils.class); + + // IP地址查询 + public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp"; + + // 未知地址 + public static final String UNKNOWN = "XX XX"; + + public static String getRealAddressByIP(String ip) + { + // 内网不查询 + if (IpUtils.internalIp(ip)) + { + return "内网IP"; + } + if (StaffingConfig.isAddressEnabled()) + { + try + { + String rspStr = HttpUtils.sendGet(IP_URL, "ip=" + ip + "&json=true", Constants.GBK); + if (StringUtils.isEmpty(rspStr)) + { + log.error("获取地理位置异常 {}", ip); + return UNKNOWN; + } + JSONObject obj = JSON.parseObject(rspStr); + String region = obj.getString("pro"); + String city = obj.getString("city"); + return String.format("%s %s", region, city); + } + catch (Exception e) + { + log.error("获取地理位置异常 {}", ip); + } + } + return UNKNOWN; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/ip/IpUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/ip/IpUtils.java new file mode 100644 index 0000000..6c1bfa8 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/ip/IpUtils.java @@ -0,0 +1,382 @@ +package com.staffing.common.utils.ip; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import javax.servlet.http.HttpServletRequest; +import com.staffing.common.utils.ServletUtils; +import com.staffing.common.utils.StringUtils; + +/** + * 获取IP方法 + * + * @author staffing + */ +public class IpUtils +{ + public final static String REGX_0_255 = "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)"; + // 匹配 ip + public final static String REGX_IP = "((" + REGX_0_255 + "\\.){3}" + REGX_0_255 + ")"; + public final static String REGX_IP_WILDCARD = "(((\\*\\.){3}\\*)|(" + REGX_0_255 + "(\\.\\*){3})|(" + REGX_0_255 + "\\." + REGX_0_255 + ")(\\.\\*){2}" + "|((" + REGX_0_255 + "\\.){3}\\*))"; + // 匹配网段 + public final static String REGX_IP_SEG = "(" + REGX_IP + "\\-" + REGX_IP + ")"; + + /** + * 获取客户端IP + * + * @return IP地址 + */ + public static String getIpAddr() + { + return getIpAddr(ServletUtils.getRequest()); + } + + /** + * 获取客户端IP + * + * @param request 请求对象 + * @return IP地址 + */ + 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" : getMultistageReverseProxyIp(ip); + } + + /** + * 检查是否为内部IP地址 + * + * @param ip IP地址 + * @return 结果 + */ + public static boolean internalIp(String ip) + { + byte[] addr = textToNumericFormatV4(ip); + return internalIp(addr) || "127.0.0.1".equals(ip); + } + + /** + * 检查是否为内部IP地址 + * + * @param addr byte地址 + * @return 结果 + */ + 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; + } + } + + /** + * 将IPv4地址转换成字节 + * + * @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; + } + + /** + * 获取IP地址 + * + * @return 本地IP地址 + */ + public static String getHostIp() + { + try + { + return InetAddress.getLocalHost().getHostAddress(); + } + catch (UnknownHostException e) + { + } + return "127.0.0.1"; + } + + /** + * 获取主机名 + * + * @return 本地主机名 + */ + public static String getHostName() + { + try + { + return InetAddress.getLocalHost().getHostName(); + } + catch (UnknownHostException e) + { + } + return "未知"; + } + + /** + * 从多级反向代理中获得第一个非unknown IP地址 + * + * @param ip 获得的IP地址 + * @return 第一个非unknown IP地址 + */ + public static String getMultistageReverseProxyIp(String ip) + { + // 多级反向代理检测 + if (ip != null && ip.indexOf(",") > 0) + { + final String[] ips = ip.trim().split(","); + for (String subIp : ips) + { + if (false == isUnknown(subIp)) + { + ip = subIp; + break; + } + } + } + return StringUtils.substring(ip, 0, 255); + } + + /** + * 检测给定字符串是否为未知,多用于检测HTTP请求相关 + * + * @param checkString 被检测的字符串 + * @return 是否未知 + */ + public static boolean isUnknown(String checkString) + { + return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString); + } + + /** + * 是否为IP + */ + public static boolean isIP(String ip) + { + return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP); + } + + /** + * 是否为IP,或 *为间隔的通配符地址 + */ + public static boolean isIpWildCard(String ip) + { + return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP_WILDCARD); + } + + /** + * 检测参数是否在ip通配符里 + */ + public static boolean ipIsInWildCardNoCheck(String ipWildCard, String ip) + { + String[] s1 = ipWildCard.split("\\."); + String[] s2 = ip.split("\\."); + boolean isMatchedSeg = true; + for (int i = 0; i < s1.length && !s1[i].equals("*"); i++) + { + if (!s1[i].equals(s2[i])) + { + isMatchedSeg = false; + break; + } + } + return isMatchedSeg; + } + + /** + * 是否为特定格式如:“10.10.10.1-10.10.10.99”的ip段字符串 + */ + public static boolean isIPSegment(String ipSeg) + { + return StringUtils.isNotBlank(ipSeg) && ipSeg.matches(REGX_IP_SEG); + } + + /** + * 判断ip是否在指定网段中 + */ + public static boolean ipIsInNetNoCheck(String iparea, String ip) + { + int idx = iparea.indexOf('-'); + String[] sips = iparea.substring(0, idx).split("\\."); + String[] sipe = iparea.substring(idx + 1).split("\\."); + String[] sipt = ip.split("\\."); + long ips = 0L, ipe = 0L, ipt = 0L; + for (int i = 0; i < 4; ++i) + { + ips = ips << 8 | Integer.parseInt(sips[i]); + ipe = ipe << 8 | Integer.parseInt(sipe[i]); + ipt = ipt << 8 | Integer.parseInt(sipt[i]); + } + if (ips > ipe) + { + long t = ips; + ips = ipe; + ipe = t; + } + return ips <= ipt && ipt <= ipe; + } + + /** + * 校验ip是否符合过滤串规则 + * + * @param filter 过滤IP列表,支持后缀'*'通配,支持网段如:`10.10.10.1-10.10.10.99` + * @param ip 校验IP地址 + * @return boolean 结果 + */ + public static boolean isMatchedIp(String filter, String ip) + { + if (StringUtils.isEmpty(filter) || StringUtils.isEmpty(ip)) + { + return false; + } + String[] ips = filter.split(";"); + for (String iStr : ips) + { + if (isIP(iStr) && iStr.equals(ip)) + { + return true; + } + else if (isIpWildCard(iStr) && ipIsInWildCardNoCheck(iStr, ip)) + { + return true; + } + else if (isIPSegment(iStr) && ipIsInNetNoCheck(iStr, ip)) + { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/staffing-common/src/main/java/com/staffing/common/utils/poi/ExcelHandlerAdapter.java b/staffing-common/src/main/java/com/staffing/common/utils/poi/ExcelHandlerAdapter.java new file mode 100644 index 0000000..b2537a2 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/poi/ExcelHandlerAdapter.java @@ -0,0 +1,24 @@ +package com.staffing.common.utils.poi; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Workbook; + +/** + * Excel数据格式处理适配器 + * + * @author staffing + */ +public interface ExcelHandlerAdapter +{ + /** + * 格式化 + * + * @param value 单元格数据值 + * @param args excel注解args参数组 + * @param cell 单元格对象 + * @param wb 工作簿对象 + * + * @return 处理后的值 + */ + Object format(Object value, String[] args, Cell cell, Workbook wb); +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/poi/ExcelUtil.java b/staffing-common/src/main/java/com/staffing/common/utils/poi/ExcelUtil.java new file mode 100644 index 0000000..8f7b362 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/poi/ExcelUtil.java @@ -0,0 +1,1812 @@ +package com.staffing.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.lang.reflect.ParameterizedType; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.RegExUtils; +import org.apache.commons.lang3.reflect.FieldUtils; +import org.apache.poi.hssf.usermodel.HSSFClientAnchor; +import org.apache.poi.hssf.usermodel.HSSFPicture; +import org.apache.poi.hssf.usermodel.HSSFPictureData; +import org.apache.poi.hssf.usermodel.HSSFShape; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ooxml.POIXMLDocumentPart; +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.ClientAnchor; +import org.apache.poi.ss.usermodel.DataFormat; +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.Drawing; +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.Name; +import org.apache.poi.ss.usermodel.PictureData; +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.CellRangeAddress; +import org.apache.poi.ss.util.CellRangeAddressList; +import org.apache.poi.util.IOUtils; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDataValidation; +import org.apache.poi.xssf.usermodel.XSSFDrawing; +import org.apache.poi.xssf.usermodel.XSSFPicture; +import org.apache.poi.xssf.usermodel.XSSFShape; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.staffing.common.annotation.Excel; +import com.staffing.common.annotation.Excel.ColumnType; +import com.staffing.common.annotation.Excel.Type; +import com.staffing.common.annotation.Excels; +import com.staffing.common.config.StaffingConfig; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.text.Convert; +import com.staffing.common.exception.UtilException; +import com.staffing.common.utils.DateUtils; +import com.staffing.common.utils.DictUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.file.FileTypeUtils; +import com.staffing.common.utils.file.FileUtils; +import com.staffing.common.utils.file.ImageUtils; +import com.staffing.common.utils.reflect.ReflectUtils; + +/** + * Excel相关处理 + * + * @author staffing + */ +public class ExcelUtil +{ + private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class); + + public static final String FORMULA_REGEX_STR = "=|-|\\+|@"; + + public static final String[] FORMULA_STR = { "=", "-", "+", "@" }; + + /** + * 用于dictType属性数据存储,避免重复查缓存 + */ + public Map sysDictMap = new HashMap(); + + /** + * Excel sheet最大行数,默认65536 + */ + public static final int sheetSize = 65536; + + /** + * 工作表名称 + */ + private String sheetName; + + /** + * 导出类型(EXPORT:导出数据;IMPORT:导入模板) + */ + private Type type; + + /** + * 工作薄对象 + */ + private Workbook wb; + + /** + * 工作表对象 + */ + private Sheet sheet; + + /** + * 样式列表 + */ + private Map styles; + + /** + * 导入导出数据列表 + */ + private List list; + + /** + * 注解列表 + */ + private List fields; + + /** + * 当前行号 + */ + private int rownum; + + /** + * 标题 + */ + private String title; + + /** + * 最大高度 + */ + private short maxHeight; + + /** + * 合并后最后行数 + */ + private int subMergedLastRowNum = 0; + + /** + * 合并后开始行数 + */ + private int subMergedFirstRowNum = 1; + + /** + * 对象的子列表方法 + */ + private Method subMethod; + + /** + * 对象的子列表属性 + */ + private List subFields; + + /** + * 统计列表 + */ + private Map statistics = new HashMap(); + + /** + * 数字格式 + */ + private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00"); + + /** + * 实体对象 + */ + public Class clazz; + + /** + * 需要排除列属性 + */ + public String[] excludeFields; + + public ExcelUtil(Class clazz) + { + this.clazz = clazz; + } + + /** + * 隐藏Excel中列属性 + * + * @param fields 列属性名 示例[单个"name"/多个"id","name"] + * @throws Exception + */ + public void hideColumn(String... fields) + { + this.excludeFields = fields; + } + + public void init(List list, String sheetName, String title, Type type) + { + if (list == null) + { + list = new ArrayList(); + } + this.list = list; + this.sheetName = sheetName; + this.type = type; + this.title = title; + createExcelField(); + createWorkbook(); + createTitle(); + createSubHead(); + } + + /** + * 创建excel第一行标题 + */ + public void createTitle() + { + if (StringUtils.isNotEmpty(title)) + { + subMergedFirstRowNum++; + subMergedLastRowNum++; + int titleLastCol = this.fields.size() - 1; + if (isSubList()) + { + titleLastCol = titleLastCol + subFields.size() - 1; + } + Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0); + titleRow.setHeightInPoints(30); + Cell titleCell = titleRow.createCell(0); + titleCell.setCellStyle(styles.get("title")); + titleCell.setCellValue(title); + sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(), titleLastCol)); + } + } + + /** + * 创建对象的子列表名称 + */ + public void createSubHead() + { + if (isSubList()) + { + subMergedFirstRowNum++; + subMergedLastRowNum++; + Row subRow = sheet.createRow(rownum); + int excelNum = 0; + for (Object[] objects : fields) + { + Excel attr = (Excel) objects[1]; + Cell headCell1 = subRow.createCell(excelNum); + headCell1.setCellValue(attr.name()); + headCell1.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()))); + excelNum++; + } + int headFirstRow = excelNum - 1; + int headLastRow = headFirstRow + subFields.size() - 1; + if (headLastRow > headFirstRow) + { + sheet.addMergedRegion(new CellRangeAddress(rownum, rownum, headFirstRow, headLastRow)); + } + rownum++; + } + } + + /** + * 对excel表单默认第一个索引名转换成list + * + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(InputStream is) + { + List list = null; + try + { + list = importExcel(is, 0); + } + catch (Exception e) + { + log.error("导入Excel异常{}", e.getMessage()); + throw new UtilException(e.getMessage()); + } + finally + { + IOUtils.closeQuietly(is); + } + return list; + } + + /** + * 对excel表单默认第一个索引名转换成list + * + * @param is 输入流 + * @param titleNum 标题占用行数 + * @return 转换后集合 + */ + public List importExcel(InputStream is, int titleNum) throws Exception + { + return importExcel(StringUtils.EMPTY, is, titleNum); + } + + /** + * 对excel表单指定表格索引名转换成list + * + * @param sheetName 表格索引名 + * @param titleNum 标题占用行数 + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(String sheetName, InputStream is, int titleNum) throws Exception + { + this.type = Type.IMPORT; + this.wb = WorkbookFactory.create(is); + List list = new ArrayList(); + // 如果指定sheet名,则取指定sheet中的内容 否则默认指向第1个sheet + Sheet sheet = StringUtils.isNotEmpty(sheetName) ? wb.getSheet(sheetName) : wb.getSheetAt(0); + if (sheet == null) + { + throw new IOException("文件sheet不存在"); + } + boolean isXSSFWorkbook = !(wb instanceof HSSFWorkbook); + Map pictures; + if (isXSSFWorkbook) + { + pictures = getSheetPictures07((XSSFSheet) sheet, (XSSFWorkbook) wb); + } + else + { + pictures = getSheetPictures03((HSSFSheet) sheet, (HSSFWorkbook) wb); + } + // 获取最后一个非空行的行下标,比如总行数为n,则返回的为n-1 + int rows = sheet.getLastRowNum(); + if (rows > 0) + { + // 定义一个map用于存放excel列的序号和field. + Map cellMap = new HashMap(); + // 获取表头 + Row heard = sheet.getRow(titleNum); + for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) + { + Cell cell = heard.getCell(i); + if (StringUtils.isNotNull(cell)) + { + String value = this.getCellValue(heard, i).toString(); + cellMap.put(value, i); + } + else + { + cellMap.put(null, i); + } + } + // 有数据时才处理 得到类的所有field. + List fields = this.getFields(); + Map fieldsMap = new HashMap(); + for (Object[] objects : fields) + { + Excel attr = (Excel) objects[1]; + Integer column = cellMap.get(attr.name()); + if (column != null) + { + fieldsMap.put(column, objects); + } + } + for (int i = titleNum + 1; i <= rows; i++) + { + // 从第2行开始取数据,默认第一行是表头. + Row row = sheet.getRow(i); + // 判断当前行是否是空行 + if (isRowEmpty(row)) + { + continue; + } + T entity = null; + for (Map.Entry entry : fieldsMap.entrySet()) + { + Object val = this.getCellValue(row, entry.getKey()); + + // 如果不存在实例则新建. + entity = (entity == null ? clazz.newInstance() : entity); + // 从map中得到对应列的field. + Field field = (Field) entry.getValue()[0]; + Excel attr = (Excel) entry.getValue()[1]; + // 取得类型,并根据对象类型设置值. + Class fieldType = field.getType(); + if (String.class == fieldType) + { + String s = Convert.toStr(val); + if (StringUtils.endsWith(s, ".0")) + { + val = StringUtils.substringBefore(s, ".0"); + } + else + { + String dateFormat = field.getAnnotation(Excel.class).dateFormat(); + if (StringUtils.isNotEmpty(dateFormat)) + { + val = parseDateToStr(dateFormat, val); + } + else + { + val = Convert.toStr(val); + } + } + } + else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) + { + val = Convert.toInt(val); + } + else if ((Long.TYPE == fieldType || Long.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) + { + 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); + } + } + else if (Boolean.TYPE == fieldType || Boolean.class == fieldType) + { + val = Convert.toBool(val, false); + } + if (StringUtils.isNotNull(fieldType)) + { + String propertyName = field.getName(); + if (StringUtils.isNotEmpty(attr.targetAttr())) + { + propertyName = field.getName() + "." + attr.targetAttr(); + } + if (StringUtils.isNotEmpty(attr.readConverterExp())) + { + val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator()); + } + else if (StringUtils.isNotEmpty(attr.dictType())) + { + if (!sysDictMap.containsKey(attr.dictType() + val)) + { + String dictValue = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator()); + sysDictMap.put(attr.dictType() + val, dictValue); + } + val = sysDictMap.get(attr.dictType() + val); + } + else if (!attr.handler().equals(ExcelHandlerAdapter.class)) + { + val = dataFormatHandlerAdapter(val, attr, null); + } + else if (ColumnType.IMAGE == attr.cellType() && StringUtils.isNotEmpty(pictures)) + { + PictureData image = pictures.get(row.getRowNum() + "_" + entry.getKey()); + if (image == null) + { + val = ""; + } + else + { + byte[] data = image.getData(); + val = FileUtils.writeImportBytes(data); + } + } + ReflectUtils.invokeSetter(entity, propertyName, val); + } + } + list.add(entity); + } + } + return list; + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + */ + public AjaxResult exportExcel(List list, String sheetName) + { + return exportExcel(list, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public AjaxResult exportExcel(List list, String sheetName, String title) + { + this.init(list, sheetName, title, Type.EXPORT); + return exportExcel(); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param response 返回数据 + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + */ + public void exportExcel(HttpServletResponse response, List list, String sheetName) + { + exportExcel(response, list, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param response 返回数据 + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public void exportExcel(HttpServletResponse response, List list, String sheetName, String title) + { + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + this.init(list, sheetName, title, Type.EXPORT); + exportExcel(response); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @return 结果 + */ + public AjaxResult importTemplateExcel(String sheetName) + { + return importTemplateExcel(sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public AjaxResult importTemplateExcel(String sheetName, String title) + { + this.init(null, sheetName, title, Type.IMPORT); + return exportExcel(); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @return 结果 + */ + public void importTemplateExcel(HttpServletResponse response, String sheetName) + { + importTemplateExcel(response, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public void importTemplateExcel(HttpServletResponse response, String sheetName, String title) + { + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + this.init(null, sheetName, title, Type.IMPORT); + exportExcel(response); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @return 结果 + */ + public void exportExcel(HttpServletResponse response) + { + try + { + writeSheet(); + wb.write(response.getOutputStream()); + } + catch (Exception e) + { + log.error("导出Excel异常{}", e.getMessage()); + } + finally + { + IOUtils.closeQuietly(wb); + } + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @return 结果 + */ + public AjaxResult exportExcel() + { + OutputStream out = null; + try + { + writeSheet(); + 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 UtilException("导出Excel失败,请联系网站管理员!"); + } + finally + { + IOUtils.closeQuietly(wb); + IOUtils.closeQuietly(out); + } + } + + /** + * 创建写入数据到Sheet + */ + public void writeSheet() + { + // 取出一共有多少个sheet. + int sheetNo = Math.max(1, (int) Math.ceil(list.size() * 1.0 / sheetSize)); + for (int index = 0; index < sheetNo; index++) + { + createSheet(sheetNo, index); + + // 产生一行 + Row row = sheet.createRow(rownum); + int column = 0; + // 写入各个字段的列头名称 + for (Object[] os : fields) + { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + if (Collection.class.isAssignableFrom(field.getType())) + { + for (Field subField : subFields) + { + Excel subExcel = subField.getAnnotation(Excel.class); + this.createHeadCell(subExcel, row, column++); + } + } + else + { + this.createHeadCell(excel, row, column++); + } + } + if (Type.EXPORT.equals(type)) + { + fillExcelData(index, row); + addStatisticsRow(); + } + } + } + + /** + * 填充excel数据 + * + * @param index 序号 + * @param row 单元格行 + */ + @SuppressWarnings("unchecked") + public void fillExcelData(int index, Row row) + { + int startNo = index * sheetSize; + int endNo = Math.min(startNo + sheetSize, list.size()); + int rowNo = (1 + rownum) - startNo; + for (int i = startNo; i < endNo; i++) + { + rowNo = isSubList() ? (i > 1 ? rowNo + 1 : rowNo + i) : i + 1 + rownum - startNo; + row = sheet.createRow(rowNo); + // 得到导出对象. + T vo = (T) list.get(i); + Collection subList = null; + if (isSubList()) + { + if (isSubListValue(vo)) + { + subList = getListCellValue(vo); + subMergedLastRowNum = subMergedLastRowNum + subList.size(); + } + else + { + subMergedFirstRowNum++; + subMergedLastRowNum++; + } + } + int column = 0; + for (Object[] os : fields) + { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + if (Collection.class.isAssignableFrom(field.getType()) && StringUtils.isNotNull(subList)) + { + boolean subFirst = false; + for (Object obj : subList) + { + if (subFirst) + { + rowNo++; + row = sheet.createRow(rowNo); + } + List subFields = FieldUtils.getFieldsListWithAnnotation(obj.getClass(), Excel.class); + int subIndex = 0; + for (Field subField : subFields) + { + if (subField.isAnnotationPresent(Excel.class)) + { + subField.setAccessible(true); + Excel attr = subField.getAnnotation(Excel.class); + this.addCell(attr, row, (T) obj, subField, column + subIndex); + } + subIndex++; + } + subFirst = true; + } + this.subMergedFirstRowNum = this.subMergedFirstRowNum + subList.size(); + } + else + { + this.addCell(excel, row, vo, field, column++); + } + } + } + } + + /** + * 创建表格样式 + * + * @param wb 工作薄对象 + * @return 样式列表 + */ + private Map createStyles(Workbook wb) + { + // 写入各条记录,每条记录对应excel表中的一行 + Map styles = new HashMap(); + CellStyle style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font titleFont = wb.createFont(); + titleFont.setFontName("Arial"); + titleFont.setFontHeightInPoints((short) 16); + titleFont.setBold(true); + style.setFont(titleFont); + DataFormat dataFormat = wb.createDataFormat(); + style.setDataFormat(dataFormat.getFormat("@")); + styles.put("title", style); + + 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.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font totalFont = wb.createFont(); + totalFont.setFontName("Arial"); + totalFont.setFontHeightInPoints((short) 10); + style.setFont(totalFont); + styles.put("total", style); + + styles.putAll(annotationHeaderStyles(wb, styles)); + + styles.putAll(annotationDataStyles(wb)); + + return styles; + } + + /** + * 根据Excel注解创建表格头样式 + * + * @param wb 工作薄对象 + * @return 自定义样式列表 + */ + private Map annotationHeaderStyles(Workbook wb, Map styles) + { + Map headerStyles = new HashMap(); + for (Object[] os : fields) + { + Excel excel = (Excel) os[1]; + String key = StringUtils.format("header_{}_{}", excel.headerColor(), excel.headerBackgroundColor()); + if (!headerStyles.containsKey(key)) + { + CellStyle style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setFillForegroundColor(excel.headerBackgroundColor().index); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + Font headerFont = wb.createFont(); + headerFont.setFontName("Arial"); + headerFont.setFontHeightInPoints((short) 10); + headerFont.setBold(true); + headerFont.setColor(excel.headerColor().index); + style.setFont(headerFont); + // 设置表格头单元格文本形式 + DataFormat dataFormat = wb.createDataFormat(); + style.setDataFormat(dataFormat.getFormat("@")); + headerStyles.put(key, style); + } + } + return headerStyles; + } + + /** + * 根据Excel注解创建表格列样式 + * + * @param wb 工作薄对象 + * @return 自定义样式列表 + */ + private Map annotationDataStyles(Workbook wb) + { + Map styles = new HashMap(); + for (Object[] os : fields) + { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + if (Collection.class.isAssignableFrom(field.getType())) + { + ParameterizedType pt = (ParameterizedType) field.getGenericType(); + Class subClass = (Class) pt.getActualTypeArguments()[0]; + List subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class); + for (Field subField : subFields) + { + Excel subExcel = subField.getAnnotation(Excel.class); + annotationDataStyles(styles, subField, subExcel); + } + } + else + { + annotationDataStyles(styles, field, excel); + } + } + return styles; + } + + /** + * 根据Excel注解创建表格列样式 + * + * @param styles 自定义样式列表 + * @param field 属性列信息 + * @param excel 注解信息 + */ + public void annotationDataStyles(Map styles, Field field, Excel excel) + { + String key = StringUtils.format("data_{}_{}_{}_{}", excel.align(), excel.color(), excel.backgroundColor(), excel.cellType()); + if (!styles.containsKey(key)) + { + CellStyle style = wb.createCellStyle(); + style.setAlignment(excel.align()); + 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()); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + style.setFillForegroundColor(excel.backgroundColor().getIndex()); + Font dataFont = wb.createFont(); + dataFont.setFontName("Arial"); + dataFont.setFontHeightInPoints((short) 10); + dataFont.setColor(excel.color().index); + style.setFont(dataFont); + if (ColumnType.TEXT == excel.cellType()) + { + DataFormat dataFormat = wb.createDataFormat(); + style.setDataFormat(dataFormat.getFormat("@")); + } + styles.put(key, style); + } + } + + /** + * 创建单元格 + */ + public Cell createHeadCell(Excel attr, Row row, int column) + { + // 创建列 + Cell cell = row.createCell(column); + // 写入列信息 + cell.setCellValue(attr.name()); + setDataValidation(attr, row, column); + cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()))); + if (isSubList()) + { + // 填充默认样式,防止合并单元格样式失效 + sheet.setDefaultColumnStyle(column, styles.get(StringUtils.format("data_{}_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor(), attr.cellType()))); + if (attr.needMerge()) + { + sheet.addMergedRegion(new CellRangeAddress(rownum - 1, rownum, column, column)); + } + } + return cell; + } + + /** + * 设置单元格信息 + * + * @param value 单元格值 + * @param attr 注解相关 + * @param cell 单元格信息 + */ + public void setCellVo(Object value, Excel attr, Cell cell) + { + if (ColumnType.STRING == attr.cellType() || ColumnType.TEXT == attr.cellType()) + { + String cellValue = Convert.toStr(value); + // 对于任何以表达式触发字符 =-+@开头的单元格,直接使用tab字符作为前缀,防止CSV注入。 + if (StringUtils.startsWithAny(cellValue, FORMULA_STR)) + { + cellValue = RegExUtils.replaceFirst(cellValue, FORMULA_REGEX_STR, "\t$0"); + } + if (value instanceof Collection && StringUtils.equals("[]", cellValue)) + { + cellValue = StringUtils.EMPTY; + } + cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix()); + } + else if (ColumnType.NUMERIC == attr.cellType()) + { + if (StringUtils.isNotNull(value)) + { + cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : Convert.toInt(value)); + } + } + else if (ColumnType.IMAGE == attr.cellType()) + { + ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1); + String imagePath = Convert.toStr(value); + if (StringUtils.isNotEmpty(imagePath)) + { + byte[] data = ImageUtils.getImage(imagePath); + getDrawingPatriarch(cell.getSheet()).createPicture(anchor, + cell.getSheet().getWorkbook().addPicture(data, getImageType(data))); + } + } + } + + /** + * 获取画布 + */ + public static Drawing getDrawingPatriarch(Sheet sheet) + { + if (sheet.getDrawingPatriarch() == null) + { + sheet.createDrawingPatriarch(); + } + return sheet.getDrawingPatriarch(); + } + + /** + * 获取图片类型,设置图片插入类型 + */ + public int getImageType(byte[] value) + { + String type = FileTypeUtils.getFileExtendName(value); + if ("JPG".equalsIgnoreCase(type)) + { + return Workbook.PICTURE_TYPE_JPEG; + } + else if ("PNG".equalsIgnoreCase(type)) + { + return Workbook.PICTURE_TYPE_PNG; + } + return Workbook.PICTURE_TYPE_JPEG; + } + + /** + * 创建表格样式 + */ + 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)); + } + if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0 || attr.comboReadDict()) + { + String[] comboArray = attr.combo(); + if (attr.comboReadDict()) + { + if (!sysDictMap.containsKey("combo_" + attr.dictType())) + { + String labels = DictUtils.getDictLabels(attr.dictType()); + sysDictMap.put("combo_" + attr.dictType(), labels); + } + String val = sysDictMap.get("combo_" + attr.dictType()); + comboArray = StringUtils.split(val, DictUtils.SEPARATOR); + } + if (comboArray.length > 15 || StringUtils.join(comboArray).length() > 255) + { + // 如果下拉数大于15或字符串长度大于255,则使用一个新sheet存储,避免生成的模板下拉值获取不到 + setXSSFValidationWithHidden(sheet, comboArray, attr.prompt(), 1, 100, column, column); + } + else + { + // 提示信息或只能选择不能输入的列内容. + setPromptOrValidation(sheet, comboArray, attr.prompt(), 1, 100, column, column); + } + } + } + + /** + * 添加单元格 + */ + public Cell addCell(Excel attr, Row row, T vo, Field field, int column) + { + Cell cell = null; + try + { + // 设置行高 + row.setHeight(maxHeight); + // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列. + if (attr.isExport()) + { + // 创建cell + cell = row.createCell(column); + if (isSubListValue(vo) && getListCellValue(vo).size() > 1 && attr.needMerge()) + { + CellRangeAddress cellAddress = new CellRangeAddress(subMergedFirstRowNum, subMergedLastRowNum, column, column); + sheet.addMergedRegion(cellAddress); + } + cell.setCellStyle(styles.get(StringUtils.format("data_{}_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor(), attr.cellType()))); + + // 用于读取对象中的属性 + Object value = getTargetValue(vo, field, attr); + String dateFormat = attr.dateFormat(); + String readConverterExp = attr.readConverterExp(); + String separator = attr.separator(); + String dictType = attr.dictType(); + if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)) + { + cell.setCellValue(parseDateToStr(dateFormat, value)); + } + else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)) + { + cell.setCellValue(convertByExp(Convert.toStr(value), readConverterExp, separator)); + } + else if (StringUtils.isNotEmpty(dictType) && StringUtils.isNotNull(value)) + { + if (!sysDictMap.containsKey(dictType + value)) + { + String lable = convertDictByExp(Convert.toStr(value), dictType, separator); + sysDictMap.put(dictType + value, lable); + } + cell.setCellValue(sysDictMap.get(dictType + value)); + } + else if (value instanceof BigDecimal && -1 != attr.scale()) + { + cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).doubleValue()); + } + else if (!attr.handler().equals(ExcelHandlerAdapter.class)) + { + cell.setCellValue(dataFormatHandlerAdapter(value, attr, cell)); + } + else + { + // 设置列类型 + setCellVo(value, attr, cell); + } + addStatisticsData(column, Convert.toStr(value), attr); + } + } + catch (Exception e) + { + log.error("导出Excel失败{}", e); + } + return cell; + } + + /** + * 设置 POI XSSFSheet 单元格提示或选择框 + * + * @param sheet 表单 + * @param textlist 下拉框显示的内容 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setPromptOrValidation(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, + int firstCol, int endCol) + { + DataValidationHelper helper = sheet.getDataValidationHelper(); + DataValidationConstraint constraint = textlist.length > 0 ? helper.createExplicitListConstraint(textlist) : helper.createCustomConstraint("DD1"); + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + DataValidation dataValidation = helper.createValidation(constraint, regions); + if (StringUtils.isNotEmpty(promptContent)) + { + // 如果设置了提示信息则鼠标放上去提示 + dataValidation.createPromptBox("", promptContent); + dataValidation.setShowPromptBox(true); + } + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) + { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } + else + { + dataValidation.setSuppressDropDownArrow(false); + } + sheet.addValidationData(dataValidation); + } + + /** + * 设置某些列的值只能输入预制的数据,显示下拉框(兼容超出一定数量的下拉框). + * + * @param sheet 要设置的sheet. + * @param textlist 下拉框显示的内容 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setXSSFValidationWithHidden(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, int firstCol, int endCol) + { + String hideSheetName = "combo_" + firstCol + "_" + endCol; + Sheet hideSheet = wb.createSheet(hideSheetName); // 用于存储 下拉菜单数据 + for (int i = 0; i < textlist.length; i++) + { + hideSheet.createRow(i).createCell(0).setCellValue(textlist[i]); + } + // 创建名称,可被其他单元格引用 + Name name = wb.createName(); + name.setNameName(hideSheetName + "_data"); + name.setRefersToFormula(hideSheetName + "!$A$1:$A$" + textlist.length); + DataValidationHelper helper = sheet.getDataValidationHelper(); + // 加载下拉列表内容 + DataValidationConstraint constraint = helper.createFormulaListConstraint(hideSheetName + "_data"); + // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列 + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + // 数据有效性对象 + DataValidation dataValidation = helper.createValidation(constraint, regions); + if (StringUtils.isNotEmpty(promptContent)) + { + // 如果设置了提示信息则鼠标放上去提示 + dataValidation.createPromptBox("", promptContent); + dataValidation.setShowPromptBox(true); + } + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) + { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } + else + { + dataValidation.setSuppressDropDownArrow(false); + } + + sheet.addValidationData(dataValidation); + // 设置hiddenSheet隐藏 + wb.setSheetHidden(wb.getSheetIndex(hideSheet), true); + } + + /** + * 解析导出值 0=男,1=女,2=未知 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String convertByExp(String propertyValue, String converterExp, String separator) + { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(propertyValue, separator)) + { + for (String value : propertyValue.split(separator)) + { + if (itemArray[0].equals(value)) + { + propertyString.append(itemArray[1] + separator); + break; + } + } + } + else + { + if (itemArray[0].equals(propertyValue)) + { + return itemArray[1]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 反向解析值 男=0,女=1,未知=2 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String reverseByExp(String propertyValue, String converterExp, String separator) + { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(propertyValue, separator)) + { + for (String value : propertyValue.split(separator)) + { + if (itemArray[1].equals(value)) + { + propertyString.append(itemArray[0] + separator); + break; + } + } + } + else + { + if (itemArray[1].equals(propertyValue)) + { + return itemArray[0]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 解析字典值 + * + * @param dictValue 字典值 + * @param dictType 字典类型 + * @param separator 分隔符 + * @return 字典标签 + */ + public static String convertDictByExp(String dictValue, String dictType, String separator) + { + return DictUtils.getDictLabel(dictType, dictValue, separator); + } + + /** + * 反向解析值字典值 + * + * @param dictLabel 字典标签 + * @param dictType 字典类型 + * @param separator 分隔符 + * @return 字典值 + */ + public static String reverseDictByExp(String dictLabel, String dictType, String separator) + { + return DictUtils.getDictValue(dictType, dictLabel, separator); + } + + /** + * 数据处理器 + * + * @param value 数据值 + * @param excel 数据注解 + * @return + */ + public String dataFormatHandlerAdapter(Object value, Excel excel, Cell cell) + { + try + { + Object instance = excel.handler().newInstance(); + Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class, Cell.class, Workbook.class }); + value = formatMethod.invoke(instance, value, excel.args(), cell, this.wb); + } + catch (Exception e) + { + log.error("不能格式化数据 " + excel.handler(), e.getMessage()); + } + return Convert.toStr(value); + } + + /** + * 合计统计信息 + */ + private void addStatisticsData(Integer index, String text, Excel entity) + { + if (entity != null && entity.isStatistics()) + { + Double temp = 0D; + if (!statistics.containsKey(index)) + { + statistics.put(index, temp); + } + try + { + temp = Double.valueOf(text); + } + catch (NumberFormatException e) + { + } + statistics.put(index, statistics.get(index) + temp); + } + } + + /** + * 创建统计行 + */ + public void addStatisticsRow() + { + if (statistics.size() > 0) + { + Row row = sheet.createRow(sheet.getLastRowNum() + 1); + Set keys = statistics.keySet(); + Cell cell = row.createCell(0); + cell.setCellStyle(styles.get("total")); + cell.setCellValue("合计"); + + for (Integer key : keys) + { + cell = row.createCell(key); + cell.setCellStyle(styles.get("total")); + cell.setCellValue(DOUBLE_FORMAT.format(statistics.get(key))); + } + statistics.clear(); + } + } + + /** + * 编码文件名 + */ + public String encodingFilename(String filename) + { + filename = UUID.randomUUID() + "_" + filename + ".xlsx"; + return filename; + } + + /** + * 获取下载路径 + * + * @param filename 文件名称 + */ + public String getAbsoluteFile(String filename) + { + String downloadPath = StaffingConfig.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.contains(".")) + { + 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.isNotNull(o) && StringUtils.isNotEmpty(name)) + { + Class clazz = o.getClass(); + Field field = clazz.getDeclaredField(name); + field.setAccessible(true); + o = field.get(o); + } + return o; + } + + /** + * 得到所有定义字段 + */ + private void createExcelField() + { + this.fields = getFields(); + this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList()); + this.maxHeight = getRowHeight(); + } + + /** + * 获取字段注解信息 + */ + public List getFields() + { + List fields = new ArrayList(); + List tempFields = new ArrayList<>(); + tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); + tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); + for (Field field : tempFields) + { + if (!ArrayUtils.contains(this.excludeFields, field.getName())) + { + // 单注解 + if (field.isAnnotationPresent(Excel.class)) + { + Excel attr = field.getAnnotation(Excel.class); + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + field.setAccessible(true); + fields.add(new Object[] { field, attr }); + } + if (Collection.class.isAssignableFrom(field.getType())) + { + subMethod = getSubMethod(field.getName(), clazz); + ParameterizedType pt = (ParameterizedType) field.getGenericType(); + Class subClass = (Class) pt.getActualTypeArguments()[0]; + this.subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class); + } + } + + // 多注解 + if (field.isAnnotationPresent(Excels.class)) + { + Excels attrs = field.getAnnotation(Excels.class); + Excel[] excels = attrs.value(); + for (Excel attr : excels) + { + if (!ArrayUtils.contains(this.excludeFields, field.getName() + "." + attr.targetAttr()) + && (attr != null && (attr.type() == Type.ALL || attr.type() == type))) + { + field.setAccessible(true); + fields.add(new Object[] { field, attr }); + } + } + } + } + } + return fields; + } + + /** + * 根据注解获取最大行高 + */ + public short getRowHeight() + { + double maxHeight = 0; + for (Object[] os : this.fields) + { + Excel excel = (Excel) os[1]; + maxHeight = Math.max(maxHeight, excel.height()); + } + return (short) (maxHeight * 20); + } + + /** + * 创建一个工作簿 + */ + public void createWorkbook() + { + this.wb = new SXSSFWorkbook(500); + this.sheet = wb.createSheet(); + wb.setSheetName(0, sheetName); + this.styles = createStyles(wb); + } + + /** + * 创建工作表 + * + * @param sheetNo sheet数量 + * @param index 序号 + */ + public void createSheet(int sheetNo, int index) + { + // 设置工作表的名称. + if (sheetNo > 1 && index > 0) + { + this.sheet = wb.createSheet(); + this.createTitle(); + 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 (StringUtils.isNotNull(cell)) + { + if (cell.getCellType() == CellType.NUMERIC || cell.getCellType() == CellType.FORMULA) + { + val = cell.getNumericCellValue(); + if (DateUtil.isCellDateFormatted(cell)) + { + val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换 + } + else + { + if ((Double) val % 1 != 0) + { + val = new BigDecimal(val.toString()); + } + else + { + val = new DecimalFormat("0").format(val); + } + } + } + else if (cell.getCellType() == CellType.STRING) + { + val = cell.getStringCellValue(); + } + else if (cell.getCellType() == CellType.BOOLEAN) + { + val = cell.getBooleanCellValue(); + } + else if (cell.getCellType() == CellType.ERROR) + { + val = cell.getErrorCellValue(); + } + + } + } + catch (Exception e) + { + return val; + } + return val; + } + + /** + * 判断是否是空行 + * + * @param row 判断的行 + * @return + */ + private boolean isRowEmpty(Row row) + { + if (row == null) + { + return true; + } + for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) + { + Cell cell = row.getCell(i); + if (cell != null && cell.getCellType() != CellType.BLANK) + { + return false; + } + } + return true; + } + + /** + * 获取Excel2003图片 + * + * @param sheet 当前sheet对象 + * @param workbook 工作簿对象 + * @return Map key:图片单元格索引(1_1)String,value:图片流PictureData + */ + public static Map getSheetPictures03(HSSFSheet sheet, HSSFWorkbook workbook) + { + Map sheetIndexPicMap = new HashMap(); + List pictures = workbook.getAllPictures(); + if (!pictures.isEmpty()) + { + for (HSSFShape shape : sheet.getDrawingPatriarch().getChildren()) + { + HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor(); + if (shape instanceof HSSFPicture) + { + HSSFPicture pic = (HSSFPicture) shape; + int pictureIndex = pic.getPictureIndex() - 1; + HSSFPictureData picData = pictures.get(pictureIndex); + String picIndex = anchor.getRow1() + "_" + anchor.getCol1(); + sheetIndexPicMap.put(picIndex, picData); + } + } + return sheetIndexPicMap; + } + else + { + return sheetIndexPicMap; + } + } + + /** + * 获取Excel2007图片 + * + * @param sheet 当前sheet对象 + * @param workbook 工作簿对象 + * @return Map key:图片单元格索引(1_1)String,value:图片流PictureData + */ + public static Map getSheetPictures07(XSSFSheet sheet, XSSFWorkbook workbook) + { + Map sheetIndexPicMap = new HashMap(); + for (POIXMLDocumentPart dr : sheet.getRelations()) + { + if (dr instanceof XSSFDrawing) + { + XSSFDrawing drawing = (XSSFDrawing) dr; + List shapes = drawing.getShapes(); + for (XSSFShape shape : shapes) + { + if (shape instanceof XSSFPicture) + { + XSSFPicture pic = (XSSFPicture) shape; + XSSFClientAnchor anchor = pic.getPreferredSize(); + CTMarker ctMarker = anchor.getFrom(); + String picIndex = ctMarker.getRow() + "_" + ctMarker.getCol(); + sheetIndexPicMap.put(picIndex, pic.getPictureData()); + } + } + } + } + return sheetIndexPicMap; + } + + /** + * 格式化不同类型的日期对象 + * + * @param dateFormat 日期格式 + * @param val 被格式化的日期对象 + * @return 格式化后的日期字符 + */ + public String parseDateToStr(String dateFormat, Object val) + { + if (val == null) + { + return ""; + } + String str; + if (val instanceof Date) + { + str = DateUtils.parseDateToStr(dateFormat, (Date) val); + } + else if (val instanceof LocalDateTime) + { + str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDateTime) val)); + } + else if (val instanceof LocalDate) + { + str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDate) val)); + } + else + { + str = val.toString(); + } + return str; + } + + /** + * 是否有对象的子列表 + */ + public boolean isSubList() + { + return StringUtils.isNotNull(subFields) && subFields.size() > 0; + } + + /** + * 是否有对象的子列表,集合不为空 + */ + public boolean isSubListValue(T vo) + { + return StringUtils.isNotNull(subFields) && subFields.size() > 0 && StringUtils.isNotNull(getListCellValue(vo)) && getListCellValue(vo).size() > 0; + } + + /** + * 获取集合的值 + */ + public Collection getListCellValue(Object obj) + { + Object value; + try + { + value = subMethod.invoke(obj, new Object[] {}); + } + catch (Exception e) + { + return new ArrayList(); + } + return (Collection) value; + } + + /** + * 获取对象的子列表方法 + * + * @param name 名称 + * @param pojoClass 类对象 + * @return 子列表方法 + */ + public Method getSubMethod(String name, Class pojoClass) + { + StringBuffer getMethodName = new StringBuffer("get"); + getMethodName.append(name.substring(0, 1).toUpperCase()); + getMethodName.append(name.substring(1)); + Method method = null; + try + { + method = pojoClass.getMethod(getMethodName.toString(), new Class[] {}); + } + catch (Exception e) + { + log.error("获取对象异常{}", e.getMessage()); + } + return method; + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/reflect/ReflectUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/reflect/ReflectUtils.java new file mode 100644 index 0000000..82654bc --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/reflect/ReflectUtils.java @@ -0,0 +1,410 @@ +package com.staffing.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.staffing.common.core.text.Convert; +import com.staffing.common.utils.DateUtils; + +/** + * 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数. + * + * @author staffing + */ +@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 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 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修饰符, 不经过getter函数. + */ + @SuppressWarnings("unchecked") + public static 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修饰符, 不经过setter函数. + */ + public static 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 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 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]); + } + } + else if (cs[i] == boolean.class || cs[i] == Boolean.class) + { + args[i] = Convert.toBool(args[i]); + } + } + } + return (E) method.invoke(obj, args); + } + catch (Exception e) + { + String msg = "method: " + method + ", obj: " + obj + ", args: " + args + ""; + throw convertReflectionExceptionToUnchecked(msg, e); + } + } + + /** + * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问. + * 如向上转型到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; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 匹配函数名+参数类型。 + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用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; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 只匹配函数名。 + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用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的SecurityManager抱怨。 + */ + 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的SecurityManager抱怨。 + */ + 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定义中声明的泛型参数的类型, 注意泛型必须定义在父类处 + * 如无法找到, 返回Object.class. + */ + @SuppressWarnings("unchecked") + public static Class getClassGenricType(final Class clazz) + { + return getClassGenricType(clazz, 0); + } + + /** + * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. + * 如无法找到, 返回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; + + } + + /** + * 将反射时的checked exception转换为unchecked 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/staffing-common/src/main/java/com/staffing/common/utils/sign/Base64.java b/staffing-common/src/main/java/com/staffing/common/utils/sign/Base64.java new file mode 100644 index 0000000..56b59cb --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/sign/Base64.java @@ -0,0 +1,291 @@ +package com.staffing.common.utils.sign; + +/** + * Base64工具类 + * + * @author staffing + */ +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/staffing-common/src/main/java/com/staffing/common/utils/sign/Md5Utils.java b/staffing-common/src/main/java/com/staffing/common/utils/sign/Md5Utils.java new file mode 100644 index 0000000..8ee0b9a --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/sign/Md5Utils.java @@ -0,0 +1,67 @@ +package com.staffing.common.utils.sign; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Md5加密方法 + * + * @author staffing + */ +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(StandardCharsets.UTF_8), StandardCharsets.UTF_8); + } + catch (Exception e) + { + log.error("not supported charset...{}", e); + return s; + } + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/spring/SpringUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/spring/SpringUtils.java new file mode 100644 index 0000000..e331053 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/spring/SpringUtils.java @@ -0,0 +1,158 @@ +package com.staffing.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.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; +import com.staffing.common.utils.StringUtils; + +/** + * spring工具类 方便在非spring管理环境中获取bean + * + * @author staffing + */ +@Component +public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware +{ + /** Spring应用上下文环境 */ + private static ConfigurableListableBeanFactory beanFactory; + + private static ApplicationContext applicationContext; + + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException + { + SpringUtils.beanFactory = beanFactory; + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException + { + SpringUtils.applicationContext = applicationContext; + } + + /** + * 获取对象 + * + * @param name + * @return Object 一个以所给名字注册的bean的实例 + * @throws org.springframework.beans.BeansException + * + */ + @SuppressWarnings("unchecked") + public static T getBean(String name) throws BeansException + { + return (T) beanFactory.getBean(name); + } + + /** + * 获取类型为requiredType的对象 + * + * @param clz + * @return + * @throws org.springframework.beans.BeansException + * + */ + public static T getBean(Class 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定义是一个singleton还是一个prototype。 如果与给定名字相应的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); + } + + /** + * 如果给定的bean名字在bean定义中有别名,则返回这些别名 + * + * @param name + * @return + * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException + * + */ + public static String[] getAliases(String name) throws NoSuchBeanDefinitionException + { + return beanFactory.getAliases(name); + } + + /** + * 获取aop代理对象 + * + * @param invoker + * @return + */ + @SuppressWarnings("unchecked") + public static T getAopProxy(T invoker) + { + return (T) AopContext.currentProxy(); + } + + /** + * 获取当前的环境配置,无配置返回null + * + * @return 当前的环境配置 + */ + public static String[] getActiveProfiles() + { + return applicationContext.getEnvironment().getActiveProfiles(); + } + + /** + * 获取当前的环境配置,当有多个环境配置时,只获取第一个 + * + * @return 当前的环境配置 + */ + public static String getActiveProfile() + { + final String[] activeProfiles = getActiveProfiles(); + return StringUtils.isNotEmpty(activeProfiles) ? activeProfiles[0] : null; + } + + /** + * 获取配置文件中的值 + * + * @param key 配置文件的key + * @return 当前的配置文件的值 + * + */ + public static String getRequiredProperty(String key) + { + return applicationContext.getEnvironment().getRequiredProperty(key); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/sql/SqlUtil.java b/staffing-common/src/main/java/com/staffing/common/utils/sql/SqlUtil.java new file mode 100644 index 0000000..6611d40 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/sql/SqlUtil.java @@ -0,0 +1,70 @@ +package com.staffing.common.utils.sql; + +import com.staffing.common.exception.UtilException; +import com.staffing.common.utils.StringUtils; + +/** + * sql操作工具类 + * + * @author staffing + */ +public class SqlUtil +{ + /** + * 定义常用的 sql关键字 + */ + public static String SQL_REGEX = "and |extractvalue|updatexml|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |+|user()"; + + /** + * 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序) + */ + public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+"; + + /** + * 限制orderBy最大长度 + */ + private static final int ORDER_BY_MAX_LENGTH = 500; + + /** + * 检查字符,防止注入绕过 + */ + public static String escapeOrderBySql(String value) + { + if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) + { + throw new UtilException("参数不符合规范,不能进行查询"); + } + if (StringUtils.length(value) > ORDER_BY_MAX_LENGTH) + { + throw new UtilException("参数已超过最大限制,不能进行查询"); + } + return value; + } + + /** + * 验证 order by 语法是否符合规范 + */ + public static boolean isValidOrderBySql(String value) + { + return value.matches(SQL_PATTERN); + } + + /** + * SQL关键字检查 + */ + public static void filterKeyword(String value) + { + if (StringUtils.isEmpty(value)) + { + return; + } + String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|"); + for (String sqlKeyword : sqlKeywords) + { + if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1) + { + throw new UtilException("参数存在SQL注入风险"); + } + } + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/uuid/IdUtils.java b/staffing-common/src/main/java/com/staffing/common/utils/uuid/IdUtils.java new file mode 100644 index 0000000..bbb7d38 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/uuid/IdUtils.java @@ -0,0 +1,49 @@ +package com.staffing.common.utils.uuid; + +/** + * ID生成器工具类 + * + * @author staffing + */ +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,使用性能更好的ThreadLocalRandom生成UUID + * + * @return 随机UUID + */ + public static String fastUUID() + { + return UUID.fastUUID().toString(); + } + + /** + * 简化的UUID,去掉了横线,使用性能更好的ThreadLocalRandom生成UUID + * + * @return 简化的UUID,去掉了横线 + */ + public static String fastSimpleUUID() + { + return UUID.fastUUID().toString(true); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/uuid/Seq.java b/staffing-common/src/main/java/com/staffing/common/utils/uuid/Seq.java new file mode 100644 index 0000000..6fbe262 --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/uuid/Seq.java @@ -0,0 +1,86 @@ +package com.staffing.common.utils.uuid; + +import java.util.concurrent.atomic.AtomicInteger; +import com.staffing.common.utils.DateUtils; +import com.staffing.common.utils.StringUtils; + +/** + * @author staffing 序列生成类 + */ +public class Seq +{ + // 通用序列类型 + public static final String commSeqType = "COMMON"; + + // 上传序列类型 + public static final String uploadSeqType = "UPLOAD"; + + // 通用接口序列数 + private static AtomicInteger commSeq = new AtomicInteger(1); + + // 上传接口序列数 + private static AtomicInteger uploadSeq = new AtomicInteger(1); + + // 机器标识 + private static final String machineCode = "A"; + + /** + * 获取通用序列号 + * + * @return 序列值 + */ + public static String getId() + { + return getId(commSeqType); + } + + /** + * 默认16位序列号 yyMMddHHmmss + 一位机器标识 + 3长度循环递增字符串 + * + * @return 序列值 + */ + public static String getId(String type) + { + AtomicInteger atomicInt = commSeq; + if (uploadSeqType.equals(type)) + { + atomicInt = uploadSeq; + } + return getId(atomicInt, 3); + } + + /** + * 通用接口序列号 yyMMddHHmmss + 一位机器标识 + length长度循环递增字符串 + * + * @param atomicInt 序列数 + * @param length 数值长度 + * @return 序列值 + */ + public static String getId(AtomicInteger atomicInt, int length) + { + String result = DateUtils.dateTimeNow(); + result += machineCode; + result += getSeq(atomicInt, length); + return result; + } + + /** + * 序列循环递增字符串[1, 10 的 (length)幂次方), 用0左补齐length位数 + * + * @return 序列值 + */ + private synchronized static String getSeq(AtomicInteger atomicInt, int length) + { + // 先取值再+1 + int value = atomicInt.getAndIncrement(); + + // 如果更新后值>=10 的 (length)幂次方则重置为1 + int maxSeq = (int) Math.pow(10, length); + if (atomicInt.get() >= maxSeq) + { + atomicInt.set(1); + } + // 转字符串,用0左补齐 + return StringUtils.padl(value, length); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/utils/uuid/UUID.java b/staffing-common/src/main/java/com/staffing/common/utils/uuid/UUID.java new file mode 100644 index 0000000..5607d1e --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/utils/uuid/UUID.java @@ -0,0 +1,484 @@ +package com.staffing.common.utils.uuid; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; +import com.staffing.common.exception.UtilException; + +/** + * 提供通用唯一识别码(universally unique identifier)(UUID)实现 + * + * @author staffing + */ +public final class UUID implements java.io.Serializable, Comparable +{ + private static final long serialVersionUID = -1185015143654744140L; + + /** + * SecureRandom 的单例 + * + */ + private static class Holder + { + static final SecureRandom numberGenerator = getSecureRandom(); + } + + /** 此UUID的最高64有效位 */ + private final long mostSigBits; + + /** 此UUID的最低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 的静态工厂。 + * + * @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(基于名称的)UUID 的静态工厂。 + * + * @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} 是如何生成的。 + *

+ * 版本号具有以下含意: + *

    + *
  • 1 基于时间的 UUID + *
  • 2 DCE 安全 UUID + *
  • 3 基于名称的 UUID + *
  • 4 随机生成的 UUID + *
+ * + * @return 此 {@code UUID} 的版本号 + */ + public int version() + { + // Version is bits masked by 0x000000000000F000 in MS long + return (int) ((mostSigBits >> 12) & 0x0f); + } + + /** + * 与此 {@code UUID} 相关联的变体号。变体号描述 {@code UUID} 的布局。 + *

+ * 变体号具有以下含意: + *

    + *
  • 0 为 NCS 向后兼容保留 + *
  • 2 IETF RFC 4122(Leach-Salz), 用于此类 + *
  • 6 保留,微软向后兼容 + *
  • 7 保留供以后定义使用 + *
+ * + * @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 相关联的时间戳值。 + * + *

+ * 60 位的时间戳值根据此 {@code UUID} 的 time_low、time_mid 和 time_hi 字段构造。
+ * 所得到的时间戳以 100 毫微秒为单位,从 UTC(通用协调时间) 1582 年 10 月 15 日零时开始。 + * + *

+ * 时间戳值仅在在基于时间的 UUID(其 version 类型为 1)中才有意义。
+ * 如果此 {@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 相关联的时钟序列值。 + * + *

+ * 14 位的时钟序列值根据此 UUID 的 clock_seq 字段构造。clock_seq 字段用于保证在基于时间的 UUID 中的时间唯一性。 + *

+ * {@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 相关的节点值。 + * + *

+ * 48 位的节点值根据此 UUID 的 node 字段构造。此字段旨在用于保存机器的 IEEE 802 地址,该地址用于生成此 UUID 以保证空间唯一性。 + *

+ * 节点值仅在基于时间的 UUID(其 version 类型为 1)中才有意义。
+ * 如果此 UUID 不是基于时间的 UUID,则此方法抛出 UnsupportedOperationException。 + * + * @return 此 {@code UUID} 的节点值 + * + * @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1 + */ + public long node() throws UnsupportedOperationException + { + checkTimeBase(); + return leastSigBits & 0x0000FFFFFFFFFFFFL; + } + + /** + * 返回此{@code UUID} 的字符串表现形式。 + * + *

+ * UUID 的字符串表示形式由此 BNF 描述: + * + *

+     * {@code
+     * UUID                   = ----
+     * time_low               = 4*
+     * time_mid               = 2*
+     * time_high_and_version  = 2*
+     * variant_and_sequence   = 2*
+     * node                   = 6*
+     * hexOctet               = 
+     * hexDigit               = [0-9a-fA-F]
+     * }
+     * 
+ * + * + * + * @return 此{@code UUID} 的字符串表现形式 + * @see #toString(boolean) + */ + @Override + public String toString() + { + return toString(false); + } + + /** + * 返回此{@code UUID} 的字符串表现形式。 + * + *

+ * UUID 的字符串表示形式由此 BNF 描述: + * + *

+     * {@code
+     * UUID                   = ----
+     * time_low               = 4*
+     * time_mid               = 2*
+     * time_high_and_version  = 2*
+     * variant_and_sequence   = 2*
+     * node                   = 6*
+     * hexOctet               = 
+     * hexDigit               = [0-9a-fA-F]
+     * }
+     * 
+ * + * + * + * @param isSimple 是否简单模式,简单模式为不带'-'的UUID字符串 + * @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 (!isSimple) + { + builder.append('-'); + } + // time_mid + builder.append(digits(mostSigBits >> 16, 4)); + if (!isSimple) + { + builder.append('-'); + } + // time_high_and_version + builder.append(digits(mostSigBits, 4)); + if (!isSimple) + { + builder.append('-'); + } + // variant_and_sequence + builder.append(digits(leastSigBits >> 48, 4)); + if (!isSimple) + { + builder.append('-'); + } + // node + builder.append(digits(leastSigBits, 12)); + + return builder.toString(); + } + + /** + * 返回此 UUID 的哈希码。 + * + * @return UUID 的哈希码值。 + */ + @Override + public int hashCode() + { + long hilo = mostSigBits ^ leastSigBits; + return ((int) (hilo >> 32)) ^ (int) hilo; + } + + /** + * 将此对象与指定对象比较。 + *

+ * 当且仅当参数不为 {@code null}、而是一个 UUID 对象、具有与此 UUID 相同的 varriant、包含相同的值(每一位均相同)时,结果才为 {@code true}。 + * + * @param obj 要与之比较的对象 + * + * @return 如果对象相同,则返回 {@code true};否则返回 {@code false} + */ + @Override + 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 比较。 + * + *

+ * 如果两个 UUID 不同,且第一个 UUID 的最高有效字段大于第二个 UUID 的对应字段,则第一个 UUID 大于第二个 UUID。 + * + * @param val 与此 UUID 比较的 UUID + * + * @return 在此 UUID 小于、等于或大于 val 时,分别返回 -1、0 或 1。 + * + */ + @Override + 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 + /** + * 返回指定数字对应的hex值 + * + * @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); + } + } + + /** + * 获取随机数生成器对象
+ * ThreadLocalRandom是JDK 7之后提供并发产生随机数,能够解决多个线程发生的竞争争夺。 + * + * @return {@link ThreadLocalRandom} + */ + public static ThreadLocalRandom getRandom() + { + return ThreadLocalRandom.current(); + } +} diff --git a/staffing-common/src/main/java/com/staffing/common/xss/Xss.java b/staffing-common/src/main/java/com/staffing/common/xss/Xss.java new file mode 100644 index 0000000..828436c --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/xss/Xss.java @@ -0,0 +1,27 @@ +package com.staffing.common.xss; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 自定义xss校验注解 + * + * @author staffing + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(value = { ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER }) +@Constraint(validatedBy = { XssValidator.class }) +public @interface Xss +{ + String message() + + default "不允许任何脚本运行"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/staffing-common/src/main/java/com/staffing/common/xss/XssValidator.java b/staffing-common/src/main/java/com/staffing/common/xss/XssValidator.java new file mode 100644 index 0000000..a6dbbbc --- /dev/null +++ b/staffing-common/src/main/java/com/staffing/common/xss/XssValidator.java @@ -0,0 +1,39 @@ +package com.staffing.common.xss; + +import com.staffing.common.utils.StringUtils; +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 自定义xss校验注解实现 + * + * @author staffing + */ +public class XssValidator implements ConstraintValidator +{ + private static final String HTML_PATTERN = "<(\\S*?)[^>]*>.*?|<.*? />"; + + @Override + public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) + { + if (StringUtils.isBlank(value)) + { + return true; + } + return !containsHtml(value); + } + + public static boolean containsHtml(String value) + { + StringBuilder sHtml = new StringBuilder(); + Pattern pattern = Pattern.compile(HTML_PATTERN); + Matcher matcher = pattern.matcher(value); + while (matcher.find()) + { + sHtml.append(matcher.group()); + } + return pattern.matcher(sHtml).matches(); + } +} \ No newline at end of file diff --git a/staffing-framework/pom.xml b/staffing-framework/pom.xml new file mode 100644 index 0000000..8f61c1f --- /dev/null +++ b/staffing-framework/pom.xml @@ -0,0 +1,64 @@ + + + + staffing + com.staffing + 3.8.8 + + 4.0.0 + + staffing-framework + + + framework框架核心 + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-aop + + + + + com.alibaba + druid-spring-boot-starter + + + + + pro.fessional + kaptcha + + + servlet-api + javax.servlet + + + + + + + com.github.oshi + oshi-core + + + + + com.staffing + staffing-system + + + + + \ No newline at end of file diff --git a/staffing-framework/src/main/java/com/staffing/framework/aspectj/DataScopeAspect.java b/staffing-framework/src/main/java/com/staffing/framework/aspectj/DataScopeAspect.java new file mode 100644 index 0000000..9a01dca --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/aspectj/DataScopeAspect.java @@ -0,0 +1,184 @@ +package com.staffing.framework.aspectj; + +import java.util.ArrayList; +import java.util.List; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.springframework.stereotype.Component; +import com.staffing.common.annotation.DataScope; +import com.staffing.common.core.domain.BaseEntity; +import com.staffing.common.core.domain.entity.SysRole; +import com.staffing.common.core.domain.entity.SysUser; +import com.staffing.common.core.domain.model.LoginUser; +import com.staffing.common.core.text.Convert; +import com.staffing.common.utils.SecurityUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.framework.security.context.PermissionContextHolder; + +/** + * 数据过滤处理 + * + * @author staffing + */ +@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"; + + /** + * 数据权限过滤关键字 + */ + public static final String DATA_SCOPE = "dataScope"; + + @Before("@annotation(controllerDataScope)") + public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable + { + clearDataScope(point); + handleDataScope(point, controllerDataScope); + } + + protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope) + { + // 获取当前的用户 + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNotNull(loginUser)) + { + SysUser currentUser = loginUser.getUser(); + // 如果是超级管理员,则不过滤数据 + if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) + { + String permission = StringUtils.defaultIfEmpty(controllerDataScope.permission(), PermissionContextHolder.getContext()); + dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(), + controllerDataScope.userAlias(), permission); + } + } + } + + /** + * 数据范围过滤 + * + * @param joinPoint 切点 + * @param user 用户 + * @param deptAlias 部门别名 + * @param userAlias 用户别名 + * @param permission 权限字符 + */ + public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias, String permission) + { + StringBuilder sqlString = new StringBuilder(); + List conditions = new ArrayList(); + List scopeCustomIds = new ArrayList(); + user.getRoles().forEach(role -> { + if (DATA_SCOPE_CUSTOM.equals(role.getDataScope()) && StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))) + { + scopeCustomIds.add(Convert.toStr(role.getRoleId())); + } + }); + + for (SysRole role : user.getRoles()) + { + String dataScope = role.getDataScope(); + if (conditions.contains(dataScope)) + { + continue; + } + if (!StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))) + { + continue; + } + if (DATA_SCOPE_ALL.equals(dataScope)) + { + sqlString = new StringBuilder(); + conditions.add(dataScope); + break; + } + else if (DATA_SCOPE_CUSTOM.equals(dataScope)) + { + if (scopeCustomIds.size() > 1) + { + // 多个自定数据权限使用in查询,避免多次拼接。 + sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id in ({}) ) ", deptAlias, String.join(",", scopeCustomIds))); + } + else + { + 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 + { + // 数据权限为仅本人且没有userAlias别名不查询任何数据 + sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias)); + } + } + conditions.add(dataScope); + } + + // 角色都不包含传递过来的权限字符,这个时候sqlString也会为空,所以要限制一下,不查询任何数据 + if (StringUtils.isEmpty(conditions)) + { + sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias)); + } + + if (StringUtils.isNotBlank(sqlString.toString())) + { + Object params = joinPoint.getArgs()[0]; + if (StringUtils.isNotNull(params) && params instanceof BaseEntity) + { + BaseEntity baseEntity = (BaseEntity) params; + baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")"); + } + } + } + + /** + * 拼接权限sql前先清空params.dataScope参数防止注入 + */ + private void clearDataScope(final JoinPoint joinPoint) + { + Object params = joinPoint.getArgs()[0]; + if (StringUtils.isNotNull(params) && params instanceof BaseEntity) + { + BaseEntity baseEntity = (BaseEntity) params; + baseEntity.getParams().put(DATA_SCOPE, ""); + } + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/aspectj/DataSourceAspect.java b/staffing-framework/src/main/java/com/staffing/framework/aspectj/DataSourceAspect.java new file mode 100644 index 0000000..0a88fc4 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/aspectj/DataSourceAspect.java @@ -0,0 +1,72 @@ +package com.staffing.framework.aspectj; + +import java.util.Objects; +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.AnnotationUtils; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import com.staffing.common.annotation.DataSource; +import com.staffing.common.utils.StringUtils; +import com.staffing.framework.datasource.DynamicDataSourceContextHolder; + +/** + * 多数据源处理 + * + * @author staffing + */ +@Aspect +@Order(1) +@Component +public class DataSourceAspect +{ + protected Logger logger = LoggerFactory.getLogger(getClass()); + + @Pointcut("@annotation(com.staffing.common.annotation.DataSource)" + + "|| @within(com.staffing.common.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(); + DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class); + if (Objects.nonNull(dataSource)) + { + return dataSource; + } + + return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class); + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/aspectj/LogAspect.java b/staffing-framework/src/main/java/com/staffing/framework/aspectj/LogAspect.java new file mode 100644 index 0000000..165b195 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/aspectj/LogAspect.java @@ -0,0 +1,255 @@ +package com.staffing.framework.aspectj; + +import java.util.Collection; +import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.ArrayUtils; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.NamedThreadLocal; +import org.springframework.stereotype.Component; +import org.springframework.validation.BindingResult; +import org.springframework.web.multipart.MultipartFile; +import com.alibaba.fastjson2.JSON; +import com.staffing.common.annotation.Log; +import com.staffing.common.core.domain.entity.SysUser; +import com.staffing.common.core.domain.model.LoginUser; +import com.staffing.common.enums.BusinessStatus; +import com.staffing.common.enums.HttpMethod; +import com.staffing.common.filter.PropertyPreExcludeFilter; +import com.staffing.common.utils.SecurityUtils; +import com.staffing.common.utils.ServletUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.ip.IpUtils; +import com.staffing.framework.manager.AsyncManager; +import com.staffing.framework.manager.factory.AsyncFactory; +import com.staffing.system.domain.SysOperLog; + +/** + * 操作日志记录处理 + * + * @author staffing + */ +@Aspect +@Component +public class LogAspect +{ + private static final Logger log = LoggerFactory.getLogger(LogAspect.class); + + /** 排除敏感属性字段 */ + public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" }; + + /** 计算操作消耗时间 */ + private static final ThreadLocal TIME_THREADLOCAL = new NamedThreadLocal("Cost Time"); + + /** + * 处理请求前执行 + */ + @Before(value = "@annotation(controllerLog)") + public void boBefore(JoinPoint joinPoint, Log controllerLog) + { + TIME_THREADLOCAL.set(System.currentTimeMillis()); + } + + /** + * 处理完请求后执行 + * + * @param joinPoint 切点 + */ + @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult") + public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) + { + handleLog(joinPoint, controllerLog, null, jsonResult); + } + + /** + * 拦截异常操作 + * + * @param joinPoint 切点 + * @param e 异常 + */ + @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e") + public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) + { + handleLog(joinPoint, controllerLog, e, null); + } + + protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) + { + try + { + // 获取当前的用户 + LoginUser loginUser = SecurityUtils.getLoginUser(); + + // *========数据库日志=========*// + SysOperLog operLog = new SysOperLog(); + operLog.setStatus(BusinessStatus.SUCCESS.ordinal()); + // 请求的地址 + String ip = IpUtils.getIpAddr(); + operLog.setOperIp(ip); + operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255)); + if (loginUser != null) + { + operLog.setOperName(loginUser.getUsername()); + SysUser currentUser = loginUser.getUser(); + if (StringUtils.isNotNull(currentUser) && StringUtils.isNotNull(currentUser.getDept())) + { + operLog.setDeptName(currentUser.getDept().getDeptName()); + } + } + + 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, jsonResult); + // 设置消耗时间 + operLog.setCostTime(System.currentTimeMillis() - TIME_THREADLOCAL.get()); + // 保存数据库 + AsyncManager.me().execute(AsyncFactory.recordOper(operLog)); + } + catch (Exception exp) + { + // 记录本地异常日志 + log.error("异常信息:{}", exp.getMessage()); + exp.printStackTrace(); + } + finally + { + TIME_THREADLOCAL.remove(); + } + } + + /** + * 获取注解中对方法的描述信息 用于Controller层注解 + * + * @param log 日志 + * @param operLog 操作日志 + * @throws Exception + */ + public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog, Object jsonResult) throws Exception + { + // 设置action动作 + operLog.setBusinessType(log.businessType().ordinal()); + // 设置标题 + operLog.setTitle(log.title()); + // 设置操作人类别 + operLog.setOperatorType(log.operatorType().ordinal()); + // 是否需要保存request,参数和值 + if (log.isSaveRequestData()) + { + // 获取参数的信息,传入到数据库中。 + setRequestValue(joinPoint, operLog, log.excludeParamNames()); + } + // 是否需要保存response,参数和值 + if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult)) + { + operLog.setJsonResult(StringUtils.substring(JSON.toJSONString(jsonResult), 0, 2000)); + } + } + + /** + * 获取请求的参数,放到log中 + * + * @param operLog 操作日志 + * @throws Exception 异常 + */ + private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog, String[] excludeParamNames) throws Exception + { + Map paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest()); + String requestMethod = operLog.getRequestMethod(); + if (StringUtils.isEmpty(paramsMap) + && (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod))) + { + String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames); + operLog.setOperParam(StringUtils.substring(params, 0, 2000)); + } + else + { + operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, 2000)); + } + } + + /** + * 参数拼装 + */ + private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames) + { + String params = ""; + if (paramsArray != null && paramsArray.length > 0) + { + for (Object o : paramsArray) + { + if (StringUtils.isNotNull(o) && !isFilterObject(o)) + { + try + { + String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames)); + params += jsonObj.toString() + " "; + } + catch (Exception e) + { + } + } + } + } + return params.trim(); + } + + /** + * 忽略敏感属性 + */ + public PropertyPreExcludeFilter excludePropertyPreFilter(String[] excludeParamNames) + { + return new PropertyPreExcludeFilter().addExcludes(ArrayUtils.addAll(EXCLUDE_PROPERTIES, excludeParamNames)); + } + + /** + * 判断是否需要过滤的对象。 + * + * @param o 对象信息。 + * @return 如果是需要过滤的对象,则返回true;否则返回false。 + */ + @SuppressWarnings("rawtypes") + public boolean isFilterObject(final Object o) + { + Class clazz = o.getClass(); + if (clazz.isArray()) + { + return clazz.getComponentType().isAssignableFrom(MultipartFile.class); + } + else if (Collection.class.isAssignableFrom(clazz)) + { + Collection collection = (Collection) o; + for (Object value : collection) + { + return value instanceof MultipartFile; + } + } + else if (Map.class.isAssignableFrom(clazz)) + { + Map map = (Map) o; + for (Object value : map.entrySet()) + { + Map.Entry entry = (Map.Entry) value; + return entry.getValue() instanceof MultipartFile; + } + } + return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse + || o instanceof BindingResult; + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/aspectj/RateLimiterAspect.java b/staffing-framework/src/main/java/com/staffing/framework/aspectj/RateLimiterAspect.java new file mode 100644 index 0000000..5f74384 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/aspectj/RateLimiterAspect.java @@ -0,0 +1,89 @@ +package com.staffing.framework.aspectj; + +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.List; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.script.RedisScript; +import org.springframework.stereotype.Component; +import com.staffing.common.annotation.RateLimiter; +import com.staffing.common.enums.LimitType; +import com.staffing.common.exception.ServiceException; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.ip.IpUtils; + +/** + * 限流处理 + * + * @author staffing + */ +@Aspect +@Component +public class RateLimiterAspect +{ + private static final Logger log = LoggerFactory.getLogger(RateLimiterAspect.class); + + private RedisTemplate redisTemplate; + + private RedisScript limitScript; + + @Autowired + public void setRedisTemplate1(RedisTemplate redisTemplate) + { + this.redisTemplate = redisTemplate; + } + + @Autowired + public void setLimitScript(RedisScript limitScript) + { + this.limitScript = limitScript; + } + + @Before("@annotation(rateLimiter)") + public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable + { + int time = rateLimiter.time(); + int count = rateLimiter.count(); + + String combineKey = getCombineKey(rateLimiter, point); + List keys = Collections.singletonList(combineKey); + try + { + Long number = redisTemplate.execute(limitScript, keys, count, time); + if (StringUtils.isNull(number) || number.intValue() > count) + { + throw new ServiceException("访问过于频繁,请稍候再试"); + } + log.info("限制请求'{}',当前请求'{}',缓存key'{}'", count, number.intValue(), combineKey); + } + catch (ServiceException e) + { + throw e; + } + catch (Exception e) + { + throw new RuntimeException("服务器限流异常,请稍候再试"); + } + } + + public String getCombineKey(RateLimiter rateLimiter, JoinPoint point) + { + StringBuffer stringBuffer = new StringBuffer(rateLimiter.key()); + if (rateLimiter.limitType() == LimitType.IP) + { + stringBuffer.append(IpUtils.getIpAddr()).append("-"); + } + MethodSignature signature = (MethodSignature) point.getSignature(); + Method method = signature.getMethod(); + Class targetClass = method.getDeclaringClass(); + stringBuffer.append(targetClass.getName()).append("-").append(method.getName()); + return stringBuffer.toString(); + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/config/ApplicationConfig.java b/staffing-framework/src/main/java/com/staffing/framework/config/ApplicationConfig.java new file mode 100644 index 0000000..109be5c --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/config/ApplicationConfig.java @@ -0,0 +1,30 @@ +package com.staffing.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 staffing + */ +@Configuration +// 表示通过aop框架暴露该代理对象,AopContext能够访问 +@EnableAspectJAutoProxy(exposeProxy = true) +// 指定要扫描的Mapper类的包的路径 +@MapperScan("com.staffing.**.mapper") +public class ApplicationConfig +{ + /** + * 时区配置 + */ + @Bean + public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() + { + return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault()); + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/config/CaptchaConfig.java b/staffing-framework/src/main/java/com/staffing/framework/config/CaptchaConfig.java new file mode 100644 index 0000000..d7eca30 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/config/CaptchaConfig.java @@ -0,0 +1,83 @@ +package com.staffing.framework.config; + +import java.util.Properties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import com.google.code.kaptcha.impl.DefaultKaptcha; +import com.google.code.kaptcha.util.Config; +import static com.google.code.kaptcha.Constants.*; + +/** + * 验证码配置 + * + * @author staffing + */ +@Configuration +public class CaptchaConfig +{ + @Bean(name = "captchaProducer") + public DefaultKaptcha getKaptchaBean() + { + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + Properties properties = new Properties(); + // 是否有边框 默认为true 我们可以自己设置yes,no + properties.setProperty(KAPTCHA_BORDER, "yes"); + // 验证码文本字符颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black"); + // 验证码图片宽度 默认为200 + properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); + // 验证码图片高度 默认为50 + properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); + // 验证码文本字符大小 默认为40 + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38"); + // KAPTCHA_SESSION_KEY + properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode"); + // 验证码文本字符长度 默认为5 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4"); + // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); + // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy + properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); + Config config = new Config(properties); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } + + @Bean(name = "captchaProducerMath") + public DefaultKaptcha getKaptchaBeanMath() + { + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + Properties properties = new Properties(); + // 是否有边框 默认为true 我们可以自己设置yes,no + properties.setProperty(KAPTCHA_BORDER, "yes"); + // 边框颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90"); + // 验证码文本字符颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue"); + // 验证码图片宽度 默认为200 + properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); + // 验证码图片高度 默认为50 + properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); + // 验证码文本字符大小 默认为40 + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35"); + // KAPTCHA_SESSION_KEY + properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath"); + // 验证码文本生成器 + properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.staffing.framework.config.KaptchaTextCreator"); + // 验证码文本字符间距 默认为2 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3"); + // 验证码文本字符长度 默认为5 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6"); + // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); + // 验证码噪点颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_NOISE_COLOR, "white"); + // 干扰实现类 + properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise"); + // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy + properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); + Config config = new Config(properties); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/config/DruidConfig.java b/staffing-framework/src/main/java/com/staffing/framework/config/DruidConfig.java new file mode 100644 index 0000000..43d869c --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/config/DruidConfig.java @@ -0,0 +1,126 @@ +package com.staffing.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.staffing.common.enums.DataSourceType; +import com.staffing.common.utils.spring.SpringUtils; +import com.staffing.framework.config.properties.DruidProperties; +import com.staffing.framework.datasource.DynamicDataSource; + +/** + * druid 配置多数据源 + * + * @author staffing + */ +@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 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 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); + // 正则替换banner, 除去底部的广告信息 + text = text.replaceAll("
", ""); + text = text.replaceAll("powered.*?shrek.wang", ""); + response.getWriter().write(text); + } + @Override + public void destroy() + { + } + }; + FilterRegistrationBean registrationBean = new FilterRegistrationBean(); + registrationBean.setFilter(filter); + registrationBean.addUrlPatterns(commonJsPattern); + return registrationBean; + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/config/FastJson2JsonRedisSerializer.java b/staffing-framework/src/main/java/com/staffing/framework/config/FastJson2JsonRedisSerializer.java new file mode 100644 index 0000000..48f5d8a --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/config/FastJson2JsonRedisSerializer.java @@ -0,0 +1,52 @@ +package com.staffing.framework.config; + +import java.nio.charset.Charset; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.SerializationException; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONReader; +import com.alibaba.fastjson2.JSONWriter; +import com.alibaba.fastjson2.filter.Filter; +import com.staffing.common.constant.Constants; + +/** + * Redis使用FastJson序列化 + * + * @author staffing + */ +public class FastJson2JsonRedisSerializer implements RedisSerializer +{ + public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); + + static final Filter AUTO_TYPE_FILTER = JSONReader.autoTypeFilter(Constants.JSON_WHITELIST_STR); + + private Class clazz; + + public FastJson2JsonRedisSerializer(Class clazz) + { + super(); + this.clazz = clazz; + } + + @Override + public byte[] serialize(T t) throws SerializationException + { + if (t == null) + { + return new byte[0]; + } + return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET); + } + + @Override + 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, AUTO_TYPE_FILTER); + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/config/FilterConfig.java b/staffing-framework/src/main/java/com/staffing/framework/config/FilterConfig.java new file mode 100644 index 0000000..bca1100 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/config/FilterConfig.java @@ -0,0 +1,58 @@ +package com.staffing.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.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import com.staffing.common.filter.RepeatableFilter; +import com.staffing.common.filter.XssFilter; +import com.staffing.common.utils.StringUtils; + +/** + * Filter配置 + * + * @author staffing + */ +@Configuration +public class FilterConfig +{ + @Value("${xss.excludes}") + private String excludes; + + @Value("${xss.urlPatterns}") + private String urlPatterns; + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Bean + @ConditionalOnProperty(value = "xss.enabled", havingValue = "true") + 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(FilterRegistrationBean.HIGHEST_PRECEDENCE); + Map initParameters = new HashMap(); + initParameters.put("excludes", excludes); + registration.setInitParameters(initParameters); + return registration; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Bean + public FilterRegistrationBean someFilterRegistration() + { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setFilter(new RepeatableFilter()); + registration.addUrlPatterns("/*"); + registration.setName("repeatableFilter"); + registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE); + return registration; + } + +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/config/I18nConfig.java b/staffing-framework/src/main/java/com/staffing/framework/config/I18nConfig.java new file mode 100644 index 0000000..0bf7336 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/config/I18nConfig.java @@ -0,0 +1,43 @@ +package com.staffing.framework.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; +import org.springframework.web.servlet.i18n.SessionLocaleResolver; +import com.staffing.common.constant.Constants; + +/** + * 资源文件配置加载 + * + * @author staffing + */ +@Configuration +public class I18nConfig implements WebMvcConfigurer +{ + @Bean + public LocaleResolver localeResolver() + { + SessionLocaleResolver slr = new SessionLocaleResolver(); + // 默认语言 + slr.setDefaultLocale(Constants.DEFAULT_LOCALE); + return slr; + } + + @Bean + public LocaleChangeInterceptor localeChangeInterceptor() + { + LocaleChangeInterceptor lci = new LocaleChangeInterceptor(); + // 参数名 + lci.setParamName("lang"); + return lci; + } + + @Override + public void addInterceptors(InterceptorRegistry registry) + { + registry.addInterceptor(localeChangeInterceptor()); + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/config/KaptchaTextCreator.java b/staffing-framework/src/main/java/com/staffing/framework/config/KaptchaTextCreator.java new file mode 100644 index 0000000..70aa82f --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/config/KaptchaTextCreator.java @@ -0,0 +1,68 @@ +package com.staffing.framework.config; + +import java.util.Random; +import com.google.code.kaptcha.text.impl.DefaultTextCreator; + +/** + * 验证码文本生成器 + * + * @author staffing + */ +public class KaptchaTextCreator extends DefaultTextCreator +{ + private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(","); + + @Override + public String getText() + { + Integer result = 0; + Random random = new Random(); + int x = random.nextInt(10); + int y = random.nextInt(10); + StringBuilder suChinese = new StringBuilder(); + int randomoperands = random.nextInt(3); + if (randomoperands == 0) + { + result = x * y; + suChinese.append(CNUMBERS[x]); + suChinese.append("*"); + suChinese.append(CNUMBERS[y]); + } + else if (randomoperands == 1) + { + if ((x != 0) && y % x == 0) + { + result = y / x; + suChinese.append(CNUMBERS[y]); + suChinese.append("/"); + suChinese.append(CNUMBERS[x]); + } + else + { + result = x + y; + suChinese.append(CNUMBERS[x]); + suChinese.append("+"); + suChinese.append(CNUMBERS[y]); + } + } + else + { + if (x >= y) + { + result = x - y; + suChinese.append(CNUMBERS[x]); + suChinese.append("-"); + suChinese.append(CNUMBERS[y]); + } + else + { + result = y - x; + suChinese.append(CNUMBERS[y]); + suChinese.append("-"); + suChinese.append(CNUMBERS[x]); + } + } + suChinese.append("=?@" + result); + return suChinese.toString(); + } +} \ No newline at end of file diff --git a/staffing-framework/src/main/java/com/staffing/framework/config/MyBatisConfig.java b/staffing-framework/src/main/java/com/staffing/framework/config/MyBatisConfig.java new file mode 100644 index 0000000..2c1fed2 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/config/MyBatisConfig.java @@ -0,0 +1,132 @@ +package com.staffing.framework.config; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +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.DefaultResourceLoader; +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; +import com.staffing.common.utils.StringUtils; + +/** + * Mybatis支持*匹配扫描包 + * + * @author staffing + */ +@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 allResult = new ArrayList(); + try + { + for (String aliasesPackage : typeAliasesPackage.split(",")) + { + List result = new ArrayList(); + 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 hashResult = new HashSet(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; + } + + public Resource[] resolveMapperLocations(String[] mapperLocations) + { + ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + List resources = new ArrayList(); + if (mapperLocations != null) + { + for (String mapperLocation : mapperLocations) + { + try + { + Resource[] mappers = resourceResolver.getResources(mapperLocation); + resources.addAll(Arrays.asList(mappers)); + } + catch (IOException e) + { + // ignore + } + } + } + return resources.toArray(new Resource[resources.size()]); + } + + @Bean + public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception + { + String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage"); + String mapperLocations = env.getProperty("mybatis.mapperLocations"); + String configLocation = env.getProperty("mybatis.configLocation"); + typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage); + VFS.addImplClass(SpringBootVFS.class); + + final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); + sessionFactory.setDataSource(dataSource); + sessionFactory.setTypeAliasesPackage(typeAliasesPackage); + sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ","))); + sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation)); + return sessionFactory.getObject(); + } +} \ No newline at end of file diff --git a/staffing-framework/src/main/java/com/staffing/framework/config/RedisConfig.java b/staffing-framework/src/main/java/com/staffing/framework/config/RedisConfig.java new file mode 100644 index 0000000..4bed748 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/config/RedisConfig.java @@ -0,0 +1,69 @@ +package com.staffing.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.core.script.DefaultRedisScript; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * redis配置 + * + * @author staffing + */ +@Configuration +@EnableCaching +public class RedisConfig extends CachingConfigurerSupport +{ + @Bean + @SuppressWarnings(value = { "unchecked", "rawtypes" }) + public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) + { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(connectionFactory); + + FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); + + // 使用StringRedisSerializer来序列化和反序列化redis的key值 + template.setKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(serializer); + + // Hash的key也采用StringRedisSerializer的序列化方式 + template.setHashKeySerializer(new StringRedisSerializer()); + template.setHashValueSerializer(serializer); + + template.afterPropertiesSet(); + return template; + } + + @Bean + public DefaultRedisScript limitScript() + { + DefaultRedisScript redisScript = new DefaultRedisScript<>(); + redisScript.setScriptText(limitScriptText()); + redisScript.setResultType(Long.class); + return redisScript; + } + + /** + * 限流脚本 + */ + private String limitScriptText() + { + return "local key = KEYS[1]\n" + + "local count = tonumber(ARGV[1])\n" + + "local time = tonumber(ARGV[2])\n" + + "local current = redis.call('get', key);\n" + + "if current and tonumber(current) > count then\n" + + " return tonumber(current);\n" + + "end\n" + + "current = redis.call('incr', key)\n" + + "if tonumber(current) == 1 then\n" + + " redis.call('expire', key, time)\n" + + "end\n" + + "return tonumber(current);"; + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/config/ResourcesConfig.java b/staffing-framework/src/main/java/com/staffing/framework/config/ResourcesConfig.java new file mode 100644 index 0000000..950d569 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/config/ResourcesConfig.java @@ -0,0 +1,73 @@ +package com.staffing.framework.config; + +import java.util.concurrent.TimeUnit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.CacheControl; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; +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.staffing.common.config.StaffingConfig; +import com.staffing.common.constant.Constants; +import com.staffing.framework.interceptor.RepeatSubmitInterceptor; + +/** + * 通用配置 + * + * @author staffing + */ +@Configuration +public class ResourcesConfig implements WebMvcConfigurer +{ + @Autowired + private RepeatSubmitInterceptor repeatSubmitInterceptor; + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) + { + /** 本地文件上传路径 */ + registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**") + .addResourceLocations("file:" + StaffingConfig.getProfile() + "/"); + + /** swagger配置 */ + registry.addResourceHandler("/swagger-ui/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/") + .setCacheControl(CacheControl.maxAge(5, TimeUnit.HOURS).cachePublic());; + } + + /** + * 自定义拦截规则 + */ + @Override + public void addInterceptors(InterceptorRegistry registry) + { + registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**"); + } + + /** + * 跨域配置 + */ + @Bean + public CorsFilter corsFilter() + { + CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(true); + // 设置访问源地址 + config.addAllowedOriginPattern("*"); + // 设置访问源请求头 + config.addAllowedHeader("*"); + // 设置访问源请求方法 + config.addAllowedMethod("*"); + // 有效期 1800秒 + config.setMaxAge(1800L); + // 添加映射路径,拦截一切请求 + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", config); + // 返回新的CorsFilter + return new CorsFilter(source); + } +} \ No newline at end of file diff --git a/staffing-framework/src/main/java/com/staffing/framework/config/SecurityConfig.java b/staffing-framework/src/main/java/com/staffing/framework/config/SecurityConfig.java new file mode 100644 index 0000000..7e38209 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/config/SecurityConfig.java @@ -0,0 +1,143 @@ +package com.staffing.framework.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +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.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.authentication.logout.LogoutFilter; +import org.springframework.web.filter.CorsFilter; +import com.staffing.framework.config.properties.PermitAllUrlProperties; +import com.staffing.framework.security.filter.JwtAuthenticationTokenFilter; +import com.staffing.framework.security.handle.AuthenticationEntryPointImpl; +import com.staffing.framework.security.handle.LogoutSuccessHandlerImpl; + +/** + * spring security配置 + * + * @author staffing + */ +@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true) +@Configuration +public class SecurityConfig +{ + /** + * 自定义用户认证逻辑 + */ + @Autowired + private UserDetailsService userDetailsService; + + /** + * 认证失败处理类 + */ + @Autowired + private AuthenticationEntryPointImpl unauthorizedHandler; + + /** + * 退出处理类 + */ + @Autowired + private LogoutSuccessHandlerImpl logoutSuccessHandler; + + /** + * token认证过滤器 + */ + @Autowired + private JwtAuthenticationTokenFilter authenticationTokenFilter; + + /** + * 跨域过滤器 + */ + @Autowired + private CorsFilter corsFilter; + + /** + * 允许匿名访问的地址 + */ + @Autowired + private PermitAllUrlProperties permitAllUrl; + + /** + * 身份验证实现 + */ + @Bean + public AuthenticationManager authenticationManager() + { + DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider(); + daoAuthenticationProvider.setUserDetailsService(userDetailsService); + daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder()); + return new ProviderManager(daoAuthenticationProvider); + } + + /** + * anyRequest | 匹配所有请求路径 + * access | SpringEl表达式结果为true时可以访问 + * anonymous | 匿名可以访问 + * denyAll | 用户不能访问 + * fullyAuthenticated | 用户完全认证可以访问(非remember-me下自动登录) + * hasAnyAuthority | 如果有参数,参数表示权限,则其中任何一个权限可以访问 + * hasAnyRole | 如果有参数,参数表示角色,则其中任何一个角色可以访问 + * hasAuthority | 如果有参数,参数表示权限,则其权限可以访问 + * hasIpAddress | 如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问 + * hasRole | 如果有参数,参数表示角色,则其角色可以访问 + * permitAll | 用户可以任意访问 + * rememberMe | 允许通过remember-me登录的用户访问 + * authenticated | 用户登录后可访问 + */ + @Bean + protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception + { + return httpSecurity + // CSRF禁用,因为不使用session + .csrf(csrf -> csrf.disable()) + // 禁用HTTP响应标头 + .headers((headersCustomizer) -> { + headersCustomizer.cacheControl(cache -> cache.disable()).frameOptions(options -> options.sameOrigin()); + }) + // 认证失败处理类 + .exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler)) + // 基于token,所以不需要session + .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + // 注解标记允许匿名访问的url + .authorizeHttpRequests((requests) -> { + permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll()); + // 对于登录login 注册register 验证码captchaImage 允许匿名访问 , "/employee/**/**", "/employee/**", "/merchant/**/**", "/merchant/**" + requests.antMatchers("/login", "/register", "/captchaImage" + , "/employee/task/getTask" + , "/employee/user/login", "/employee/user/wxlogin", "/employee/user/register", "/employee/user/captchaImage" + , "/merchant/user/login", "/merchant/user/wxlogin", "/merchant/user/register", "/merchant/user/captchaImage" + , "/merchant/fund/fxResult").permitAll() + // 静态资源,可匿名访问 + .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() + .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() + // 除上面外的所有请求全部需要鉴权认证 + .anyRequest().authenticated(); + }) + // 添加Logout filter + .logout(logout -> logout.logoutUrl("/**/logout").logoutSuccessHandler(logoutSuccessHandler)) + // 添加JWT filter + .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class) + // 添加CORS filter + .addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class) + .addFilterBefore(corsFilter, LogoutFilter.class) + .build(); + } + + /** + * 强散列哈希加密实现 + */ + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder() + { + return new BCryptPasswordEncoder(); + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/config/ServerConfig.java b/staffing-framework/src/main/java/com/staffing/framework/config/ServerConfig.java new file mode 100644 index 0000000..d3ca890 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/config/ServerConfig.java @@ -0,0 +1,32 @@ +package com.staffing.framework.config; + +import javax.servlet.http.HttpServletRequest; +import org.springframework.stereotype.Component; +import com.staffing.common.utils.ServletUtils; + +/** + * 服务相关配置 + * + * @author staffing + */ +@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/staffing-framework/src/main/java/com/staffing/framework/config/ThreadPoolConfig.java b/staffing-framework/src/main/java/com/staffing/framework/config/ThreadPoolConfig.java new file mode 100644 index 0000000..18f2b4d --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/config/ThreadPoolConfig.java @@ -0,0 +1,63 @@ +package com.staffing.framework.config; + +import com.staffing.common.utils.Threads; +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 java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * 线程池配置 + * + * @author staffing + **/ +@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(), + new ThreadPoolExecutor.CallerRunsPolicy()) + { + @Override + protected void afterExecute(Runnable r, Throwable t) + { + super.afterExecute(r, t); + Threads.printException(r, t); + } + }; + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/config/properties/DruidProperties.java b/staffing-framework/src/main/java/com/staffing/framework/config/properties/DruidProperties.java new file mode 100644 index 0000000..b1fd0dc --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/config/properties/DruidProperties.java @@ -0,0 +1,89 @@ +package com.staffing.framework.config.properties; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import com.alibaba.druid.pool.DruidDataSource; + +/** + * druid 配置属性 + * + * @author staffing + */ +@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.connectTimeout}") + private int connectTimeout; + + @Value("${spring.datasource.druid.socketTimeout}") + private int socketTimeout; + + @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.setConnectTimeout(connectTimeout); + + /** 配置网络超时时间,等待数据库操作完成的网络超时时间,单位是毫秒 */ + datasource.setSocketTimeout(socketTimeout); + + /** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */ + datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); + + /** 配置一个连接在池中最小、最大生存的时间,单位是毫秒 */ + datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); + datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis); + + /** + * 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。 + */ + datasource.setValidationQuery(validationQuery); + /** 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 */ + datasource.setTestWhileIdle(testWhileIdle); + /** 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */ + datasource.setTestOnBorrow(testOnBorrow); + /** 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */ + datasource.setTestOnReturn(testOnReturn); + return datasource; + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/config/properties/PermitAllUrlProperties.java b/staffing-framework/src/main/java/com/staffing/framework/config/properties/PermitAllUrlProperties.java new file mode 100644 index 0000000..dfb30e4 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/config/properties/PermitAllUrlProperties.java @@ -0,0 +1,73 @@ +package com.staffing.framework.config.properties; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.regex.Pattern; +import org.apache.commons.lang3.RegExUtils; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; +import com.staffing.common.annotation.Anonymous; + +/** + * 设置Anonymous注解允许匿名访问的url + * + * @author staffing + */ +@Configuration +public class PermitAllUrlProperties implements InitializingBean, ApplicationContextAware +{ + private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}"); + + private ApplicationContext applicationContext; + + private List urls = new ArrayList<>(); + + public String ASTERISK = "*"; + + @Override + public void afterPropertiesSet() + { + RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class); + Map map = mapping.getHandlerMethods(); + + map.keySet().forEach(info -> { + HandlerMethod handlerMethod = map.get(info); + + // 获取方法上边的注解 替代path variable 为 * + Anonymous method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class); + Optional.ofNullable(method).ifPresent(anonymous -> Objects.requireNonNull(info.getPatternsCondition().getPatterns()) + .forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK)))); + + // 获取类上边的注解, 替代path variable 为 * + Anonymous controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class); + Optional.ofNullable(controller).ifPresent(anonymous -> Objects.requireNonNull(info.getPatternsCondition().getPatterns()) + .forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK)))); + }); + } + + @Override + public void setApplicationContext(ApplicationContext context) throws BeansException + { + this.applicationContext = context; + } + + public List getUrls() + { + return urls; + } + + public void setUrls(List urls) + { + this.urls = urls; + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/datasource/DynamicDataSource.java b/staffing-framework/src/main/java/com/staffing/framework/datasource/DynamicDataSource.java new file mode 100644 index 0000000..dd0995a --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/datasource/DynamicDataSource.java @@ -0,0 +1,26 @@ +package com.staffing.framework.datasource; + +import java.util.Map; +import javax.sql.DataSource; +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; + +/** + * 动态数据源 + * + * @author staffing + */ +public class DynamicDataSource extends AbstractRoutingDataSource +{ + public DynamicDataSource(DataSource defaultTargetDataSource, Map 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/staffing-framework/src/main/java/com/staffing/framework/datasource/DynamicDataSourceContextHolder.java b/staffing-framework/src/main/java/com/staffing/framework/datasource/DynamicDataSourceContextHolder.java new file mode 100644 index 0000000..b2689e3 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/datasource/DynamicDataSourceContextHolder.java @@ -0,0 +1,45 @@ +package com.staffing.framework.datasource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 数据源切换处理 + * + * @author staffing + */ +public class DynamicDataSourceContextHolder +{ + public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class); + + /** + * 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本, + * 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 + */ + private static final ThreadLocal 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/staffing-framework/src/main/java/com/staffing/framework/interceptor/RepeatSubmitInterceptor.java b/staffing-framework/src/main/java/com/staffing/framework/interceptor/RepeatSubmitInterceptor.java new file mode 100644 index 0000000..a4b8bca --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/interceptor/RepeatSubmitInterceptor.java @@ -0,0 +1,56 @@ +package com.staffing.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.HandlerInterceptor; +import com.alibaba.fastjson2.JSON; +import com.staffing.common.annotation.RepeatSubmit; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.utils.ServletUtils; + +/** + * 防止重复提交拦截器 + * + * @author staffing + */ +@Component +public abstract class RepeatSubmitInterceptor implements HandlerInterceptor +{ + @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, annotation)) + { + AjaxResult ajaxResult = AjaxResult.error(annotation.message()); + ServletUtils.renderString(response, JSON.toJSONString(ajaxResult)); + return false; + } + } + return true; + } + else + { + return true; + } + } + + /** + * 验证是否重复提交由子类实现具体的防重复提交的规则 + * + * @param request 请求信息 + * @param annotation 防重复注解参数 + * @return 结果 + * @throws Exception + */ + public abstract boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation); +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/interceptor/impl/SameUrlDataInterceptor.java b/staffing-framework/src/main/java/com/staffing/framework/interceptor/impl/SameUrlDataInterceptor.java new file mode 100644 index 0000000..5b47695 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/interceptor/impl/SameUrlDataInterceptor.java @@ -0,0 +1,110 @@ +package com.staffing.framework.interceptor.impl; + +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.alibaba.fastjson2.JSON; +import com.staffing.common.annotation.RepeatSubmit; +import com.staffing.common.constant.CacheConstants; +import com.staffing.common.core.redis.RedisCache; +import com.staffing.common.filter.RepeatedlyRequestWrapper; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.http.HttpHelper; +import com.staffing.framework.interceptor.RepeatSubmitInterceptor; + +/** + * 判断请求url和数据是否和上一次相同, + * 如果和上次相同,则是重复提交表单。 有效时间为10秒内。 + * + * @author staffing + */ +@Component +public class SameUrlDataInterceptor extends RepeatSubmitInterceptor +{ + public final String REPEAT_PARAMS = "repeatParams"; + + public final String REPEAT_TIME = "repeatTime"; + + // 令牌自定义标识 + @Value("${token.header}") + private String header; + + @Autowired + private RedisCache redisCache; + + @SuppressWarnings("unchecked") + @Override + public boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation) + { + String nowParams = ""; + if (request instanceof RepeatedlyRequestWrapper) + { + RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request; + nowParams = HttpHelper.getBodyString(repeatedlyRequest); + } + + // body参数为空,获取Parameter的数据 + if (StringUtils.isEmpty(nowParams)) + { + nowParams = JSON.toJSONString(request.getParameterMap()); + } + Map nowDataMap = new HashMap(); + nowDataMap.put(REPEAT_PARAMS, nowParams); + nowDataMap.put(REPEAT_TIME, System.currentTimeMillis()); + + // 请求地址(作为存放cache的key值) + String url = request.getRequestURI(); + + // 唯一值(没有消息头则使用请求地址) + String submitKey = StringUtils.trimToEmpty(request.getHeader(header)); + + // 唯一标识(指定key + url + 消息头) + String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY + url + submitKey; + + Object sessionObj = redisCache.getCacheObject(cacheRepeatKey); + if (sessionObj != null) + { + Map sessionMap = (Map) sessionObj; + if (sessionMap.containsKey(url)) + { + Map preDataMap = (Map) sessionMap.get(url); + if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap, annotation.interval())) + { + return true; + } + } + } + Map cacheMap = new HashMap(); + cacheMap.put(url, nowDataMap); + redisCache.setCacheObject(cacheRepeatKey, cacheMap, annotation.interval(), TimeUnit.MILLISECONDS); + return false; + } + + /** + * 判断参数是否相同 + */ + private boolean compareParams(Map nowMap, Map preMap) + { + String nowParams = (String) nowMap.get(REPEAT_PARAMS); + String preParams = (String) preMap.get(REPEAT_PARAMS); + return nowParams.equals(preParams); + } + + /** + * 判断两次间隔时间 + */ + private boolean compareTime(Map nowMap, Map preMap, int interval) + { + long time1 = (Long) nowMap.get(REPEAT_TIME); + long time2 = (Long) preMap.get(REPEAT_TIME); + if ((time1 - time2) < interval) + { + return true; + } + return false; + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/manager/AsyncManager.java b/staffing-framework/src/main/java/com/staffing/framework/manager/AsyncManager.java new file mode 100644 index 0000000..dbe2e63 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/manager/AsyncManager.java @@ -0,0 +1,55 @@ +package com.staffing.framework.manager; + +import java.util.TimerTask; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import com.staffing.common.utils.Threads; +import com.staffing.common.utils.spring.SpringUtils; + +/** + * 异步任务管理器 + * + * @author staffing + */ +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/staffing-framework/src/main/java/com/staffing/framework/manager/ShutdownManager.java b/staffing-framework/src/main/java/com/staffing/framework/manager/ShutdownManager.java new file mode 100644 index 0000000..12097db --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/manager/ShutdownManager.java @@ -0,0 +1,39 @@ +package com.staffing.framework.manager; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import javax.annotation.PreDestroy; + +/** + * 确保应用退出时能关闭后台线程 + * + * @author staffing + */ +@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/staffing-framework/src/main/java/com/staffing/framework/manager/factory/AsyncFactory.java b/staffing-framework/src/main/java/com/staffing/framework/manager/factory/AsyncFactory.java new file mode 100644 index 0000000..053f910 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/manager/factory/AsyncFactory.java @@ -0,0 +1,102 @@ +package com.staffing.framework.manager.factory; + +import java.util.TimerTask; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.staffing.common.constant.Constants; +import com.staffing.common.utils.LogUtils; +import com.staffing.common.utils.ServletUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.ip.AddressUtils; +import com.staffing.common.utils.ip.IpUtils; +import com.staffing.common.utils.spring.SpringUtils; +import com.staffing.system.domain.SysLogininfor; +import com.staffing.system.domain.SysOperLog; +import com.staffing.system.service.ISysLogininforService; +import com.staffing.system.service.ISysOperLogService; +import eu.bitwalker.useragentutils.UserAgent; + +/** + * 异步工厂(产生任务用) + * + * @author staffing + */ +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(); + 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 (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) + { + 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/staffing-framework/src/main/java/com/staffing/framework/security/context/AuthenticationContextHolder.java b/staffing-framework/src/main/java/com/staffing/framework/security/context/AuthenticationContextHolder.java new file mode 100644 index 0000000..1dcd894 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/security/context/AuthenticationContextHolder.java @@ -0,0 +1,28 @@ +package com.staffing.framework.security.context; + +import org.springframework.security.core.Authentication; + +/** + * 身份验证信息 + * + * @author staffing + */ +public class AuthenticationContextHolder +{ + private static final ThreadLocal contextHolder = new ThreadLocal<>(); + + public static Authentication getContext() + { + return contextHolder.get(); + } + + public static void setContext(Authentication context) + { + contextHolder.set(context); + } + + public static void clearContext() + { + contextHolder.remove(); + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/security/context/PermissionContextHolder.java b/staffing-framework/src/main/java/com/staffing/framework/security/context/PermissionContextHolder.java new file mode 100644 index 0000000..4da71fb --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/security/context/PermissionContextHolder.java @@ -0,0 +1,27 @@ +package com.staffing.framework.security.context; + +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import com.staffing.common.core.text.Convert; + +/** + * 权限信息 + * + * @author staffing + */ +public class PermissionContextHolder +{ + private static final String PERMISSION_CONTEXT_ATTRIBUTES = "PERMISSION_CONTEXT"; + + public static void setContext(String permission) + { + RequestContextHolder.currentRequestAttributes().setAttribute(PERMISSION_CONTEXT_ATTRIBUTES, permission, + RequestAttributes.SCOPE_REQUEST); + } + + public static String getContext() + { + return Convert.toStr(RequestContextHolder.currentRequestAttributes().getAttribute(PERMISSION_CONTEXT_ATTRIBUTES, + RequestAttributes.SCOPE_REQUEST)); + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/security/filter/JwtAuthenticationTokenFilter.java b/staffing-framework/src/main/java/com/staffing/framework/security/filter/JwtAuthenticationTokenFilter.java new file mode 100644 index 0000000..dc4f140 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/security/filter/JwtAuthenticationTokenFilter.java @@ -0,0 +1,44 @@ +package com.staffing.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.staffing.common.core.domain.model.LoginUser; +import com.staffing.common.utils.SecurityUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.framework.web.service.TokenService; + +/** + * token过滤器 验证token有效性 + * + * @author staffing + */ +@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/staffing-framework/src/main/java/com/staffing/framework/security/handle/AuthenticationEntryPointImpl.java b/staffing-framework/src/main/java/com/staffing/framework/security/handle/AuthenticationEntryPointImpl.java new file mode 100644 index 0000000..ac02765 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/security/handle/AuthenticationEntryPointImpl.java @@ -0,0 +1,34 @@ +package com.staffing.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.fastjson2.JSON; +import com.staffing.common.constant.HttpStatus; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.utils.ServletUtils; +import com.staffing.common.utils.StringUtils; + +/** + * 认证失败处理类 返回未授权 + * + * @author staffing + */ +@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/staffing-framework/src/main/java/com/staffing/framework/security/handle/LogoutSuccessHandlerImpl.java b/staffing-framework/src/main/java/com/staffing/framework/security/handle/LogoutSuccessHandlerImpl.java new file mode 100644 index 0000000..b10fbf7 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/security/handle/LogoutSuccessHandlerImpl.java @@ -0,0 +1,53 @@ +package com.staffing.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.fastjson2.JSON; +import com.staffing.common.constant.Constants; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.domain.model.LoginUser; +import com.staffing.common.utils.MessageUtils; +import com.staffing.common.utils.ServletUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.framework.manager.AsyncManager; +import com.staffing.framework.manager.factory.AsyncFactory; +import com.staffing.framework.web.service.TokenService; + +/** + * 自定义退出处理类 返回成功 + * + * @author staffing + */ +@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, MessageUtils.message("user.logout.success"))); + } + ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.success(MessageUtils.message("user.logout.success")))); + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/web/domain/Server.java b/staffing-framework/src/main/java/com/staffing/framework/web/domain/Server.java new file mode 100644 index 0000000..08cf3cb --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/web/domain/Server.java @@ -0,0 +1,240 @@ +package com.staffing.framework.web.domain; + +import java.net.UnknownHostException; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; +import com.staffing.common.utils.Arith; +import com.staffing.common.utils.ip.IpUtils; +import com.staffing.framework.web.domain.server.Cpu; +import com.staffing.framework.web.domain.server.Jvm; +import com.staffing.framework.web.domain.server.Mem; +import com.staffing.framework.web.domain.server.Sys; +import com.staffing.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 staffing + */ +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 sysFiles = new LinkedList(); + + 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 getSysFiles() + { + return sysFiles; + } + + public void setSysFiles(List 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(); + List 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/staffing-framework/src/main/java/com/staffing/framework/web/domain/server/Cpu.java b/staffing-framework/src/main/java/com/staffing/framework/web/domain/server/Cpu.java new file mode 100644 index 0000000..7befdc4 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/web/domain/server/Cpu.java @@ -0,0 +1,101 @@ +package com.staffing.framework.web.domain.server; + +import com.staffing.common.utils.Arith; + +/** + * CPU相关信息 + * + * @author staffing + */ +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/staffing-framework/src/main/java/com/staffing/framework/web/domain/server/Jvm.java b/staffing-framework/src/main/java/com/staffing/framework/web/domain/server/Jvm.java new file mode 100644 index 0000000..de947b8 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/web/domain/server/Jvm.java @@ -0,0 +1,130 @@ +package com.staffing.framework.web.domain.server; + +import java.lang.management.ManagementFactory; +import com.staffing.common.utils.Arith; +import com.staffing.common.utils.DateUtils; + +/** + * JVM相关信息 + * + * @author staffing + */ +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.timeDistance(DateUtils.getNowDate(), DateUtils.getServerStartDate()); + } + + /** + * 运行参数 + */ + public String getInputArgs() + { + return ManagementFactory.getRuntimeMXBean().getInputArguments().toString(); + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/web/domain/server/Mem.java b/staffing-framework/src/main/java/com/staffing/framework/web/domain/server/Mem.java new file mode 100644 index 0000000..a318b15 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/web/domain/server/Mem.java @@ -0,0 +1,61 @@ +package com.staffing.framework.web.domain.server; + +import com.staffing.common.utils.Arith; + +/** + * 內存相关信息 + * + * @author staffing + */ +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/staffing-framework/src/main/java/com/staffing/framework/web/domain/server/Sys.java b/staffing-framework/src/main/java/com/staffing/framework/web/domain/server/Sys.java new file mode 100644 index 0000000..eec9967 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/web/domain/server/Sys.java @@ -0,0 +1,84 @@ +package com.staffing.framework.web.domain.server; + +/** + * 系统相关信息 + * + * @author staffing + */ +public class Sys +{ + /** + * 服务器名称 + */ + private String computerName; + + /** + * 服务器Ip + */ + 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/staffing-framework/src/main/java/com/staffing/framework/web/domain/server/SysFile.java b/staffing-framework/src/main/java/com/staffing/framework/web/domain/server/SysFile.java new file mode 100644 index 0000000..a9859c1 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/web/domain/server/SysFile.java @@ -0,0 +1,114 @@ +package com.staffing.framework.web.domain.server; + +/** + * 系统文件相关信息 + * + * @author staffing + */ +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/staffing-framework/src/main/java/com/staffing/framework/web/exception/GlobalExceptionHandler.java b/staffing-framework/src/main/java/com/staffing/framework/web/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..d7766f3 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/web/exception/GlobalExceptionHandler.java @@ -0,0 +1,145 @@ +package com.staffing.framework.web.exception; + +import javax.servlet.http.HttpServletRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.validation.BindException; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.MissingPathVariableException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; +import com.staffing.common.constant.HttpStatus; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.text.Convert; +import com.staffing.common.exception.DemoModeException; +import com.staffing.common.exception.ServiceException; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.html.EscapeUtil; + +/** + * 全局异常处理器 + * + * @author staffing + */ +@RestControllerAdvice +public class GlobalExceptionHandler +{ + private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); + + /** + * 权限校验异常 + */ + @ExceptionHandler(AccessDeniedException.class) + public AjaxResult handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',权限校验失败'{}'", requestURI, e.getMessage()); + return AjaxResult.error(HttpStatus.FORBIDDEN, "没有权限,请联系管理员授权"); + } + + /** + * 请求方式不支持 + */ + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) + public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, + HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod()); + return AjaxResult.error(e.getMessage()); + } + + /** + * 业务异常 + */ + @ExceptionHandler(ServiceException.class) + public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request) + { + log.error(e.getMessage(), e); + Integer code = e.getCode(); + return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage()); + } + + /** + * 请求路径中缺少必需的路径变量 + */ + @ExceptionHandler(MissingPathVariableException.class) + public AjaxResult handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI, e); + return AjaxResult.error(String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName())); + } + + /** + * 请求参数类型不匹配 + */ + @ExceptionHandler(MethodArgumentTypeMismatchException.class) + public AjaxResult handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + String value = Convert.toStr(e.getValue()); + if (StringUtils.isNotEmpty(value)) + { + value = EscapeUtil.clean(value); + } + log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e); + return AjaxResult.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), value)); + } + + /** + * 拦截未知的运行时异常 + */ + @ExceptionHandler(RuntimeException.class) + public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',发生未知异常.", requestURI, e); + return AjaxResult.error(e.getMessage()); + } + + /** + * 系统异常 + */ + @ExceptionHandler(Exception.class) + public AjaxResult handleException(Exception e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',发生系统异常.", requestURI, e); + return AjaxResult.error(e.getMessage()); + } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(BindException.class) + public AjaxResult handleBindException(BindException e) + { + log.error(e.getMessage(), e); + String message = e.getAllErrors().get(0).getDefaultMessage(); + return AjaxResult.error(message); + } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) + { + log.error(e.getMessage(), e); + String message = e.getBindingResult().getFieldError().getDefaultMessage(); + return AjaxResult.error(message); + } + + /** + * 演示模式异常 + */ + @ExceptionHandler(DemoModeException.class) + public AjaxResult handleDemoModeException(DemoModeException e) + { + return AjaxResult.error("演示模式,不允许操作"); + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/web/service/PermissionService.java b/staffing-framework/src/main/java/com/staffing/framework/web/service/PermissionService.java new file mode 100644 index 0000000..e7e79cf --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/web/service/PermissionService.java @@ -0,0 +1,159 @@ +package com.staffing.framework.web.service; + +import java.util.Set; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import com.staffing.common.constant.Constants; +import com.staffing.common.core.domain.entity.SysRole; +import com.staffing.common.core.domain.model.LoginUser; +import com.staffing.common.utils.SecurityUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.framework.security.context.PermissionContextHolder; + +/** + * staffing首创 自定义权限实现,ss取自SpringSecurity首字母 + * + * @author staffing + */ +@Service("ss") +public class PermissionService +{ + /** + * 验证用户是否具备某权限 + * + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + public boolean hasPermi(String permission) + { + if (StringUtils.isEmpty(permission)) + { + return false; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) + { + return false; + } + PermissionContextHolder.setContext(permission); + return hasPermissions(loginUser.getPermissions(), permission); + } + + /** + * 验证用户是否不具备某权限,与 hasPermi逻辑相反 + * + * @param permission 权限字符串 + * @return 用户是否不具备某权限 + */ + public boolean lacksPermi(String permission) + { + return hasPermi(permission) != true; + } + + /** + * 验证用户是否具有以下任意一个权限 + * + * @param permissions 以 PERMISSION_DELIMETER 为分隔符的权限列表 + * @return 用户是否具有以下任意一个权限 + */ + public boolean hasAnyPermi(String permissions) + { + if (StringUtils.isEmpty(permissions)) + { + return false; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) + { + return false; + } + PermissionContextHolder.setContext(permissions); + Set authorities = loginUser.getPermissions(); + for (String permission : permissions.split(Constants.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 = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) + { + return false; + } + for (SysRole sysRole : loginUser.getUser().getRoles()) + { + String roleKey = sysRole.getRoleKey(); + if (Constants.SUPER_ADMIN.equals(roleKey) || roleKey.equals(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 = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) + { + return false; + } + for (String role : roles.split(Constants.ROLE_DELIMETER)) + { + if (hasRole(role)) + { + return true; + } + } + return false; + } + + /** + * 判断是否包含权限 + * + * @param permissions 权限列表 + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + private boolean hasPermissions(Set permissions, String permission) + { + return permissions.contains(Constants.ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission)); + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/web/service/SysLoginService.java b/staffing-framework/src/main/java/com/staffing/framework/web/service/SysLoginService.java new file mode 100644 index 0000000..81e664e --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/web/service/SysLoginService.java @@ -0,0 +1,295 @@ +package com.staffing.framework.web.service; + +import javax.annotation.Resource; + +import com.staffing.common.core.domain.WxLogin; +import com.staffing.common.core.domain.WxPhone; +import com.staffing.common.core.domain.WxToken; +import com.staffing.common.enums.UserStatus; +import com.staffing.common.utils.WxUtil; +import com.staffing.custom.domain.StEmployee; +import com.staffing.custom.service.IStEmployeeService; +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.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; +import com.staffing.common.constant.CacheConstants; +import com.staffing.common.constant.Constants; +import com.staffing.common.constant.UserConstants; +import com.staffing.common.core.domain.entity.SysUser; +import com.staffing.common.core.domain.model.LoginUser; +import com.staffing.common.core.redis.RedisCache; +import com.staffing.common.exception.ServiceException; +import com.staffing.common.exception.user.BlackListException; +import com.staffing.common.exception.user.CaptchaException; +import com.staffing.common.exception.user.CaptchaExpireException; +import com.staffing.common.exception.user.UserNotExistsException; +import com.staffing.common.exception.user.UserPasswordNotMatchException; +import com.staffing.common.utils.DateUtils; +import com.staffing.common.utils.MessageUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.ip.IpUtils; +import com.staffing.framework.manager.AsyncManager; +import com.staffing.framework.manager.factory.AsyncFactory; +import com.staffing.framework.security.context.AuthenticationContextHolder; +import com.staffing.system.service.ISysConfigService; +import com.staffing.system.service.ISysUserService; + +import java.util.ArrayList; +import java.util.HashSet; + +/** + * 登录校验方法 + * + * @author staffing + */ +@Component +public class SysLoginService +{ + @Autowired + private TokenService tokenService; + + @Resource + private AuthenticationManager authenticationManager; + + @Autowired + private RedisCache redisCache; + + @Autowired + private ISysUserService userService; + + @Autowired + private ISysConfigService configService; + @Autowired + private IStEmployeeService stEmployeeService; + @Autowired + private SysPermissionService permissionService; + /** + * 登录验证 + * + * @param username 用户名 + * @param password 密码 + * @param code 验证码 + * @param uuid 唯一标识 + * @return 结果 + */ + public String login(String username, String password, String code, String uuid) + { + // 验证码校验 + validateCaptcha(username, code, uuid); + // 登录前置校验 + loginPreCheck(username, password); + // 用户验证 + Authentication authentication = null; + try + { + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password); + AuthenticationContextHolder.setContext(authenticationToken); + // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername + authentication = authenticationManager.authenticate(authenticationToken); + } + 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 ServiceException(e.getMessage()); + } + } + finally + { + AuthenticationContextHolder.clearContext(); + } + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); + LoginUser loginUser = (LoginUser) authentication.getPrincipal(); + recordLoginInfo(loginUser.getUserId()); + // 生成token + return tokenService.createToken(loginUser); + } + /** + * 登录验证 + * @return 结果 + */ + public String wxLogin(String loginCode, String phoneCode) + { + + // 登录前置校验 +// loginPreCheck(username, password); + // 用户验证 + LoginUser loginUser = null; + try + { + WxLogin login = WxUtil.login(loginCode); + WxPhone wxPhone = WxUtil.getPhoneNumber(phoneCode, login.getOpenid()); + String phoneNumber = wxPhone.getPhoneNumber(); + + StEmployee stEmployee = stEmployeeService.selectStEmployeeByPhone(phoneNumber); + if (stEmployee == null){ + stEmployee = new StEmployee(); + stEmployee.setPhone(phoneNumber); + stEmployee.setOpenId(login.getOpenid()); + stEmployee.setRealName("微信用户"); + stEmployeeService.insertStEmployee(stEmployee); + } + if (stEmployee.getOpenId() == null){ + stEmployee.setOpenId(login.getOpenid()); + stEmployeeService.updateStEmployee(stEmployee); + } + + SysUser user = new SysUser(); + user.setUserId(stEmployee.getId()); + user.setPhonenumber(stEmployee.getPhone()); + user.setIdCard(stEmployee.getIdCard()); + user.setNickName(stEmployee.getRealName()); + user.setOpenId(stEmployee.getOpenId()); + loginUser = new LoginUser(stEmployee.getId(), 0l, user, new HashSet<>()); + } + catch (Exception e) + { + throw e; + } + finally + { + AuthenticationContextHolder.clearContext(); + } + // 生成token + return tokenService.createToken(loginUser); + } + /** + * 登录验证 + * @return 结果 + */ + public String wxMerchantLogin(String loginCode, String phoneCode) + { + + // 登录前置校验 +// loginPreCheck(username, password); + // 用户验证 + LoginUser loginUser = null; + try + { + WxLogin login = WxUtil.login(loginCode); + WxPhone wxPhone = WxUtil.getPhoneNumber(phoneCode, login.getOpenid()); + String phoneNumber = wxPhone.getPhoneNumber(); + + SysUser user = userService.selectUserByPhone(phoneNumber); + if (StringUtils.isNull(user)) + { + throw new ServiceException(MessageUtils.message("user.not.exists")); + } + else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) + { + throw new ServiceException(MessageUtils.message("user.password.delete")); + } + else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) + { + throw new ServiceException(MessageUtils.message("user.blocked")); + } + + loginUser = createLoginUser(user); + + recordLoginInfo(loginUser.getUserId()); + } + catch (Exception e) + { + throw e; + } + finally + { + AuthenticationContextHolder.clearContext(); + } + // 生成token + return tokenService.createToken(loginUser); + } + public LoginUser createLoginUser(SysUser user) + { + return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user)); + } + + /** + * 校验验证码 + * + * @param username 用户名 + * @param code 验证码 + * @param uuid 唯一标识 + * @return 结果 + */ + public void validateCaptcha(String username, String code, String uuid) + { + boolean captchaEnabled = configService.selectCaptchaEnabled(); + if (captchaEnabled) + { + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); + String captcha = redisCache.getCacheObject(verifyKey); + if (captcha == null) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"))); + throw new CaptchaExpireException(); + } + redisCache.deleteObject(verifyKey); + if (!code.equalsIgnoreCase(captcha)) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"))); + throw new CaptchaException(); + } + } + } + + /** + * 登录前置校验 + * @param username 用户名 + * @param password 用户密码 + */ + public void loginPreCheck(String username, String password) + { + // 用户名或密码为空 错误 + if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null"))); + throw new UserNotExistsException(); + } + // 密码如果不在指定范围内 错误 + if (password.length() < UserConstants.PASSWORD_MIN_LENGTH + || password.length() > UserConstants.PASSWORD_MAX_LENGTH) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); + throw new UserPasswordNotMatchException(); + } + // 用户名不在指定范围内 错误 + if (username.length() < UserConstants.USERNAME_MIN_LENGTH + || username.length() > UserConstants.USERNAME_MAX_LENGTH) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); + throw new UserPasswordNotMatchException(); + } + // IP黑名单校验 + String blackStr = configService.selectConfigByKey("sys.login.blackIPList"); + if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked"))); + throw new BlackListException(); + } + } + + /** + * 记录登录信息 + * + * @param userId 用户ID + */ + public void recordLoginInfo(Long userId) + { + SysUser sysUser = new SysUser(); + sysUser.setUserId(userId); + sysUser.setLoginIp(IpUtils.getIpAddr()); + sysUser.setLoginDate(DateUtils.getNowDate()); + userService.updateUserProfile(sysUser); + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/web/service/SysPasswordService.java b/staffing-framework/src/main/java/com/staffing/framework/web/service/SysPasswordService.java new file mode 100644 index 0000000..2a338c4 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/web/service/SysPasswordService.java @@ -0,0 +1,86 @@ +package com.staffing.framework.web.service; + +import java.util.concurrent.TimeUnit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; +import com.staffing.common.constant.CacheConstants; +import com.staffing.common.core.domain.entity.SysUser; +import com.staffing.common.core.redis.RedisCache; +import com.staffing.common.exception.user.UserPasswordNotMatchException; +import com.staffing.common.exception.user.UserPasswordRetryLimitExceedException; +import com.staffing.common.utils.SecurityUtils; +import com.staffing.framework.security.context.AuthenticationContextHolder; + +/** + * 登录密码方法 + * + * @author staffing + */ +@Component +public class SysPasswordService +{ + @Autowired + private RedisCache redisCache; + + @Value(value = "${user.password.maxRetryCount}") + private int maxRetryCount; + + @Value(value = "${user.password.lockTime}") + private int lockTime; + + /** + * 登录账户密码错误次数缓存键名 + * + * @param username 用户名 + * @return 缓存键key + */ + private String getCacheKey(String username) + { + return CacheConstants.PWD_ERR_CNT_KEY + username; + } + + public void validate(SysUser user) + { + Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext(); + String username = usernamePasswordAuthenticationToken.getName(); + String password = usernamePasswordAuthenticationToken.getCredentials().toString(); + + Integer retryCount = redisCache.getCacheObject(getCacheKey(username)); + + if (retryCount == null) + { + retryCount = 0; + } + + if (retryCount >= Integer.valueOf(maxRetryCount).intValue()) + { + throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime); + } + + if (!matches(user, password)) + { + retryCount = retryCount + 1; + redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES); + throw new UserPasswordNotMatchException(); + } + else + { + clearLoginRecordCache(username); + } + } + + public boolean matches(SysUser user, String rawPassword) + { + return SecurityUtils.matchesPassword(rawPassword, user.getPassword()); + } + + public void clearLoginRecordCache(String loginName) + { + if (redisCache.hasKey(getCacheKey(loginName))) + { + redisCache.deleteObject(getCacheKey(loginName)); + } + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/web/service/SysPermissionService.java b/staffing-framework/src/main/java/com/staffing/framework/web/service/SysPermissionService.java new file mode 100644 index 0000000..2d7a7af --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/web/service/SysPermissionService.java @@ -0,0 +1,83 @@ +package com.staffing.framework.web.service; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import com.staffing.common.core.domain.entity.SysRole; +import com.staffing.common.core.domain.entity.SysUser; +import com.staffing.system.service.ISysMenuService; +import com.staffing.system.service.ISysRoleService; + +/** + * 用户权限处理 + * + * @author staffing + */ +@Component +public class SysPermissionService +{ + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysMenuService menuService; + + /** + * 获取角色数据权限 + * + * @param user 用户信息 + * @return 角色权限信息 + */ + public Set getRolePermission(SysUser user) + { + Set roles = new HashSet(); + // 管理员拥有所有权限 + if (user.isAdmin()) + { + roles.add("admin"); + } + else + { + roles.addAll(roleService.selectRolePermissionByUserId(user.getUserId())); + } + return roles; + } + + /** + * 获取菜单数据权限 + * + * @param user 用户信息 + * @return 菜单权限信息 + */ + public Set getMenuPermission(SysUser user) + { + Set perms = new HashSet(); + // 管理员拥有所有权限 + if (user.isAdmin()) + { + perms.add("*:*:*"); + } + else + { + List roles = user.getRoles(); + if (!CollectionUtils.isEmpty(roles)) + { + // 多角色设置permissions属性,以便数据权限匹配权限 + for (SysRole role : roles) + { + Set rolePerms = menuService.selectMenuPermsByRoleId(role.getRoleId()); + role.setPermissions(rolePerms); + perms.addAll(rolePerms); + } + } + else + { + perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId())); + } + } + return perms; + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/web/service/SysRegisterService.java b/staffing-framework/src/main/java/com/staffing/framework/web/service/SysRegisterService.java new file mode 100644 index 0000000..6adb826 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/web/service/SysRegisterService.java @@ -0,0 +1,115 @@ +package com.staffing.framework.web.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.staffing.common.constant.CacheConstants; +import com.staffing.common.constant.Constants; +import com.staffing.common.constant.UserConstants; +import com.staffing.common.core.domain.entity.SysUser; +import com.staffing.common.core.domain.model.RegisterBody; +import com.staffing.common.core.redis.RedisCache; +import com.staffing.common.exception.user.CaptchaException; +import com.staffing.common.exception.user.CaptchaExpireException; +import com.staffing.common.utils.MessageUtils; +import com.staffing.common.utils.SecurityUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.framework.manager.AsyncManager; +import com.staffing.framework.manager.factory.AsyncFactory; +import com.staffing.system.service.ISysConfigService; +import com.staffing.system.service.ISysUserService; + +/** + * 注册校验方法 + * + * @author staffing + */ +@Component +public class SysRegisterService +{ + @Autowired + private ISysUserService userService; + + @Autowired + private ISysConfigService configService; + + @Autowired + private RedisCache redisCache; + + /** + * 注册 + */ + public String register(RegisterBody registerBody) + { + String msg = "", username = registerBody.getUsername(), password = registerBody.getPassword(); + SysUser sysUser = new SysUser(); + sysUser.setUserName(username); + + // 验证码开关 + boolean captchaEnabled = configService.selectCaptchaEnabled(); + if (captchaEnabled) + { + validateCaptcha(username, registerBody.getCode(), registerBody.getUuid()); + } + + if (StringUtils.isEmpty(username)) + { + msg = "用户名不能为空"; + } + else if (StringUtils.isEmpty(password)) + { + msg = "用户密码不能为空"; + } + else if (username.length() < UserConstants.USERNAME_MIN_LENGTH + || username.length() > UserConstants.USERNAME_MAX_LENGTH) + { + msg = "账户长度必须在2到20个字符之间"; + } + else if (password.length() < UserConstants.PASSWORD_MIN_LENGTH + || password.length() > UserConstants.PASSWORD_MAX_LENGTH) + { + msg = "密码长度必须在5到20个字符之间"; + } + else if (!userService.checkUserNameUnique(sysUser)) + { + msg = "保存用户'" + username + "'失败,注册账号已存在"; + } + else + { + sysUser.setNickName(username); + sysUser.setPassword(SecurityUtils.encryptPassword(password)); + boolean regFlag = userService.registerUser(sysUser); + if (!regFlag) + { + msg = "注册失败,请联系系统管理人员"; + } + else + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.register.success"))); + } + } + return msg; + } + + /** + * 校验验证码 + * + * @param username 用户名 + * @param code 验证码 + * @param uuid 唯一标识 + * @return 结果 + */ + public void validateCaptcha(String username, String code, String uuid) + { + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); + String captcha = redisCache.getCacheObject(verifyKey); + redisCache.deleteObject(verifyKey); + if (captcha == null) + { + throw new CaptchaExpireException(); + } + if (!code.equalsIgnoreCase(captcha)) + { + throw new CaptchaException(); + } + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/web/service/TokenService.java b/staffing-framework/src/main/java/com/staffing/framework/web/service/TokenService.java new file mode 100644 index 0000000..a1d724d --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/web/service/TokenService.java @@ -0,0 +1,231 @@ +package com.staffing.framework.web.service; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import javax.servlet.http.HttpServletRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import com.staffing.common.constant.CacheConstants; +import com.staffing.common.constant.Constants; +import com.staffing.common.core.domain.model.LoginUser; +import com.staffing.common.core.redis.RedisCache; +import com.staffing.common.utils.ServletUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.ip.AddressUtils; +import com.staffing.common.utils.ip.IpUtils; +import com.staffing.common.utils.uuid.IdUtils; +import eu.bitwalker.useragentutils.UserAgent; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; + +/** + * token验证处理 + * + * @author staffing + */ +@Component +public class TokenService +{ + private static final Logger log = LoggerFactory.getLogger(TokenService.class); + + // 令牌自定义标识 + @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)) + { + try + { + Claims claims = parseToken(token); + // 解析对应的权限以及用户信息 + String uuid = (String) claims.get(Constants.LOGIN_USER_KEY); + String userKey = getTokenKey(uuid); + LoginUser user = redisCache.getCacheObject(userKey); + return user; + } + catch (Exception e) + { + log.error("获取用户信息异常'{}'", e.getMessage()); + } + } + return null; + } + + /** + * 设置用户身份信息 + */ + public void setLoginUser(LoginUser loginUser) + { + if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) + { + refreshToken(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 claims = new HashMap<>(); + claims.put(Constants.LOGIN_USER_KEY, token); + return createToken(claims); + } + + /** + * 验证令牌有效期,相差不足20分钟,自动刷新缓存 + * + * @param loginUser + * @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将loginUser缓存 + String userKey = getTokenKey(loginUser.getToken()); + redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES); + } + + /** + * 设置用户代理信息 + * + * @param loginUser 登录信息 + */ + public void setUserAgent(LoginUser loginUser) + { + UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent")); + String ip = IpUtils.getIpAddr(); + loginUser.setIpaddr(ip); + loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); + loginUser.setBrowser(userAgent.getBrowser().getName()); + loginUser.setOs(userAgent.getOperatingSystem().getName()); + } + + /** + * 从数据声明生成令牌 + * + * @param claims 数据声明 + * @return 令牌 + */ + private String createToken(Map 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 CacheConstants.LOGIN_TOKEN_KEY + uuid; + } +} diff --git a/staffing-framework/src/main/java/com/staffing/framework/web/service/UserDetailsServiceImpl.java b/staffing-framework/src/main/java/com/staffing/framework/web/service/UserDetailsServiceImpl.java new file mode 100644 index 0000000..bb707b6 --- /dev/null +++ b/staffing-framework/src/main/java/com/staffing/framework/web/service/UserDetailsServiceImpl.java @@ -0,0 +1,66 @@ +package com.staffing.framework.web.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.staffing.common.core.domain.entity.SysUser; +import com.staffing.common.core.domain.model.LoginUser; +import com.staffing.common.enums.UserStatus; +import com.staffing.common.exception.ServiceException; +import com.staffing.common.utils.MessageUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.system.service.ISysUserService; + +/** + * 用户验证处理 + * + * @author staffing + */ +@Service +public class UserDetailsServiceImpl implements UserDetailsService +{ + private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class); + + @Autowired + private ISysUserService userService; + + @Autowired + private SysPasswordService passwordService; + + @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 ServiceException(MessageUtils.message("user.not.exists")); + } + else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) + { + log.info("登录用户:{} 已被删除.", username); + throw new ServiceException(MessageUtils.message("user.password.delete")); + } + else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) + { + log.info("登录用户:{} 已被停用.", username); + throw new ServiceException(MessageUtils.message("user.blocked")); + } + + passwordService.validate(user); + + return createLoginUser(user); + } + + public UserDetails createLoginUser(SysUser user) + { + return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user)); + } +} diff --git a/staffing-generator/pom.xml b/staffing-generator/pom.xml new file mode 100644 index 0000000..edb1510 --- /dev/null +++ b/staffing-generator/pom.xml @@ -0,0 +1,40 @@ + + + + staffing + com.staffing + 3.8.8 + + 4.0.0 + + staffing-generator + + + generator代码生成 + + + + + + + org.apache.velocity + velocity-engine-core + + + + + com.staffing + staffing-common + + + + + com.alibaba + druid-spring-boot-starter + + + + + \ No newline at end of file diff --git a/staffing-generator/src/main/java/com/staffing/generator/config/GenConfig.java b/staffing-generator/src/main/java/com/staffing/generator/config/GenConfig.java new file mode 100644 index 0000000..983ae84 --- /dev/null +++ b/staffing-generator/src/main/java/com/staffing/generator/config/GenConfig.java @@ -0,0 +1,73 @@ +package com.staffing.generator.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; + +/** + * 读取代码生成相关配置 + * + * @author staffing + */ +@Component +@ConfigurationProperties(prefix = "gen") +@PropertySource(value = { "classpath:generator.yml" }) +public class GenConfig +{ + /** 作者 */ + public static String author; + + /** 生成包路径 */ + public static String packageName; + + /** 自动去除表前缀,默认是false */ + public static boolean autoRemovePre; + + /** 表前缀(类名不会包含表前缀) */ + public static String tablePrefix; + + public static String getAuthor() + { + return author; + } + + @Value("${author}") + public void setAuthor(String author) + { + GenConfig.author = author; + } + + public static String getPackageName() + { + return packageName; + } + + @Value("${packageName}") + public void setPackageName(String packageName) + { + GenConfig.packageName = packageName; + } + + public static boolean getAutoRemovePre() + { + return autoRemovePre; + } + + @Value("${autoRemovePre}") + public void setAutoRemovePre(boolean autoRemovePre) + { + GenConfig.autoRemovePre = autoRemovePre; + } + + public static String getTablePrefix() + { + return tablePrefix; + } + + @Value("${tablePrefix}") + public void setTablePrefix(String tablePrefix) + { + GenConfig.tablePrefix = tablePrefix; + } +} diff --git a/staffing-generator/src/main/java/com/staffing/generator/controller/GenController.java b/staffing-generator/src/main/java/com/staffing/generator/controller/GenController.java new file mode 100644 index 0000000..3ce9185 --- /dev/null +++ b/staffing-generator/src/main/java/com/staffing/generator/controller/GenController.java @@ -0,0 +1,258 @@ +package com.staffing.generator.controller; + +import java.io.IOException; +import java.util.ArrayList; +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.alibaba.druid.DbType; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement; +import com.staffing.common.annotation.Log; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.page.TableDataInfo; +import com.staffing.common.core.text.Convert; +import com.staffing.common.enums.BusinessType; +import com.staffing.common.utils.SecurityUtils; +import com.staffing.common.utils.sql.SqlUtil; +import com.staffing.generator.domain.GenTable; +import com.staffing.generator.domain.GenTableColumn; +import com.staffing.generator.service.IGenTableColumnService; +import com.staffing.generator.service.IGenTableService; + +/** + * 代码生成 操作处理 + * + * @author staffing + */ +@RestController +@RequestMapping("/tool/gen") +public class GenController extends BaseController +{ + @Autowired + private IGenTableService genTableService; + + @Autowired + private IGenTableColumnService genTableColumnService; + + /** + * 查询代码生成列表 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:list')") + @GetMapping("/list") + public TableDataInfo genList(GenTable genTable) + { + startPage(); + List list = genTableService.selectGenTableList(genTable); + return getDataTable(list); + } + + /** + * 修改代码生成业务 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:query')") + @GetMapping(value = "/{tableId}") + public AjaxResult getInfo(@PathVariable Long tableId) + { + GenTable table = genTableService.selectGenTableById(tableId); + List tables = genTableService.selectGenTableAll(); + List list = genTableColumnService.selectGenTableColumnListByTableId(tableId); + Map map = new HashMap(); + map.put("info", table); + map.put("rows", list); + map.put("tables", tables); + return success(map); + } + + /** + * 查询数据库列表 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:list')") + @GetMapping("/db/list") + public TableDataInfo dataList(GenTable genTable) + { + startPage(); + List list = genTableService.selectDbTableList(genTable); + return getDataTable(list); + } + + /** + * 查询数据表字段列表 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:list')") + @GetMapping(value = "/column/{tableId}") + public TableDataInfo columnList(Long tableId) + { + TableDataInfo dataInfo = new TableDataInfo(); + List list = genTableColumnService.selectGenTableColumnListByTableId(tableId); + dataInfo.setRows(list); + dataInfo.setTotal(list.size()); + return dataInfo; + } + + /** + * 导入表结构(保存) + */ + @PreAuthorize("@ss.hasPermi('tool:gen:import')") + @Log(title = "代码生成", businessType = BusinessType.IMPORT) + @PostMapping("/importTable") + public AjaxResult importTableSave(String tables) + { + String[] tableNames = Convert.toStrArray(tables); + // 查询表信息 + List tableList = genTableService.selectDbTableListByNames(tableNames); + genTableService.importGenTable(tableList, SecurityUtils.getUsername()); + return success(); + } + + /** + * 创建表结构(保存) + */ + @PreAuthorize("@ss.hasRole('admin')") + @Log(title = "创建表", businessType = BusinessType.OTHER) + @PostMapping("/createTable") + public AjaxResult createTableSave(String sql) + { + try + { + SqlUtil.filterKeyword(sql); + List sqlStatements = SQLUtils.parseStatements(sql, DbType.mysql); + List tableNames = new ArrayList<>(); + for (SQLStatement sqlStatement : sqlStatements) + { + if (sqlStatement instanceof MySqlCreateTableStatement) + { + MySqlCreateTableStatement createTableStatement = (MySqlCreateTableStatement) sqlStatement; + if (genTableService.createTable(createTableStatement.toString())) + { + String tableName = createTableStatement.getTableName().replaceAll("`", ""); + tableNames.add(tableName); + } + } + } + List tableList = genTableService.selectDbTableListByNames(tableNames.toArray(new String[tableNames.size()])); + String operName = SecurityUtils.getUsername(); + genTableService.importGenTable(tableList, operName); + return AjaxResult.success(); + } + catch (Exception e) + { + logger.error(e.getMessage(), e); + return AjaxResult.error("创建表结构异常"); + } + } + + /** + * 修改保存代码生成业务 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:edit')") + @Log(title = "代码生成", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult editSave(@Validated @RequestBody GenTable genTable) + { + genTableService.validateEdit(genTable); + genTableService.updateGenTable(genTable); + return success(); + } + + /** + * 删除代码生成 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:remove')") + @Log(title = "代码生成", businessType = BusinessType.DELETE) + @DeleteMapping("/{tableIds}") + public AjaxResult remove(@PathVariable Long[] tableIds) + { + genTableService.deleteGenTableByIds(tableIds); + return success(); + } + + /** + * 预览代码 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:preview')") + @GetMapping("/preview/{tableId}") + public AjaxResult preview(@PathVariable("tableId") Long tableId) throws IOException + { + Map dataMap = genTableService.previewCode(tableId); + return success(dataMap); + } + + /** + * 生成代码(下载方式) + */ + @PreAuthorize("@ss.hasPermi('tool:gen:code')") + @Log(title = "代码生成", businessType = BusinessType.GENCODE) + @GetMapping("/download/{tableName}") + public void download(HttpServletResponse response, @PathVariable("tableName") String tableName) throws IOException + { + byte[] data = genTableService.downloadCode(tableName); + genCode(response, data); + } + + /** + * 生成代码(自定义路径) + */ + @PreAuthorize("@ss.hasPermi('tool:gen:code')") + @Log(title = "代码生成", businessType = BusinessType.GENCODE) + @GetMapping("/genCode/{tableName}") + public AjaxResult genCode(@PathVariable("tableName") String tableName) + { + genTableService.generatorCode(tableName); + return success(); + } + + /** + * 同步数据库 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:edit')") + @Log(title = "代码生成", businessType = BusinessType.UPDATE) + @GetMapping("/synchDb/{tableName}") + public AjaxResult synchDb(@PathVariable("tableName") String tableName) + { + genTableService.synchDb(tableName); + return success(); + } + + /** + * 批量生成代码 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:code')") + @Log(title = "代码生成", businessType = BusinessType.GENCODE) + @GetMapping("/batchGenCode") + public void batchGenCode(HttpServletResponse response, String tables) throws IOException + { + String[] tableNames = Convert.toStrArray(tables); + byte[] data = genTableService.downloadCode(tableNames); + genCode(response, data); + } + + /** + * 生成zip文件 + */ + private void genCode(HttpServletResponse response, byte[] data) throws IOException + { + response.reset(); + response.addHeader("Access-Control-Allow-Origin", "*"); + response.addHeader("Access-Control-Expose-Headers", "Content-Disposition"); + response.setHeader("Content-Disposition", "attachment; filename=\"staffing.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/staffing-generator/src/main/java/com/staffing/generator/domain/GenTable.java b/staffing-generator/src/main/java/com/staffing/generator/domain/GenTable.java new file mode 100644 index 0000000..3e42b57 --- /dev/null +++ b/staffing-generator/src/main/java/com/staffing/generator/domain/GenTable.java @@ -0,0 +1,385 @@ +package com.staffing.generator.domain; + +import java.util.List; +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import org.apache.commons.lang3.ArrayUtils; +import com.staffing.common.constant.GenConstants; +import com.staffing.common.core.domain.BaseEntity; +import com.staffing.common.utils.StringUtils; + +/** + * 业务表 gen_table + * + * @author staffing + */ +public class GenTable extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 编号 */ + private Long tableId; + + /** 表名称 */ + @NotBlank(message = "表名称不能为空") + private String tableName; + + /** 表描述 */ + @NotBlank(message = "表描述不能为空") + private String tableComment; + + /** 关联父表的表名 */ + private String subTableName; + + /** 本表关联父表的外键名 */ + private String subTableFkName; + + /** 实体类名称(首字母大写) */ + @NotBlank(message = "实体类名称不能为空") + private String className; + + /** 使用的模板(crud单表操作 tree树表操作 sub主子表操作) */ + private String tplCategory; + + /** 前端类型(element-ui模版 element-plus模版) */ + private String tplWebType; + + /** 生成包路径 */ + @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; + + /** 生成代码方式(0zip压缩包 1自定义路径) */ + private String genType; + + /** 生成路径(不填默认项目路径) */ + private String genPath; + + /** 主键信息 */ + private GenTableColumn pkColumn; + + /** 子表信息 */ + private GenTable subTable; + + /** 表列信息 */ + @Valid + private List columns; + + /** 其它生成选项 */ + private String options; + + /** 树编码字段 */ + private String treeCode; + + /** 树父编码字段 */ + private String treeParentCode; + + /** 树名称字段 */ + private String treeName; + + /** 上级菜单ID字段 */ + private String parentMenuId; + + /** 上级菜单名称字段 */ + private String parentMenuName; + + 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 getSubTableName() + { + return subTableName; + } + + public void setSubTableName(String subTableName) + { + this.subTableName = subTableName; + } + + public String getSubTableFkName() + { + return subTableFkName; + } + + public void setSubTableFkName(String subTableFkName) + { + this.subTableFkName = subTableFkName; + } + + 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 getTplWebType() + { + return tplWebType; + } + + public void setTplWebType(String tplWebType) + { + this.tplWebType = tplWebType; + } + + 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 String getGenType() + { + return genType; + } + + public void setGenType(String genType) + { + this.genType = genType; + } + + public String getGenPath() + { + return genPath; + } + + public void setGenPath(String genPath) + { + this.genPath = genPath; + } + + public GenTableColumn getPkColumn() + { + return pkColumn; + } + + public void setPkColumn(GenTableColumn pkColumn) + { + this.pkColumn = pkColumn; + } + + public GenTable getSubTable() + { + return subTable; + } + + public void setSubTable(GenTable subTable) + { + this.subTable = subTable; + } + + public List getColumns() + { + return columns; + } + + public void setColumns(List 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 String getParentMenuId() + { + return parentMenuId; + } + + public void setParentMenuId(String parentMenuId) + { + this.parentMenuId = parentMenuId; + } + + public String getParentMenuName() + { + return parentMenuName; + } + + public void setParentMenuName(String parentMenuName) + { + this.parentMenuName = parentMenuName; + } + + public boolean isSub() + { + return isSub(this.tplCategory); + } + + public static boolean isSub(String tplCategory) + { + return tplCategory != null && StringUtils.equals(GenConstants.TPL_SUB, tplCategory); + } + + 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)) + { + return StringUtils.equalsAnyIgnoreCase(javaField, + ArrayUtils.addAll(GenConstants.TREE_ENTITY, GenConstants.BASE_ENTITY)); + } + return StringUtils.equalsAnyIgnoreCase(javaField, GenConstants.BASE_ENTITY); + } +} \ No newline at end of file diff --git a/staffing-generator/src/main/java/com/staffing/generator/domain/GenTableColumn.java b/staffing-generator/src/main/java/com/staffing/generator/domain/GenTableColumn.java new file mode 100644 index 0000000..183dd13 --- /dev/null +++ b/staffing-generator/src/main/java/com/staffing/generator/domain/GenTableColumn.java @@ -0,0 +1,373 @@ +package com.staffing.generator.domain; + +import javax.validation.constraints.NotBlank; +import com.staffing.common.core.domain.BaseEntity; +import com.staffing.common.utils.StringUtils; + +/** + * 代码生成业务字段表 gen_table_column + * + * @author staffing + */ +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; + + /** 查询方式(EQ等于、NE不等于、GT大于、LT小于、LIKE模糊、BETWEEN范围) */ + private String queryType; + + /** 显示类型(input文本框、textarea文本域、select下拉框、checkbox复选框、radio单选框、datetime日期控件、image图片上传控件、upload文件上传控件、editor富文本控件) */ + 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 String getCapJavaField() + { + return StringUtils.capitalize(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", "remark"); + } + + 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; + } + } +} diff --git a/staffing-generator/src/main/java/com/staffing/generator/mapper/GenTableColumnMapper.java b/staffing-generator/src/main/java/com/staffing/generator/mapper/GenTableColumnMapper.java new file mode 100644 index 0000000..c0bd077 --- /dev/null +++ b/staffing-generator/src/main/java/com/staffing/generator/mapper/GenTableColumnMapper.java @@ -0,0 +1,60 @@ +package com.staffing.generator.mapper; + +import java.util.List; +import com.staffing.generator.domain.GenTableColumn; + +/** + * 业务字段 数据层 + * + * @author staffing + */ +public interface GenTableColumnMapper +{ + /** + * 根据表名称查询列信息 + * + * @param tableName 表名称 + * @return 列信息 + */ + public List selectDbTableColumnsByName(String tableName); + + /** + * 查询业务字段列表 + * + * @param tableId 业务字段编号 + * @return 业务字段集合 + */ + public List selectGenTableColumnListByTableId(Long tableId); + + /** + * 新增业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int insertGenTableColumn(GenTableColumn genTableColumn); + + /** + * 修改业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int updateGenTableColumn(GenTableColumn genTableColumn); + + /** + * 删除业务字段 + * + * @param genTableColumns 列数据 + * @return 结果 + */ + public int deleteGenTableColumns(List genTableColumns); + + /** + * 批量删除业务字段 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteGenTableColumnByIds(Long[] ids); +} diff --git a/staffing-generator/src/main/java/com/staffing/generator/mapper/GenTableMapper.java b/staffing-generator/src/main/java/com/staffing/generator/mapper/GenTableMapper.java new file mode 100644 index 0000000..4dddeb0 --- /dev/null +++ b/staffing-generator/src/main/java/com/staffing/generator/mapper/GenTableMapper.java @@ -0,0 +1,91 @@ +package com.staffing.generator.mapper; + +import java.util.List; +import com.staffing.generator.domain.GenTable; + +/** + * 业务 数据层 + * + * @author staffing + */ +public interface GenTableMapper +{ + /** + * 查询业务列表 + * + * @param genTable 业务信息 + * @return 业务集合 + */ + public List selectGenTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param genTable 业务信息 + * @return 数据库表集合 + */ + public List selectDbTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param tableNames 表名称组 + * @return 数据库表集合 + */ + public List selectDbTableListByNames(String[] tableNames); + + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + public List selectGenTableAll(); + + /** + * 查询表ID业务信息 + * + * @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); + + /** + * 创建表 + * + * @param sql 表结构 + * @return 结果 + */ + public int createTable(String sql); +} diff --git a/staffing-generator/src/main/java/com/staffing/generator/service/GenTableColumnServiceImpl.java b/staffing-generator/src/main/java/com/staffing/generator/service/GenTableColumnServiceImpl.java new file mode 100644 index 0000000..e297284 --- /dev/null +++ b/staffing-generator/src/main/java/com/staffing/generator/service/GenTableColumnServiceImpl.java @@ -0,0 +1,68 @@ +package com.staffing.generator.service; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.staffing.common.core.text.Convert; +import com.staffing.generator.domain.GenTableColumn; +import com.staffing.generator.mapper.GenTableColumnMapper; + +/** + * 业务字段 服务层实现 + * + * @author staffing + */ +@Service +public class GenTableColumnServiceImpl implements IGenTableColumnService +{ + @Autowired + private GenTableColumnMapper genTableColumnMapper; + + /** + * 查询业务字段列表 + * + * @param tableId 业务字段编号 + * @return 业务字段集合 + */ + @Override + public List 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)); + } +} diff --git a/staffing-generator/src/main/java/com/staffing/generator/service/GenTableServiceImpl.java b/staffing-generator/src/main/java/com/staffing/generator/service/GenTableServiceImpl.java new file mode 100644 index 0000000..aea523f --- /dev/null +++ b/staffing-generator/src/main/java/com/staffing/generator/service/GenTableServiceImpl.java @@ -0,0 +1,531 @@ +package com.staffing.generator.service; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; +import org.apache.commons.io.FileUtils; +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.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.staffing.common.constant.Constants; +import com.staffing.common.constant.GenConstants; +import com.staffing.common.core.text.CharsetKit; +import com.staffing.common.exception.ServiceException; +import com.staffing.common.utils.StringUtils; +import com.staffing.generator.domain.GenTable; +import com.staffing.generator.domain.GenTableColumn; +import com.staffing.generator.mapper.GenTableColumnMapper; +import com.staffing.generator.mapper.GenTableMapper; +import com.staffing.generator.util.GenUtils; +import com.staffing.generator.util.VelocityInitializer; +import com.staffing.generator.util.VelocityUtils; + +/** + * 业务 服务层实现 + * + * @author staffing + */ +@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 selectGenTableList(GenTable genTable) + { + return genTableMapper.selectGenTableList(genTable); + } + + /** + * 查询据库列表 + * + * @param genTable 业务信息 + * @return 数据库表集合 + */ + @Override + public List selectDbTableList(GenTable genTable) + { + return genTableMapper.selectDbTableList(genTable); + } + + /** + * 查询据库列表 + * + * @param tableNames 表名称组 + * @return 数据库表集合 + */ + @Override + public List selectDbTableListByNames(String[] tableNames) + { + return genTableMapper.selectDbTableListByNames(tableNames); + } + + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + @Override + public List selectGenTableAll() + { + return genTableMapper.selectGenTableAll(); + } + + /** + * 修改业务 + * + * @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 tableIds 需要删除的数据ID + * @return 结果 + */ + @Override + @Transactional + public void deleteGenTableByIds(Long[] tableIds) + { + genTableMapper.deleteGenTableByIds(tableIds); + genTableColumnMapper.deleteGenTableColumnByIds(tableIds); + } + + /** + * 创建表 + * + * @param sql 创建表语句 + * @return 结果 + */ + @Override + public boolean createTable(String sql) + { + return genTableMapper.createTable(sql) == 0; + } + + /** + * 导入表结构 + * + * @param tableList 导入表列表 + */ + @Override + @Transactional + public void importGenTable(List tableList, String operName) + { + try + { + for (GenTable table : tableList) + { + String tableName = table.getTableName(); + GenUtils.initTable(table, operName); + int row = genTableMapper.insertGenTable(table); + if (row > 0) + { + // 保存列信息 + List genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); + for (GenTableColumn column : genTableColumns) + { + GenUtils.initColumnField(column, table); + genTableColumnMapper.insertGenTableColumn(column); + } + } + } + } + catch (Exception e) + { + throw new ServiceException("导入失败:" + e.getMessage()); + } + } + + /** + * 预览代码 + * + * @param tableId 表编号 + * @return 预览数据列表 + */ + @Override + public Map previewCode(Long tableId) + { + Map dataMap = new LinkedHashMap<>(); + // 查询表信息 + GenTable table = genTableMapper.selectGenTableById(tableId); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 获取模板列表 + List templates = VelocityUtils.getTemplateList(table.getTplCategory(), table.getTplWebType()); + 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; + } + + /** + * 生成代码(下载方式) + * + * @param tableName 表名称 + * @return 数据 + */ + @Override + public byte[] downloadCode(String tableName) + { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(outputStream); + generatorCode(tableName, zip); + IOUtils.closeQuietly(zip); + return outputStream.toByteArray(); + } + + /** + * 生成代码(自定义路径) + * + * @param tableName 表名称 + */ + @Override + public void generatorCode(String tableName) + { + // 查询表信息 + GenTable table = genTableMapper.selectGenTableByName(tableName); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); + + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 获取模板列表 + List templates = VelocityUtils.getTemplateList(table.getTplCategory(), table.getTplWebType()); + for (String template : templates) + { + if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm")) + { + // 渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, Constants.UTF8); + tpl.merge(context, sw); + try + { + String path = getGenPath(table, template); + FileUtils.writeStringToFile(new File(path), sw.toString(), CharsetKit.UTF_8); + } + catch (IOException e) + { + throw new ServiceException("渲染模板失败,表名:" + table.getTableName()); + } + } + } + } + + /** + * 同步数据库 + * + * @param tableName 表名称 + */ + @Override + @Transactional + public void synchDb(String tableName) + { + GenTable table = genTableMapper.selectGenTableByName(tableName); + List tableColumns = table.getColumns(); + Map tableColumnMap = tableColumns.stream().collect(Collectors.toMap(GenTableColumn::getColumnName, Function.identity())); + + List dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); + if (StringUtils.isEmpty(dbTableColumns)) + { + throw new ServiceException("同步数据失败,原表结构不存在"); + } + List dbTableColumnNames = dbTableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList()); + + dbTableColumns.forEach(column -> { + GenUtils.initColumnField(column, table); + if (tableColumnMap.containsKey(column.getColumnName())) + { + GenTableColumn prevColumn = tableColumnMap.get(column.getColumnName()); + column.setColumnId(prevColumn.getColumnId()); + if (column.isList()) + { + // 如果是列表,继续保留查询方式/字典类型选项 + column.setDictType(prevColumn.getDictType()); + column.setQueryType(prevColumn.getQueryType()); + } + if (StringUtils.isNotEmpty(prevColumn.getIsRequired()) && !column.isPk() + && (column.isInsert() || column.isEdit()) + && ((column.isUsableColumn()) || (!column.isSuperColumn()))) + { + // 如果是(新增/修改&非主键/非忽略及父属性),继续保留必填/显示类型选项 + column.setIsRequired(prevColumn.getIsRequired()); + column.setHtmlType(prevColumn.getHtmlType()); + } + genTableColumnMapper.updateGenTableColumn(column); + } + else + { + genTableColumnMapper.insertGenTableColumn(column); + } + }); + + List delColumns = tableColumns.stream().filter(column -> !dbTableColumnNames.contains(column.getColumnName())).collect(Collectors.toList()); + if (StringUtils.isNotEmpty(delColumns)) + { + genTableColumnMapper.deleteGenTableColumns(delColumns); + } + } + + /** + * 批量生成代码(下载方式) + * + * @param tableNames 表数组 + * @return 数据 + */ + @Override + public byte[] downloadCode(String[] tableNames) + { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(outputStream); + for (String tableName : tableNames) + { + generatorCode(tableName, zip); + } + IOUtils.closeQuietly(zip); + return outputStream.toByteArray(); + } + + /** + * 查询表信息并生成代码 + */ + private void generatorCode(String tableName, ZipOutputStream zip) + { + // 查询表信息 + GenTable table = genTableMapper.selectGenTableByName(tableName); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); + + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 获取模板列表 + List templates = VelocityUtils.getTemplateList(table.getTplCategory(), table.getTplWebType()); + for (String template : templates) + { + // 渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, Constants.UTF8); + tpl.merge(context, sw); + try + { + // 添加到zip + 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 业务信息 + */ + @Override + public void validateEdit(GenTable genTable) + { + if (GenConstants.TPL_TREE.equals(genTable.getTplCategory())) + { + String options = JSON.toJSONString(genTable.getParams()); + JSONObject paramsObj = JSON.parseObject(options); + if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_CODE))) + { + throw new ServiceException("树编码字段不能为空"); + } + else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_PARENT_CODE))) + { + throw new ServiceException("树父编码字段不能为空"); + } + else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_NAME))) + { + throw new ServiceException("树名称字段不能为空"); + } + else if (GenConstants.TPL_SUB.equals(genTable.getTplCategory())) + { + if (StringUtils.isEmpty(genTable.getSubTableName())) + { + throw new ServiceException("关联子表的表名不能为空"); + } + else if (StringUtils.isEmpty(genTable.getSubTableFkName())) + { + throw new ServiceException("子表关联的外键名不能为空"); + } + } + } + } + + /** + * 设置主键列信息 + * + * @param table 业务表信息 + */ + public void setPkColumn(GenTable table) + { + for (GenTableColumn column : table.getColumns()) + { + if (column.isPk()) + { + table.setPkColumn(column); + break; + } + } + if (StringUtils.isNull(table.getPkColumn())) + { + table.setPkColumn(table.getColumns().get(0)); + } + if (GenConstants.TPL_SUB.equals(table.getTplCategory())) + { + for (GenTableColumn column : table.getSubTable().getColumns()) + { + if (column.isPk()) + { + table.getSubTable().setPkColumn(column); + break; + } + } + if (StringUtils.isNull(table.getSubTable().getPkColumn())) + { + table.getSubTable().setPkColumn(table.getSubTable().getColumns().get(0)); + } + } + } + + /** + * 设置主子表信息 + * + * @param table 业务表信息 + */ + public void setSubTable(GenTable table) + { + String subTableName = table.getSubTableName(); + if (StringUtils.isNotEmpty(subTableName)) + { + table.setSubTable(genTableMapper.selectGenTableByName(subTableName)); + } + } + + /** + * 设置代码生成其他选项值 + * + * @param genTable 设置后的生成对象 + */ + public void setTableFromOptions(GenTable genTable) + { + JSONObject paramsObj = JSON.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); + String parentMenuId = paramsObj.getString(GenConstants.PARENT_MENU_ID); + String parentMenuName = paramsObj.getString(GenConstants.PARENT_MENU_NAME); + + genTable.setTreeCode(treeCode); + genTable.setTreeParentCode(treeParentCode); + genTable.setTreeName(treeName); + genTable.setParentMenuId(parentMenuId); + genTable.setParentMenuName(parentMenuName); + } + } + + /** + * 获取代码生成地址 + * + * @param table 业务表信息 + * @param template 模板文件路径 + * @return 生成地址 + */ + public static String getGenPath(GenTable table, String template) + { + String genPath = table.getGenPath(); + if (StringUtils.equals(genPath, "/")) + { + return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table); + } + return genPath + File.separator + VelocityUtils.getFileName(template, table); + } +} \ No newline at end of file diff --git a/staffing-generator/src/main/java/com/staffing/generator/service/IGenTableColumnService.java b/staffing-generator/src/main/java/com/staffing/generator/service/IGenTableColumnService.java new file mode 100644 index 0000000..7806625 --- /dev/null +++ b/staffing-generator/src/main/java/com/staffing/generator/service/IGenTableColumnService.java @@ -0,0 +1,44 @@ +package com.staffing.generator.service; + +import java.util.List; +import com.staffing.generator.domain.GenTableColumn; + +/** + * 业务字段 服务层 + * + * @author staffing + */ +public interface IGenTableColumnService +{ + /** + * 查询业务字段列表 + * + * @param tableId 业务字段编号 + * @return 业务字段集合 + */ + public List 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/staffing-generator/src/main/java/com/staffing/generator/service/IGenTableService.java b/staffing-generator/src/main/java/com/staffing/generator/service/IGenTableService.java new file mode 100644 index 0000000..1b519df --- /dev/null +++ b/staffing-generator/src/main/java/com/staffing/generator/service/IGenTableService.java @@ -0,0 +1,130 @@ +package com.staffing.generator.service; + +import java.util.List; +import java.util.Map; +import com.staffing.generator.domain.GenTable; + +/** + * 业务 服务层 + * + * @author staffing + */ +public interface IGenTableService +{ + /** + * 查询业务列表 + * + * @param genTable 业务信息 + * @return 业务集合 + */ + public List selectGenTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param genTable 业务信息 + * @return 数据库表集合 + */ + public List selectDbTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param tableNames 表名称组 + * @return 数据库表集合 + */ + public List selectDbTableListByNames(String[] tableNames); + + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + public List selectGenTableAll(); + + /** + * 查询业务信息 + * + * @param id 业务ID + * @return 业务信息 + */ + public GenTable selectGenTableById(Long id); + + /** + * 修改业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + public void updateGenTable(GenTable genTable); + + /** + * 删除业务信息 + * + * @param tableIds 需要删除的表数据ID + * @return 结果 + */ + public void deleteGenTableByIds(Long[] tableIds); + + /** + * 创建表 + * + * @param sql 创建表语句 + * @return 结果 + */ + public boolean createTable(String sql); + + /** + * 导入表结构 + * + * @param tableList 导入表列表 + * @param operName 操作人员 + */ + public void importGenTable(List tableList, String operName); + + /** + * 预览代码 + * + * @param tableId 表编号 + * @return 预览数据列表 + */ + public Map previewCode(Long tableId); + + /** + * 生成代码(下载方式) + * + * @param tableName 表名称 + * @return 数据 + */ + public byte[] downloadCode(String tableName); + + /** + * 生成代码(自定义路径) + * + * @param tableName 表名称 + * @return 数据 + */ + public void generatorCode(String tableName); + + /** + * 同步数据库 + * + * @param tableName 表名称 + */ + public void synchDb(String tableName); + + /** + * 批量生成代码(下载方式) + * + * @param tableNames 表数组 + * @return 数据 + */ + public byte[] downloadCode(String[] tableNames); + + /** + * 修改保存参数校验 + * + * @param genTable 业务信息 + */ + public void validateEdit(GenTable genTable); +} diff --git a/staffing-generator/src/main/java/com/staffing/generator/util/GenUtils.java b/staffing-generator/src/main/java/com/staffing/generator/util/GenUtils.java new file mode 100644 index 0000000..c43af28 --- /dev/null +++ b/staffing-generator/src/main/java/com/staffing/generator/util/GenUtils.java @@ -0,0 +1,257 @@ +package com.staffing.generator.util; + +import java.util.Arrays; +import org.apache.commons.lang3.RegExUtils; +import com.staffing.common.constant.GenConstants; +import com.staffing.common.utils.StringUtils; +import com.staffing.generator.config.GenConfig; +import com.staffing.generator.domain.GenTable; +import com.staffing.generator.domain.GenTableColumn; + +/** + * 代码生成器 工具类 + * + * @author staffing + */ +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)); + // 设置默认类型 + column.setJavaType(GenConstants.TYPE_STRING); + column.setQueryType(GenConstants.QUERY_EQ); + + if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType) || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType)) + { + // 字符串长度超过500设置为文本域 + Integer columnLength = getColumnLength(column.getColumnType()); + String htmlType = columnLength >= 500 || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType) ? 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); + + // 如果是浮点型 统一用BigDecimal + String[] str = StringUtils.split(StringUtils.substringBetween(column.getColumnType(), "(", ")"), ","); + if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0) + { + column.setJavaType(GenConstants.TYPE_BIGDECIMAL); + } + // 如果是整形 + 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); + } + // 图片字段设置图片上传控件 + else if (StringUtils.endsWithIgnoreCase(columnName, "image")) + { + column.setHtmlType(GenConstants.HTML_IMAGE_UPLOAD); + } + // 文件字段设置文件上传控件 + else if (StringUtils.endsWithIgnoreCase(columnName, "file")) + { + column.setHtmlType(GenConstants.HTML_FILE_UPLOAD); + } + // 内容字段设置富文本控件 + else if (StringUtils.endsWithIgnoreCase(columnName, "content")) + { + column.setHtmlType(GenConstants.HTML_EDITOR); + } + } + + /** + * 校验数组是否包含指定值 + * + * @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(); + return StringUtils.substring(packageName, lastIndex + 1, nameLength); + } + + /** + * 获取业务名 + * + * @param tableName 表名 + * @return 业务名 + */ + public static String getBusinessName(String tableName) + { + int lastIndex = tableName.lastIndexOf("_"); + int nameLength = tableName.length(); + return StringUtils.substring(tableName, lastIndex + 1, nameLength); + } + + /** + * 表名转换成Java类名 + * + * @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, ","); + tableName = replaceFirst(tableName, searchList); + } + return StringUtils.convertToCamelCase(tableName); + } + + /** + * 批量替换前缀 + * + * @param replacementm 替换值 + * @param searchList 替换列表 + * @return + */ + public static String replaceFirst(String replacementm, String[] searchList) + { + String text = replacementm; + for (String searchString : searchList) + { + if (replacementm.startsWith(searchString)) + { + text = replacementm.replaceFirst(searchString, ""); + break; + } + } + return text; + } + + /** + * 关键字替换 + * + * @param text 需要被替换的名字 + * @return 替换后的名字 + */ + public static String replaceText(String text) + { + return RegExUtils.replaceAll(text, "(?:表|xx)", ""); + } + + /** + * 获取数据库类型字段 + * + * @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; + } + } +} diff --git a/staffing-generator/src/main/java/com/staffing/generator/util/VelocityInitializer.java b/staffing-generator/src/main/java/com/staffing/generator/util/VelocityInitializer.java new file mode 100644 index 0000000..f5b7df7 --- /dev/null +++ b/staffing-generator/src/main/java/com/staffing/generator/util/VelocityInitializer.java @@ -0,0 +1,34 @@ +package com.staffing.generator.util; + +import java.util.Properties; +import org.apache.velocity.app.Velocity; +import com.staffing.common.constant.Constants; + +/** + * VelocityEngine工厂 + * + * @author staffing + */ +public class VelocityInitializer +{ + /** + * 初始化vm方法 + */ + public static void initVelocity() + { + Properties p = new Properties(); + try + { + // 加载classpath目录下的vm文件 + p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + // 定义字符集 + p.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8); + // 初始化Velocity引擎,指定配置Properties + Velocity.init(p); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } +} diff --git a/staffing-generator/src/main/java/com/staffing/generator/util/VelocityUtils.java b/staffing-generator/src/main/java/com/staffing/generator/util/VelocityUtils.java new file mode 100644 index 0000000..f86cbe3 --- /dev/null +++ b/staffing-generator/src/main/java/com/staffing/generator/util/VelocityUtils.java @@ -0,0 +1,408 @@ +package com.staffing.generator.util; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.apache.velocity.VelocityContext; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.staffing.common.constant.GenConstants; +import com.staffing.common.utils.DateUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.generator.domain.GenTable; +import com.staffing.generator.domain.GenTableColumn; + +/** + * 模板处理工具类 + * + * @author ruoyi + */ +public class VelocityUtils +{ + /** 项目空间路径 */ + private static final String PROJECT_PATH = "main/java"; + + /** mybatis空间路径 */ + private static final String MYBATIS_PATH = "main/resources/mapper"; + + /** 默认上级菜单,系统工具 */ + private static final String DEFAULT_PARENT_MENU_ID = "3"; + + /** + * 设置模板变量信息 + * + * @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)); + velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName)); + velocityContext.put("columns", genTable.getColumns()); + velocityContext.put("table", genTable); + velocityContext.put("dicts", getDicts(genTable)); + setMenuVelocityContext(velocityContext, genTable); + if (GenConstants.TPL_TREE.equals(tplCategory)) + { + setTreeVelocityContext(velocityContext, genTable); + } + if (GenConstants.TPL_SUB.equals(tplCategory)) + { + setSubVelocityContext(velocityContext, genTable); + } + return velocityContext; + } + + public static void setMenuVelocityContext(VelocityContext context, GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSON.parseObject(options); + String parentMenuId = getParentMenuId(paramsObj); + context.put("parentMenuId", parentMenuId); + } + + public static void setTreeVelocityContext(VelocityContext context, GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSON.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)); + } + } + + public static void setSubVelocityContext(VelocityContext context, GenTable genTable) + { + GenTable subTable = genTable.getSubTable(); + String subTableName = genTable.getSubTableName(); + String subTableFkName = genTable.getSubTableFkName(); + String subClassName = genTable.getSubTable().getClassName(); + String subTableFkClassName = StringUtils.convertToCamelCase(subTableFkName); + + context.put("subTable", subTable); + context.put("subTableName", subTableName); + context.put("subTableFkName", subTableFkName); + context.put("subTableFkClassName", subTableFkClassName); + context.put("subTableFkclassName", StringUtils.uncapitalize(subTableFkClassName)); + context.put("subClassName", subClassName); + context.put("subclassName", StringUtils.uncapitalize(subClassName)); + context.put("subImportList", getImportList(genTable.getSubTable())); + } + + /** + * 获取模板信息 + * @param tplCategory 生成的模板 + * @param tplWebType 前端类型 + * @return 模板列表 + */ + public static List getTemplateList(String tplCategory, String tplWebType) + { + String useWebType = "vm/vue"; + if ("element-plus".equals(tplWebType)) + { + useWebType = "vm/vue/v3"; + } + List templates = new ArrayList(); + 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"); + if (GenConstants.TPL_CRUD.equals(tplCategory)) + { + templates.add(useWebType + "/index.vue.vm"); + } + else if (GenConstants.TPL_TREE.equals(tplCategory)) + { + templates.add(useWebType + "/index-tree.vue.vm"); + } + else if (GenConstants.TPL_SUB.equals(tplCategory)) + { + templates.add(useWebType + "/index.vue.vm"); + templates.add("vm/java/sub-domain.java.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); + } + if (template.contains("sub-domain.java.vm") && StringUtils.equals(GenConstants.TPL_SUB, genTable.getTplCategory())) + { + fileName = StringUtils.format("{}/domain/{}.java", javaPath, genTable.getSubTable().getClassName()); + } + 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("api.js.vm")) + { + fileName = StringUtils.format("{}/api/{}/{}.js", vuePath, moduleName, businessName); + } + else if (template.contains("index.vue.vm")) + { + fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); + } + else if (template.contains("index-tree.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("."); + return StringUtils.substring(packageName, 0, lastIndex); + } + + /** + * 根据列类型获取导入包 + * + * @param genTable 业务表对象 + * @return 返回需要导入的包列表 + */ + public static HashSet getImportList(GenTable genTable) + { + List columns = genTable.getColumns(); + GenTable subGenTable = genTable.getSubTable(); + HashSet importList = new HashSet(); + if (StringUtils.isNotNull(subGenTable)) + { + importList.add("java.util.List"); + } + for (GenTableColumn column : columns) + { + if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType())) + { + importList.add("java.util.Date"); + importList.add("com.fasterxml.jackson.annotation.JsonFormat"); + } + else if (!column.isSuperColumn() && GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType())) + { + importList.add("java.math.BigDecimal"); + } + } + return importList; + } + + /** + * 根据列类型获取字典组 + * + * @param genTable 业务表对象 + * @return 返回字典组 + */ + public static String getDicts(GenTable genTable) + { + List columns = genTable.getColumns(); + Set dicts = new HashSet(); + addDicts(dicts, columns); + if (StringUtils.isNotNull(genTable.getSubTable())) + { + List subColumns = genTable.getSubTable().getColumns(); + addDicts(dicts, subColumns); + } + return StringUtils.join(dicts, ", "); + } + + /** + * 添加字典列表 + * + * @param dicts 字典列表 + * @param columns 列集合 + */ + public static void addDicts(Set dicts, List columns) + { + for (GenTableColumn column : columns) + { + if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny( + column.getHtmlType(), + new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX })) + { + dicts.add("'" + column.getDictType() + "'"); + } + } + } + + /** + * 获取权限前缀 + * + * @param moduleName 模块名称 + * @param businessName 业务名称 + * @return 返回权限前缀 + */ + public static String getPermissionPrefix(String moduleName, String businessName) + { + return StringUtils.format("{}:{}", moduleName, businessName); + } + + /** + * 获取上级菜单ID字段 + * + * @param paramsObj 生成其他选项 + * @return 上级菜单ID字段 + */ + public static String getParentMenuId(JSONObject paramsObj) + { + if (StringUtils.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID) + && StringUtils.isNotEmpty(paramsObj.getString(GenConstants.PARENT_MENU_ID))) + { + return paramsObj.getString(GenConstants.PARENT_MENU_ID); + } + return DEFAULT_PARENT_MENU_ID; + } + + /** + * 获取树编码 + * + * @param paramsObj 生成其他选项 + * @return 树编码 + */ + public static String getTreecode(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_CODE)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_CODE)); + } + return StringUtils.EMPTY; + } + + /** + * 获取树父编码 + * + * @param paramsObj 生成其他选项 + * @return 树父编码 + */ + public static String getTreeParentCode(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_PARENT_CODE)); + } + return StringUtils.EMPTY; + } + + /** + * 获取树名称 + * + * @param paramsObj 生成其他选项 + * @return 树名称 + */ + public static String getTreeName(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_NAME)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_NAME)); + } + return StringUtils.EMPTY; + } + + /** + * 获取需要在哪一列上面显示展开按钮 + * + * @param genTable 业务表对象 + * @return 展开按钮列序号 + */ + public static int getExpandColumn(GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSON.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; + } +} diff --git a/staffing-generator/src/main/resources/generator.yml b/staffing-generator/src/main/resources/generator.yml new file mode 100644 index 0000000..16803db --- /dev/null +++ b/staffing-generator/src/main/resources/generator.yml @@ -0,0 +1,10 @@ +# 代码生成 +gen: + # 作者 + author: staffing + # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool + packageName: com.staffing.system + # 自动去除表前缀,默认是false + autoRemovePre: false + # 表前缀(生成类名不会包含表前缀,多个用逗号分隔) + tablePrefix: sys_ \ No newline at end of file diff --git a/staffing-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml b/staffing-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml new file mode 100644 index 0000000..2887a47 --- /dev/null +++ b/staffing-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + + + + insert into gen_table_column ( + 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 + )values( + #{tableId}, + #{columnName}, + #{columnComment}, + #{columnType}, + #{javaType}, + #{javaField}, + #{isPk}, + #{isIncrement}, + #{isRequired}, + #{isInsert}, + #{isEdit}, + #{isList}, + #{isQuery}, + #{queryType}, + #{htmlType}, + #{dictType}, + #{sort}, + #{createBy}, + sysdate() + ) + + + + update gen_table_column + + 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() + + where column_id = #{columnId} + + + + delete from gen_table_column where table_id in + + #{tableId} + + + + + delete from gen_table_column where column_id in + + #{item.columnId} + + + + \ No newline at end of file diff --git a/staffing-generator/src/main/resources/mapper/generator/GenTableMapper.xml b/staffing-generator/src/main/resources/mapper/generator/GenTableMapper.xml new file mode 100644 index 0000000..4727945 --- /dev/null +++ b/staffing-generator/src/main/resources/mapper/generator/GenTableMapper.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select table_id, table_name, table_comment, sub_table_name, sub_table_fk_name, class_name, tpl_category, tpl_web_type, package_name, module_name, business_name, function_name, function_author, gen_type, gen_path, options, create_by, create_time, update_by, update_time, remark from gen_table + + + + + + + + + + + + + + + + + + insert into gen_table ( + table_name, + table_comment, + class_name, + tpl_category, + tpl_web_type, + package_name, + module_name, + business_name, + function_name, + function_author, + gen_type, + gen_path, + remark, + create_by, + create_time + )values( + #{tableName}, + #{tableComment}, + #{className}, + #{tplCategory}, + #{tplWebType}, + #{packageName}, + #{moduleName}, + #{businessName}, + #{functionName}, + #{functionAuthor}, + #{genType}, + #{genPath}, + #{remark}, + #{createBy}, + sysdate() + ) + + + + ${sql} + + + + update gen_table + + table_name = #{tableName}, + table_comment = #{tableComment}, + sub_table_name = #{subTableName}, + sub_table_fk_name = #{subTableFkName}, + class_name = #{className}, + function_author = #{functionAuthor}, + gen_type = #{genType}, + gen_path = #{genPath}, + tpl_category = #{tplCategory}, + tpl_web_type = #{tplWebType}, + package_name = #{packageName}, + module_name = #{moduleName}, + business_name = #{businessName}, + function_name = #{functionName}, + options = #{options}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = sysdate() + + where table_id = #{tableId} + + + + delete from gen_table where table_id in + + #{tableId} + + + + \ No newline at end of file diff --git a/staffing-generator/src/main/resources/vm/java/controller.java.vm b/staffing-generator/src/main/resources/vm/java/controller.java.vm new file mode 100644 index 0000000..1920655 --- /dev/null +++ b/staffing-generator/src/main/resources/vm/java/controller.java.vm @@ -0,0 +1,115 @@ +package ${packageName}.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +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.staffing.common.annotation.Log; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.enums.BusinessType; +import ${packageName}.domain.${ClassName}; +import ${packageName}.service.I${ClassName}Service; +import com.staffing.common.utils.poi.ExcelUtil; +#if($table.crud || $table.sub) +import com.staffing.common.core.page.TableDataInfo; +#elseif($table.tree) +#end + +/** + * ${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") +#if($table.crud || $table.sub) + public TableDataInfo list(${ClassName} ${className}) + { + startPage(); + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + return getDataTable(list); + } +#elseif($table.tree) + public AjaxResult list(${ClassName} ${className}) + { + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + return success(list); + } +#end + + /** + * 导出${functionName}列表 + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:export')") + @Log(title = "${functionName}", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, ${ClassName} ${className}) + { + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}.class); + util.exportExcel(response, list, "${functionName}数据"); + } + + /** + * 获取${functionName}详细信息 + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:query')") + @GetMapping(value = "/{${pkColumn.javaField}}") + public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}) + { + return success(${className}Service.select${ClassName}By${pkColumn.capJavaField}(${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}By${pkColumn.capJavaField}s(${pkColumn.javaField}s)); + } +} diff --git a/staffing-generator/src/main/resources/vm/java/domain.java.vm b/staffing-generator/src/main/resources/vm/java/domain.java.vm new file mode 100644 index 0000000..10e44b8 --- /dev/null +++ b/staffing-generator/src/main/resources/vm/java/domain.java.vm @@ -0,0 +1,101 @@ +package ${packageName}.domain; + +#foreach ($import in $importList) +import ${import}; +#end +import com.staffing.common.annotation.Excel; +#if($table.crud || $table.sub) +#elseif($table.tree) +#end + +/** + * ${functionName}对象 ${tableName} + * + * @author ${author} + * @date ${datetime} + */ +#if($table.crud || $table.sub) +#set($Entity="BaseEntity") +#elseif($table.tree) +#set($Entity="TreeEntity") +#end +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') + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd") +#else + @Excel(name = "${comment}") +#end +#end + private $column.javaType $column.javaField; + +#end +#end +#if($table.sub) + /** $table.subTable.functionName信息 */ + private List<${subClassName}> ${subclassName}List; + +#end +#foreach ($column in $columns) +#if(!$table.isSuperColumn($column.javaField)) +#if($column.javaField.length() > 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 + +#if($table.sub) + public List<${subClassName}> get${subClassName}List() + { + return ${subclassName}List; + } + + public void set${subClassName}List(List<${subClassName}> ${subclassName}List) + { + this.${subclassName}List = ${subclassName}List; + } + +#end + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) +#foreach ($column in $columns) +#if($column.javaField.length() > 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 +#if($table.sub) + .append("${subclassName}List", get${subClassName}List()) +#end + .toString(); + } +} diff --git a/staffing-generator/src/main/resources/vm/java/mapper.java.vm b/staffing-generator/src/main/resources/vm/java/mapper.java.vm new file mode 100644 index 0000000..7e7d7c2 --- /dev/null +++ b/staffing-generator/src/main/resources/vm/java/mapper.java.vm @@ -0,0 +1,91 @@ +package ${packageName}.mapper; + +import java.util.List; +import ${packageName}.domain.${ClassName}; +#if($table.sub) +import ${packageName}.domain.${subClassName}; +#end + +/** + * ${functionName}Mapper接口 + * + * @author ${author} + * @date ${datetime} + */ +public interface ${ClassName}Mapper +{ + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${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}主键 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的数据主键集合 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); +#if($table.sub) + + /** + * 批量删除${subTable.functionName} + * + * @param ${pkColumn.javaField}s 需要删除的数据主键集合 + * @return 结果 + */ + public int delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); + + /** + * 批量新增${subTable.functionName} + * + * @param ${subclassName}List ${subTable.functionName}列表 + * @return 结果 + */ + public int batch${subClassName}(List<${subClassName}> ${subclassName}List); + + + /** + * 通过${functionName}主键删除${subTable.functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}ID + * @return 结果 + */ + public int delete${subClassName}By${subTableFkClassName}(${pkColumn.javaType} ${pkColumn.javaField}); +#end +} diff --git a/staffing-generator/src/main/resources/vm/java/service.java.vm b/staffing-generator/src/main/resources/vm/java/service.java.vm new file mode 100644 index 0000000..264882b --- /dev/null +++ b/staffing-generator/src/main/resources/vm/java/service.java.vm @@ -0,0 +1,61 @@ +package ${packageName}.service; + +import java.util.List; +import ${packageName}.domain.${ClassName}; + +/** + * ${functionName}Service接口 + * + * @author ${author} + * @date ${datetime} + */ +public interface I${ClassName}Service +{ + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${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}主键集合 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); + + /** + * 删除${functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); +} diff --git a/staffing-generator/src/main/resources/vm/java/serviceImpl.java.vm b/staffing-generator/src/main/resources/vm/java/serviceImpl.java.vm new file mode 100644 index 0000000..0d048c7 --- /dev/null +++ b/staffing-generator/src/main/resources/vm/java/serviceImpl.java.vm @@ -0,0 +1,169 @@ +package ${packageName}.service.impl; + +import java.util.List; +#foreach ($column in $columns) +#if($column.javaField == 'createTime' || $column.javaField == 'updateTime') +import com.staffing.common.utils.DateUtils; +#break +#end +#end +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +#if($table.sub) +import java.util.ArrayList; +import com.staffing.common.utils.StringUtils; +import org.springframework.transaction.annotation.Transactional; +import ${packageName}.domain.${subClassName}; +#end +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}主键 + * @return ${functionName} + */ + @Override + public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) + { + return ${className}Mapper.select${ClassName}By${pkColumn.capJavaField}(${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 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int insert${ClassName}(${ClassName} ${className}) + { +#foreach ($column in $columns) +#if($column.javaField == 'createTime') + ${className}.setCreateTime(DateUtils.getNowDate()); +#end +#end +#if($table.sub) + int rows = ${className}Mapper.insert${ClassName}(${className}); + insert${subClassName}(${className}); + return rows; +#else + return ${className}Mapper.insert${ClassName}(${className}); +#end + } + + /** + * 修改${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int update${ClassName}(${ClassName} ${className}) + { +#foreach ($column in $columns) +#if($column.javaField == 'updateTime') + ${className}.setUpdateTime(DateUtils.getNowDate()); +#end +#end +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${className}.get${pkColumn.capJavaField}()); + insert${subClassName}(${className}); +#end + return ${className}Mapper.update${ClassName}(${className}); + } + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的${functionName}主键 + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s) + { +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaField}s); +#end + return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s); + } + + /** + * 删除${functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) + { +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${pkColumn.javaField}); +#end + return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}); + } +#if($table.sub) + + /** + * 新增${subTable.functionName}信息 + * + * @param ${className} ${functionName}对象 + */ + public void insert${subClassName}(${ClassName} ${className}) + { + List<${subClassName}> ${subclassName}List = ${className}.get${subClassName}List(); + ${pkColumn.javaType} ${pkColumn.javaField} = ${className}.get${pkColumn.capJavaField}(); + if (StringUtils.isNotNull(${subclassName}List)) + { + List<${subClassName}> list = new ArrayList<${subClassName}>(); + for (${subClassName} ${subclassName} : ${subclassName}List) + { + ${subclassName}.set${subTableFkClassName}(${pkColumn.javaField}); + list.add(${subclassName}); + } + if (list.size() > 0) + { + ${className}Mapper.batch${subClassName}(list); + } + } + } +#end +} diff --git a/staffing-generator/src/main/resources/vm/java/sub-domain.java.vm b/staffing-generator/src/main/resources/vm/java/sub-domain.java.vm new file mode 100644 index 0000000..0cd7b90 --- /dev/null +++ b/staffing-generator/src/main/resources/vm/java/sub-domain.java.vm @@ -0,0 +1,73 @@ +package ${packageName}.domain; + +#foreach ($import in $subImportList) +import ${import}; +#end +import com.staffing.common.annotation.Excel; + +/** + * ${subTable.functionName}对象 ${subTableName} + * + * @author ${author} + * @date ${datetime} + */ +public class ${subClassName} extends BaseEntity +{ + private static final long serialVersionUID = 1L; + +#foreach ($column in $subTable.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') + @JsonFormat(pattern = "yyyy-MM-dd") + @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 $subTable.columns) +#if(!$table.isSuperColumn($column.javaField)) +#if($column.javaField.length() > 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 $subTable.columns) +#if($column.javaField.length() > 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/staffing-generator/src/main/resources/vm/js/api.js.vm b/staffing-generator/src/main/resources/vm/js/api.js.vm new file mode 100644 index 0000000..9295524 --- /dev/null +++ b/staffing-generator/src/main/resources/vm/js/api.js.vm @@ -0,0 +1,44 @@ +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' + }) +} diff --git a/staffing-generator/src/main/resources/vm/sql/sql.vm b/staffing-generator/src/main/resources/vm/sql/sql.vm new file mode 100644 index 0000000..0575583 --- /dev/null +++ b/staffing-generator/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, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}', '${parentMenuId}', '1', '${businessName}', '${moduleName}/${businessName}/index', 1, 0, 'C', '0', '0', '${permissionPrefix}:list', '#', 'admin', sysdate(), '', null, '${functionName}菜单'); + +-- 按钮父菜单ID +SELECT @parentId := LAST_INSERT_ID(); + +-- 按钮 SQL +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}查询', @parentId, '1', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:query', '#', 'admin', sysdate(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}新增', @parentId, '2', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:add', '#', 'admin', sysdate(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}修改', @parentId, '3', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:edit', '#', 'admin', sysdate(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}删除', @parentId, '4', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:remove', '#', 'admin', sysdate(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}导出', @parentId, '5', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:export', '#', 'admin', sysdate(), '', null, ''); \ No newline at end of file diff --git a/staffing-generator/src/main/resources/vm/vue/index-tree.vue.vm b/staffing-generator/src/main/resources/vm/vue/index-tree.vue.vm new file mode 100644 index 0000000..4819c2a --- /dev/null +++ b/staffing-generator/src/main/resources/vm/vue/index-tree.vue.vm @@ -0,0 +1,505 @@ + + + diff --git a/staffing-generator/src/main/resources/vm/vue/index.vue.vm b/staffing-generator/src/main/resources/vm/vue/index.vue.vm new file mode 100644 index 0000000..6296014 --- /dev/null +++ b/staffing-generator/src/main/resources/vm/vue/index.vue.vm @@ -0,0 +1,602 @@ + + + diff --git a/staffing-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm b/staffing-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm new file mode 100644 index 0000000..c54d62b --- /dev/null +++ b/staffing-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm @@ -0,0 +1,474 @@ + + + diff --git a/staffing-generator/src/main/resources/vm/vue/v3/index.vue.vm b/staffing-generator/src/main/resources/vm/vue/v3/index.vue.vm new file mode 100644 index 0000000..8b25665 --- /dev/null +++ b/staffing-generator/src/main/resources/vm/vue/v3/index.vue.vm @@ -0,0 +1,590 @@ + + + diff --git a/staffing-generator/src/main/resources/vm/xml/mapper.xml.vm b/staffing-generator/src/main/resources/vm/xml/mapper.xml.vm new file mode 100644 index 0000000..456755b --- /dev/null +++ b/staffing-generator/src/main/resources/vm/xml/mapper.xml.vm @@ -0,0 +1,140 @@ + + + + + +#foreach ($column in $columns) + +#end + +#if($table.sub) + + + + + + +#foreach ($column in $subTable.columns) + +#end + +#end + + + select#foreach($column in $columns) $column.columnName#if($foreach.count != $columns.size()),#end#end from ${tableName} + + + + + +#if($table.sub) + + +#end + + + insert into ${tableName} + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment) + $column.columnName, +#end +#end + + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment) + #{$column.javaField}, +#end +#end + + + + + update ${tableName} + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName) + $column.columnName = #{$column.javaField}, +#end +#end + + where ${pkColumn.columnName} = #{${pkColumn.javaField}} + + + + delete from ${tableName} where ${pkColumn.columnName} = #{${pkColumn.javaField}} + + + + delete from ${tableName} where ${pkColumn.columnName} in + + #{${pkColumn.javaField}} + + +#if($table.sub) + + + delete from ${subTableName} where ${subTableFkName} in + + #{${subTableFkclassName}} + + + + + delete from ${subTableName} where ${subTableFkName} = #{${subTableFkclassName}} + + + + insert into ${subTableName}(#foreach($column in $subTable.columns) $column.columnName#if($foreach.count != $subTable.columns.size()),#end#end) values + + (#foreach($column in $subTable.columns) #{item.$column.javaField}#if($foreach.count != $subTable.columns.size()),#end#end) + + +#end + \ No newline at end of file diff --git a/staffing-quartz/pom.xml b/staffing-quartz/pom.xml new file mode 100644 index 0000000..b8e3b66 --- /dev/null +++ b/staffing-quartz/pom.xml @@ -0,0 +1,40 @@ + + + + staffing + com.staffing + 3.8.8 + + 4.0.0 + + staffing-quartz + + + quartz定时任务 + + + + + + + org.quartz-scheduler + quartz + + + com.mchange + c3p0 + + + + + + + com.staffing + staffing-common + + + + + \ No newline at end of file diff --git a/staffing-quartz/src/main/java/com/staffing/quartz/config/ScheduleConfig.java b/staffing-quartz/src/main/java/com/staffing/quartz/config/ScheduleConfig.java new file mode 100644 index 0000000..1f5c7e8 --- /dev/null +++ b/staffing-quartz/src/main/java/com/staffing/quartz/config/ScheduleConfig.java @@ -0,0 +1,57 @@ +//package com.staffing.quartz.config; +// +//import org.springframework.context.annotation.Bean; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.scheduling.quartz.SchedulerFactoryBean; +//import javax.sql.DataSource; +//import java.util.Properties; +// +///** +// * 定时任务配置(单机部署建议删除此类和qrtz数据库表,默认走内存会最高效) +// * +// * @author staffing +// */ +//@Configuration +//public class ScheduleConfig +//{ +// @Bean +// public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) +// { +// SchedulerFactoryBean factory = new SchedulerFactoryBean(); +// factory.setDataSource(dataSource); +// +// // quartz参数 +// Properties prop = new Properties(); +// prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler"); +// prop.put("org.quartz.scheduler.instanceId", "AUTO"); +// // 线程池配置 +// prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); +// prop.put("org.quartz.threadPool.threadCount", "20"); +// prop.put("org.quartz.threadPool.threadPriority", "5"); +// // JobStore配置 +// prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore"); +// // 集群配置 +// prop.put("org.quartz.jobStore.isClustered", "true"); +// prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); +// prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "10"); +// prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true"); +// +// // sqlserver 启用 +// // prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); +// prop.put("org.quartz.jobStore.misfireThreshold", "12000"); +// prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_"); +// factory.setQuartzProperties(prop); +// +// factory.setSchedulerName("RuoyiScheduler"); +// // 延时启动 +// factory.setStartupDelay(1); +// factory.setApplicationContextSchedulerContextKey("applicationContextKey"); +// // 可选,QuartzScheduler +// // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 +// factory.setOverwriteExistingJobs(true); +// // 设置自动启动,默认为true +// factory.setAutoStartup(true); +// +// return factory; +// } +//} diff --git a/staffing-quartz/src/main/java/com/staffing/quartz/controller/SysJobController.java b/staffing-quartz/src/main/java/com/staffing/quartz/controller/SysJobController.java new file mode 100644 index 0000000..a2aeee5 --- /dev/null +++ b/staffing-quartz/src/main/java/com/staffing/quartz/controller/SysJobController.java @@ -0,0 +1,185 @@ +package com.staffing.quartz.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.quartz.SchedulerException; +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.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.staffing.common.annotation.Log; +import com.staffing.common.constant.Constants; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.page.TableDataInfo; +import com.staffing.common.enums.BusinessType; +import com.staffing.common.exception.job.TaskException; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.poi.ExcelUtil; +import com.staffing.quartz.domain.SysJob; +import com.staffing.quartz.service.ISysJobService; +import com.staffing.quartz.util.CronUtils; +import com.staffing.quartz.util.ScheduleUtils; + +/** + * 调度任务信息操作处理 + * + * @author staffing + */ +@RestController +@RequestMapping("/monitor/job") +public class SysJobController extends BaseController +{ + @Autowired + private ISysJobService jobService; + + /** + * 查询定时任务列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:list')") + @GetMapping("/list") + public TableDataInfo list(SysJob sysJob) + { + startPage(); + List list = jobService.selectJobList(sysJob); + return getDataTable(list); + } + + /** + * 导出定时任务列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:export')") + @Log(title = "定时任务", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysJob sysJob) + { + List list = jobService.selectJobList(sysJob); + ExcelUtil util = new ExcelUtil(SysJob.class); + util.exportExcel(response, list, "定时任务"); + } + + /** + * 获取定时任务详细信息 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:query')") + @GetMapping(value = "/{jobId}") + public AjaxResult getInfo(@PathVariable("jobId") Long jobId) + { + return success(jobService.selectJobById(jobId)); + } + + /** + * 新增定时任务 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:add')") + @Log(title = "定时任务", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysJob job) throws SchedulerException, TaskException + { + if (!CronUtils.isValid(job.getCronExpression())) + { + return error("新增任务'" + job.getJobName() + "'失败,Cron表达式不正确"); + } + else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS })) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串存在违规"); + } + else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不在白名单内"); + } + job.setCreateBy(getUsername()); + return toAjax(jobService.insertJob(job)); + } + + /** + * 修改定时任务 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:edit')") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysJob job) throws SchedulerException, TaskException + { + if (!CronUtils.isValid(job.getCronExpression())) + { + return error("修改任务'" + job.getJobName() + "'失败,Cron表达式不正确"); + } + else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS })) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串存在违规"); + } + else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不在白名单内"); + } + job.setUpdateBy(getUsername()); + return toAjax(jobService.updateJob(job)); + } + + /** + * 定时任务状态修改 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysJob job) throws SchedulerException + { + SysJob newJob = jobService.selectJobById(job.getJobId()); + newJob.setStatus(job.getStatus()); + return toAjax(jobService.changeStatus(newJob)); + } + + /** + * 定时任务立即执行一次 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping("/run") + public AjaxResult run(@RequestBody SysJob job) throws SchedulerException + { + boolean result = jobService.run(job); + return result ? success() : error("任务不存在或已过期!"); + } + + /** + * 删除定时任务 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:remove')") + @Log(title = "定时任务", businessType = BusinessType.DELETE) + @DeleteMapping("/{jobIds}") + public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException + { + jobService.deleteJobByIds(jobIds); + return success(); + } +} diff --git a/staffing-quartz/src/main/java/com/staffing/quartz/controller/SysJobLogController.java b/staffing-quartz/src/main/java/com/staffing/quartz/controller/SysJobLogController.java new file mode 100644 index 0000000..148374d --- /dev/null +++ b/staffing-quartz/src/main/java/com/staffing/quartz/controller/SysJobLogController.java @@ -0,0 +1,92 @@ +package com.staffing.quartz.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +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.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.staffing.common.annotation.Log; +import com.staffing.common.core.controller.BaseController; +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.page.TableDataInfo; +import com.staffing.common.enums.BusinessType; +import com.staffing.common.utils.poi.ExcelUtil; +import com.staffing.quartz.domain.SysJobLog; +import com.staffing.quartz.service.ISysJobLogService; + +/** + * 调度日志操作处理 + * + * @author staffing + */ +@RestController +@RequestMapping("/monitor/jobLog") +public class SysJobLogController extends BaseController +{ + @Autowired + private ISysJobLogService jobLogService; + + /** + * 查询定时任务调度日志列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:list')") + @GetMapping("/list") + public TableDataInfo list(SysJobLog sysJobLog) + { + startPage(); + List list = jobLogService.selectJobLogList(sysJobLog); + return getDataTable(list); + } + + /** + * 导出定时任务调度日志列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:export')") + @Log(title = "任务调度日志", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysJobLog sysJobLog) + { + List list = jobLogService.selectJobLogList(sysJobLog); + ExcelUtil util = new ExcelUtil(SysJobLog.class); + util.exportExcel(response, list, "调度日志"); + } + + /** + * 根据调度编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:query')") + @GetMapping(value = "/{jobLogId}") + public AjaxResult getInfo(@PathVariable Long jobLogId) + { + return success(jobLogService.selectJobLogById(jobLogId)); + } + + + /** + * 删除定时任务调度日志 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:remove')") + @Log(title = "定时任务调度日志", businessType = BusinessType.DELETE) + @DeleteMapping("/{jobLogIds}") + public AjaxResult remove(@PathVariable Long[] jobLogIds) + { + return toAjax(jobLogService.deleteJobLogByIds(jobLogIds)); + } + + /** + * 清空定时任务调度日志 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:remove')") + @Log(title = "调度日志", businessType = BusinessType.CLEAN) + @DeleteMapping("/clean") + public AjaxResult clean() + { + jobLogService.cleanJobLog(); + return success(); + } +} diff --git a/staffing-quartz/src/main/java/com/staffing/quartz/domain/SysJob.java b/staffing-quartz/src/main/java/com/staffing/quartz/domain/SysJob.java new file mode 100644 index 0000000..2b89dbe --- /dev/null +++ b/staffing-quartz/src/main/java/com/staffing/quartz/domain/SysJob.java @@ -0,0 +1,171 @@ +package com.staffing.quartz.domain; + +import java.util.Date; +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.fasterxml.jackson.annotation.JsonFormat; +import com.staffing.common.annotation.Excel; +import com.staffing.common.annotation.Excel.ColumnType; +import com.staffing.common.constant.ScheduleConstants; +import com.staffing.common.core.domain.BaseEntity; +import com.staffing.common.utils.StringUtils; +import com.staffing.quartz.util.CronUtils; + +/** + * 定时任务调度表 sys_job + * + * @author staffing + */ +public class SysJob extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 任务ID */ + @Excel(name = "任务序号", cellType = ColumnType.NUMERIC) + private Long jobId; + + /** 任务名称 */ + @Excel(name = "任务名称") + private String jobName; + + /** 任务组名 */ + @Excel(name = "任务组名") + private String jobGroup; + + /** 调用目标字符串 */ + @Excel(name = "调用目标字符串") + private String invokeTarget; + + /** cron执行表达式 */ + @Excel(name = "执行表达式 ") + private String cronExpression; + + /** cron计划策略 */ + @Excel(name = "计划策略 ", readConverterExp = "0=默认,1=立即触发执行,2=触发一次执行,3=不触发立即执行") + private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT; + + /** 是否并发执行(0允许 1禁止) */ + @Excel(name = "并发执行", readConverterExp = "0=允许,1=禁止") + private String concurrent; + + /** 任务状态(0正常 1暂停) */ + @Excel(name = "任务状态", readConverterExp = "0=正常,1=暂停") + private String status; + + public Long getJobId() + { + return jobId; + } + + public void setJobId(Long jobId) + { + this.jobId = jobId; + } + + @NotBlank(message = "任务名称不能为空") + @Size(min = 0, max = 64, message = "任务名称不能超过64个字符") + public String getJobName() + { + return jobName; + } + + public void setJobName(String jobName) + { + this.jobName = jobName; + } + + public String getJobGroup() + { + return jobGroup; + } + + public void setJobGroup(String jobGroup) + { + this.jobGroup = jobGroup; + } + + @NotBlank(message = "调用目标字符串不能为空") + @Size(min = 0, max = 500, message = "调用目标字符串长度不能超过500个字符") + public String getInvokeTarget() + { + return invokeTarget; + } + + public void setInvokeTarget(String invokeTarget) + { + this.invokeTarget = invokeTarget; + } + + @NotBlank(message = "Cron执行表达式不能为空") + @Size(min = 0, max = 255, message = "Cron执行表达式不能超过255个字符") + public String getCronExpression() + { + return cronExpression; + } + + public void setCronExpression(String cronExpression) + { + this.cronExpression = cronExpression; + } + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + public Date getNextValidTime() + { + if (StringUtils.isNotEmpty(cronExpression)) + { + return CronUtils.getNextExecution(cronExpression); + } + return null; + } + + public String getMisfirePolicy() + { + return misfirePolicy; + } + + public void setMisfirePolicy(String misfirePolicy) + { + this.misfirePolicy = misfirePolicy; + } + + public String getConcurrent() + { + return concurrent; + } + + public void setConcurrent(String concurrent) + { + this.concurrent = concurrent; + } + + 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("jobId", getJobId()) + .append("jobName", getJobName()) + .append("jobGroup", getJobGroup()) + .append("cronExpression", getCronExpression()) + .append("nextValidTime", getNextValidTime()) + .append("misfirePolicy", getMisfirePolicy()) + .append("concurrent", getConcurrent()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/staffing-quartz/src/main/java/com/staffing/quartz/domain/SysJobLog.java b/staffing-quartz/src/main/java/com/staffing/quartz/domain/SysJobLog.java new file mode 100644 index 0000000..d638eb7 --- /dev/null +++ b/staffing-quartz/src/main/java/com/staffing/quartz/domain/SysJobLog.java @@ -0,0 +1,155 @@ +package com.staffing.quartz.domain; + +import java.util.Date; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.staffing.common.annotation.Excel; +import com.staffing.common.core.domain.BaseEntity; + +/** + * 定时任务调度日志表 sys_job_log + * + * @author staffing + */ +public class SysJobLog extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** ID */ + @Excel(name = "日志序号") + private Long jobLogId; + + /** 任务名称 */ + @Excel(name = "任务名称") + private String jobName; + + /** 任务组名 */ + @Excel(name = "任务组名") + private String jobGroup; + + /** 调用目标字符串 */ + @Excel(name = "调用目标字符串") + private String invokeTarget; + + /** 日志信息 */ + @Excel(name = "日志信息") + private String jobMessage; + + /** 执行状态(0正常 1失败) */ + @Excel(name = "执行状态", readConverterExp = "0=正常,1=失败") + private String status; + + /** 异常信息 */ + @Excel(name = "异常信息") + private String exceptionInfo; + + /** 开始时间 */ + private Date startTime; + + /** 停止时间 */ + private Date stopTime; + + public Long getJobLogId() + { + return jobLogId; + } + + public void setJobLogId(Long jobLogId) + { + this.jobLogId = jobLogId; + } + + public String getJobName() + { + return jobName; + } + + public void setJobName(String jobName) + { + this.jobName = jobName; + } + + public String getJobGroup() + { + return jobGroup; + } + + public void setJobGroup(String jobGroup) + { + this.jobGroup = jobGroup; + } + + public String getInvokeTarget() + { + return invokeTarget; + } + + public void setInvokeTarget(String invokeTarget) + { + this.invokeTarget = invokeTarget; + } + + public String getJobMessage() + { + return jobMessage; + } + + public void setJobMessage(String jobMessage) + { + this.jobMessage = jobMessage; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getExceptionInfo() + { + return exceptionInfo; + } + + public void setExceptionInfo(String exceptionInfo) + { + this.exceptionInfo = exceptionInfo; + } + + public Date getStartTime() + { + return startTime; + } + + public void setStartTime(Date startTime) + { + this.startTime = startTime; + } + + public Date getStopTime() + { + return stopTime; + } + + public void setStopTime(Date stopTime) + { + this.stopTime = stopTime; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("jobLogId", getJobLogId()) + .append("jobName", getJobName()) + .append("jobGroup", getJobGroup()) + .append("jobMessage", getJobMessage()) + .append("status", getStatus()) + .append("exceptionInfo", getExceptionInfo()) + .append("startTime", getStartTime()) + .append("stopTime", getStopTime()) + .toString(); + } +} diff --git a/staffing-quartz/src/main/java/com/staffing/quartz/mapper/SysJobLogMapper.java b/staffing-quartz/src/main/java/com/staffing/quartz/mapper/SysJobLogMapper.java new file mode 100644 index 0000000..2e6f4c9 --- /dev/null +++ b/staffing-quartz/src/main/java/com/staffing/quartz/mapper/SysJobLogMapper.java @@ -0,0 +1,64 @@ +package com.staffing.quartz.mapper; + +import java.util.List; +import com.staffing.quartz.domain.SysJobLog; + +/** + * 调度任务日志信息 数据层 + * + * @author staffing + */ +public interface SysJobLogMapper +{ + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + public List selectJobLogList(SysJobLog jobLog); + + /** + * 查询所有调度任务日志 + * + * @return 调度任务日志列表 + */ + public List selectJobLogAll(); + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + public SysJobLog selectJobLogById(Long jobLogId); + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + * @return 结果 + */ + public int insertJobLog(SysJobLog jobLog); + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的数据ID + * @return 结果 + */ + public int deleteJobLogByIds(Long[] logIds); + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + * @return 结果 + */ + public int deleteJobLogById(Long jobId); + + /** + * 清空任务日志 + */ + public void cleanJobLog(); +} diff --git a/staffing-quartz/src/main/java/com/staffing/quartz/mapper/SysJobMapper.java b/staffing-quartz/src/main/java/com/staffing/quartz/mapper/SysJobMapper.java new file mode 100644 index 0000000..9ed4ddc --- /dev/null +++ b/staffing-quartz/src/main/java/com/staffing/quartz/mapper/SysJobMapper.java @@ -0,0 +1,67 @@ +package com.staffing.quartz.mapper; + +import java.util.List; +import com.staffing.quartz.domain.SysJob; + +/** + * 调度任务信息 数据层 + * + * @author staffing + */ +public interface SysJobMapper +{ + /** + * 查询调度任务日志集合 + * + * @param job 调度信息 + * @return 操作日志集合 + */ + public List selectJobList(SysJob job); + + /** + * 查询所有调度任务 + * + * @return 调度任务列表 + */ + public List selectJobAll(); + + /** + * 通过调度ID查询调度任务信息 + * + * @param jobId 调度ID + * @return 角色对象信息 + */ + public SysJob selectJobById(Long jobId); + + /** + * 通过调度ID删除调度任务信息 + * + * @param jobId 调度ID + * @return 结果 + */ + public int deleteJobById(Long jobId); + + /** + * 批量删除调度任务信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteJobByIds(Long[] ids); + + /** + * 修改调度任务信息 + * + * @param job 调度任务信息 + * @return 结果 + */ + public int updateJob(SysJob job); + + /** + * 新增调度任务信息 + * + * @param job 调度任务信息 + * @return 结果 + */ + public int insertJob(SysJob job); +} diff --git a/staffing-quartz/src/main/java/com/staffing/quartz/service/ISysJobLogService.java b/staffing-quartz/src/main/java/com/staffing/quartz/service/ISysJobLogService.java new file mode 100644 index 0000000..46576e1 --- /dev/null +++ b/staffing-quartz/src/main/java/com/staffing/quartz/service/ISysJobLogService.java @@ -0,0 +1,56 @@ +package com.staffing.quartz.service; + +import java.util.List; +import com.staffing.quartz.domain.SysJobLog; + +/** + * 定时任务调度日志信息信息 服务层 + * + * @author staffing + */ +public interface ISysJobLogService +{ + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + public List selectJobLogList(SysJobLog jobLog); + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + public SysJobLog selectJobLogById(Long jobLogId); + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + */ + public void addJobLog(SysJobLog jobLog); + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的日志ID + * @return 结果 + */ + public int deleteJobLogByIds(Long[] logIds); + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + * @return 结果 + */ + public int deleteJobLogById(Long jobId); + + /** + * 清空任务日志 + */ + public void cleanJobLog(); +} diff --git a/staffing-quartz/src/main/java/com/staffing/quartz/service/ISysJobService.java b/staffing-quartz/src/main/java/com/staffing/quartz/service/ISysJobService.java new file mode 100644 index 0000000..18fad51 --- /dev/null +++ b/staffing-quartz/src/main/java/com/staffing/quartz/service/ISysJobService.java @@ -0,0 +1,102 @@ +package com.staffing.quartz.service; + +import java.util.List; +import org.quartz.SchedulerException; +import com.staffing.common.exception.job.TaskException; +import com.staffing.quartz.domain.SysJob; + +/** + * 定时任务调度信息信息 服务层 + * + * @author staffing + */ +public interface ISysJobService +{ + /** + * 获取quartz调度器的计划任务 + * + * @param job 调度信息 + * @return 调度任务集合 + */ + public List selectJobList(SysJob job); + + /** + * 通过调度任务ID查询调度信息 + * + * @param jobId 调度任务ID + * @return 调度任务对象信息 + */ + public SysJob selectJobById(Long jobId); + + /** + * 暂停任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int pauseJob(SysJob job) throws SchedulerException; + + /** + * 恢复任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int resumeJob(SysJob job) throws SchedulerException; + + /** + * 删除任务后,所对应的trigger也将被删除 + * + * @param job 调度信息 + * @return 结果 + */ + public int deleteJob(SysJob job) throws SchedulerException; + + /** + * 批量删除调度信息 + * + * @param jobIds 需要删除的任务ID + * @return 结果 + */ + public void deleteJobByIds(Long[] jobIds) throws SchedulerException; + + /** + * 任务调度状态修改 + * + * @param job 调度信息 + * @return 结果 + */ + public int changeStatus(SysJob job) throws SchedulerException; + + /** + * 立即运行任务 + * + * @param job 调度信息 + * @return 结果 + */ + public boolean run(SysJob job) throws SchedulerException; + + /** + * 新增任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int insertJob(SysJob job) throws SchedulerException, TaskException; + + /** + * 更新任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int updateJob(SysJob job) throws SchedulerException, TaskException; + + /** + * 校验cron表达式是否有效 + * + * @param cronExpression 表达式 + * @return 结果 + */ + public boolean checkCronExpressionIsValid(String cronExpression); +} diff --git a/staffing-quartz/src/main/java/com/staffing/quartz/service/impl/SysJobLogServiceImpl.java b/staffing-quartz/src/main/java/com/staffing/quartz/service/impl/SysJobLogServiceImpl.java new file mode 100644 index 0000000..4bfafd9 --- /dev/null +++ b/staffing-quartz/src/main/java/com/staffing/quartz/service/impl/SysJobLogServiceImpl.java @@ -0,0 +1,87 @@ +package com.staffing.quartz.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.staffing.quartz.domain.SysJobLog; +import com.staffing.quartz.mapper.SysJobLogMapper; +import com.staffing.quartz.service.ISysJobLogService; + +/** + * 定时任务调度日志信息 服务层 + * + * @author staffing + */ +@Service +public class SysJobLogServiceImpl implements ISysJobLogService +{ + @Autowired + private SysJobLogMapper jobLogMapper; + + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + @Override + public List selectJobLogList(SysJobLog jobLog) + { + return jobLogMapper.selectJobLogList(jobLog); + } + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + @Override + public SysJobLog selectJobLogById(Long jobLogId) + { + return jobLogMapper.selectJobLogById(jobLogId); + } + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + */ + @Override + public void addJobLog(SysJobLog jobLog) + { + jobLogMapper.insertJobLog(jobLog); + } + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的数据ID + * @return 结果 + */ + @Override + public int deleteJobLogByIds(Long[] logIds) + { + return jobLogMapper.deleteJobLogByIds(logIds); + } + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + */ + @Override + public int deleteJobLogById(Long jobId) + { + return jobLogMapper.deleteJobLogById(jobId); + } + + /** + * 清空任务日志 + */ + @Override + public void cleanJobLog() + { + jobLogMapper.cleanJobLog(); + } +} diff --git a/staffing-quartz/src/main/java/com/staffing/quartz/service/impl/SysJobServiceImpl.java b/staffing-quartz/src/main/java/com/staffing/quartz/service/impl/SysJobServiceImpl.java new file mode 100644 index 0000000..4fa2d1f --- /dev/null +++ b/staffing-quartz/src/main/java/com/staffing/quartz/service/impl/SysJobServiceImpl.java @@ -0,0 +1,261 @@ +package com.staffing.quartz.service.impl; + +import java.util.List; +import javax.annotation.PostConstruct; +import org.quartz.JobDataMap; +import org.quartz.JobKey; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.staffing.common.constant.ScheduleConstants; +import com.staffing.common.exception.job.TaskException; +import com.staffing.quartz.domain.SysJob; +import com.staffing.quartz.mapper.SysJobMapper; +import com.staffing.quartz.service.ISysJobService; +import com.staffing.quartz.util.CronUtils; +import com.staffing.quartz.util.ScheduleUtils; + +/** + * 定时任务调度信息 服务层 + * + * @author staffing + */ +@Service +public class SysJobServiceImpl implements ISysJobService +{ + @Autowired + private Scheduler scheduler; + + @Autowired + private SysJobMapper jobMapper; + + /** + * 项目启动时,初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理(注:不能手动修改数据库ID和任务组名,否则会导致脏数据) + */ + @PostConstruct + public void init() throws SchedulerException, TaskException + { + scheduler.clear(); + List jobList = jobMapper.selectJobAll(); + for (SysJob job : jobList) + { + ScheduleUtils.createScheduleJob(scheduler, job); + } + } + + /** + * 获取quartz调度器的计划任务列表 + * + * @param job 调度信息 + * @return + */ + @Override + public List selectJobList(SysJob job) + { + return jobMapper.selectJobList(job); + } + + /** + * 通过调度任务ID查询调度信息 + * + * @param jobId 调度任务ID + * @return 调度任务对象信息 + */ + @Override + public SysJob selectJobById(Long jobId) + { + return jobMapper.selectJobById(jobId); + } + + /** + * 暂停任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int pauseJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 恢复任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int resumeJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + job.setStatus(ScheduleConstants.Status.NORMAL.getValue()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + scheduler.resumeJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 删除任务后,所对应的trigger也将被删除 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + int rows = jobMapper.deleteJobById(jobId); + if (rows > 0) + { + scheduler.deleteJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 批量删除调度信息 + * + * @param jobIds 需要删除的任务ID + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteJobByIds(Long[] jobIds) throws SchedulerException + { + for (Long jobId : jobIds) + { + SysJob job = jobMapper.selectJobById(jobId); + deleteJob(job); + } + } + + /** + * 任务调度状态修改 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int changeStatus(SysJob job) throws SchedulerException + { + int rows = 0; + String status = job.getStatus(); + if (ScheduleConstants.Status.NORMAL.getValue().equals(status)) + { + rows = resumeJob(job); + } + else if (ScheduleConstants.Status.PAUSE.getValue().equals(status)) + { + rows = pauseJob(job); + } + return rows; + } + + /** + * 立即运行任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean run(SysJob job) throws SchedulerException + { + boolean result = false; + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + SysJob properties = selectJobById(job.getJobId()); + // 参数 + JobDataMap dataMap = new JobDataMap(); + dataMap.put(ScheduleConstants.TASK_PROPERTIES, properties); + JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup); + if (scheduler.checkExists(jobKey)) + { + result = true; + scheduler.triggerJob(jobKey, dataMap); + } + return result; + } + + /** + * 新增任务 + * + * @param job 调度信息 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int insertJob(SysJob job) throws SchedulerException, TaskException + { + job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); + int rows = jobMapper.insertJob(job); + if (rows > 0) + { + ScheduleUtils.createScheduleJob(scheduler, job); + } + return rows; + } + + /** + * 更新任务的时间表达式 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int updateJob(SysJob job) throws SchedulerException, TaskException + { + SysJob properties = selectJobById(job.getJobId()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + updateSchedulerJob(job, properties.getJobGroup()); + } + return rows; + } + + /** + * 更新任务 + * + * @param job 任务对象 + * @param jobGroup 任务组名 + */ + public void updateSchedulerJob(SysJob job, String jobGroup) throws SchedulerException, TaskException + { + Long jobId = job.getJobId(); + // 判断是否存在 + JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup); + if (scheduler.checkExists(jobKey)) + { + // 防止创建时存在数据问题 先移除,然后在执行创建操作 + scheduler.deleteJob(jobKey); + } + ScheduleUtils.createScheduleJob(scheduler, job); + } + + /** + * 校验cron表达式是否有效 + * + * @param cronExpression 表达式 + * @return 结果 + */ + @Override + public boolean checkCronExpressionIsValid(String cronExpression) + { + return CronUtils.isValid(cronExpression); + } +} diff --git a/staffing-quartz/src/main/java/com/staffing/quartz/task/RyTask.java b/staffing-quartz/src/main/java/com/staffing/quartz/task/RyTask.java new file mode 100644 index 0000000..e349745 --- /dev/null +++ b/staffing-quartz/src/main/java/com/staffing/quartz/task/RyTask.java @@ -0,0 +1,28 @@ +package com.staffing.quartz.task; + +import org.springframework.stereotype.Component; +import com.staffing.common.utils.StringUtils; + +/** + * 定时任务调度测试 + * + * @author staffing + */ +@Component("ryTask") +public class RyTask +{ + public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) + { + System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i)); + } + + public void ryParams(String params) + { + System.out.println("执行有参方法:" + params); + } + + public void ryNoParams() + { + System.out.println("执行无参方法"); + } +} diff --git a/staffing-quartz/src/main/java/com/staffing/quartz/util/AbstractQuartzJob.java b/staffing-quartz/src/main/java/com/staffing/quartz/util/AbstractQuartzJob.java new file mode 100644 index 0000000..1044dff --- /dev/null +++ b/staffing-quartz/src/main/java/com/staffing/quartz/util/AbstractQuartzJob.java @@ -0,0 +1,107 @@ +package com.staffing.quartz.util; + +import java.util.Date; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.staffing.common.constant.Constants; +import com.staffing.common.constant.ScheduleConstants; +import com.staffing.common.utils.ExceptionUtil; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.bean.BeanUtils; +import com.staffing.common.utils.spring.SpringUtils; +import com.staffing.quartz.domain.SysJob; +import com.staffing.quartz.domain.SysJobLog; +import com.staffing.quartz.service.ISysJobLogService; + +/** + * 抽象quartz调用 + * + * @author staffing + */ +public abstract class AbstractQuartzJob implements Job +{ + private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class); + + /** + * 线程本地变量 + */ + private static ThreadLocal threadLocal = new ThreadLocal<>(); + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException + { + SysJob sysJob = new SysJob(); + BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES)); + try + { + before(context, sysJob); + if (sysJob != null) + { + doExecute(context, sysJob); + } + after(context, sysJob, null); + } + catch (Exception e) + { + log.error("任务执行异常 - :", e); + after(context, sysJob, e); + } + } + + /** + * 执行前 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + */ + protected void before(JobExecutionContext context, SysJob sysJob) + { + threadLocal.set(new Date()); + } + + /** + * 执行后 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + */ + protected void after(JobExecutionContext context, SysJob sysJob, Exception e) + { + Date startTime = threadLocal.get(); + threadLocal.remove(); + + final SysJobLog sysJobLog = new SysJobLog(); + sysJobLog.setJobName(sysJob.getJobName()); + sysJobLog.setJobGroup(sysJob.getJobGroup()); + sysJobLog.setInvokeTarget(sysJob.getInvokeTarget()); + sysJobLog.setStartTime(startTime); + sysJobLog.setStopTime(new Date()); + long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime(); + sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒"); + if (e != null) + { + sysJobLog.setStatus(Constants.FAIL); + String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000); + sysJobLog.setExceptionInfo(errorMsg); + } + else + { + sysJobLog.setStatus(Constants.SUCCESS); + } + + // 写入数据库当中 + SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog); + } + + /** + * 执行方法,由子类重载 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + * @throws Exception 执行过程中的异常 + */ + protected abstract void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception; +} diff --git a/staffing-quartz/src/main/java/com/staffing/quartz/util/CronUtils.java b/staffing-quartz/src/main/java/com/staffing/quartz/util/CronUtils.java new file mode 100644 index 0000000..3a771bb --- /dev/null +++ b/staffing-quartz/src/main/java/com/staffing/quartz/util/CronUtils.java @@ -0,0 +1,63 @@ +package com.staffing.quartz.util; + +import java.text.ParseException; +import java.util.Date; +import org.quartz.CronExpression; + +/** + * cron表达式工具类 + * + * @author staffing + * + */ +public class CronUtils +{ + /** + * 返回一个布尔值代表一个给定的Cron表达式的有效性 + * + * @param cronExpression Cron表达式 + * @return boolean 表达式是否有效 + */ + public static boolean isValid(String cronExpression) + { + return CronExpression.isValidExpression(cronExpression); + } + + /** + * 返回一个字符串值,表示该消息无效Cron表达式给出有效性 + * + * @param cronExpression Cron表达式 + * @return String 无效时返回表达式错误描述,如果有效返回null + */ + public static String getInvalidMessage(String cronExpression) + { + try + { + new CronExpression(cronExpression); + return null; + } + catch (ParseException pe) + { + return pe.getMessage(); + } + } + + /** + * 返回下一个执行时间根据给定的Cron表达式 + * + * @param cronExpression Cron表达式 + * @return Date 下次Cron表达式执行时间 + */ + public static Date getNextExecution(String cronExpression) + { + try + { + CronExpression cron = new CronExpression(cronExpression); + return cron.getNextValidTimeAfter(new Date(System.currentTimeMillis())); + } + catch (ParseException e) + { + throw new IllegalArgumentException(e.getMessage()); + } + } +} diff --git a/staffing-quartz/src/main/java/com/staffing/quartz/util/JobInvokeUtil.java b/staffing-quartz/src/main/java/com/staffing/quartz/util/JobInvokeUtil.java new file mode 100644 index 0000000..ca5b5e8 --- /dev/null +++ b/staffing-quartz/src/main/java/com/staffing/quartz/util/JobInvokeUtil.java @@ -0,0 +1,182 @@ +package com.staffing.quartz.util; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.List; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.spring.SpringUtils; +import com.staffing.quartz.domain.SysJob; + +/** + * 任务执行工具 + * + * @author staffing + */ +public class JobInvokeUtil +{ + /** + * 执行方法 + * + * @param sysJob 系统任务 + */ + public static void invokeMethod(SysJob sysJob) throws Exception + { + String invokeTarget = sysJob.getInvokeTarget(); + String beanName = getBeanName(invokeTarget); + String methodName = getMethodName(invokeTarget); + List methodParams = getMethodParams(invokeTarget); + + if (!isValidClassName(beanName)) + { + Object bean = SpringUtils.getBean(beanName); + invokeMethod(bean, methodName, methodParams); + } + else + { + Object bean = Class.forName(beanName).getDeclaredConstructor().newInstance(); + invokeMethod(bean, methodName, methodParams); + } + } + + /** + * 调用任务方法 + * + * @param bean 目标对象 + * @param methodName 方法名称 + * @param methodParams 方法参数 + */ + private static void invokeMethod(Object bean, String methodName, List methodParams) + throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, + InvocationTargetException + { + if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0) + { + Method method = bean.getClass().getMethod(methodName, getMethodParamsType(methodParams)); + method.invoke(bean, getMethodParamsValue(methodParams)); + } + else + { + Method method = bean.getClass().getMethod(methodName); + method.invoke(bean); + } + } + + /** + * 校验是否为为class包名 + * + * @param invokeTarget 名称 + * @return true是 false否 + */ + public static boolean isValidClassName(String invokeTarget) + { + return StringUtils.countMatches(invokeTarget, ".") > 1; + } + + /** + * 获取bean名称 + * + * @param invokeTarget 目标字符串 + * @return bean名称 + */ + public static String getBeanName(String invokeTarget) + { + String beanName = StringUtils.substringBefore(invokeTarget, "("); + return StringUtils.substringBeforeLast(beanName, "."); + } + + /** + * 获取bean方法 + * + * @param invokeTarget 目标字符串 + * @return method方法 + */ + public static String getMethodName(String invokeTarget) + { + String methodName = StringUtils.substringBefore(invokeTarget, "("); + return StringUtils.substringAfterLast(methodName, "."); + } + + /** + * 获取method方法参数相关列表 + * + * @param invokeTarget 目标字符串 + * @return method方法相关参数列表 + */ + public static List getMethodParams(String invokeTarget) + { + String methodStr = StringUtils.substringBetween(invokeTarget, "(", ")"); + if (StringUtils.isEmpty(methodStr)) + { + return null; + } + String[] methodParams = methodStr.split(",(?=([^\"']*[\"'][^\"']*[\"'])*[^\"']*$)"); + List classs = new LinkedList<>(); + for (int i = 0; i < methodParams.length; i++) + { + String str = StringUtils.trimToEmpty(methodParams[i]); + // String字符串类型,以'或"开头 + if (StringUtils.startsWithAny(str, "'", "\"")) + { + classs.add(new Object[] { StringUtils.substring(str, 1, str.length() - 1), String.class }); + } + // boolean布尔类型,等于true或者false + else if ("true".equalsIgnoreCase(str) || "false".equalsIgnoreCase(str)) + { + classs.add(new Object[] { Boolean.valueOf(str), Boolean.class }); + } + // long长整形,以L结尾 + else if (StringUtils.endsWith(str, "L")) + { + classs.add(new Object[] { Long.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Long.class }); + } + // double浮点类型,以D结尾 + else if (StringUtils.endsWith(str, "D")) + { + classs.add(new Object[] { Double.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Double.class }); + } + // 其他类型归类为整形 + else + { + classs.add(new Object[] { Integer.valueOf(str), Integer.class }); + } + } + return classs; + } + + /** + * 获取参数类型 + * + * @param methodParams 参数相关列表 + * @return 参数类型列表 + */ + public static Class[] getMethodParamsType(List methodParams) + { + Class[] classs = new Class[methodParams.size()]; + int index = 0; + for (Object[] os : methodParams) + { + classs[index] = (Class) os[1]; + index++; + } + return classs; + } + + /** + * 获取参数值 + * + * @param methodParams 参数相关列表 + * @return 参数值列表 + */ + public static Object[] getMethodParamsValue(List methodParams) + { + Object[] classs = new Object[methodParams.size()]; + int index = 0; + for (Object[] os : methodParams) + { + classs[index] = (Object) os[0]; + index++; + } + return classs; + } +} diff --git a/staffing-quartz/src/main/java/com/staffing/quartz/util/QuartzDisallowConcurrentExecution.java b/staffing-quartz/src/main/java/com/staffing/quartz/util/QuartzDisallowConcurrentExecution.java new file mode 100644 index 0000000..8217c22 --- /dev/null +++ b/staffing-quartz/src/main/java/com/staffing/quartz/util/QuartzDisallowConcurrentExecution.java @@ -0,0 +1,21 @@ +package com.staffing.quartz.util; + +import org.quartz.DisallowConcurrentExecution; +import org.quartz.JobExecutionContext; +import com.staffing.quartz.domain.SysJob; + +/** + * 定时任务处理(禁止并发执行) + * + * @author staffing + * + */ +@DisallowConcurrentExecution +public class QuartzDisallowConcurrentExecution extends AbstractQuartzJob +{ + @Override + protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception + { + JobInvokeUtil.invokeMethod(sysJob); + } +} diff --git a/staffing-quartz/src/main/java/com/staffing/quartz/util/QuartzJobExecution.java b/staffing-quartz/src/main/java/com/staffing/quartz/util/QuartzJobExecution.java new file mode 100644 index 0000000..30b37a6 --- /dev/null +++ b/staffing-quartz/src/main/java/com/staffing/quartz/util/QuartzJobExecution.java @@ -0,0 +1,19 @@ +package com.staffing.quartz.util; + +import org.quartz.JobExecutionContext; +import com.staffing.quartz.domain.SysJob; + +/** + * 定时任务处理(允许并发执行) + * + * @author staffing + * + */ +public class QuartzJobExecution extends AbstractQuartzJob +{ + @Override + protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception + { + JobInvokeUtil.invokeMethod(sysJob); + } +} diff --git a/staffing-quartz/src/main/java/com/staffing/quartz/util/ScheduleUtils.java b/staffing-quartz/src/main/java/com/staffing/quartz/util/ScheduleUtils.java new file mode 100644 index 0000000..b1440f8 --- /dev/null +++ b/staffing-quartz/src/main/java/com/staffing/quartz/util/ScheduleUtils.java @@ -0,0 +1,141 @@ +package com.staffing.quartz.util; + +import org.quartz.CronScheduleBuilder; +import org.quartz.CronTrigger; +import org.quartz.Job; +import org.quartz.JobBuilder; +import org.quartz.JobDetail; +import org.quartz.JobKey; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.quartz.TriggerBuilder; +import org.quartz.TriggerKey; +import com.staffing.common.constant.Constants; +import com.staffing.common.constant.ScheduleConstants; +import com.staffing.common.exception.job.TaskException; +import com.staffing.common.exception.job.TaskException.Code; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.spring.SpringUtils; +import com.staffing.quartz.domain.SysJob; + +/** + * 定时任务工具类 + * + * @author staffing + * + */ +public class ScheduleUtils +{ + /** + * 得到quartz任务类 + * + * @param sysJob 执行计划 + * @return 具体执行任务类 + */ + private static Class getQuartzJobClass(SysJob sysJob) + { + boolean isConcurrent = "0".equals(sysJob.getConcurrent()); + return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class; + } + + /** + * 构建任务触发对象 + */ + public static TriggerKey getTriggerKey(Long jobId, String jobGroup) + { + return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); + } + + /** + * 构建任务键对象 + */ + public static JobKey getJobKey(Long jobId, String jobGroup) + { + return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); + } + + /** + * 创建定时任务 + */ + public static void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException + { + Class jobClass = getQuartzJobClass(job); + // 构建job信息 + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(jobId, jobGroup)).build(); + + // 表达式调度构建器 + CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); + cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder); + + // 按新的cronExpression表达式构建一个新的trigger + CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup)) + .withSchedule(cronScheduleBuilder).build(); + + // 放入参数,运行时的方法可以获取 + jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job); + + // 判断是否存在 + if (scheduler.checkExists(getJobKey(jobId, jobGroup))) + { + // 防止创建时存在数据问题 先移除,然后在执行创建操作 + scheduler.deleteJob(getJobKey(jobId, jobGroup)); + } + + // 判断任务是否过期 + if (StringUtils.isNotNull(CronUtils.getNextExecution(job.getCronExpression()))) + { + // 执行调度任务 + scheduler.scheduleJob(jobDetail, trigger); + } + + // 暂停任务 + if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) + { + scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + } + + /** + * 设置定时任务策略 + */ + public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb) + throws TaskException + { + switch (job.getMisfirePolicy()) + { + case ScheduleConstants.MISFIRE_DEFAULT: + return cb; + case ScheduleConstants.MISFIRE_IGNORE_MISFIRES: + return cb.withMisfireHandlingInstructionIgnoreMisfires(); + case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED: + return cb.withMisfireHandlingInstructionFireAndProceed(); + case ScheduleConstants.MISFIRE_DO_NOTHING: + return cb.withMisfireHandlingInstructionDoNothing(); + default: + throw new TaskException("The task misfire policy '" + job.getMisfirePolicy() + + "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR); + } + } + + /** + * 检查包名是否为白名单配置 + * + * @param invokeTarget 目标字符串 + * @return 结果 + */ + public static boolean whiteList(String invokeTarget) + { + String packageName = StringUtils.substringBefore(invokeTarget, "("); + int count = StringUtils.countMatches(packageName, "."); + if (count > 1) + { + return StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR); + } + Object obj = SpringUtils.getBean(StringUtils.split(invokeTarget, ".")[0]); + String beanPackageName = obj.getClass().getPackage().getName(); + return StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_WHITELIST_STR) + && !StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_ERROR_STR); + } +} diff --git a/staffing-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml b/staffing-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml new file mode 100644 index 0000000..613ff01 --- /dev/null +++ b/staffing-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + select job_log_id, job_name, job_group, invoke_target, job_message, status, exception_info, create_time + from sys_job_log + + + + + + + + + + delete from sys_job_log where job_log_id = #{jobLogId} + + + + delete from sys_job_log where job_log_id in + + #{jobLogId} + + + + + truncate table sys_job_log + + + + insert into sys_job_log( + job_log_id, + job_name, + job_group, + invoke_target, + job_message, + status, + exception_info, + create_time + )values( + #{jobLogId}, + #{jobName}, + #{jobGroup}, + #{invokeTarget}, + #{jobMessage}, + #{status}, + #{exceptionInfo}, + sysdate() + ) + + + \ No newline at end of file diff --git a/staffing-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml b/staffing-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml new file mode 100644 index 0000000..06ed6da --- /dev/null +++ b/staffing-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + select job_id, job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark + from sys_job + + + + + + + + + + delete from sys_job where job_id = #{jobId} + + + + delete from sys_job where job_id in + + #{jobId} + + + + + update sys_job + + job_name = #{jobName}, + job_group = #{jobGroup}, + invoke_target = #{invokeTarget}, + cron_expression = #{cronExpression}, + misfire_policy = #{misfirePolicy}, + concurrent = #{concurrent}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = sysdate() + + where job_id = #{jobId} + + + + insert into sys_job( + job_id, + job_name, + job_group, + invoke_target, + cron_expression, + misfire_policy, + concurrent, + status, + remark, + create_by, + create_time + )values( + #{jobId}, + #{jobName}, + #{jobGroup}, + #{invokeTarget}, + #{cronExpression}, + #{misfirePolicy}, + #{concurrent}, + #{status}, + #{remark}, + #{createBy}, + sysdate() + ) + + + \ No newline at end of file diff --git a/staffing-system/pom.xml b/staffing-system/pom.xml new file mode 100644 index 0000000..5844454 --- /dev/null +++ b/staffing-system/pom.xml @@ -0,0 +1,34 @@ + + + + staffing + com.staffing + 3.8.8 + + 4.0.0 + + staffing-system + + + system系统模块 + + + + + + + + + + + com.staffing + wx-pay + 3.8.8 + compile + + + + + \ No newline at end of file diff --git a/staffing-system/src/main/java/com/staffing/custom/domain/StEmployee.java b/staffing-system/src/main/java/com/staffing/custom/domain/StEmployee.java new file mode 100644 index 0000000..b71acaa --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/domain/StEmployee.java @@ -0,0 +1,234 @@ +package com.staffing.custom.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.staffing.common.annotation.Excel; +import com.staffing.common.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 员工对象 st_employee + * + * @author staffing + * @date 2024-08-27 + */ +public class StEmployee extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** id */ + private Long id; + + /** 名字 */ + @Excel(name = "名字") + private String realName; + + /** 手机 */ + @Excel(name = "手机") + private String phone; + + /** 身份证 */ + @Excel(name = "身份证") + private String idCard; + + /** 性别 */ + @Excel(name = "性别") + private Integer sex; + + /** 民族 */ + @Excel(name = "民族") + private String nation; + + /** 年龄 */ + @Excel(name = "年龄") + private Long age; + + /** 用工单位 */ + @Excel(name = "用工单位") + private String useUnit; + + /** 面试日期 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "面试日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date interviewDate; + + /** 入职日期 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "入职日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date entryDate; + + /** 供应商 */ + @Excel(name = "供应商") + private String supplier; + + /** 员工单价 */ + @Excel(name = "员工单价") + private String employeePrice; + + /** 供应商单价 */ + @Excel(name = "供应商单价") + private String supplierPrice; + + /** 用工类型 */ + @Excel(name = "用工类型") + private Long employeeType; + + private String openId; + + public String getOpenId() { + return openId; + } + + public void setOpenId(String openId) { + this.openId = openId; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setRealName(String realName) + { + this.realName = realName; + } + + public String getRealName() + { + return realName; + } + public void setPhone(String phone) + { + this.phone = phone; + } + + public String getPhone() + { + return phone; + } + public void setIdCard(String idCard) + { + this.idCard = idCard; + } + + public String getIdCard() + { + return idCard; + } + public void setSex(Integer sex) + { + this.sex = sex; + } + + public Integer getSex() + { + return sex; + } + public void setNation(String nation) + { + this.nation = nation; + } + + public String getNation() + { + return nation; + } + public void setAge(Long age) + { + this.age = age; + } + + public Long getAge() + { + return age; + } + public void setUseUnit(String useUnit) + { + this.useUnit = useUnit; + } + + public String getUseUnit() + { + return useUnit; + } + public void setInterviewDate(Date interviewDate) + { + this.interviewDate = interviewDate; + } + + public Date getInterviewDate() + { + return interviewDate; + } + public void setEntryDate(Date entryDate) + { + this.entryDate = entryDate; + } + + public Date getEntryDate() + { + return entryDate; + } + public void setSupplier(String supplier) + { + this.supplier = supplier; + } + + public String getSupplier() + { + return supplier; + } + public void setEmployeePrice(String employeePrice) + { + this.employeePrice = employeePrice; + } + + public String getEmployeePrice() + { + return employeePrice; + } + public void setSupplierPrice(String supplierPrice) + { + this.supplierPrice = supplierPrice; + } + + public String getSupplierPrice() + { + return supplierPrice; + } + public void setEmployeeType(Long employeeType) + { + this.employeeType = employeeType; + } + + public Long getEmployeeType() + { + return employeeType; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("realName", getRealName()) + .append("phone", getPhone()) + .append("idCard", getIdCard()) + .append("sex", getSex()) + .append("nation", getNation()) + .append("age", getAge()) + .append("useUnit", getUseUnit()) + .append("interviewDate", getInterviewDate()) + .append("entryDate", getEntryDate()) + .append("supplier", getSupplier()) + .append("employeePrice", getEmployeePrice()) + .append("supplierPrice", getSupplierPrice()) + .append("employeeType", getEmployeeType()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/staffing-system/src/main/java/com/staffing/custom/domain/StEmployeeFundRecord.java b/staffing-system/src/main/java/com/staffing/custom/domain/StEmployeeFundRecord.java new file mode 100644 index 0000000..bc32e06 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/domain/StEmployeeFundRecord.java @@ -0,0 +1,303 @@ +package com.staffing.custom.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.staffing.common.annotation.Excel; +import com.staffing.common.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 员工资金流水对象 st_employee_fund_record + * + * @author staffing + * @date 2024-08-27 + */ +public class StEmployeeFundRecord extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** id */ + private Long id; + + /** 任务id */ + @Excel(name = "任务id") + private Long taskId; + + /** 任务名称 */ + @Excel(name = "任务名称") + private String taskName; + + /** 任务时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "任务时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date taskDate; + + /** 员工id */ + @Excel(name = "员工id") + private Long employeeId; + + /** 名字 */ + @Excel(name = "名字") + private String employeeName; + + /** 手机 */ + @Excel(name = "手机") + private String phone; + + /** 身份证 */ + @Excel(name = "身份证") + private String idCard; + + /** 日结单价 */ + @Excel(name = "日结单价") + private String dayPrice; + + /** 应发金额 */ + @Excel(name = "应发金额") + private String shouldPrice; + + /** 实发金额 */ + @Excel(name = "实发金额") + private String realPrice; + + /** 发薪方式 */ + @Excel(name = "发薪方式") + private String payWayStr; + + private Long payWay; + + /** 发薪账户 */ + @Excel(name = "发薪账户") + private String payAccountStr; + + private Long payAccount; + + /** 发薪时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "发薪时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date payTime; + + /** 发放状态 0未发 1已发 2发放失败*/ + private Long payStatus; + + @Excel(name = "发放状态(未发/已发/发放失败)") + private String payStatusStr; + + //转账订单号 + private String transferNo; + + //查询时赋值 + @Excel(name = "二次核验备注") + private String remark; + + private StTaskSign stTaskSign; + + public String getTransferNo() { + return transferNo; + } + + public void setTransferNo(String transferNo) { + this.transferNo = transferNo; + } + + public String getPayWayStr() { + return payWayStr; + } + + public void setPayWayStr(String payWayStr) { + this.payWayStr = payWayStr; + } + + public String getPayAccountStr() { + return payAccountStr; + } + + public void setPayAccountStr(String payAccountStr) { + this.payAccountStr = payAccountStr; + } + + public StTaskSign getStTaskSign() { + return stTaskSign; + } + + public void setStTaskSign(StTaskSign stTaskSign) { + this.stTaskSign = stTaskSign; + } + + public String getPayStatusStr() { + return payStatusStr; + } + + public void setPayStatusStr(String payStatusStr) { + this.payStatusStr = payStatusStr; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setTaskId(Long taskId) + { + this.taskId = taskId; + } + + public Long getTaskId() + { + return taskId; + } + public void setTaskName(String taskName) + { + this.taskName = taskName; + } + + public String getTaskName() + { + return taskName; + } + public void setTaskDate(Date taskDate) + { + this.taskDate = taskDate; + } + + public Date getTaskDate() + { + return taskDate; + } + public void setEmployeeId(Long employeeId) + { + this.employeeId = employeeId; + } + + public Long getEmployeeId() + { + return employeeId; + } + public void setEmployeeName(String employeeName) + { + this.employeeName = employeeName; + } + + public String getEmployeeName() + { + return employeeName; + } + public void setPhone(String phone) + { + this.phone = phone; + } + + public String getPhone() + { + return phone; + } + public void setIdCard(String idCard) + { + this.idCard = idCard; + } + + public String getIdCard() + { + return idCard; + } + public void setDayPrice(String dayPrice) + { + this.dayPrice = dayPrice; + } + + public String getDayPrice() + { + return dayPrice; + } + public void setShouldPrice(String shouldPrice) + { + this.shouldPrice = shouldPrice; + } + + public String getShouldPrice() + { + return shouldPrice; + } + public void setRealPrice(String realPrice) + { + this.realPrice = realPrice; + } + + public String getRealPrice() + { + return realPrice; + } + public void setPayWay(Long payWay) + { + this.payWay = payWay; + } + + public Long getPayWay() + { + return payWay; + } + public void setPayAccount(Long payAccount) + { + this.payAccount = payAccount; + } + + public Long getPayAccount() + { + return payAccount; + } + public void setPayTime(Date payTime) + { + this.payTime = payTime; + } + + public Date getPayTime() + { + return payTime; + } + public void setPayStatus(Long payStatus) + { + this.payStatus = payStatus; + } + + public Long getPayStatus() + { + return payStatus; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("taskId", getTaskId()) + .append("taskName", getTaskName()) + .append("taskDate", getTaskDate()) + .append("employeeId", getEmployeeId()) + .append("employeeName", getEmployeeName()) + .append("phone", getPhone()) + .append("idCard", getIdCard()) + .append("dayPrice", getDayPrice()) + .append("shouldPrice", getShouldPrice()) + .append("realPrice", getRealPrice()) + .append("payWay", getPayWay()) + .append("payAccount", getPayAccount()) + .append("payTime", getPayTime()) + .append("updateTime", getUpdateTime()) + .append("payStatus", getPayStatus()) + .toString(); + } + + @Override + public String getRemark() { + return remark; + } + + @Override + public void setRemark(String remark) { + this.remark = remark; + } +} diff --git a/staffing-system/src/main/java/com/staffing/custom/domain/StTask.java b/staffing-system/src/main/java/com/staffing/custom/domain/StTask.java new file mode 100644 index 0000000..350b389 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/domain/StTask.java @@ -0,0 +1,287 @@ +package com.staffing.custom.domain; + +import java.util.Collection; +import java.util.Date; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.staffing.common.annotation.Excel; +import com.staffing.common.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 任务对象 st_task + * + * @author staffing + * @date 2024-08-27 + */ +public class StTask extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** id */ + private Long id; + + /** 任务名称 */ + @Excel(name = "任务名称") + private String taskName; + + /** 任务时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "任务时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date taskDate; + + /** 日结单价 */ + @Excel(name = "日结单价") + private String dayPrice; + + /** 用工数量 */ + @Excel(name = "用工数量") + private int useNum; + + /** 二维码 */ + @Excel(name = "二维码") + private String codePic; + + /** 任务状态 */ + @Excel(name = "任务状态") + private Integer status; + + /** 更新时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + /** 更新时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + @Excel(name = "报名人数") + private int baomingNum; + + @Excel(name = "签到数量") + private int signNum; + +//组装参数 + private List listSign; + private StTaskSign selfSign; + private int yfNum; + private int sfNum; + private int dfNum; + private String yfPrice; + private String sfPrice; + private String dfPrice; + +//查询参数 + /**0全部 1进行中 2已结束 根据时间查询的参数 */ + private Integer dateStatus; + /** 任务时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") +// @Excel(name = "任务时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date taskDateCompare; + + private Collection taskIds; + + + @Override + public Date getCreateTime() { + return createTime; + } + + @Override + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public List getListSign() { + return listSign; + } + public String getYfPrice() { + return yfPrice; + } + + public void setYfPrice(String yfPrice) { + this.yfPrice = yfPrice; + } + + public String getSfPrice() { + return sfPrice; + } + + public void setSfPrice(String sfPrice) { + this.sfPrice = sfPrice; + } + + public String getDfPrice() { + return dfPrice; + } + + public void setDfPrice(String dfPrice) { + this.dfPrice = dfPrice; + } + + public int getYfNum() { + return yfNum; + } + + public void setYfNum(int yfNum) { + this.yfNum = yfNum; + } + + public int getSfNum() { + return sfNum; + } + + public void setSfNum(int sfNum) { + this.sfNum = sfNum; + } + + public int getDfNum() { + return dfNum; + } + + public void setDfNum(int dfNum) { + this.dfNum = dfNum; + } + + public void setListSign(List listSign) { + this.listSign = listSign; + } + + public int getBaomingNum() { + return baomingNum; + } + + public void setBaomingNum(int baomingNum) { + this.baomingNum = baomingNum; + } + + public int getSignNum() { + return signNum; + } + + public void setSignNum(int signNum) { + this.signNum = signNum; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setTaskName(String taskName) + { + this.taskName = taskName; + } + + public String getTaskName() + { + return taskName; + } + public void setTaskDate(Date taskDate) + { + this.taskDate = taskDate; + } + + public Date getTaskDate() + { + return taskDate; + } + public void setDayPrice(String dayPrice) + { + this.dayPrice = dayPrice; + } + + public String getDayPrice() + { + return dayPrice; + } + public void setUseNum(int useNum) + { + this.useNum = useNum; + } + + public int getUseNum() + { + return useNum; + } + public void setCodePic(String codePic) + { + this.codePic = codePic; + } + + public String getCodePic() + { + return codePic; + } + public void setStatus(Integer status) + { + this.status = status; + } + + public Integer getStatus() + { + return status; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("taskName", getTaskName()) + .append("taskDate", getTaskDate()) + .append("dayPrice", getDayPrice()) + .append("useNum", getUseNum()) + .append("codePic", getCodePic()) + .append("status", getStatus()) + .append("updateTime", getUpdateTime()) + .toString(); + } + + @Override + public Date getUpdateTime() { + return updateTime; + } + + @Override + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + + public Integer getDateStatus() { + return dateStatus; + } + + public void setDateStatus(Integer dateStatus) { + this.dateStatus = dateStatus; + } + + + public Date getTaskDateCompare() { + return taskDateCompare; + } + + public void setTaskDateCompare(Date taskDateCompare) { + this.taskDateCompare = taskDateCompare; + } + + public StTaskSign getSelfSign() { + return selfSign; + } + + public void setSelfSign(StTaskSign selfSign) { + this.selfSign = selfSign; + } + + public Collection getTaskIds() { + return taskIds; + } + + public void setTaskIds(Collection taskIds) { + this.taskIds = taskIds; + } +} diff --git a/staffing-system/src/main/java/com/staffing/custom/domain/StTaskSign.java b/staffing-system/src/main/java/com/staffing/custom/domain/StTaskSign.java new file mode 100644 index 0000000..caba32b --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/domain/StTaskSign.java @@ -0,0 +1,198 @@ +package com.staffing.custom.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.staffing.common.annotation.Excel; +import com.staffing.common.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 签到对象 st_task_sign + * + * @author staffing + * @date 2024-08-27 + */ +public class StTaskSign extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** id */ + private Long id; + + /** 任务id */ + private Long taskId; + + /** 任务名称 */ + @Excel(name = "任务名称") + private String taskName; + + /** 日结单价 */ + @Excel(name = "日结单价") + private String dayPrice; + + /** 签到时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "签到时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date signTime; + + /** 员工id */ + private Long employeeId; + + /** 名字 */ + @Excel(name = "名字") + private String employeeName; + + /** 手机 */ + @Excel(name = "手机") + private String phone; + + /** 身份证 */ + @Excel(name = "身份证") + private String idCard; + + /** 签到状态 */ + @Excel(name = "签到状态") + private String statusStr; + + private Integer status; + + @Excel(name = "二次核验备注") + private String remark; + + public String getStatusStr() { + return statusStr; + } + + public void setStatusStr(String statusStr) { + this.statusStr = statusStr; + } + + private StEmployeeFundRecord stEmployeeFundRecord; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setTaskId(Long taskId) + { + this.taskId = taskId; + } + + public Long getTaskId() + { + return taskId; + } + public void setTaskName(String taskName) + { + this.taskName = taskName; + } + + public String getTaskName() + { + return taskName; + } + public void setDayPrice(String dayPrice) + { + this.dayPrice = dayPrice; + } + + public String getDayPrice() + { + return dayPrice; + } + public void setSignTime(Date signTime) + { + this.signTime = signTime; + } + + public Date getSignTime() + { + return signTime; + } + public void setEmployeeId(Long employeeId) + { + this.employeeId = employeeId; + } + + public Long getEmployeeId() + { + return employeeId; + } + public void setEmployeeName(String employeeName) + { + this.employeeName = employeeName; + } + + public String getEmployeeName() + { + return employeeName; + } + public void setPhone(String phone) + { + this.phone = phone; + } + + public String getPhone() + { + return phone; + } + public void setIdCard(String idCard) + { + this.idCard = idCard; + } + + public String getIdCard() + { + return idCard; + } + public void setStatus(Integer status) + { + this.status = status; + } + + public Integer getStatus() + { + return status; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("taskId", getTaskId()) + .append("taskName", getTaskName()) + .append("dayPrice", getDayPrice()) + .append("signTime", getSignTime()) + .append("employeeId", getEmployeeId()) + .append("employeeName", getEmployeeName()) + .append("phone", getPhone()) + .append("idCard", getIdCard()) + .append("status", getStatus()) + .append("remark", getRemark()) + .toString(); + } + + public StEmployeeFundRecord getStEmployeeFundRecord() { + return stEmployeeFundRecord; + } + + public void setStEmployeeFundRecord(StEmployeeFundRecord stEmployeeFundRecord) { + this.stEmployeeFundRecord = stEmployeeFundRecord; + } + + @Override + public String getRemark() { + return remark; + } + + @Override + public void setRemark(String remark) { + this.remark = remark; + } +} diff --git a/staffing-system/src/main/java/com/staffing/custom/domain/StTransferRecord.java b/staffing-system/src/main/java/com/staffing/custom/domain/StTransferRecord.java new file mode 100644 index 0000000..1e6fa8a --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/domain/StTransferRecord.java @@ -0,0 +1,123 @@ +package com.staffing.custom.domain; + +import com.staffing.common.annotation.Excel; +import com.staffing.common.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 微信转账记录对象 st_transfer_record + * + * @author staffing + * @date 2024-09-06 + */ +public class StTransferRecord extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** id */ + private Long id; + + /** 任务id */ + @Excel(name = "任务id") + private Long taskId; + + /** 任务名称 */ + @Excel(name = "任务名称") + private String taskName; + + /** 转账订单号 */ + @Excel(name = "转账订单号") + private String transferNo; + + /** 总金额 */ + @Excel(name = "总金额") + private String countPrice; + + /** 发薪职工id */ + @Excel(name = "发薪职工id") + private String employeeIds; + + /** 待商户确认、已受理、转账中、已完成、已关闭 */ + @Excel(name = "待商户确认、已受理、转账中、已完成、已关闭") + private int payStatus; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setTaskId(Long taskId) + { + this.taskId = taskId; + } + + public Long getTaskId() + { + return taskId; + } + public void setTaskName(String taskName) + { + this.taskName = taskName; + } + + public String getTaskName() + { + return taskName; + } + public void setTransferNo(String transferNo) + { + this.transferNo = transferNo; + } + + public String getTransferNo() + { + return transferNo; + } + public void setCountPrice(String countPrice) + { + this.countPrice = countPrice; + } + + public String getCountPrice() + { + return countPrice; + } + public void setEmployeeIds(String employeeIds) + { + this.employeeIds = employeeIds; + } + + public String getEmployeeIds() + { + return employeeIds; + } + public void setPayStatus(int payStatus) + { + this.payStatus = payStatus; + } + + public int getPayStatus() + { + return payStatus; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("taskId", getTaskId()) + .append("taskName", getTaskName()) + .append("transferNo", getTransferNo()) + .append("countPrice", getCountPrice()) + .append("employeeIds", getEmployeeIds()) + .append("createTime", getCreateTime()) + .append("updateTime", getUpdateTime()) + .append("payStatus", getPayStatus()) + .toString(); + } +} diff --git a/staffing-system/src/main/java/com/staffing/custom/mapper/StEmployeeFundRecordMapper.java b/staffing-system/src/main/java/com/staffing/custom/mapper/StEmployeeFundRecordMapper.java new file mode 100644 index 0000000..e640b80 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/mapper/StEmployeeFundRecordMapper.java @@ -0,0 +1,68 @@ +package com.staffing.custom.mapper; + +import com.staffing.custom.domain.StEmployeeFundRecord; +import com.staffing.custom.domain.StTaskSign; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 员工资金流水Mapper接口 + * + * @author staffing + * @date 2024-08-27 + */ +public interface StEmployeeFundRecordMapper +{ + /** + * 查询员工资金流水 + * + * @param id 员工资金流水主键 + * @return 员工资金流水 + */ + public StEmployeeFundRecord selectStEmployeeFundRecordById(Long id); + + public StEmployeeFundRecord selectStEmployeeFundRecordByUidAndTaskId(@Param("taskId") Long taskId, @Param("employeeId") Long employeeId); + + public List selectStEmployeeFundRecordByTaskIds(@Param("taskIds") List id); + /** + * 查询员工资金流水列表 + * + * @param stEmployeeFundRecord 员工资金流水 + * @return 员工资金流水集合 + */ + public List selectStEmployeeFundRecordList(StEmployeeFundRecord stEmployeeFundRecord); + + /** + * 新增员工资金流水 + * + * @param stEmployeeFundRecord 员工资金流水 + * @return 结果 + */ + public int insertStEmployeeFundRecord(StEmployeeFundRecord stEmployeeFundRecord); + + /** + * 修改员工资金流水 + * + * @param stEmployeeFundRecord 员工资金流水 + * @return 结果 + */ + public int updateStEmployeeFundRecord(StEmployeeFundRecord stEmployeeFundRecord); + public int updateStEmployeeFundRecordByTaskAndUid(StEmployeeFundRecord stEmployeeFundRecord); + + /** + * 删除员工资金流水 + * + * @param id 员工资金流水主键 + * @return 结果 + */ + public int deleteStEmployeeFundRecordById(Long id); + + /** + * 批量删除员工资金流水 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteStEmployeeFundRecordByIds(Long[] ids); +} diff --git a/staffing-system/src/main/java/com/staffing/custom/mapper/StEmployeeMapper.java b/staffing-system/src/main/java/com/staffing/custom/mapper/StEmployeeMapper.java new file mode 100644 index 0000000..9a7911a --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/mapper/StEmployeeMapper.java @@ -0,0 +1,69 @@ +package com.staffing.custom.mapper; + +import java.util.List; +import com.staffing.custom.domain.StEmployee; +import org.apache.ibatis.annotations.Param; + +/** + * 员工Mapper接口 + * + * @author staffing + * @date 2024-08-27 + */ +public interface StEmployeeMapper +{ + /** + * 查询员工 + * + * @param id 员工主键 + * @return 员工 + */ + public StEmployee selectStEmployeeById(Long id); + + public StEmployee selectStEmployeeByPhone(@Param("phone") String phone); + + + public List selectStEmployeeByIds(@Param("uids")List ids); + /** + * 查询员工列表 + * + * @param stEmployee 员工 + * @return 员工集合 + */ + public List selectStEmployeeList(StEmployee stEmployee); + + /** + * 新增员工 + * + * @param stEmployee 员工 + * @return 结果 + */ + public int insertStEmployee(StEmployee stEmployee); + + /** + * 修改员工 + * + * @param stEmployee 员工 + * @return 结果 + */ + public int updateStEmployee(StEmployee stEmployee); + + public int updateStEmployeeOrNull(StEmployee stEmployee); + + + /** + * 删除员工 + * + * @param id 员工主键 + * @return 结果 + */ + public int deleteStEmployeeById(Long id); + + /** + * 批量删除员工 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteStEmployeeByIds(Long[] ids); +} diff --git a/staffing-system/src/main/java/com/staffing/custom/mapper/StTaskMapper.java b/staffing-system/src/main/java/com/staffing/custom/mapper/StTaskMapper.java new file mode 100644 index 0000000..a4a9be0 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/mapper/StTaskMapper.java @@ -0,0 +1,63 @@ +package com.staffing.custom.mapper; + +import java.util.Collection; +import java.util.List; +import com.staffing.custom.domain.StTask; +import com.staffing.custom.domain.StTaskSign; +import org.apache.ibatis.annotations.Param; + +/** + * 任务Mapper接口 + * + * @author staffing + * @date 2024-08-27 + */ +public interface StTaskMapper +{ + /** + * 查询任务 + * + * @param id 任务主键 + * @return 任务 + */ + public StTask selectStTaskById(Long id); + + /** + * 查询任务列表 + * + * @param stTask 任务 + * @return 任务集合 + */ + public List selectStTaskList(StTask stTask); + /** + * 新增任务 + * + * @param stTask 任务 + * @return 结果 + */ + public int insertStTask(StTask stTask); + + /** + * 修改任务 + * + * @param stTask 任务 + * @return 结果 + */ + public int updateStTask(StTask stTask); + + /** + * 删除任务 + * + * @param id 任务主键 + * @return 结果 + */ + public int deleteStTaskById(Long id); + + /** + * 批量删除任务 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteStTaskByIds(Long[] ids); +} diff --git a/staffing-system/src/main/java/com/staffing/custom/mapper/StTaskSignMapper.java b/staffing-system/src/main/java/com/staffing/custom/mapper/StTaskSignMapper.java new file mode 100644 index 0000000..a7926b6 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/mapper/StTaskSignMapper.java @@ -0,0 +1,68 @@ +package com.staffing.custom.mapper; + +import java.util.List; +import com.staffing.custom.domain.StTaskSign; +import org.apache.ibatis.annotations.Param; + +/** + * 签到Mapper接口 + * + * @author staffing + * @date 2024-08-27 + */ +public interface StTaskSignMapper +{ + /** + * 查询签到 + * + * @param id 签到主键 + * @return 签到 + */ + public StTaskSign selectStTaskSignById(Long id); + + + public StTaskSign selectStTaskSignByTaskIdAndUserId(@Param("taskId") Long tid, @Param("uid") Long uid); + + public List selectStTaskSignByTaskIds(@Param("taskIds") List id); + /** + * 查询签到列表 + * + * @param stTaskSign 签到 + * @return 签到集合 + */ + public List selectStTaskSignList(StTaskSign stTaskSign); + + /** + * 新增签到 + * + * @param stTaskSign 签到 + * @return 结果 + */ + public int insertStTaskSign(StTaskSign stTaskSign); + + /** + * 修改签到 + * + * @param stTaskSign 签到 + * @return 结果 + */ + public int updateStTaskSign(StTaskSign stTaskSign); + + + int updateStTaskSignByTaskIdAndEmId(StTaskSign stTaskSign); + /** + * 删除签到 + * + * @param id 签到主键 + * @return 结果 + */ + public int deleteStTaskSignById(Long id); + + /** + * 批量删除签到 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteStTaskSignByIds(Long[] ids); +} diff --git a/staffing-system/src/main/java/com/staffing/custom/mapper/StTransferRecordMapper.java b/staffing-system/src/main/java/com/staffing/custom/mapper/StTransferRecordMapper.java new file mode 100644 index 0000000..fb78d5b --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/mapper/StTransferRecordMapper.java @@ -0,0 +1,61 @@ +package com.staffing.custom.mapper; + +import java.util.List; +import com.staffing.custom.domain.StTransferRecord; + +/** + * 微信转账记录Mapper接口 + * + * @author staffing + * @date 2024-09-06 + */ +public interface StTransferRecordMapper +{ + /** + * 查询微信转账记录 + * + * @param id 微信转账记录主键 + * @return 微信转账记录 + */ + public StTransferRecord selectStTransferRecordById(Long id); + + /** + * 查询微信转账记录列表 + * + * @param stTransferRecord 微信转账记录 + * @return 微信转账记录集合 + */ + public List selectStTransferRecordList(StTransferRecord stTransferRecord); + + /** + * 新增微信转账记录 + * + * @param stTransferRecord 微信转账记录 + * @return 结果 + */ + public int insertStTransferRecord(StTransferRecord stTransferRecord); + + /** + * 修改微信转账记录 + * + * @param stTransferRecord 微信转账记录 + * @return 结果 + */ + public int updateStTransferRecord(StTransferRecord stTransferRecord); + + /** + * 删除微信转账记录 + * + * @param id 微信转账记录主键 + * @return 结果 + */ + public int deleteStTransferRecordById(Long id); + + /** + * 批量删除微信转账记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteStTransferRecordByIds(Long[] ids); +} diff --git a/staffing-system/src/main/java/com/staffing/custom/param/FxParam.java b/staffing-system/src/main/java/com/staffing/custom/param/FxParam.java new file mode 100644 index 0000000..8352fbc --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/param/FxParam.java @@ -0,0 +1,24 @@ +package com.staffing.custom.param; + +import java.util.List; + +public class FxParam { + private Long taskId; + private List employeeIds; + + public Long getTaskId() { + return taskId; + } + + public void setTaskId(Long taskId) { + this.taskId = taskId; + } + + public List getEmployeeIds() { + return employeeIds; + } + + public void setEmployeeIds(List employeeIds) { + this.employeeIds = employeeIds; + } +} diff --git a/staffing-system/src/main/java/com/staffing/custom/service/IStEmployeeFundRecordService.java b/staffing-system/src/main/java/com/staffing/custom/service/IStEmployeeFundRecordService.java new file mode 100644 index 0000000..e77e2ed --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/service/IStEmployeeFundRecordService.java @@ -0,0 +1,67 @@ +package com.staffing.custom.service; + +import com.staffing.custom.domain.StEmployeeFundRecord; +import com.staffing.custom.param.FxParam; + +import java.util.List; + +/** + * 员工资金流水Service接口 + * + * @author staffing + * @date 2024-08-27 + */ +public interface IStEmployeeFundRecordService +{ + /** + * 查询员工资金流水 + * + * @param id 员工资金流水主键 + * @return 员工资金流水 + */ + public StEmployeeFundRecord selectStEmployeeFundRecordById(Long id); + + /** + * 查询员工资金流水列表 + * + * @param stEmployeeFundRecord 员工资金流水 + * @return 员工资金流水集合 + */ + public List selectStEmployeeFundRecordList(StEmployeeFundRecord stEmployeeFundRecord); + + /** + * 新增员工资金流水 + * + * @param stEmployeeFundRecord 员工资金流水 + * @return 结果 + */ + public int insertStEmployeeFundRecord(StEmployeeFundRecord stEmployeeFundRecord); + + /** + * 修改员工资金流水 + * + * @param stEmployeeFundRecord 员工资金流水 + * @return 结果 + */ + public int updateStEmployeeFundRecord(StEmployeeFundRecord stEmployeeFundRecord); + + /** + * 批量删除员工资金流水 + * + * @param ids 需要删除的员工资金流水主键集合 + * @return 结果 + */ + public int deleteStEmployeeFundRecordByIds(Long[] ids); + + /** + * 删除员工资金流水信息 + * + * @param id 员工资金流水主键 + * @return 结果 + */ + public int deleteStEmployeeFundRecordById(Long id); + + String importRecord(List userList); + + String faxin(FxParam fxParam); +} diff --git a/staffing-system/src/main/java/com/staffing/custom/service/IStEmployeeService.java b/staffing-system/src/main/java/com/staffing/custom/service/IStEmployeeService.java new file mode 100644 index 0000000..c7b9ee8 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/service/IStEmployeeService.java @@ -0,0 +1,64 @@ +package com.staffing.custom.service; + +import java.util.List; +import com.staffing.custom.domain.StEmployee; + +/** + * 员工Service接口 + * + * @author staffing + * @date 2024-08-27 + */ +public interface IStEmployeeService +{ + /** + * 查询员工 + * + * @param id 员工主键 + * @return 员工 + */ + public StEmployee selectStEmployeeById(Long id); + + public StEmployee selectStEmployeeByPhone(String phone); + + /** + * 查询员工列表 + * + * @param stEmployee 员工 + * @return 员工集合 + */ + public List selectStEmployeeList(StEmployee stEmployee); + + /** + * 新增员工 + * + * @param stEmployee 员工 + * @return 结果 + */ + public int insertStEmployee(StEmployee stEmployee); + + /** + * 修改员工 + * + * @param stEmployee 员工 + * @return 结果 + */ + public int updateStEmployee(StEmployee stEmployee); + + public int updateStEmployeeOrNull(StEmployee stEmployee); + /** + * 批量删除员工 + * + * @param ids 需要删除的员工主键集合 + * @return 结果 + */ + public int deleteStEmployeeByIds(Long[] ids); + + /** + * 删除员工信息 + * + * @param id 员工主键 + * @return 结果 + */ + public int deleteStEmployeeById(Long id); +} diff --git a/staffing-system/src/main/java/com/staffing/custom/service/IStTaskService.java b/staffing-system/src/main/java/com/staffing/custom/service/IStTaskService.java new file mode 100644 index 0000000..cdf0db4 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/service/IStTaskService.java @@ -0,0 +1,77 @@ +package com.staffing.custom.service; + +import java.util.List; +import com.staffing.custom.domain.StTask; + +/** + * 任务Service接口 + * + * @author staffing + * @date 2024-08-27 + */ +public interface IStTaskService +{ + /** + * 查询任务 + * + * @param id 任务主键 + * @return 任务 + */ + public StTask selectStTaskById(Long id); + + /** + * 查询任务 + * @param id + * @param filterSign 过滤掉没签到的人员,再发薪页面调用的 + * @return + */ + public StTask selectStTaskById(Long id, boolean filterSign); + + /** + * 查询任务列表 + * + * @param stTask 任务 + * @return 任务集合 + */ + public List selectStTaskList(StTask stTask, long uid); + + /** + * 查询任务列表 + * + * @param stTask 任务 + * @return 任务集合 + */ + public List selectStTaskListByUserId(StTask stTask, Long userId, boolean sign); + + /** + * 新增任务 + * + * @param stTask 任务 + * @return 结果 + */ + public int insertStTask(StTask stTask); + + /** + * 修改任务 + * + * @param stTask 任务 + * @return 结果 + */ + public int updateStTask(StTask stTask); + + /** + * 批量删除任务 + * + * @param ids 需要删除的任务主键集合 + * @return 结果 + */ + public int deleteStTaskByIds(Long[] ids); + + /** + * 删除任务信息 + * + * @param id 任务主键 + * @return 结果 + */ + public int deleteStTaskById(Long id); +} diff --git a/staffing-system/src/main/java/com/staffing/custom/service/IStTaskSignService.java b/staffing-system/src/main/java/com/staffing/custom/service/IStTaskSignService.java new file mode 100644 index 0000000..1d8968f --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/service/IStTaskSignService.java @@ -0,0 +1,66 @@ +package com.staffing.custom.service; + +import java.util.List; + +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.custom.domain.StTaskSign; + +/** + * 签到Service接口 + * + * @author staffing + * @date 2024-08-27 + */ +public interface IStTaskSignService +{ + /** + * 查询签到 + * + * @param id 签到主键 + * @return 签到 + */ + public StTaskSign selectStTaskSignById(Long id); + + /** + * 查询签到列表 + * + * @param stTaskSign 签到 + * @return 签到集合 + */ + public List selectStTaskSignList(StTaskSign stTaskSign); + + AjaxResult baoming(StTaskSign taskSign); + /** + * 新增签到 + * + * @param stTaskSign 签到 + * @return 结果 + */ + public int insertStTaskSign(StTaskSign stTaskSign); + + /** + * 修改签到 + * + * @param stTaskSign 签到 + * @return 结果 + */ + public int updateStTaskSign(StTaskSign stTaskSign); + int updateStTaskSignByTaskIdAndEmId(StTaskSign stTaskSign); + + int signUp(StTaskSign stTaskSign); + /** + * 批量删除签到 + * + * @param ids 需要删除的签到主键集合 + * @return 结果 + */ + public int deleteStTaskSignByIds(Long[] ids); + + /** + * 删除签到信息 + * + * @param id 签到主键 + * @return 结果 + */ + public int deleteStTaskSignById(Long id); +} diff --git a/staffing-system/src/main/java/com/staffing/custom/service/IStTransferRecordService.java b/staffing-system/src/main/java/com/staffing/custom/service/IStTransferRecordService.java new file mode 100644 index 0000000..5b5454e --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/service/IStTransferRecordService.java @@ -0,0 +1,61 @@ +package com.staffing.custom.service; + +import java.util.List; +import com.staffing.custom.domain.StTransferRecord; + +/** + * 微信转账记录Service接口 + * + * @author staffing + * @date 2024-09-06 + */ +public interface IStTransferRecordService +{ + /** + * 查询微信转账记录 + * + * @param id 微信转账记录主键 + * @return 微信转账记录 + */ + public StTransferRecord selectStTransferRecordById(Long id); + + /** + * 查询微信转账记录列表 + * + * @param stTransferRecord 微信转账记录 + * @return 微信转账记录集合 + */ + public List selectStTransferRecordList(StTransferRecord stTransferRecord); + + /** + * 新增微信转账记录 + * + * @param stTransferRecord 微信转账记录 + * @return 结果 + */ + public int insertStTransferRecord(StTransferRecord stTransferRecord); + + /** + * 修改微信转账记录 + * + * @param stTransferRecord 微信转账记录 + * @return 结果 + */ + public int updateStTransferRecord(StTransferRecord stTransferRecord); + + /** + * 批量删除微信转账记录 + * + * @param ids 需要删除的微信转账记录主键集合 + * @return 结果 + */ + public int deleteStTransferRecordByIds(Long[] ids); + + /** + * 删除微信转账记录信息 + * + * @param id 微信转账记录主键 + * @return 结果 + */ + public int deleteStTransferRecordById(Long id); +} diff --git a/staffing-system/src/main/java/com/staffing/custom/service/TransferBatchService.java b/staffing-system/src/main/java/com/staffing/custom/service/TransferBatchService.java new file mode 100644 index 0000000..c4770bb --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/service/TransferBatchService.java @@ -0,0 +1,150 @@ +package com.staffing.custom.service; + +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.RSAAutoCertificateConfig; +import com.wechat.pay.java.core.exception.ValidationException; +import com.wechat.pay.java.core.notification.NotificationConfig; +import com.wechat.pay.java.core.notification.NotificationParser; +import com.wechat.pay.java.core.notification.RequestParam; +import com.wechat.pay.java.service.transferbatch.TransferBatchServiceBase; +import com.wechat.pay.java.service.transferbatch.model.*; +import org.apache.ibatis.transaction.Transaction; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + + +/** TransferBatchService使用示例 */ +@Component +public class TransferBatchService { + private final static Logger logger = LoggerFactory.getLogger(TransferBatchService.class); + + public static String appId = "wx7bc7df6eb945a84f"; + + /** 商户号 */ + public static String merchantId = "1684628563"; + + /** 商户API私钥路径 */ + public static String privateKeyPath = "apiclient_key.pem"; + + /** 商户证书序列号 执行获得: openssl x509 -noout -serial -in apiclient_cert.pem */ + public static String merchantSerialNumber = "4710F9274C2CB57B1222BC511C852ADE740B07C1"; + + /** 商户APIV3密钥 */ + public static String apiV3Key = "Ps0123456789abcdefghijklmnopqrst"; + + public TransferBatchServiceBase service; + + public static void main(String[] args) { +// // 初始化商户配置 +// Config config = +// new RSAAutoCertificateConfig.Builder() +// .merchantId(merchantId) +// // 使用 com.wechat.pay.java.core.util +// // 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名 +// .privateKeyFromPath(privateKeyPath) +// .merchantSerialNumber(merchantSerialNumber) +// .apiV3Key(apiV3Key) +// .build(); +// +// // 初始化服务 +// service = new TransferBatchService.Builder().config(config).build(); +// // ... 调用接口 +// initiateBatchTransfer(); + } + @PostConstruct + public void init(){ + // 初始化商户配置 + Config config = + new RSAAutoCertificateConfig.Builder() + .merchantId(merchantId) + // 使用 com.wechat.pay.java.core.util + // 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名 + .privateKeyFromPath(privateKeyPath) + .merchantSerialNumber(merchantSerialNumber) + .apiV3Key(apiV3Key) + .build(); + + // 初始化服务 + service = new TransferBatchServiceBase.Builder().config(config).build(); + // ... 调用接口 +// initiateBatchTransfer(); + } + + /** 通过微信批次单号查询批次单 */ + public TransferBatchEntity getTransferBatchByNo() { + + GetTransferBatchByNoRequest request = new GetTransferBatchByNoRequest(); + return service.getTransferBatchByNo(request); + } + + /** 通过商家批次单号查询批次单 */ + public TransferBatchEntity getTransferBatchByOutNo() { + + GetTransferBatchByOutNoRequest request = new GetTransferBatchByOutNoRequest(); + return service.getTransferBatchByOutNo(request); + } + + /** 发起商家转账 */ + public InitiateBatchTransferResponse initiateBatchTransfer() { + InitiateBatchTransferRequest request = new InitiateBatchTransferRequest(); + return service.initiateBatchTransfer(request); + } + /** 发起商家转账 */ + public InitiateBatchTransferResponse initiateBatchTransfer(InitiateBatchTransferRequest request) { + return service.initiateBatchTransfer(request); + } + + /** 通过微信明细单号查询明细单 */ + public TransferDetailEntity getTransferDetailByNo() { + + GetTransferDetailByNoRequest request = new GetTransferDetailByNoRequest(); + return service.getTransferDetailByNo(request); + } + + /** 通过商家明细单号查询明细单 */ + public TransferDetailEntity getTransferDetailByOutNo() { + + GetTransferDetailByOutNoRequest request = new GetTransferDetailByOutNoRequest(); + return service.getTransferDetailByOutNo(request); + } + + + public ResponseEntity.BodyBuilder parse(RequestParam requestParam){ + + +// 如果已经初始化了 RSAAutoCertificateConfig,可直接使用 +// 没有的话,则构造一个 + NotificationConfig config = new RSAAutoCertificateConfig.Builder() + .merchantId(merchantId) + .privateKeyFromPath(privateKeyPath) + .merchantSerialNumber(merchantSerialNumber) + .apiV3Key(apiV3Key) + .build(); + +// 初始化 NotificationParser + NotificationParser parser = new NotificationParser(config); + + try { + // 以支付通知回调为例,验签、解密并转换成 Transaction + Transaction transaction = parser.parse(requestParam, Transaction.class); + } catch (ValidationException e) { + // 签名验证失败,返回 401 UNAUTHORIZED 状态码 + logger.error("sign verification failed", e); + return ResponseEntity.status(HttpStatus.UNAUTHORIZED); + } + +// 如果处理失败,应返回 4xx/5xx 的状态码,例如 500 INTERNAL_SERVER_ERROR +// if (/* process error */) { +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR); +// } + +// 处理成功,返回 200 OK 状态码 + return ResponseEntity.status(HttpStatus.OK); + + } +} diff --git a/staffing-system/src/main/java/com/staffing/custom/service/impl/StEmployeeFundRecordServiceImpl.java b/staffing-system/src/main/java/com/staffing/custom/service/impl/StEmployeeFundRecordServiceImpl.java new file mode 100644 index 0000000..21e4bcf --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/service/impl/StEmployeeFundRecordServiceImpl.java @@ -0,0 +1,251 @@ +package com.staffing.custom.service.impl; + +import java.math.BigDecimal; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +import com.staffing.common.exception.ServiceException; +import com.staffing.common.utils.DateUtils; +import com.staffing.common.utils.OrderUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.custom.domain.*; +import com.staffing.custom.mapper.StEmployeeFundRecordMapper; +import com.staffing.custom.mapper.StEmployeeMapper; +import com.staffing.custom.mapper.StTaskSignMapper; +import com.staffing.custom.mapper.StTransferRecordMapper; +import com.staffing.custom.param.FxParam; +import com.staffing.custom.service.IStEmployeeFundRecordService; +import com.staffing.custom.service.IStTaskService; +import com.staffing.custom.service.TransferBatchService; +import com.staffing.system.service.impl.SysUserServiceImpl; +import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferRequest; +import com.wechat.pay.java.service.transferbatch.model.TransferDetailInput; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * 员工资金流水Service业务层处理 + * + * @author staffing + * @date 2024-08-27 + */ +@Service +public class StEmployeeFundRecordServiceImpl implements IStEmployeeFundRecordService +{ + private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class); + + @Autowired + private StEmployeeFundRecordMapper stEmployeeFundRecordMapper; + @Autowired + private StEmployeeMapper stEmployeeMapper; + @Autowired + private StTaskSignMapper taskSignMapper; + @Autowired + private IStTaskService stTaskService; + + @Autowired + private StTransferRecordMapper stTransferRecordMapper; + + @Autowired + private TransferBatchService transferBatchService; + /** + * 查询员工资金流水 + * + * @param id 员工资金流水主键 + * @return 员工资金流水 + */ + @Override + public StEmployeeFundRecord selectStEmployeeFundRecordById(Long id) + { + return stEmployeeFundRecordMapper.selectStEmployeeFundRecordById(id); + } + + /** + * 查询员工资金流水列表 + * + * @param stEmployeeFundRecord 员工资金流水 + * @return 员工资金流水 + */ + @Override + public List selectStEmployeeFundRecordList(StEmployeeFundRecord stEmployeeFundRecord) + { + List fundRecords = stEmployeeFundRecordMapper.selectStEmployeeFundRecordList(stEmployeeFundRecord); + for (StEmployeeFundRecord fundRecord : fundRecords) { + StTaskSign stTaskSign = taskSignMapper.selectStTaskSignByTaskIdAndUserId(fundRecord.getTaskId(), fundRecord.getEmployeeId()); + fundRecord.setStTaskSign(stTaskSign); + } + return fundRecords; + } + + /** + * 新增员工资金流水 + * + * @param stEmployeeFundRecord 员工资金流水 + * @return 结果 + */ + @Override + public int insertStEmployeeFundRecord(StEmployeeFundRecord stEmployeeFundRecord) + { + return stEmployeeFundRecordMapper.insertStEmployeeFundRecord(stEmployeeFundRecord); + } + + /** + * 修改员工资金流水 + * + * @param stEmployeeFundRecord 员工资金流水 + * @return 结果 + */ + @Override + public int updateStEmployeeFundRecord(StEmployeeFundRecord stEmployeeFundRecord) + { + stEmployeeFundRecord.setUpdateTime(DateUtils.getNowDate()); + return stEmployeeFundRecordMapper.updateStEmployeeFundRecord(stEmployeeFundRecord); + } + + /** + * 批量删除员工资金流水 + * + * @param ids 需要删除的员工资金流水主键 + * @return 结果 + */ + @Override + public int deleteStEmployeeFundRecordByIds(Long[] ids) + { + return stEmployeeFundRecordMapper.deleteStEmployeeFundRecordByIds(ids); + } + + /** + * 删除员工资金流水信息 + * + * @param id 员工资金流水主键 + * @return 结果 + */ + @Override + public int deleteStEmployeeFundRecordById(Long id) + { + return stEmployeeFundRecordMapper.deleteStEmployeeFundRecordById(id); + } + + + @Override + public String importRecord(List records) + { + if (StringUtils.isNull(records) || records.size() == 0) + { + throw new ServiceException("导入数据不能为空!"); + } + int successNum = 0; + int failureNum = 0; + StringBuilder successMsg = new StringBuilder(); + StringBuilder failureMsg = new StringBuilder(); + for (StEmployeeFundRecord record : records) + { + try + { + record.setUpdateTime(new Date()); + // 验证是否存在这个用户 + StEmployeeFundRecord stEmployeeFundRecords = stEmployeeFundRecordMapper.selectStEmployeeFundRecordByUidAndTaskId(record.getTaskId(), record.getEmployeeId()); + if (stEmployeeFundRecords == null) { + stEmployeeFundRecordMapper.insertStEmployeeFundRecord(record); + successNum++; + successMsg.append("
" + successNum + "、数据导入成功"); + } else{ + int i = stEmployeeFundRecordMapper.updateStEmployeeFundRecordByTaskAndUid(record); + if (i > 0){ + successNum++; + successMsg.append("
" + successNum + "、数据导入成功"); + } + } + } + catch (Exception e) + { + failureNum++; + String msg = "
" + failureNum + "、数据导入失败:"; + failureMsg.append(msg + e.getMessage()); + log.error(msg, e); + } + } + if (failureNum > 0) + { + failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); + throw new ServiceException(failureMsg.toString()); + } + else + { + successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:"); + } + return successMsg.toString(); + } + + + public String faxin(FxParam fxParam){ + + StTask stTask = stTaskService.selectStTaskById(fxParam.getTaskId(), true); + Map taskSignMap = stTask.getListSign().stream() + .collect(Collectors.toMap(StTaskSign::getEmployeeId, Function.identity())); + + for (Long employeeId : fxParam.getEmployeeIds()) { + StTaskSign stTaskSign = taskSignMap.get(employeeId); + if (stTaskSign == null){ + return "发薪失败, 员工id:" + employeeId + "没有签到,不能发薪"; + } + StEmployeeFundRecord stEmployeeFundRecord = stTaskSign.getStEmployeeFundRecord(); + if (stEmployeeFundRecord == null){ + continue; + } + if (stEmployeeFundRecord.getPayStatus() == 1){ + return "发薪失败, 员工id:" + employeeId + "已经发放,请刷新发薪页面"; + } + } + List stEmployees = stEmployeeMapper.selectStEmployeeByIds(fxParam.getEmployeeIds()); + Map stEmployeeHashMap = stEmployees.stream() + .collect(Collectors.toMap(StEmployee::getId, Function.identity())); + + InitiateBatchTransferRequest request = new InitiateBatchTransferRequest(); + request.setAppid(TransferBatchService.appId); + request.setOutBatchNo(OrderUtils.genOrderId("B")); + request.setBatchName("工资"); + request.setBatchRemark(stTask.getTaskName() + "的工资"); + request.setTotalNum(fxParam.getEmployeeIds().size());//总笔数 + BigDecimal sumAmount = new BigDecimal(0); + for (Long employeeId : fxParam.getEmployeeIds()) { + StTaskSign stTaskSign = taskSignMap.get(employeeId); + sumAmount = sumAmount.add(new BigDecimal(stTaskSign.getStEmployeeFundRecord().getRealPrice())); + + + TransferDetailInput transferDetailInput = new TransferDetailInput(); + transferDetailInput.setOutDetailNo(stTaskSign.getStEmployeeFundRecord().getTransferNo()); + StEmployee stEmployee = stEmployeeHashMap.get(employeeId); + if (stEmployee == null){ + return "系统错误,发薪失败, 员工id:" + employeeId + "没有找到对应数据,联系开发者"; + } + transferDetailInput.setOpenid(stEmployee.getOpenId()); + transferDetailInput.setTransferAmount(new BigDecimal(stTaskSign.getStEmployeeFundRecord().getRealPrice()).multiply(new BigDecimal("100")).longValue()); + transferDetailInput.setTransferRemark(stTask.getTaskName() + "的工资"); + transferDetailInput.setUserName(stEmployee.getRealName()); + request.getTransferDetailList().add(transferDetailInput); + } + + + StTransferRecord stTransferRecord = new StTransferRecord(); + stTransferRecord.setCreateTime(new Date()); + stTransferRecord.setTaskId(fxParam.getTaskId()); + stTransferRecord.setTaskName(stTask.getTaskName()); + stTransferRecord.setPayStatus(0); + stTransferRecord.setCountPrice(sumAmount.toString()); + stTransferRecord.setTransferNo(request.getOutBatchNo()); + stTransferRecord.setEmployeeIds(fxParam.getEmployeeIds().stream().map(String::valueOf).collect(Collectors.joining(","))); + stTransferRecordMapper.insertStTransferRecord(stTransferRecord); + + + request.setTotalAmount(sumAmount.multiply(new BigDecimal("100")).longValue());//总金额 + request.setTransferSceneId(null); +// request.setNotifyUrl("https://192.168.18.122:8080/merchant/fund/fxResult"); + transferBatchService.initiateBatchTransfer(request); + + return "success"; + } +} diff --git a/staffing-system/src/main/java/com/staffing/custom/service/impl/StEmployeeServiceImpl.java b/staffing-system/src/main/java/com/staffing/custom/service/impl/StEmployeeServiceImpl.java new file mode 100644 index 0000000..ae0010b --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/service/impl/StEmployeeServiceImpl.java @@ -0,0 +1,106 @@ +package com.staffing.custom.service.impl; + +import java.util.List; +import com.staffing.common.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.staffing.custom.mapper.StEmployeeMapper; +import com.staffing.custom.domain.StEmployee; +import com.staffing.custom.service.IStEmployeeService; + +/** + * 员工Service业务层处理 + * + * @author staffing + * @date 2024-08-27 + */ +@Service +public class StEmployeeServiceImpl implements IStEmployeeService +{ + @Autowired + private StEmployeeMapper stEmployeeMapper; + + /** + * 查询员工 + * + * @param id 员工主键 + * @return 员工 + */ + @Override + public StEmployee selectStEmployeeById(Long id) + { + return stEmployeeMapper.selectStEmployeeById(id); + } + + public StEmployee selectStEmployeeByPhone(String phone){ + return stEmployeeMapper.selectStEmployeeByPhone(phone); + } + + /** + * 查询员工列表 + * + * @param stEmployee 员工 + * @return 员工 + */ + @Override + public List selectStEmployeeList(StEmployee stEmployee) + { + return stEmployeeMapper.selectStEmployeeList(stEmployee); + } + + /** + * 新增员工 + * + * @param stEmployee 员工 + * @return 结果 + */ + @Override + public int insertStEmployee(StEmployee stEmployee) + { + return stEmployeeMapper.insertStEmployee(stEmployee); + } + + /** + * 修改员工 + * + * @param stEmployee 员工 + * @return 结果 + */ + @Override + public int updateStEmployee(StEmployee stEmployee) + { + stEmployee.setUpdateTime(DateUtils.getNowDate()); + return stEmployeeMapper.updateStEmployee(stEmployee); + } + + @Override + public int updateStEmployeeOrNull(StEmployee stEmployee) + { + stEmployee.setUpdateTime(DateUtils.getNowDate()); + return stEmployeeMapper.updateStEmployeeOrNull(stEmployee); + } + + /** + * 批量删除员工 + * + * @param ids 需要删除的员工主键 + * @return 结果 + */ + @Override + public int deleteStEmployeeByIds(Long[] ids) + { + return stEmployeeMapper.deleteStEmployeeByIds(ids); + } + + /** + * 删除员工信息 + * + * @param id 员工主键 + * @return 结果 + */ + @Override + public int deleteStEmployeeById(Long id) + { + return stEmployeeMapper.deleteStEmployeeById(id); + } +} diff --git a/staffing-system/src/main/java/com/staffing/custom/service/impl/StTaskServiceImpl.java b/staffing-system/src/main/java/com/staffing/custom/service/impl/StTaskServiceImpl.java new file mode 100644 index 0000000..8ad94c6 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/service/impl/StTaskServiceImpl.java @@ -0,0 +1,349 @@ +package com.staffing.custom.service.impl; + +import java.io.InputStream; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import com.staffing.common.utils.DateUtils; +import com.staffing.common.utils.MinioUtil; +import com.staffing.common.utils.QRCodeGenerator; +import com.staffing.custom.domain.StEmployeeFundRecord; +import com.staffing.custom.domain.StTaskSign; +import com.staffing.custom.mapper.StEmployeeFundRecordMapper; +import com.staffing.custom.mapper.StTaskSignMapper; +import io.minio.ObjectWriteResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.staffing.custom.mapper.StTaskMapper; +import com.staffing.custom.domain.StTask; +import com.staffing.custom.service.IStTaskService; + +import static com.staffing.common.utils.PageUtils.startPage; + +/** + * 任务Service业务层处理 + * + * @author staffing + * @date 2024-08-27 + */ +@Service +public class StTaskServiceImpl implements IStTaskService +{ + @Autowired + private StTaskMapper stTaskMapper; + + @Autowired + private StTaskSignMapper stTaskSignMapper; + @Autowired + private StEmployeeFundRecordMapper stEmployeeFundRecordMapper; + + @Autowired + private MinioUtil minioUtil; + + protected final Logger logger = LoggerFactory.getLogger(StTaskServiceImpl.class); + + @Override + public StTask selectStTaskById(Long id){ + return selectStTaskById(id, false); + } + /** + * 查询任务 + * + * @param id 任务主键 + * @return 任务 + */ + @Override + public StTask selectStTaskById(Long id, boolean filterSign) + { + StTask stTask = stTaskMapper.selectStTaskById(id); + + StEmployeeFundRecord employeeFundRecord = new StEmployeeFundRecord(); + employeeFundRecord.setTaskId(id); + List fundRecords = stEmployeeFundRecordMapper.selectStEmployeeFundRecordList(employeeFundRecord); + Map fundMap = new HashMap<>(); + for (StEmployeeFundRecord fundRecord : fundRecords) { + fundMap.put(fundRecord.getEmployeeId(), fundRecord); + } + StTaskSign param = new StTaskSign(); + param.setTaskId(stTask.getId()); + List stTaskSignsTemp = stTaskSignMapper.selectStTaskSignList(param); + List stTaskSigns; + if (filterSign){ + stTaskSigns = new ArrayList<>(); + for (StTaskSign taskSign : stTaskSignsTemp) { + if (taskSign.getStatus() == 1){ + stTaskSigns.add(taskSign); + } + } + }else{ + stTaskSigns = stTaskSignsTemp; + } + + stTask.setListSign(stTaskSigns); + + int signNum = 0; + for (StTaskSign stTaskSign1 : stTaskSigns) { + if (stTaskSign1.getStatus() == 1){ + signNum ++; + } + stTaskSign1.setTaskName(stTask.getTaskName()); + stTaskSign1.setDayPrice(stTask.getDayPrice()); + + stTaskSign1.setStEmployeeFundRecord(fundMap.get(stTaskSign1.getEmployeeId())); + } + stTask.setSignNum(signNum); + stTask.setBaomingNum(stTask.getListSign().size()); + + return stTask; + } + + /** + * 查询任务列表 + * + * @param stTask 任务 + * @return 任务 + */ + @Override + public List selectStTaskList(StTask stTask, long uid) + { + List stTasks = stTaskMapper.selectStTaskList(stTask); + if (stTasks.isEmpty()) + return stTasks; + for (StTask task : stTasks) { + if (task.getCodePic() == null){ + generatePrCode(task); + } + } + + return supplement(stTasks, uid); + } + + + /** + * 填充签到信息 + * @param stTasks + * @return + */ + private List supplement(List stTasks, long uid) { + List taskIds = stTasks.stream().map(stTask1 -> stTask1.getId()).collect(Collectors.toList()); + if (taskIds.isEmpty()){ + return stTasks; + } + + List fundRecords = stEmployeeFundRecordMapper.selectStEmployeeFundRecordByTaskIds(taskIds); + Map> taskFundMap = new HashMap<>(); + for (StEmployeeFundRecord fundRecord : fundRecords) { + Map fundRecordMap = taskFundMap.computeIfAbsent(fundRecord.getTaskId(), v -> new HashMap<>()); + fundRecordMap.put(fundRecord.getEmployeeId(), fundRecord); + } + + List stTaskSigns = stTaskSignMapper.selectStTaskSignByTaskIds(taskIds); + Map> taskSignMap = new HashMap<>(); + for (StTaskSign stTaskSign : stTaskSigns) { + List stTaskSignsList = taskSignMap.computeIfAbsent(stTaskSign.getTaskId(), v -> new ArrayList<>()); + stTaskSignsList.add(stTaskSign); + } + + for (StTask task : stTasks) { + task.setListSign(taskSignMap.get(task.getId())); + Map employeeFundRecordMap = taskFundMap.get(task.getId()); + + + if (task.getListSign() == null){ + task.setSignNum(0); + task.setBaomingNum(0); + task.setYfNum(0); + task.setSfNum(0); + task.setDfNum(0); + task.setYfPrice(0+""); + task.setSfPrice(0+""); + task.setDfPrice(0+""); + continue; + } + int signNum = 0; + int yfNum = 0;//应发 + int sfNum = 0;//实发 + int dfNum = 0;//待发 + BigDecimal yfPrice = new BigDecimal(0); + BigDecimal sfPrice = new BigDecimal(0); + BigDecimal dfPrice = new BigDecimal(0); + + + for (StTaskSign stTaskSign : task.getListSign()) { + if (employeeFundRecordMap != null){ + StEmployeeFundRecord fundRecord = employeeFundRecordMap.get(stTaskSign.getEmployeeId()); + if (fundRecord != null){ + stTaskSign.setStEmployeeFundRecord(fundRecord); + if (fundRecord.getPayStatus() == 1){ + sfNum++; + sfPrice = sfPrice.add(new BigDecimal(fundRecord.getRealPrice())); + } + yfPrice = yfPrice.add(new BigDecimal(fundRecord.getRealPrice())); + } + } + + if (stTaskSign.getStatus() == 1){ + signNum ++; + yfNum++; + } + + stTaskSign.setTaskName(task.getTaskName()); + stTaskSign.setDayPrice(task.getDayPrice()); + + + if (stTaskSign.getEmployeeId() == uid){ + task.setSelfSign(stTaskSign); + } + } + dfNum = yfNum - sfNum; + dfPrice = yfPrice.subtract(sfPrice); + + task.setYfNum(yfNum); + task.setSfNum(sfNum); + task.setDfNum(dfNum); + task.setYfPrice(yfPrice.toString()); + task.setSfPrice(sfPrice.toString()); + task.setDfPrice(dfPrice.toString()); + task.setSignNum(signNum); + task.setBaomingNum(task.getListSign().size()); + + } + return stTasks; + } + + public List selectStTaskListByUserId(StTask stTask, Long userId, boolean sign){ + StTaskSign stTaskSign = new StTaskSign(); + stTaskSign.setEmployeeId(userId); + if (sign){ + stTaskSign.setStatus(1); + } + + List stTaskSigns = stTaskSignMapper.selectStTaskSignList(stTaskSign); + if (stTaskSigns.isEmpty()){ + return new ArrayList<>(); + } + + Map taskSignMap = new HashMap<>(); + for (StTaskSign taskSign : stTaskSigns) { + taskSignMap.put(taskSign.getTaskId(), taskSign); + } + stTask.setTaskIds(taskSignMap.keySet()); + startPage(); + List stTasks = stTaskMapper.selectStTaskList(stTask); + + for (StTask task : stTasks) { + task.setSelfSign(taskSignMap.get(task.getId())); + } + + return supplement(stTasks, userId); + } + + /** + * 新增任务 + * + * @param stTask 任务 + * @return 结果 + */ + @Override + public int insertStTask(StTask stTask) + { + int i = stTaskMapper.insertStTask(stTask); + List listSign = stTask.getListSign(); + for (StTaskSign stTaskSign : listSign) { + stTaskSign.setTaskId(stTask.getId()); + stTaskSign.setStatus(0); + stTaskSign.setDayPrice(stTask.getDayPrice()); + stTaskSign.setTaskName(stTask.getTaskName()); + stTaskSignMapper.insertStTaskSign(stTaskSign); + } + return i; + } + + /** + * 修改任务 + * + * @param stTask 任务 + * @return 结果 + */ + @Override + public int updateStTask(StTask stTask) + { + stTask.setUpdateTime(DateUtils.getNowDate()); + + StTaskSign param = new StTaskSign(); + param.setTaskId(stTask.getId()); + List stTaskSigns = stTaskSignMapper.selectStTaskSignList(param); + Map stTaskSignMap = new HashMap<>(); + for (StTaskSign stTaskSign : stTaskSigns) { + stTaskSignMap.put(stTaskSign.getEmployeeId(), stTaskSign); + } + + List listSign = stTask.getListSign(); + if (listSign != null){ + for (StTaskSign stTaskSign : listSign) { + stTaskSign.setTaskId(stTask.getId()); + stTaskSign.setStatus(0); + stTaskSign.setDayPrice(stTask.getDayPrice()); + stTaskSign.setTaskName(stTask.getTaskName()); + + if (!stTaskSignMap.containsKey(stTaskSign.getEmployeeId())){ + stTaskSignMapper.insertStTaskSign(stTaskSign); + } + stTaskSignMap.remove(stTaskSign.getEmployeeId()); + } + for (Map.Entry longStTaskSignEntry : stTaskSignMap.entrySet()) { + stTaskSignMapper.deleteStTaskSignById(longStTaskSignEntry.getValue().getId()); + } + } + + + + return stTaskMapper.updateStTask(stTask); + } + + public int generatePrCode(StTask stTask){ + String url = "http://yg.pusonggroup.com:81/index.html?id=" + stTask.getId(); + InputStream inputStream = QRCodeGenerator.generateQRCodeImage(url, 500, 500); + String fileName = System.currentTimeMillis() + stTask.getId() + ".png"; + try { + ObjectWriteResponse objectWriteResponse = minioUtil.putObject("yonggong" + , fileName, inputStream, inputStream.available(), "image/png"); + } catch (Exception e) { + logger.error("minioUtil.putObject error", e); + } + + stTask.setCodePic(fileName); + + return updateStTask(stTask); + } + + /** + * 批量删除任务 + * + * @param ids 需要删除的任务主键 + * @return 结果 + */ + @Override + public int deleteStTaskByIds(Long[] ids) + { + return stTaskMapper.deleteStTaskByIds(ids); + } + + /** + * 删除任务信息 + * + * @param id 任务主键 + * @return 结果 + */ + @Override + public int deleteStTaskById(Long id) + { + return stTaskMapper.deleteStTaskById(id); + } +} diff --git a/staffing-system/src/main/java/com/staffing/custom/service/impl/StTaskSignServiceImpl.java b/staffing-system/src/main/java/com/staffing/custom/service/impl/StTaskSignServiceImpl.java new file mode 100644 index 0000000..dc79471 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/service/impl/StTaskSignServiceImpl.java @@ -0,0 +1,187 @@ +package com.staffing.custom.service.impl; + +import java.util.Date; +import java.util.List; + +import com.staffing.common.core.domain.AjaxResult; +import com.staffing.common.core.domain.entity.SysUser; +import com.staffing.common.utils.OrderUtils; +import com.staffing.common.utils.SecurityUtils; +import com.staffing.custom.domain.StEmployeeFundRecord; +import com.staffing.custom.domain.StTask; +import com.staffing.custom.mapper.StEmployeeFundRecordMapper; +import com.staffing.custom.service.IStEmployeeFundRecordService; +import com.staffing.custom.service.IStTaskService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.staffing.custom.mapper.StTaskSignMapper; +import com.staffing.custom.domain.StTaskSign; +import com.staffing.custom.service.IStTaskSignService; + +import static com.staffing.common.core.domain.AjaxResult.error; + +/** + * 签到Service业务层处理 + * + * @author staffing + * @date 2024-08-27 + */ +@Service +public class StTaskSignServiceImpl implements IStTaskSignService +{ + @Autowired + private StTaskSignMapper stTaskSignMapper; + @Autowired + private IStEmployeeFundRecordService employeeFundRecordService; + @Autowired + private IStTaskService stTaskService; + @Autowired + private StEmployeeFundRecordMapper stEmployeeFundRecordMapper; + /** + * 查询签到 + * + * @param id 签到主键 + * @return 签到 + */ + @Override + public StTaskSign selectStTaskSignById(Long id) + { + return stTaskSignMapper.selectStTaskSignById(id); + } + + /** + * 查询签到列表 + * + * @param stTaskSign 签到 + * @return 签到 + */ + @Override + public List selectStTaskSignList(StTaskSign stTaskSign) + { + return stTaskSignMapper.selectStTaskSignList(stTaskSign); + } + + @Override + public AjaxResult baoming(StTaskSign taskSign) + { + SysUser user = SecurityUtils.getLoginUser().getUser(); + long userId = user.getUserId(); + taskSign.setEmployeeId(userId); + + StTask stTask = stTaskService.selectStTaskById(taskSign.getTaskId()); + if (stTask.getUseNum() <= stTask.getListSign().size()){ + return error(); + } + for (StTaskSign stTaskSign : stTask.getListSign()) { + if (stTaskSign.getEmployeeId().equals(taskSign.getEmployeeId())){ + return error("无法重复报名"); + } + } + taskSign.setDayPrice(stTask.getDayPrice()); + taskSign.setEmployeeName(taskSign.getEmployeeName()); + taskSign.setStatus(0); + return AjaxResult.success(); + } + + /** + * 新增签到 + * + * @param stTaskSign 签到 + * @return 结果 + */ + @Override + public int insertStTaskSign(StTaskSign stTaskSign) + { + return stTaskSignMapper.insertStTaskSign(stTaskSign); + } + + /** + * 修改签到 + * + * @param stTaskSign 签到 + * @return 结果 + */ + @Override + public int updateStTaskSign(StTaskSign stTaskSign) + { + return stTaskSignMapper.updateStTaskSign(stTaskSign); + } + + + /** + * 签到 + * @return 结果 + */ + @Override + public int signUp(StTaskSign updateStTaskSign) + { + StTaskSign stTaskSign = stTaskSignMapper.selectStTaskSignByTaskIdAndUserId(updateStTaskSign.getTaskId(), updateStTaskSign.getEmployeeId()); + if (stTaskSign == null){ + updateStTaskSign.setSignTime(new Date()); + return insertStTaskSign(updateStTaskSign); + } + if (stTaskSign.getSignTime() == null && stTaskSign.getStatus() == 0 && updateStTaskSign.getStatus() == 1){ + updateStTaskSign.setSignTime(new Date()); + } + StEmployeeFundRecord fundRecords = stEmployeeFundRecordMapper.selectStEmployeeFundRecordByUidAndTaskId(stTaskSign.getTaskId(), stTaskSign.getEmployeeId()); + if (fundRecords == null){ + StTask stTask = stTaskService.selectStTaskById(stTaskSign.getTaskId()); + StEmployeeFundRecord stEmployeeFundRecord = new StEmployeeFundRecord(); + stEmployeeFundRecord.setTaskId(stTaskSign.getTaskId()); + stEmployeeFundRecord.setTaskName(stTask.getTaskName()); + stEmployeeFundRecord.setTaskDate(stTask.getTaskDate()); + stEmployeeFundRecord.setEmployeeId(stTaskSign.getEmployeeId()); + stEmployeeFundRecord.setEmployeeName(stTaskSign.getEmployeeName()); + stEmployeeFundRecord.setPhone(stTaskSign.getPhone()); + stEmployeeFundRecord.setIdCard(stTaskSign.getIdCard()); + stEmployeeFundRecord.setDayPrice(stTaskSign.getDayPrice()); + stEmployeeFundRecord.setShouldPrice(stTask.getDayPrice()); + stEmployeeFundRecord.setRealPrice(stTask.getDayPrice());//默认实发为日结 +// stEmployeeFundRecord.setPayWay(0l); +// stEmployeeFundRecord.setPayAccount(0l); +// stEmployeeFundRecord.setPayTime(); + stEmployeeFundRecord.setPayStatus(0l); + stEmployeeFundRecord.setUpdateTime(new Date()); + stEmployeeFundRecord.setTransferNo(OrderUtils.genOrderId("D")); + employeeFundRecordService.insertStEmployeeFundRecord(stEmployeeFundRecord); + } + return updateStTaskSignByTaskIdAndEmId(updateStTaskSign); + } + + /** + * 修改签到 + * + * @param stTaskSign 签到 + * @return 结果 + */ + @Override + public int updateStTaskSignByTaskIdAndEmId(StTaskSign stTaskSign) + { + return stTaskSignMapper.updateStTaskSignByTaskIdAndEmId(stTaskSign); + } + + + /** + * 批量删除签到 + * + * @param ids 需要删除的签到主键 + * @return 结果 + */ + @Override + public int deleteStTaskSignByIds(Long[] ids) + { + return stTaskSignMapper.deleteStTaskSignByIds(ids); + } + + /** + * 删除签到信息 + * + * @param id 签到主键 + * @return 结果 + */ + @Override + public int deleteStTaskSignById(Long id) + { + return stTaskSignMapper.deleteStTaskSignById(id); + } +} diff --git a/staffing-system/src/main/java/com/staffing/custom/service/impl/StTransferRecordServiceImpl.java b/staffing-system/src/main/java/com/staffing/custom/service/impl/StTransferRecordServiceImpl.java new file mode 100644 index 0000000..856b3cb --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/custom/service/impl/StTransferRecordServiceImpl.java @@ -0,0 +1,96 @@ +package com.staffing.custom.service.impl; + +import java.util.List; +import com.staffing.common.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.staffing.custom.mapper.StTransferRecordMapper; +import com.staffing.custom.domain.StTransferRecord; +import com.staffing.custom.service.IStTransferRecordService; + +/** + * 微信转账记录Service业务层处理 + * + * @author staffing + * @date 2024-09-06 + */ +@Service +public class StTransferRecordServiceImpl implements IStTransferRecordService +{ + @Autowired + private StTransferRecordMapper stTransferRecordMapper; + + /** + * 查询微信转账记录 + * + * @param id 微信转账记录主键 + * @return 微信转账记录 + */ + @Override + public StTransferRecord selectStTransferRecordById(Long id) + { + return stTransferRecordMapper.selectStTransferRecordById(id); + } + + /** + * 查询微信转账记录列表 + * + * @param stTransferRecord 微信转账记录 + * @return 微信转账记录 + */ + @Override + public List selectStTransferRecordList(StTransferRecord stTransferRecord) + { + return stTransferRecordMapper.selectStTransferRecordList(stTransferRecord); + } + + /** + * 新增微信转账记录 + * + * @param stTransferRecord 微信转账记录 + * @return 结果 + */ + @Override + public int insertStTransferRecord(StTransferRecord stTransferRecord) + { + stTransferRecord.setCreateTime(DateUtils.getNowDate()); + return stTransferRecordMapper.insertStTransferRecord(stTransferRecord); + } + + /** + * 修改微信转账记录 + * + * @param stTransferRecord 微信转账记录 + * @return 结果 + */ + @Override + public int updateStTransferRecord(StTransferRecord stTransferRecord) + { + stTransferRecord.setUpdateTime(DateUtils.getNowDate()); + return stTransferRecordMapper.updateStTransferRecord(stTransferRecord); + } + + /** + * 批量删除微信转账记录 + * + * @param ids 需要删除的微信转账记录主键 + * @return 结果 + */ + @Override + public int deleteStTransferRecordByIds(Long[] ids) + { + return stTransferRecordMapper.deleteStTransferRecordByIds(ids); + } + + /** + * 删除微信转账记录信息 + * + * @param id 微信转账记录主键 + * @return 结果 + */ + @Override + public int deleteStTransferRecordById(Long id) + { + return stTransferRecordMapper.deleteStTransferRecordById(id); + } +} diff --git a/staffing-system/src/main/java/com/staffing/system/domain/SysCache.java b/staffing-system/src/main/java/com/staffing/system/domain/SysCache.java new file mode 100644 index 0000000..53d8d5c --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/domain/SysCache.java @@ -0,0 +1,81 @@ +package com.staffing.system.domain; + +import com.staffing.common.utils.StringUtils; + +/** + * 缓存信息 + * + * @author staffing + */ +public class SysCache +{ + /** 缓存名称 */ + private String cacheName = ""; + + /** 缓存键名 */ + private String cacheKey = ""; + + /** 缓存内容 */ + private String cacheValue = ""; + + /** 备注 */ + private String remark = ""; + + public SysCache() + { + + } + + public SysCache(String cacheName, String remark) + { + this.cacheName = cacheName; + this.remark = remark; + } + + public SysCache(String cacheName, String cacheKey, String cacheValue) + { + this.cacheName = StringUtils.replace(cacheName, ":", ""); + this.cacheKey = StringUtils.replace(cacheKey, cacheName, ""); + this.cacheValue = cacheValue; + } + + public String getCacheName() + { + return cacheName; + } + + public void setCacheName(String cacheName) + { + this.cacheName = cacheName; + } + + public String getCacheKey() + { + return cacheKey; + } + + public void setCacheKey(String cacheKey) + { + this.cacheKey = cacheKey; + } + + public String getCacheValue() + { + return cacheValue; + } + + public void setCacheValue(String cacheValue) + { + this.cacheValue = cacheValue; + } + + public String getRemark() + { + return remark; + } + + public void setRemark(String remark) + { + this.remark = remark; + } +} diff --git a/staffing-system/src/main/java/com/staffing/system/domain/SysConfig.java b/staffing-system/src/main/java/com/staffing/system/domain/SysConfig.java new file mode 100644 index 0000000..82cc998 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/domain/SysConfig.java @@ -0,0 +1,111 @@ +package com.staffing.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.staffing.common.annotation.Excel; +import com.staffing.common.annotation.Excel.ColumnType; +import com.staffing.common.core.domain.BaseEntity; + +/** + * 参数配置表 sys_config + * + * @author staffing + */ +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; + + /** 系统内置(Y是 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/staffing-system/src/main/java/com/staffing/system/domain/SysLogininfor.java b/staffing-system/src/main/java/com/staffing/system/domain/SysLogininfor.java new file mode 100644 index 0000000..db0c6f4 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/domain/SysLogininfor.java @@ -0,0 +1,144 @@ +package com.staffing.system.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.staffing.common.annotation.Excel; +import com.staffing.common.annotation.Excel.ColumnType; +import com.staffing.common.core.domain.BaseEntity; + +/** + * 系统访问记录表 sys_logininfor + * + * @author staffing + */ +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; + + /** 访问时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @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; + } +} diff --git a/staffing-system/src/main/java/com/staffing/system/domain/SysNotice.java b/staffing-system/src/main/java/com/staffing/system/domain/SysNotice.java new file mode 100644 index 0000000..d6e14b3 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/domain/SysNotice.java @@ -0,0 +1,102 @@ +package com.staffing.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.staffing.common.core.domain.BaseEntity; +import com.staffing.common.xss.Xss; + +/** + * 通知公告表 sys_notice + * + * @author staffing + */ +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正常 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; + } + + @Xss(message = "公告标题不能包含脚本字符") + @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/staffing-system/src/main/java/com/staffing/system/domain/SysOperLog.java b/staffing-system/src/main/java/com/staffing/system/domain/SysOperLog.java new file mode 100644 index 0000000..e08fdd5 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/domain/SysOperLog.java @@ -0,0 +1,269 @@ +package com.staffing.system.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.staffing.common.annotation.Excel; +import com.staffing.common.annotation.Excel.ColumnType; +import com.staffing.common.core.domain.BaseEntity; + +/** + * 操作日志记录表 oper_log + * + * @author staffing + */ +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=生成代码,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正常 1异常) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=异常") + private Integer status; + + /** 错误消息 */ + @Excel(name = "错误消息") + private String errorMsg; + + /** 操作时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "操作时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date operTime; + + /** 消耗时间 */ + @Excel(name = "消耗时间", suffix = "毫秒") + private Long costTime; + + 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; + } + + public Long getCostTime() + { + return costTime; + } + + public void setCostTime(Long costTime) + { + this.costTime = costTime; + } +} diff --git a/staffing-system/src/main/java/com/staffing/system/domain/SysPost.java b/staffing-system/src/main/java/com/staffing/system/domain/SysPost.java new file mode 100644 index 0000000..e28615a --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/domain/SysPost.java @@ -0,0 +1,124 @@ +package com.staffing.system.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.staffing.common.annotation.Excel; +import com.staffing.common.annotation.Excel.ColumnType; +import com.staffing.common.core.domain.BaseEntity; + +/** + * 岗位表 sys_post + * + * @author staffing + */ +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 Integer postSort; + + /** 状态(0正常 1停用) */ + @Excel(name = "状态", readConverterExp = "0=正常,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; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getPostSort() + { + return postSort; + } + + public void setPostSort(Integer 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/staffing-system/src/main/java/com/staffing/system/domain/SysRoleDept.java b/staffing-system/src/main/java/com/staffing/system/domain/SysRoleDept.java new file mode 100644 index 0000000..447e156 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/domain/SysRoleDept.java @@ -0,0 +1,46 @@ +package com.staffing.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 角色和部门关联 sys_role_dept + * + * @author staffing + */ +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/staffing-system/src/main/java/com/staffing/system/domain/SysRoleMenu.java b/staffing-system/src/main/java/com/staffing/system/domain/SysRoleMenu.java new file mode 100644 index 0000000..bcae606 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/domain/SysRoleMenu.java @@ -0,0 +1,46 @@ +package com.staffing.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 角色和菜单关联 sys_role_menu + * + * @author staffing + */ +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/staffing-system/src/main/java/com/staffing/system/domain/SysUserOnline.java b/staffing-system/src/main/java/com/staffing/system/domain/SysUserOnline.java new file mode 100644 index 0000000..8c0e398 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/domain/SysUserOnline.java @@ -0,0 +1,113 @@ +package com.staffing.system.domain; + +/** + * 当前在线会话 + * + * @author staffing + */ +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/staffing-system/src/main/java/com/staffing/system/domain/SysUserPost.java b/staffing-system/src/main/java/com/staffing/system/domain/SysUserPost.java new file mode 100644 index 0000000..49b14a9 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/domain/SysUserPost.java @@ -0,0 +1,46 @@ +package com.staffing.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 用户和岗位关联 sys_user_post + * + * @author staffing + */ +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/staffing-system/src/main/java/com/staffing/system/domain/SysUserRole.java b/staffing-system/src/main/java/com/staffing/system/domain/SysUserRole.java new file mode 100644 index 0000000..22aea29 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/domain/SysUserRole.java @@ -0,0 +1,46 @@ +package com.staffing.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 用户和角色关联 sys_user_role + * + * @author staffing + */ +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/staffing-system/src/main/java/com/staffing/system/domain/vo/MetaVo.java b/staffing-system/src/main/java/com/staffing/system/domain/vo/MetaVo.java new file mode 100644 index 0000000..bdce946 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/domain/vo/MetaVo.java @@ -0,0 +1,106 @@ +package com.staffing.system.domain.vo; + +import com.staffing.common.utils.StringUtils; + +/** + * 路由显示信息 + * + * @author staffing + */ +public class MetaVo +{ + /** + * 设置该路由在侧边栏和面包屑中展示的名字 + */ + private String title; + + /** + * 设置该路由的图标,对应路径src/assets/icons/svg + */ + private String icon; + + /** + * 设置为true,则不会被 缓存 + */ + private boolean noCache; + + /** + * 内链地址(http(s)://开头) + */ + private String link; + + public MetaVo() + { + } + + public MetaVo(String title, String icon) + { + this.title = title; + this.icon = icon; + } + + public MetaVo(String title, String icon, boolean noCache) + { + this.title = title; + this.icon = icon; + this.noCache = noCache; + } + + public MetaVo(String title, String icon, String link) + { + this.title = title; + this.icon = icon; + this.link = link; + } + + public MetaVo(String title, String icon, boolean noCache, String link) + { + this.title = title; + this.icon = icon; + this.noCache = noCache; + if (StringUtils.ishttp(link)) + { + this.link = link; + } + } + + public boolean isNoCache() + { + return noCache; + } + + public void setNoCache(boolean noCache) + { + this.noCache = noCache; + } + + 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; + } + + public String getLink() + { + return link; + } + + public void setLink(String link) + { + this.link = link; + } +} diff --git a/staffing-system/src/main/java/com/staffing/system/domain/vo/RouterVo.java b/staffing-system/src/main/java/com/staffing/system/domain/vo/RouterVo.java new file mode 100644 index 0000000..34b49bd --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/domain/vo/RouterVo.java @@ -0,0 +1,148 @@ +package com.staffing.system.domain.vo; + +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.List; + +/** + * 路由配置信息 + * + * @author staffing + */ +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public class RouterVo +{ + /** + * 路由名字 + */ + private String name; + + /** + * 路由地址 + */ + private String path; + + /** + * 是否隐藏路由,当设置 true 的时候该路由不会再侧边栏出现 + */ + private boolean hidden; + + /** + * 重定向地址,当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 + */ + private String redirect; + + /** + * 组件地址 + */ + private String component; + + /** + * 路由参数:如 {"id": 1, "name": "ry"} + */ + private String query; + + /** + * 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面 + */ + private Boolean alwaysShow; + + /** + * 其他元素 + */ + private MetaVo meta; + + /** + * 子路由 + */ + private List 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 boolean getHidden() + { + return hidden; + } + + public void setHidden(boolean 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 String getQuery() + { + return query; + } + + public void setQuery(String query) + { + this.query = query; + } + + 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 getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } +} diff --git a/staffing-system/src/main/java/com/staffing/system/mapper/SysConfigMapper.java b/staffing-system/src/main/java/com/staffing/system/mapper/SysConfigMapper.java new file mode 100644 index 0000000..28756e5 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/mapper/SysConfigMapper.java @@ -0,0 +1,76 @@ +package com.staffing.system.mapper; + +import java.util.List; +import com.staffing.system.domain.SysConfig; + +/** + * 参数配置 数据层 + * + * @author staffing + */ +public interface SysConfigMapper +{ + /** + * 查询参数配置信息 + * + * @param config 参数配置信息 + * @return 参数配置信息 + */ + public SysConfig selectConfig(SysConfig config); + + /** + * 通过ID查询配置 + * + * @param configId 参数ID + * @return 参数配置信息 + */ + public SysConfig selectConfigById(Long configId); + + /** + * 查询参数配置列表 + * + * @param config 参数配置信息 + * @return 参数配置集合 + */ + public List 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); +} diff --git a/staffing-system/src/main/java/com/staffing/system/mapper/SysDeptMapper.java b/staffing-system/src/main/java/com/staffing/system/mapper/SysDeptMapper.java new file mode 100644 index 0000000..63b9fa1 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/mapper/SysDeptMapper.java @@ -0,0 +1,118 @@ +package com.staffing.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.staffing.common.core.domain.entity.SysDept; + +/** + * 部门管理 数据层 + * + * @author staffing + */ +public interface SysDeptMapper +{ + /** + * 查询部门管理数据 + * + * @param dept 部门信息 + * @return 部门信息集合 + */ + public List selectDeptList(SysDept dept); + + /** + * 根据角色ID查询部门树信息 + * + * @param roleId 角色ID + * @param deptCheckStrictly 部门树选择项是否关联显示 + * @return 选中部门列表 + */ + public List selectDeptListByRoleId(@Param("roleId") Long roleId, @Param("deptCheckStrictly") boolean deptCheckStrictly); + + /** + * 根据部门ID查询信息 + * + * @param deptId 部门ID + * @return 部门信息 + */ + public SysDept selectDeptById(Long deptId); + + /** + * 根据ID查询所有子部门 + * + * @param deptId 部门ID + * @return 部门列表 + */ + public List selectChildrenDeptById(Long deptId); + + /** + * 根据ID查询所有子部门(正常状态) + * + * @param deptId 部门ID + * @return 子部门数 + */ + public int selectNormalChildrenDeptById(Long deptId); + + /** + * 是否存在子节点 + * + * @param deptId 部门ID + * @return 结果 + */ + public int hasChildByDeptId(Long deptId); + + /** + * 查询部门是否存在用户 + * + * @param deptId 部门ID + * @return 结果 + */ + public int checkDeptExistUser(Long deptId); + + /** + * 校验部门名称是否唯一 + * + * @param deptName 部门名称 + * @param parentId 父部门ID + * @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 deptIds 部门ID组 + */ + public void updateDeptStatusNormal(Long[] deptIds); + + /** + * 修改子元素关系 + * + * @param depts 子元素 + * @return 结果 + */ + public int updateDeptChildren(@Param("depts") List depts); + + /** + * 删除部门管理信息 + * + * @param deptId 部门ID + * @return 结果 + */ + public int deleteDeptById(Long deptId); +} diff --git a/staffing-system/src/main/java/com/staffing/system/mapper/SysDictDataMapper.java b/staffing-system/src/main/java/com/staffing/system/mapper/SysDictDataMapper.java new file mode 100644 index 0000000..2132fcb --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/mapper/SysDictDataMapper.java @@ -0,0 +1,95 @@ +package com.staffing.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.staffing.common.core.domain.entity.SysDictData; + +/** + * 字典表 数据层 + * + * @author staffing + */ +public interface SysDictDataMapper +{ + /** + * 根据条件分页查询字典数据 + * + * @param dictData 字典数据信息 + * @return 字典数据集合信息 + */ + public List selectDictDataList(SysDictData dictData); + + /** + * 根据字典类型查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据集合信息 + */ + public List 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/staffing-system/src/main/java/com/staffing/system/mapper/SysDictTypeMapper.java b/staffing-system/src/main/java/com/staffing/system/mapper/SysDictTypeMapper.java new file mode 100644 index 0000000..00df5c0 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/mapper/SysDictTypeMapper.java @@ -0,0 +1,83 @@ +package com.staffing.system.mapper; + +import java.util.List; +import com.staffing.common.core.domain.entity.SysDictType; + +/** + * 字典表 数据层 + * + * @author staffing + */ +public interface SysDictTypeMapper +{ + /** + * 根据条件分页查询字典类型 + * + * @param dictType 字典类型信息 + * @return 字典类型集合信息 + */ + public List selectDictTypeList(SysDictType dictType); + + /** + * 根据所有字典类型 + * + * @return 字典类型集合信息 + */ + public List 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/staffing-system/src/main/java/com/staffing/system/mapper/SysLogininforMapper.java b/staffing-system/src/main/java/com/staffing/system/mapper/SysLogininforMapper.java new file mode 100644 index 0000000..aa29ffa --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/mapper/SysLogininforMapper.java @@ -0,0 +1,42 @@ +package com.staffing.system.mapper; + +import java.util.List; +import com.staffing.system.domain.SysLogininfor; + +/** + * 系统访问日志情况信息 数据层 + * + * @author staffing + */ +public interface SysLogininforMapper +{ + /** + * 新增系统登录日志 + * + * @param logininfor 访问日志对象 + */ + public void insertLogininfor(SysLogininfor logininfor); + + /** + * 查询系统登录日志集合 + * + * @param logininfor 访问日志对象 + * @return 登录记录集合 + */ + public List selectLogininforList(SysLogininfor logininfor); + + /** + * 批量删除系统登录日志 + * + * @param infoIds 需要删除的登录日志ID + * @return 结果 + */ + public int deleteLogininforByIds(Long[] infoIds); + + /** + * 清空系统登录日志 + * + * @return 结果 + */ + public int cleanLogininfor(); +} diff --git a/staffing-system/src/main/java/com/staffing/system/mapper/SysMenuMapper.java b/staffing-system/src/main/java/com/staffing/system/mapper/SysMenuMapper.java new file mode 100644 index 0000000..060df2a --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/mapper/SysMenuMapper.java @@ -0,0 +1,125 @@ +package com.staffing.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.staffing.common.core.domain.entity.SysMenu; + +/** + * 菜单表 数据层 + * + * @author staffing + */ +public interface SysMenuMapper +{ + /** + * 查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + public List selectMenuList(SysMenu menu); + + /** + * 根据用户所有权限 + * + * @return 权限列表 + */ + public List selectMenuPerms(); + + /** + * 根据用户查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + public List selectMenuListByUserId(SysMenu menu); + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + public List selectMenuPermsByRoleId(Long roleId); + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public List selectMenuPermsByUserId(Long userId); + + /** + * 根据用户ID查询菜单 + * + * @return 菜单列表 + */ + public List selectMenuTreeAll(); + + /** + * 根据用户ID查询菜单 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuTreeByUserId(Long userId); + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @param menuCheckStrictly 菜单树选择项是否关联显示 + * @return 选中菜单列表 + */ + public List selectMenuListByRoleId(@Param("roleId") Long roleId, @Param("menuCheckStrictly") boolean menuCheckStrictly); + + /** + * 根据菜单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 父菜单ID + * @return 结果 + */ + public SysMenu checkMenuNameUnique(@Param("menuName") String menuName, @Param("parentId") Long parentId); +} diff --git a/staffing-system/src/main/java/com/staffing/system/mapper/SysNoticeMapper.java b/staffing-system/src/main/java/com/staffing/system/mapper/SysNoticeMapper.java new file mode 100644 index 0000000..15aff6b --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/mapper/SysNoticeMapper.java @@ -0,0 +1,60 @@ +package com.staffing.system.mapper; + +import java.util.List; +import com.staffing.system.domain.SysNotice; + +/** + * 通知公告表 数据层 + * + * @author staffing + */ +public interface SysNoticeMapper +{ + /** + * 查询公告信息 + * + * @param noticeId 公告ID + * @return 公告信息 + */ + public SysNotice selectNoticeById(Long noticeId); + + /** + * 查询公告列表 + * + * @param notice 公告信息 + * @return 公告集合 + */ + public List 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/staffing-system/src/main/java/com/staffing/system/mapper/SysOperLogMapper.java b/staffing-system/src/main/java/com/staffing/system/mapper/SysOperLogMapper.java new file mode 100644 index 0000000..82227e0 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/mapper/SysOperLogMapper.java @@ -0,0 +1,48 @@ +package com.staffing.system.mapper; + +import java.util.List; +import com.staffing.system.domain.SysOperLog; + +/** + * 操作日志 数据层 + * + * @author staffing + */ +public interface SysOperLogMapper +{ + /** + * 新增操作日志 + * + * @param operLog 操作日志对象 + */ + public void insertOperlog(SysOperLog operLog); + + /** + * 查询系统操作日志集合 + * + * @param operLog 操作日志对象 + * @return 操作日志集合 + */ + public List 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/staffing-system/src/main/java/com/staffing/system/mapper/SysPostMapper.java b/staffing-system/src/main/java/com/staffing/system/mapper/SysPostMapper.java new file mode 100644 index 0000000..c2aba79 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/mapper/SysPostMapper.java @@ -0,0 +1,99 @@ +package com.staffing.system.mapper; + +import java.util.List; +import com.staffing.system.domain.SysPost; + +/** + * 岗位信息 数据层 + * + * @author staffing + */ +public interface SysPostMapper +{ + /** + * 查询岗位数据集合 + * + * @param post 岗位信息 + * @return 岗位数据集合 + */ + public List selectPostList(SysPost post); + + /** + * 查询所有岗位 + * + * @return 岗位列表 + */ + public List selectPostAll(); + + /** + * 通过岗位ID查询岗位信息 + * + * @param postId 岗位ID + * @return 角色对象信息 + */ + public SysPost selectPostById(Long postId); + + /** + * 根据用户ID获取岗位选择框列表 + * + * @param userId 用户ID + * @return 选中岗位ID列表 + */ + public List selectPostListByUserId(Long userId); + + /** + * 查询用户所属岗位组 + * + * @param userName 用户名 + * @return 结果 + */ + public List 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/staffing-system/src/main/java/com/staffing/system/mapper/SysRoleDeptMapper.java b/staffing-system/src/main/java/com/staffing/system/mapper/SysRoleDeptMapper.java new file mode 100644 index 0000000..900046d --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/mapper/SysRoleDeptMapper.java @@ -0,0 +1,44 @@ +package com.staffing.system.mapper; + +import java.util.List; +import com.staffing.system.domain.SysRoleDept; + +/** + * 角色与部门关联表 数据层 + * + * @author staffing + */ +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 roleDeptList); +} diff --git a/staffing-system/src/main/java/com/staffing/system/mapper/SysRoleMapper.java b/staffing-system/src/main/java/com/staffing/system/mapper/SysRoleMapper.java new file mode 100644 index 0000000..d645c14 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/mapper/SysRoleMapper.java @@ -0,0 +1,107 @@ +package com.staffing.system.mapper; + +import java.util.List; +import com.staffing.common.core.domain.entity.SysRole; + +/** + * 角色表 数据层 + * + * @author staffing + */ +public interface SysRoleMapper +{ + /** + * 根据条件分页查询角色数据 + * + * @param role 角色信息 + * @return 角色数据集合信息 + */ + public List selectRoleList(SysRole role); + + /** + * 根据用户ID查询角色 + * + * @param userId 用户ID + * @return 角色列表 + */ + public List selectRolePermissionByUserId(Long userId); + + /** + * 查询所有角色 + * + * @return 角色列表 + */ + public List selectRoleAll(); + + /** + * 根据用户ID获取角色选择框列表 + * + * @param userId 用户ID + * @return 选中角色ID列表 + */ + public List selectRoleListByUserId(Long userId); + + /** + * 通过角色ID查询角色 + * + * @param roleId 角色ID + * @return 角色对象信息 + */ + public SysRole selectRoleById(Long roleId); + + /** + * 根据用户ID查询角色 + * + * @param userName 用户名 + * @return 角色列表 + */ + public List 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/staffing-system/src/main/java/com/staffing/system/mapper/SysRoleMenuMapper.java b/staffing-system/src/main/java/com/staffing/system/mapper/SysRoleMenuMapper.java new file mode 100644 index 0000000..a49a698 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/mapper/SysRoleMenuMapper.java @@ -0,0 +1,44 @@ +package com.staffing.system.mapper; + +import java.util.List; +import com.staffing.system.domain.SysRoleMenu; + +/** + * 角色与菜单关联表 数据层 + * + * @author staffing + */ +public interface SysRoleMenuMapper +{ + /** + * 查询菜单使用数量 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int checkMenuExistRole(Long menuId); + + /** + * 通过角色ID删除角色和菜单关联 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleMenuByRoleId(Long roleId); + + /** + * 批量删除角色菜单关联信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteRoleMenu(Long[] ids); + + /** + * 批量新增角色菜单信息 + * + * @param roleMenuList 角色菜单列表 + * @return 结果 + */ + public int batchRoleMenu(List roleMenuList); +} diff --git a/staffing-system/src/main/java/com/staffing/system/mapper/SysUserMapper.java b/staffing-system/src/main/java/com/staffing/system/mapper/SysUserMapper.java new file mode 100644 index 0000000..7824e12 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/mapper/SysUserMapper.java @@ -0,0 +1,128 @@ +package com.staffing.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.staffing.common.core.domain.entity.SysUser; + +/** + * 用户表 数据层 + * + * @author staffing + */ +public interface SysUserMapper +{ + /** + * 根据条件分页查询用户列表 + * + * @param sysUser 用户信息 + * @return 用户信息集合信息 + */ + public List selectUserList(SysUser sysUser); + + /** + * 根据条件分页查询已配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectAllocatedList(SysUser user); + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUnallocatedList(SysUser user); + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + public SysUser selectUserByUserName(String userName); + + public SysUser selectUserByPhone(@Param("phonenumber") String phone); + /** + * 通过用户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 SysUser checkUserNameUnique(String userName); + + /** + * 校验手机号码是否唯一 + * + * @param phonenumber 手机号码 + * @return 结果 + */ + public SysUser checkPhoneUnique(String phonenumber); + + /** + * 校验email是否唯一 + * + * @param email 用户邮箱 + * @return 结果 + */ + public SysUser checkEmailUnique(String email); +} diff --git a/staffing-system/src/main/java/com/staffing/system/mapper/SysUserPostMapper.java b/staffing-system/src/main/java/com/staffing/system/mapper/SysUserPostMapper.java new file mode 100644 index 0000000..8be1bce --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/mapper/SysUserPostMapper.java @@ -0,0 +1,44 @@ +package com.staffing.system.mapper; + +import java.util.List; +import com.staffing.system.domain.SysUserPost; + +/** + * 用户与岗位关联表 数据层 + * + * @author staffing + */ +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 userPostList); +} diff --git a/staffing-system/src/main/java/com/staffing/system/mapper/SysUserRoleMapper.java b/staffing-system/src/main/java/com/staffing/system/mapper/SysUserRoleMapper.java new file mode 100644 index 0000000..85413ab --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/mapper/SysUserRoleMapper.java @@ -0,0 +1,62 @@ +package com.staffing.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.staffing.system.domain.SysUserRole; + +/** + * 用户与角色关联表 数据层 + * + * @author staffing + */ +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 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/staffing-system/src/main/java/com/staffing/system/service/ISysConfigService.java b/staffing-system/src/main/java/com/staffing/system/service/ISysConfigService.java new file mode 100644 index 0000000..6ff749c --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/ISysConfigService.java @@ -0,0 +1,89 @@ +package com.staffing.system.service; + +import java.util.List; +import com.staffing.system.domain.SysConfig; + +/** + * 参数配置 服务层 + * + * @author staffing + */ +public interface ISysConfigService +{ + /** + * 查询参数配置信息 + * + * @param configId 参数配置ID + * @return 参数配置信息 + */ + public SysConfig selectConfigById(Long configId); + + /** + * 根据键名查询参数配置信息 + * + * @param configKey 参数键名 + * @return 参数键值 + */ + public String selectConfigByKey(String configKey); + + /** + * 获取验证码开关 + * + * @return true开启,false关闭 + */ + public boolean selectCaptchaEnabled(); + + /** + * 查询参数配置列表 + * + * @param config 参数配置信息 + * @return 参数配置集合 + */ + public List selectConfigList(SysConfig config); + + /** + * 新增参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int insertConfig(SysConfig config); + + /** + * 修改参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int updateConfig(SysConfig config); + + /** + * 批量删除参数信息 + * + * @param configIds 需要删除的参数ID + */ + public void deleteConfigByIds(Long[] configIds); + + /** + * 加载参数缓存数据 + */ + public void loadingConfigCache(); + + /** + * 清空参数缓存数据 + */ + public void clearConfigCache(); + + /** + * 重置参数缓存数据 + */ + public void resetConfigCache(); + + /** + * 校验参数键名是否唯一 + * + * @param config 参数信息 + * @return 结果 + */ + public boolean checkConfigKeyUnique(SysConfig config); +} diff --git a/staffing-system/src/main/java/com/staffing/system/service/ISysDeptService.java b/staffing-system/src/main/java/com/staffing/system/service/ISysDeptService.java new file mode 100644 index 0000000..9a6052d --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/ISysDeptService.java @@ -0,0 +1,124 @@ +package com.staffing.system.service; + +import java.util.List; +import com.staffing.common.core.domain.TreeSelect; +import com.staffing.common.core.domain.entity.SysDept; + +/** + * 部门管理 服务层 + * + * @author staffing + */ +public interface ISysDeptService +{ + /** + * 查询部门管理数据 + * + * @param dept 部门信息 + * @return 部门信息集合 + */ + public List selectDeptList(SysDept dept); + + /** + * 查询部门树结构信息 + * + * @param dept 部门信息 + * @return 部门树信息集合 + */ + public List selectDeptTreeList(SysDept dept); + + /** + * 构建前端所需要树结构 + * + * @param depts 部门列表 + * @return 树结构列表 + */ + public List buildDeptTree(List depts); + + /** + * 构建前端所需要下拉树结构 + * + * @param depts 部门列表 + * @return 下拉树结构列表 + */ + public List buildDeptTreeSelect(List depts); + + /** + * 根据角色ID查询部门树信息 + * + * @param roleId 角色ID + * @return 选中部门列表 + */ + public List selectDeptListByRoleId(Long roleId); + + /** + * 根据部门ID查询信息 + * + * @param deptId 部门ID + * @return 部门信息 + */ + public SysDept selectDeptById(Long deptId); + + /** + * 根据ID查询所有子部门(正常状态) + * + * @param deptId 部门ID + * @return 子部门数 + */ + public int selectNormalChildrenDeptById(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 boolean checkDeptNameUnique(SysDept dept); + + /** + * 校验部门是否有数据权限 + * + * @param deptId 部门id + */ + public void checkDeptDataScope(Long deptId); + + /** + * 新增保存部门信息 + * + * @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/staffing-system/src/main/java/com/staffing/system/service/ISysDictDataService.java b/staffing-system/src/main/java/com/staffing/system/service/ISysDictDataService.java new file mode 100644 index 0000000..2b91c07 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/ISysDictDataService.java @@ -0,0 +1,60 @@ +package com.staffing.system.service; + +import java.util.List; +import com.staffing.common.core.domain.entity.SysDictData; + +/** + * 字典 业务层 + * + * @author staffing + */ +public interface ISysDictDataService +{ + /** + * 根据条件分页查询字典数据 + * + * @param dictData 字典数据信息 + * @return 字典数据集合信息 + */ + public List selectDictDataList(SysDictData dictData); + + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValue 字典键值 + * @return 字典标签 + */ + public String selectDictLabel(String dictType, String dictValue); + + /** + * 根据字典数据ID查询信息 + * + * @param dictCode 字典数据ID + * @return 字典数据 + */ + public SysDictData selectDictDataById(Long dictCode); + + /** + * 批量删除字典数据信息 + * + * @param dictCodes 需要删除的字典数据ID + */ + public void deleteDictDataByIds(Long[] dictCodes); + + /** + * 新增保存字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int insertDictData(SysDictData dictData); + + /** + * 修改保存字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int updateDictData(SysDictData dictData); +} diff --git a/staffing-system/src/main/java/com/staffing/system/service/ISysDictTypeService.java b/staffing-system/src/main/java/com/staffing/system/service/ISysDictTypeService.java new file mode 100644 index 0000000..ac57f04 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/ISysDictTypeService.java @@ -0,0 +1,98 @@ +package com.staffing.system.service; + +import java.util.List; +import com.staffing.common.core.domain.entity.SysDictData; +import com.staffing.common.core.domain.entity.SysDictType; + +/** + * 字典 业务层 + * + * @author staffing + */ +public interface ISysDictTypeService +{ + /** + * 根据条件分页查询字典类型 + * + * @param dictType 字典类型信息 + * @return 字典类型集合信息 + */ + public List selectDictTypeList(SysDictType dictType); + + /** + * 根据所有字典类型 + * + * @return 字典类型集合信息 + */ + public List selectDictTypeAll(); + + /** + * 根据字典类型查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据集合信息 + */ + public List selectDictDataByType(String dictType); + + /** + * 根据字典类型ID查询信息 + * + * @param dictId 字典类型ID + * @return 字典类型 + */ + public SysDictType selectDictTypeById(Long dictId); + + /** + * 根据字典类型查询信息 + * + * @param dictType 字典类型 + * @return 字典类型 + */ + public SysDictType selectDictTypeByType(String dictType); + + /** + * 批量删除字典信息 + * + * @param dictIds 需要删除的字典ID + */ + public void deleteDictTypeByIds(Long[] dictIds); + + /** + * 加载字典缓存数据 + */ + public void loadingDictCache(); + + /** + * 清空字典缓存数据 + */ + public void clearDictCache(); + + /** + * 重置字典缓存数据 + */ + public void resetDictCache(); + + /** + * 新增保存字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int insertDictType(SysDictType dictType); + + /** + * 修改保存字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int updateDictType(SysDictType dictType); + + /** + * 校验字典类型称是否唯一 + * + * @param dictType 字典类型 + * @return 结果 + */ + public boolean checkDictTypeUnique(SysDictType dictType); +} diff --git a/staffing-system/src/main/java/com/staffing/system/service/ISysLogininforService.java b/staffing-system/src/main/java/com/staffing/system/service/ISysLogininforService.java new file mode 100644 index 0000000..a5e6f66 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/ISysLogininforService.java @@ -0,0 +1,40 @@ +package com.staffing.system.service; + +import java.util.List; +import com.staffing.system.domain.SysLogininfor; + +/** + * 系统访问日志情况信息 服务层 + * + * @author staffing + */ +public interface ISysLogininforService +{ + /** + * 新增系统登录日志 + * + * @param logininfor 访问日志对象 + */ + public void insertLogininfor(SysLogininfor logininfor); + + /** + * 查询系统登录日志集合 + * + * @param logininfor 访问日志对象 + * @return 登录记录集合 + */ + public List selectLogininforList(SysLogininfor logininfor); + + /** + * 批量删除系统登录日志 + * + * @param infoIds 需要删除的登录日志ID + * @return 结果 + */ + public int deleteLogininforByIds(Long[] infoIds); + + /** + * 清空系统登录日志 + */ + public void cleanLogininfor(); +} diff --git a/staffing-system/src/main/java/com/staffing/system/service/ISysMenuService.java b/staffing-system/src/main/java/com/staffing/system/service/ISysMenuService.java new file mode 100644 index 0000000..9c515ff --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/ISysMenuService.java @@ -0,0 +1,144 @@ +package com.staffing.system.service; + +import java.util.List; +import java.util.Set; +import com.staffing.common.core.domain.TreeSelect; +import com.staffing.common.core.domain.entity.SysMenu; +import com.staffing.system.domain.vo.RouterVo; + +/** + * 菜单 业务层 + * + * @author staffing + */ +public interface ISysMenuService +{ + /** + * 根据用户查询系统菜单列表 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuList(Long userId); + + /** + * 根据用户查询系统菜单列表 + * + * @param menu 菜单信息 + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuList(SysMenu menu, Long userId); + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public Set selectMenuPermsByUserId(Long userId); + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + public Set selectMenuPermsByRoleId(Long roleId); + + /** + * 根据用户ID查询菜单树信息 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuTreeByUserId(Long userId); + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @return 选中菜单列表 + */ + public List selectMenuListByRoleId(Long roleId); + + /** + * 构建前端路由所需要的菜单 + * + * @param menus 菜单列表 + * @return 路由列表 + */ + public List buildMenus(List menus); + + /** + * 构建前端所需要树结构 + * + * @param menus 菜单列表 + * @return 树结构列表 + */ + public List buildMenuTree(List menus); + + /** + * 构建前端所需要下拉树结构 + * + * @param menus 菜单列表 + * @return 下拉树结构列表 + */ + public List buildMenuTreeSelect(List 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 boolean checkMenuNameUnique(SysMenu menu); +} diff --git a/staffing-system/src/main/java/com/staffing/system/service/ISysNoticeService.java b/staffing-system/src/main/java/com/staffing/system/service/ISysNoticeService.java new file mode 100644 index 0000000..00ffc37 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/ISysNoticeService.java @@ -0,0 +1,60 @@ +package com.staffing.system.service; + +import java.util.List; +import com.staffing.system.domain.SysNotice; + +/** + * 公告 服务层 + * + * @author staffing + */ +public interface ISysNoticeService +{ + /** + * 查询公告信息 + * + * @param noticeId 公告ID + * @return 公告信息 + */ + public SysNotice selectNoticeById(Long noticeId); + + /** + * 查询公告列表 + * + * @param notice 公告信息 + * @return 公告集合 + */ + public List 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/staffing-system/src/main/java/com/staffing/system/service/ISysOperLogService.java b/staffing-system/src/main/java/com/staffing/system/service/ISysOperLogService.java new file mode 100644 index 0000000..46b2670 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/ISysOperLogService.java @@ -0,0 +1,48 @@ +package com.staffing.system.service; + +import java.util.List; +import com.staffing.system.domain.SysOperLog; + +/** + * 操作日志 服务层 + * + * @author staffing + */ +public interface ISysOperLogService +{ + /** + * 新增操作日志 + * + * @param operLog 操作日志对象 + */ + public void insertOperlog(SysOperLog operLog); + + /** + * 查询系统操作日志集合 + * + * @param operLog 操作日志对象 + * @return 操作日志集合 + */ + public List 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/staffing-system/src/main/java/com/staffing/system/service/ISysPostService.java b/staffing-system/src/main/java/com/staffing/system/service/ISysPostService.java new file mode 100644 index 0000000..30e5a1b --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/ISysPostService.java @@ -0,0 +1,99 @@ +package com.staffing.system.service; + +import java.util.List; +import com.staffing.system.domain.SysPost; + +/** + * 岗位信息 服务层 + * + * @author staffing + */ +public interface ISysPostService +{ + /** + * 查询岗位信息集合 + * + * @param post 岗位信息 + * @return 岗位列表 + */ + public List selectPostList(SysPost post); + + /** + * 查询所有岗位 + * + * @return 岗位列表 + */ + public List selectPostAll(); + + /** + * 通过岗位ID查询岗位信息 + * + * @param postId 岗位ID + * @return 角色对象信息 + */ + public SysPost selectPostById(Long postId); + + /** + * 根据用户ID获取岗位选择框列表 + * + * @param userId 用户ID + * @return 选中岗位ID列表 + */ + public List selectPostListByUserId(Long userId); + + /** + * 校验岗位名称 + * + * @param post 岗位信息 + * @return 结果 + */ + public boolean checkPostNameUnique(SysPost post); + + /** + * 校验岗位编码 + * + * @param post 岗位信息 + * @return 结果 + */ + public boolean 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 结果 + */ + public int deletePostByIds(Long[] postIds); + + /** + * 新增保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int insertPost(SysPost post); + + /** + * 修改保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int updatePost(SysPost post); +} diff --git a/staffing-system/src/main/java/com/staffing/system/service/ISysRoleService.java b/staffing-system/src/main/java/com/staffing/system/service/ISysRoleService.java new file mode 100644 index 0000000..60c970f --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/ISysRoleService.java @@ -0,0 +1,173 @@ +package com.staffing.system.service; + +import java.util.List; +import java.util.Set; +import com.staffing.common.core.domain.entity.SysRole; +import com.staffing.system.domain.SysUserRole; + +/** + * 角色业务层 + * + * @author staffing + */ +public interface ISysRoleService +{ + /** + * 根据条件分页查询角色数据 + * + * @param role 角色信息 + * @return 角色数据集合信息 + */ + public List selectRoleList(SysRole role); + + /** + * 根据用户ID查询角色列表 + * + * @param userId 用户ID + * @return 角色列表 + */ + public List selectRolesByUserId(Long userId); + + /** + * 根据用户ID查询角色权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public Set selectRolePermissionByUserId(Long userId); + + /** + * 查询所有角色 + * + * @return 角色列表 + */ + public List selectRoleAll(); + + /** + * 根据用户ID获取角色选择框列表 + * + * @param userId 用户ID + * @return 选中角色ID列表 + */ + public List selectRoleListByUserId(Long userId); + + /** + * 通过角色ID查询角色 + * + * @param roleId 角色ID + * @return 角色对象信息 + */ + public SysRole selectRoleById(Long roleId); + + /** + * 校验角色名称是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + public boolean checkRoleNameUnique(SysRole role); + + /** + * 校验角色权限是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + public boolean checkRoleKeyUnique(SysRole role); + + /** + * 校验角色是否允许操作 + * + * @param role 角色信息 + */ + public void checkRoleAllowed(SysRole role); + + /** + * 校验角色是否有数据权限 + * + * @param roleIds 角色id + */ + public void checkRoleDataScope(Long... roleIds); + + /** + * 通过角色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); + + /** + * 取消授权用户角色 + * + * @param userRole 用户和角色关联信息 + * @return 结果 + */ + public int deleteAuthUser(SysUserRole userRole); + + /** + * 批量取消授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要取消授权的用户数据ID + * @return 结果 + */ + public int deleteAuthUsers(Long roleId, Long[] userIds); + + /** + * 批量选择授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要删除的用户数据ID + * @return 结果 + */ + public int insertAuthUsers(Long roleId, Long[] userIds); +} diff --git a/staffing-system/src/main/java/com/staffing/system/service/ISysUserOnlineService.java b/staffing-system/src/main/java/com/staffing/system/service/ISysUserOnlineService.java new file mode 100644 index 0000000..dab84f7 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/ISysUserOnlineService.java @@ -0,0 +1,48 @@ +package com.staffing.system.service; + +import com.staffing.common.core.domain.model.LoginUser; +import com.staffing.system.domain.SysUserOnline; + +/** + * 在线用户 服务层 + * + * @author staffing + */ +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/staffing-system/src/main/java/com/staffing/system/service/ISysUserService.java b/staffing-system/src/main/java/com/staffing/system/service/ISysUserService.java new file mode 100644 index 0000000..5c58c87 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/ISysUserService.java @@ -0,0 +1,206 @@ +package com.staffing.system.service; + +import java.util.List; +import com.staffing.common.core.domain.entity.SysUser; + +/** + * 用户 业务层 + * + * @author staffing + */ +public interface ISysUserService +{ + /** + * 根据条件分页查询用户列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUserList(SysUser user); + + /** + * 根据条件分页查询已分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectAllocatedList(SysUser user); + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUnallocatedList(SysUser user); + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + public SysUser selectUserByUserName(String userName); + public SysUser selectUserByPhone(String phone); + /** + * 通过用户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 user 用户信息 + * @return 结果 + */ + public boolean checkUserNameUnique(SysUser user); + + /** + * 校验手机号码是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean checkPhoneUnique(SysUser user); + + /** + * 校验email是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean checkEmailUnique(SysUser user); + + /** + * 校验用户是否允许操作 + * + * @param user 用户信息 + */ + public void checkUserAllowed(SysUser user); + + /** + * 校验用户是否有数据权限 + * + * @param userId 用户id + */ + public void checkUserDataScope(Long userId); + + /** + * 新增用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int insertUser(SysUser user); + + /** + * 注册用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean registerUser(SysUser user); + + /** + * 修改用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUser(SysUser user); + + /** + * 用户授权角色 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + public void insertUserAuth(Long userId, Long[] roleIds); + + /** + * 修改用户状态 + * + * @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 userList, Boolean isUpdateSupport, String operName); +} diff --git a/staffing-system/src/main/java/com/staffing/system/service/impl/SysConfigServiceImpl.java b/staffing-system/src/main/java/com/staffing/system/service/impl/SysConfigServiceImpl.java new file mode 100644 index 0000000..e5b41f8 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/impl/SysConfigServiceImpl.java @@ -0,0 +1,232 @@ +package com.staffing.system.service.impl; + +import java.util.Collection; +import java.util.List; +import javax.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.staffing.common.annotation.DataSource; +import com.staffing.common.constant.CacheConstants; +import com.staffing.common.constant.UserConstants; +import com.staffing.common.core.redis.RedisCache; +import com.staffing.common.core.text.Convert; +import com.staffing.common.enums.DataSourceType; +import com.staffing.common.exception.ServiceException; +import com.staffing.common.utils.StringUtils; +import com.staffing.system.domain.SysConfig; +import com.staffing.system.mapper.SysConfigMapper; +import com.staffing.system.service.ISysConfigService; + +/** + * 参数配置 服务层实现 + * + * @author staffing + */ +@Service +public class SysConfigServiceImpl implements ISysConfigService +{ + @Autowired + private SysConfigMapper configMapper; + + @Autowired + private RedisCache redisCache; + + /** + * 项目启动时,初始化参数到缓存 + */ + @PostConstruct + public void init() + { + loadingConfigCache(); + } + + /** + * 查询参数配置信息 + * + * @param configId 参数配置ID + * @return 参数配置信息 + */ + @Override + @DataSource(DataSourceType.MASTER) + 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) + { + String configValue = Convert.toStr(redisCache.getCacheObject(getCacheKey(configKey))); + if (StringUtils.isNotEmpty(configValue)) + { + return configValue; + } + SysConfig config = new SysConfig(); + config.setConfigKey(configKey); + SysConfig retConfig = configMapper.selectConfig(config); + if (StringUtils.isNotNull(retConfig)) + { + redisCache.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue()); + return retConfig.getConfigValue(); + } + return StringUtils.EMPTY; + } + + /** + * 获取验证码开关 + * + * @return true开启,false关闭 + */ + @Override + public boolean selectCaptchaEnabled() + { + String captchaEnabled = selectConfigByKey("sys.account.captchaEnabled"); + if (StringUtils.isEmpty(captchaEnabled)) + { + return true; + } + return Convert.toBool(captchaEnabled); + } + + /** + * 查询参数配置列表 + * + * @param config 参数配置信息 + * @return 参数配置集合 + */ + @Override + public List selectConfigList(SysConfig config) + { + return configMapper.selectConfigList(config); + } + + /** + * 新增参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + @Override + public int insertConfig(SysConfig config) + { + int row = configMapper.insertConfig(config); + if (row > 0) + { + redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + } + return row; + } + + /** + * 修改参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + @Override + public int updateConfig(SysConfig config) + { + SysConfig temp = configMapper.selectConfigById(config.getConfigId()); + if (!StringUtils.equals(temp.getConfigKey(), config.getConfigKey())) + { + redisCache.deleteObject(getCacheKey(temp.getConfigKey())); + } + + int row = configMapper.updateConfig(config); + if (row > 0) + { + redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + } + return row; + } + + /** + * 批量删除参数信息 + * + * @param configIds 需要删除的参数ID + */ + @Override + public void deleteConfigByIds(Long[] configIds) + { + for (Long configId : configIds) + { + SysConfig config = selectConfigById(configId); + if (StringUtils.equals(UserConstants.YES, config.getConfigType())) + { + throw new ServiceException(String.format("内置参数【%1$s】不能删除 ", config.getConfigKey())); + } + configMapper.deleteConfigById(configId); + redisCache.deleteObject(getCacheKey(config.getConfigKey())); + } + } + + /** + * 加载参数缓存数据 + */ + @Override + public void loadingConfigCache() + { + List configsList = configMapper.selectConfigList(new SysConfig()); + for (SysConfig config : configsList) + { + redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + } + } + + /** + * 清空参数缓存数据 + */ + @Override + public void clearConfigCache() + { + Collection keys = redisCache.keys(CacheConstants.SYS_CONFIG_KEY + "*"); + redisCache.deleteObject(keys); + } + + /** + * 重置参数缓存数据 + */ + @Override + public void resetConfigCache() + { + clearConfigCache(); + loadingConfigCache(); + } + + /** + * 校验参数键名是否唯一 + * + * @param config 参数配置信息 + * @return 结果 + */ + @Override + public boolean 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; + } + + /** + * 设置cache key + * + * @param configKey 参数键 + * @return 缓存键key + */ + private String getCacheKey(String configKey) + { + return CacheConstants.SYS_CONFIG_KEY + configKey; + } +} diff --git a/staffing-system/src/main/java/com/staffing/system/service/impl/SysDeptServiceImpl.java b/staffing-system/src/main/java/com/staffing/system/service/impl/SysDeptServiceImpl.java new file mode 100644 index 0000000..7c5eb2c --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/impl/SysDeptServiceImpl.java @@ -0,0 +1,338 @@ +package com.staffing.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.staffing.common.annotation.DataScope; +import com.staffing.common.constant.UserConstants; +import com.staffing.common.core.domain.TreeSelect; +import com.staffing.common.core.domain.entity.SysDept; +import com.staffing.common.core.domain.entity.SysRole; +import com.staffing.common.core.domain.entity.SysUser; +import com.staffing.common.core.text.Convert; +import com.staffing.common.exception.ServiceException; +import com.staffing.common.utils.SecurityUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.spring.SpringUtils; +import com.staffing.system.mapper.SysDeptMapper; +import com.staffing.system.mapper.SysRoleMapper; +import com.staffing.system.service.ISysDeptService; + +/** + * 部门管理 服务实现 + * + * @author staffing + */ +@Service +public class SysDeptServiceImpl implements ISysDeptService +{ + @Autowired + private SysDeptMapper deptMapper; + + @Autowired + private SysRoleMapper roleMapper; + + /** + * 查询部门管理数据 + * + * @param dept 部门信息 + * @return 部门信息集合 + */ + @Override + @DataScope(deptAlias = "d") + public List selectDeptList(SysDept dept) + { + return deptMapper.selectDeptList(dept); + } + + /** + * 查询部门树结构信息 + * + * @param dept 部门信息 + * @return 部门树信息集合 + */ + @Override + public List selectDeptTreeList(SysDept dept) + { + List depts = SpringUtils.getAopProxy(this).selectDeptList(dept); + return buildDeptTreeSelect(depts); + } + + /** + * 构建前端所需要树结构 + * + * @param depts 部门列表 + * @return 树结构列表 + */ + @Override + public List buildDeptTree(List depts) + { + List returnList = new ArrayList(); + List tempList = depts.stream().map(SysDept::getDeptId).collect(Collectors.toList()); + for (SysDept dept : depts) + { + // 如果是顶级节点, 遍历该父节点的所有子节点 + if (!tempList.contains(dept.getParentId())) + { + recursionFn(depts, dept); + returnList.add(dept); + } + } + if (returnList.isEmpty()) + { + returnList = depts; + } + return returnList; + } + + /** + * 构建前端所需要下拉树结构 + * + * @param depts 部门列表 + * @return 下拉树结构列表 + */ + @Override + public List buildDeptTreeSelect(List depts) + { + List deptTrees = buildDeptTree(depts); + return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + /** + * 根据角色ID查询部门树信息 + * + * @param roleId 角色ID + * @return 选中部门列表 + */ + @Override + public List selectDeptListByRoleId(Long roleId) + { + SysRole role = roleMapper.selectRoleById(roleId); + return deptMapper.selectDeptListByRoleId(roleId, role.isDeptCheckStrictly()); + } + + /** + * 根据部门ID查询信息 + * + * @param deptId 部门ID + * @return 部门信息 + */ + @Override + public SysDept selectDeptById(Long deptId) + { + return deptMapper.selectDeptById(deptId); + } + + /** + * 根据ID查询所有子部门(正常状态) + * + * @param deptId 部门ID + * @return 子部门数 + */ + @Override + public int selectNormalChildrenDeptById(Long deptId) + { + return deptMapper.selectNormalChildrenDeptById(deptId); + } + + /** + * 是否存在子节点 + * + * @param deptId 部门ID + * @return 结果 + */ + @Override + public boolean hasChildByDeptId(Long deptId) + { + int result = deptMapper.hasChildByDeptId(deptId); + return result > 0; + } + + /** + * 查询部门是否存在用户 + * + * @param deptId 部门ID + * @return 结果 true 存在 false 不存在 + */ + @Override + public boolean checkDeptExistUser(Long deptId) + { + int result = deptMapper.checkDeptExistUser(deptId); + return result > 0; + } + + /** + * 校验部门名称是否唯一 + * + * @param dept 部门信息 + * @return 结果 + */ + @Override + public boolean 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 deptId 部门id + */ + @Override + public void checkDeptDataScope(Long deptId) + { + if (!SysUser.isAdmin(SecurityUtils.getUserId()) && StringUtils.isNotNull(deptId)) + { + SysDept dept = new SysDept(); + dept.setDeptId(deptId); + List depts = SpringUtils.getAopProxy(this).selectDeptList(dept); + if (StringUtils.isEmpty(depts)) + { + throw new ServiceException("没有权限访问部门数据!"); + } + } + } + + /** + * 新增保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + @Override + public int insertDept(SysDept dept) + { + SysDept info = deptMapper.selectDeptById(dept.getParentId()); + // 如果父节点不为正常状态,则不允许新增子节点 + if (!UserConstants.DEPT_NORMAL.equals(info.getStatus())) + { + throw new ServiceException("部门停用,不允许新增"); + } + 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()) && StringUtils.isNotEmpty(dept.getAncestors()) + && !StringUtils.equals("0", dept.getAncestors())) + { + // 如果该部门是启用状态,则启用该部门的所有上级部门 + updateParentDeptStatusNormal(dept); + } + return result; + } + + /** + * 修改该部门的父级部门状态 + * + * @param dept 当前部门 + */ + private void updateParentDeptStatusNormal(SysDept dept) + { + String ancestors = dept.getAncestors(); + Long[] deptIds = Convert.toLongArray(ancestors); + deptMapper.updateDeptStatusNormal(deptIds); + } + + /** + * 修改子元素关系 + * + * @param deptId 被修改的部门ID + * @param newAncestors 新的父ID集合 + * @param oldAncestors 旧的父ID集合 + */ + public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) + { + List children = deptMapper.selectChildrenDeptById(deptId); + for (SysDept child : children) + { + child.setAncestors(child.getAncestors().replaceFirst(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 list, SysDept t) + { + // 得到子节点列表 + List childList = getChildList(list, t); + t.setChildren(childList); + for (SysDept tChild : childList) + { + if (hasChild(list, tChild)) + { + recursionFn(list, tChild); + } + } + } + + /** + * 得到子节点列表 + */ + private List getChildList(List list, SysDept t) + { + List tlist = new ArrayList(); + Iterator 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 list, SysDept t) + { + return getChildList(list, t).size() > 0; + } +} diff --git a/staffing-system/src/main/java/com/staffing/system/service/impl/SysDictDataServiceImpl.java b/staffing-system/src/main/java/com/staffing/system/service/impl/SysDictDataServiceImpl.java new file mode 100644 index 0000000..03d558e --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/impl/SysDictDataServiceImpl.java @@ -0,0 +1,111 @@ +package com.staffing.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.staffing.common.core.domain.entity.SysDictData; +import com.staffing.common.utils.DictUtils; +import com.staffing.system.mapper.SysDictDataMapper; +import com.staffing.system.service.ISysDictDataService; + +/** + * 字典 业务层处理 + * + * @author staffing + */ +@Service +public class SysDictDataServiceImpl implements ISysDictDataService +{ + @Autowired + private SysDictDataMapper dictDataMapper; + + /** + * 根据条件分页查询字典数据 + * + * @param dictData 字典数据信息 + * @return 字典数据集合信息 + */ + @Override + public List selectDictDataList(SysDictData dictData) + { + return dictDataMapper.selectDictDataList(dictData); + } + + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @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); + } + + /** + * 批量删除字典数据信息 + * + * @param dictCodes 需要删除的字典数据ID + */ + @Override + public void deleteDictDataByIds(Long[] dictCodes) + { + for (Long dictCode : dictCodes) + { + SysDictData data = selectDictDataById(dictCode); + dictDataMapper.deleteDictDataById(dictCode); + List dictDatas = dictDataMapper.selectDictDataByType(data.getDictType()); + DictUtils.setDictCache(data.getDictType(), dictDatas); + } + } + + /** + * 新增保存字典数据信息 + * + * @param data 字典数据信息 + * @return 结果 + */ + @Override + public int insertDictData(SysDictData data) + { + int row = dictDataMapper.insertDictData(data); + if (row > 0) + { + List dictDatas = dictDataMapper.selectDictDataByType(data.getDictType()); + DictUtils.setDictCache(data.getDictType(), dictDatas); + } + return row; + } + + /** + * 修改保存字典数据信息 + * + * @param data 字典数据信息 + * @return 结果 + */ + @Override + public int updateDictData(SysDictData data) + { + int row = dictDataMapper.updateDictData(data); + if (row > 0) + { + List dictDatas = dictDataMapper.selectDictDataByType(data.getDictType()); + DictUtils.setDictCache(data.getDictType(), dictDatas); + } + return row; + } +} diff --git a/staffing-system/src/main/java/com/staffing/system/service/impl/SysDictTypeServiceImpl.java b/staffing-system/src/main/java/com/staffing/system/service/impl/SysDictTypeServiceImpl.java new file mode 100644 index 0000000..4d4f785 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/impl/SysDictTypeServiceImpl.java @@ -0,0 +1,223 @@ +package com.staffing.system.service.impl; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import javax.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.staffing.common.constant.UserConstants; +import com.staffing.common.core.domain.entity.SysDictData; +import com.staffing.common.core.domain.entity.SysDictType; +import com.staffing.common.exception.ServiceException; +import com.staffing.common.utils.DictUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.system.mapper.SysDictDataMapper; +import com.staffing.system.mapper.SysDictTypeMapper; +import com.staffing.system.service.ISysDictTypeService; + +/** + * 字典 业务层处理 + * + * @author staffing + */ +@Service +public class SysDictTypeServiceImpl implements ISysDictTypeService +{ + @Autowired + private SysDictTypeMapper dictTypeMapper; + + @Autowired + private SysDictDataMapper dictDataMapper; + + /** + * 项目启动时,初始化字典到缓存 + */ + @PostConstruct + public void init() + { + loadingDictCache(); + } + + /** + * 根据条件分页查询字典类型 + * + * @param dictType 字典类型信息 + * @return 字典类型集合信息 + */ + @Override + public List selectDictTypeList(SysDictType dictType) + { + return dictTypeMapper.selectDictTypeList(dictType); + } + + /** + * 根据所有字典类型 + * + * @return 字典类型集合信息 + */ + @Override + public List selectDictTypeAll() + { + return dictTypeMapper.selectDictTypeAll(); + } + + /** + * 根据字典类型查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据集合信息 + */ + @Override + public List selectDictDataByType(String dictType) + { + List dictDatas = DictUtils.getDictCache(dictType); + if (StringUtils.isNotEmpty(dictDatas)) + { + return dictDatas; + } + dictDatas = dictDataMapper.selectDictDataByType(dictType); + if (StringUtils.isNotEmpty(dictDatas)) + { + DictUtils.setDictCache(dictType, dictDatas); + return dictDatas; + } + return null; + } + + /** + * 根据字典类型ID查询信息 + * + * @param dictId 字典类型ID + * @return 字典类型 + */ + @Override + public SysDictType selectDictTypeById(Long dictId) + { + return dictTypeMapper.selectDictTypeById(dictId); + } + + /** + * 根据字典类型查询信息 + * + * @param dictType 字典类型 + * @return 字典类型 + */ + @Override + public SysDictType selectDictTypeByType(String dictType) + { + return dictTypeMapper.selectDictTypeByType(dictType); + } + + /** + * 批量删除字典类型信息 + * + * @param dictIds 需要删除的字典ID + */ + @Override + public void deleteDictTypeByIds(Long[] dictIds) + { + for (Long dictId : dictIds) + { + SysDictType dictType = selectDictTypeById(dictId); + if (dictDataMapper.countDictDataByType(dictType.getDictType()) > 0) + { + throw new ServiceException(String.format("%1$s已分配,不能删除", dictType.getDictName())); + } + dictTypeMapper.deleteDictTypeById(dictId); + DictUtils.removeDictCache(dictType.getDictType()); + } + } + + /** + * 加载字典缓存数据 + */ + @Override + public void loadingDictCache() + { + SysDictData dictData = new SysDictData(); + dictData.setStatus("0"); + Map> dictDataMap = dictDataMapper.selectDictDataList(dictData).stream().collect(Collectors.groupingBy(SysDictData::getDictType)); + for (Map.Entry> entry : dictDataMap.entrySet()) + { + DictUtils.setDictCache(entry.getKey(), entry.getValue().stream().sorted(Comparator.comparing(SysDictData::getDictSort)).collect(Collectors.toList())); + } + } + + /** + * 清空字典缓存数据 + */ + @Override + public void clearDictCache() + { + DictUtils.clearDictCache(); + } + + /** + * 重置字典缓存数据 + */ + @Override + public void resetDictCache() + { + clearDictCache(); + loadingDictCache(); + } + + /** + * 新增保存字典类型信息 + * + * @param dict 字典类型信息 + * @return 结果 + */ + @Override + public int insertDictType(SysDictType dict) + { + int row = dictTypeMapper.insertDictType(dict); + if (row > 0) + { + DictUtils.setDictCache(dict.getDictType(), null); + } + return row; + } + + /** + * 修改保存字典类型信息 + * + * @param dict 字典类型信息 + * @return 结果 + */ + @Override + @Transactional + public int updateDictType(SysDictType dict) + { + SysDictType oldDict = dictTypeMapper.selectDictTypeById(dict.getDictId()); + dictDataMapper.updateDictDataType(oldDict.getDictType(), dict.getDictType()); + int row = dictTypeMapper.updateDictType(dict); + if (row > 0) + { + List dictDatas = dictDataMapper.selectDictDataByType(dict.getDictType()); + DictUtils.setDictCache(dict.getDictType(), dictDatas); + } + return row; + } + + /** + * 校验字典类型称是否唯一 + * + * @param dict 字典类型 + * @return 结果 + */ + @Override + public boolean 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/staffing-system/src/main/java/com/staffing/system/service/impl/SysLogininforServiceImpl.java b/staffing-system/src/main/java/com/staffing/system/service/impl/SysLogininforServiceImpl.java new file mode 100644 index 0000000..635288c --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/impl/SysLogininforServiceImpl.java @@ -0,0 +1,65 @@ +package com.staffing.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.staffing.system.domain.SysLogininfor; +import com.staffing.system.mapper.SysLogininforMapper; +import com.staffing.system.service.ISysLogininforService; + +/** + * 系统访问日志情况信息 服务层处理 + * + * @author staffing + */ +@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 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/staffing-system/src/main/java/com/staffing/system/service/impl/SysMenuServiceImpl.java b/staffing-system/src/main/java/com/staffing/system/service/impl/SysMenuServiceImpl.java new file mode 100644 index 0000000..056c2e1 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/impl/SysMenuServiceImpl.java @@ -0,0 +1,543 @@ +package com.staffing.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.staffing.common.constant.Constants; +import com.staffing.common.constant.UserConstants; +import com.staffing.common.core.domain.TreeSelect; +import com.staffing.common.core.domain.entity.SysMenu; +import com.staffing.common.core.domain.entity.SysRole; +import com.staffing.common.core.domain.entity.SysUser; +import com.staffing.common.utils.SecurityUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.system.domain.vo.MetaVo; +import com.staffing.system.domain.vo.RouterVo; +import com.staffing.system.mapper.SysMenuMapper; +import com.staffing.system.mapper.SysRoleMapper; +import com.staffing.system.mapper.SysRoleMenuMapper; +import com.staffing.system.service.ISysMenuService; + +/** + * 菜单 业务层处理 + * + * @author staffing + */ +@Service +public class SysMenuServiceImpl implements ISysMenuService +{ + public static final String PREMISSION_STRING = "perms[\"{0}\"]"; + + @Autowired + private SysMenuMapper menuMapper; + + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysRoleMenuMapper roleMenuMapper; + + /** + * 根据用户查询系统菜单列表 + * + * @param userId 用户ID + * @return 菜单列表 + */ + @Override + public List selectMenuList(Long userId) + { + return selectMenuList(new SysMenu(), userId); + } + + /** + * 查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + @Override + public List selectMenuList(SysMenu menu, Long userId) + { + List 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 selectMenuPermsByUserId(Long userId) + { + List perms = menuMapper.selectMenuPermsByUserId(userId); + Set permsSet = new HashSet<>(); + for (String perm : perms) + { + if (StringUtils.isNotEmpty(perm)) + { + permsSet.addAll(Arrays.asList(perm.trim().split(","))); + } + } + return permsSet; + } + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + @Override + public Set selectMenuPermsByRoleId(Long roleId) + { + List perms = menuMapper.selectMenuPermsByRoleId(roleId); + Set 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 selectMenuTreeByUserId(Long userId) + { + List menus = null; + if (SecurityUtils.isAdmin(userId)) + { + menus = menuMapper.selectMenuTreeAll(); + } + else + { + menus = menuMapper.selectMenuTreeByUserId(userId); + } + return getChildPerms(menus, 0); + } + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @return 选中菜单列表 + */ + @Override + public List selectMenuListByRoleId(Long roleId) + { + SysRole role = roleMapper.selectRoleById(roleId); + return menuMapper.selectMenuListByRoleId(roleId, role.isMenuCheckStrictly()); + } + + /** + * 构建前端路由所需要的菜单 + * + * @param menus 菜单列表 + * @return 路由列表 + */ + @Override + public List buildMenus(List menus) + { + List routers = new LinkedList(); + for (SysMenu menu : menus) + { + RouterVo router = new RouterVo(); + router.setHidden("1".equals(menu.getVisible())); + router.setName(getRouteName(menu)); + router.setPath(getRouterPath(menu)); + router.setComponent(getComponent(menu)); + router.setQuery(menu.getQuery()); + router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); + List cMenus = menu.getChildren(); + if (StringUtils.isNotEmpty(cMenus) && UserConstants.TYPE_DIR.equals(menu.getMenuType())) + { + router.setAlwaysShow(true); + router.setRedirect("noRedirect"); + router.setChildren(buildMenus(cMenus)); + } + else if (isMenuFrame(menu)) + { + router.setMeta(null); + List childrenList = new ArrayList(); + RouterVo children = new RouterVo(); + children.setPath(menu.getPath()); + children.setComponent(menu.getComponent()); + children.setName(getRouteName(menu.getRouteName(), menu.getPath())); + children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); + children.setQuery(menu.getQuery()); + childrenList.add(children); + router.setChildren(childrenList); + } + else if (menu.getParentId().intValue() == 0 && isInnerLink(menu)) + { + router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon())); + router.setPath("/"); + List childrenList = new ArrayList(); + RouterVo children = new RouterVo(); + String routerPath = innerLinkReplaceEach(menu.getPath()); + children.setPath(routerPath); + children.setComponent(UserConstants.INNER_LINK); + children.setName(getRouteName(menu.getRouteName(), routerPath)); + children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath())); + childrenList.add(children); + router.setChildren(childrenList); + } + routers.add(router); + } + return routers; + } + + /** + * 构建前端所需要树结构 + * + * @param menus 菜单列表 + * @return 树结构列表 + */ + @Override + public List buildMenuTree(List menus) + { + List returnList = new ArrayList(); + List tempList = menus.stream().map(SysMenu::getMenuId).collect(Collectors.toList()); + for (Iterator iterator = menus.iterator(); iterator.hasNext();) + { + SysMenu menu = (SysMenu) iterator.next(); + // 如果是顶级节点, 遍历该父节点的所有子节点 + if (!tempList.contains(menu.getParentId())) + { + recursionFn(menus, menu); + returnList.add(menu); + } + } + if (returnList.isEmpty()) + { + returnList = menus; + } + return returnList; + } + + /** + * 构建前端所需要下拉树结构 + * + * @param menus 菜单列表 + * @return 下拉树结构列表 + */ + @Override + public List buildMenuTreeSelect(List menus) + { + List 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; + } + + /** + * 查询菜单使用数量 + * + * @param menuId 菜单ID + * @return 结果 + */ + @Override + public boolean checkMenuExistRole(Long menuId) + { + int result = roleMenuMapper.checkMenuExistRole(menuId); + return result > 0; + } + + /** + * 新增保存菜单信息 + * + * @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 boolean 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 getRouteName(SysMenu menu) + { + // 非外链并且是一级目录(类型为目录) + if (isMenuFrame(menu)) + { + return StringUtils.EMPTY; + } + return getRouteName(menu.getRouteName(), menu.getPath()); + } + + /** + * 获取路由名称,如没有配置路由名称则取路由地址 + * + * @param routerName 路由名称 + * @param path 路由地址 + * @return 路由名称(驼峰格式) + */ + public String getRouteName(String name, String path) + { + String routerName = StringUtils.isNotEmpty(name) ? name : path; + return StringUtils.capitalize(routerName); + } + + /** + * 获取路由地址 + * + * @param menu 菜单信息 + * @return 路由地址 + */ + public String getRouterPath(SysMenu menu) + { + String routerPath = menu.getPath(); + // 内链打开外网方式 + if (menu.getParentId().intValue() != 0 && isInnerLink(menu)) + { + routerPath = innerLinkReplaceEach(routerPath); + } + // 非外链并且是一级目录(类型为目录) + if (0 == menu.getParentId().intValue() && UserConstants.TYPE_DIR.equals(menu.getMenuType()) + && UserConstants.NO_FRAME.equals(menu.getIsFrame())) + { + routerPath = "/" + menu.getPath(); + } + // 非外链并且是一级目录(类型为菜单) + else if (isMenuFrame(menu)) + { + routerPath = "/"; + } + return routerPath; + } + + /** + * 获取组件信息 + * + * @param menu 菜单信息 + * @return 组件信息 + */ + public String getComponent(SysMenu menu) + { + String component = UserConstants.LAYOUT; + if (StringUtils.isNotEmpty(menu.getComponent()) && !isMenuFrame(menu)) + { + component = menu.getComponent(); + } + else if (StringUtils.isEmpty(menu.getComponent()) && menu.getParentId().intValue() != 0 && isInnerLink(menu)) + { + component = UserConstants.INNER_LINK; + } + else if (StringUtils.isEmpty(menu.getComponent()) && isParentView(menu)) + { + component = UserConstants.PARENT_VIEW; + } + return component; + } + + /** + * 是否为菜单内部跳转 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isMenuFrame(SysMenu menu) + { + return menu.getParentId().intValue() == 0 && UserConstants.TYPE_MENU.equals(menu.getMenuType()) + && menu.getIsFrame().equals(UserConstants.NO_FRAME); + } + + /** + * 是否为内链组件 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isInnerLink(SysMenu menu) + { + return menu.getIsFrame().equals(UserConstants.NO_FRAME) && StringUtils.ishttp(menu.getPath()); + } + + /** + * 是否为parent_view组件 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isParentView(SysMenu menu) + { + return menu.getParentId().intValue() != 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType()); + } + + /** + * 根据父节点的ID获取所有子节点 + * + * @param list 分类表 + * @param parentId 传入的父节点ID + * @return String + */ + public List getChildPerms(List list, int parentId) + { + List returnList = new ArrayList(); + for (Iterator iterator = list.iterator(); iterator.hasNext();) + { + SysMenu t = (SysMenu) iterator.next(); + // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点 + if (t.getParentId() == parentId) + { + recursionFn(list, t); + returnList.add(t); + } + } + return returnList; + } + + /** + * 递归列表 + * + * @param list 分类表 + * @param t 子节点 + */ + private void recursionFn(List list, SysMenu t) + { + // 得到子节点列表 + List childList = getChildList(list, t); + t.setChildren(childList); + for (SysMenu tChild : childList) + { + if (hasChild(list, tChild)) + { + recursionFn(list, tChild); + } + } + } + + /** + * 得到子节点列表 + */ + private List getChildList(List list, SysMenu t) + { + List tlist = new ArrayList(); + Iterator 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 list, SysMenu t) + { + return getChildList(list, t).size() > 0; + } + + /** + * 内链域名特殊字符替换 + * + * @return 替换后的内链域名 + */ + public String innerLinkReplaceEach(String path) + { + return StringUtils.replaceEach(path, new String[] { Constants.HTTP, Constants.HTTPS, Constants.WWW, ".", ":" }, + new String[] { "", "", "", "/", "/" }); + } +} diff --git a/staffing-system/src/main/java/com/staffing/system/service/impl/SysNoticeServiceImpl.java b/staffing-system/src/main/java/com/staffing/system/service/impl/SysNoticeServiceImpl.java new file mode 100644 index 0000000..a5f209e --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/impl/SysNoticeServiceImpl.java @@ -0,0 +1,92 @@ +package com.staffing.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.staffing.system.domain.SysNotice; +import com.staffing.system.mapper.SysNoticeMapper; +import com.staffing.system.service.ISysNoticeService; + +/** + * 公告 服务层实现 + * + * @author staffing + */ +@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 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 结果 + */ + @Override + public int deleteNoticeByIds(Long[] noticeIds) + { + return noticeMapper.deleteNoticeByIds(noticeIds); + } +} diff --git a/staffing-system/src/main/java/com/staffing/system/service/impl/SysOperLogServiceImpl.java b/staffing-system/src/main/java/com/staffing/system/service/impl/SysOperLogServiceImpl.java new file mode 100644 index 0000000..8006f0f --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/impl/SysOperLogServiceImpl.java @@ -0,0 +1,76 @@ +package com.staffing.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.staffing.system.domain.SysOperLog; +import com.staffing.system.mapper.SysOperLogMapper; +import com.staffing.system.service.ISysOperLogService; + +/** + * 操作日志 服务层处理 + * + * @author staffing + */ +@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 selectOperLogList(SysOperLog operLog) + { + return operLogMapper.selectOperLogList(operLog); + } + + /** + * 批量删除系统操作日志 + * + * @param operIds 需要删除的操作日志ID + * @return 结果 + */ + @Override + 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/staffing-system/src/main/java/com/staffing/system/service/impl/SysPostServiceImpl.java b/staffing-system/src/main/java/com/staffing/system/service/impl/SysPostServiceImpl.java new file mode 100644 index 0000000..658674d --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/impl/SysPostServiceImpl.java @@ -0,0 +1,178 @@ +package com.staffing.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.staffing.common.constant.UserConstants; +import com.staffing.common.exception.ServiceException; +import com.staffing.common.utils.StringUtils; +import com.staffing.system.domain.SysPost; +import com.staffing.system.mapper.SysPostMapper; +import com.staffing.system.mapper.SysUserPostMapper; +import com.staffing.system.service.ISysPostService; + +/** + * 岗位信息 服务层处理 + * + * @author staffing + */ +@Service +public class SysPostServiceImpl implements ISysPostService +{ + @Autowired + private SysPostMapper postMapper; + + @Autowired + private SysUserPostMapper userPostMapper; + + /** + * 查询岗位信息集合 + * + * @param post 岗位信息 + * @return 岗位信息集合 + */ + @Override + public List selectPostList(SysPost post) + { + return postMapper.selectPostList(post); + } + + /** + * 查询所有岗位 + * + * @return 岗位列表 + */ + @Override + public List 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列表 + */ + @Override + public List selectPostListByUserId(Long userId) + { + return postMapper.selectPostListByUserId(userId); + } + + /** + * 校验岗位名称是否唯一 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public boolean 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 boolean 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 结果 + */ + @Override + public int deletePostByIds(Long[] postIds) + { + for (Long postId : postIds) + { + SysPost post = selectPostById(postId); + if (countUserPostById(postId) > 0) + { + throw new ServiceException(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/staffing-system/src/main/java/com/staffing/system/service/impl/SysRoleServiceImpl.java b/staffing-system/src/main/java/com/staffing/system/service/impl/SysRoleServiceImpl.java new file mode 100644 index 0000000..a1dea65 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/impl/SysRoleServiceImpl.java @@ -0,0 +1,427 @@ +package com.staffing.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.staffing.common.annotation.DataScope; +import com.staffing.common.constant.UserConstants; +import com.staffing.common.core.domain.entity.SysRole; +import com.staffing.common.core.domain.entity.SysUser; +import com.staffing.common.exception.ServiceException; +import com.staffing.common.utils.SecurityUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.spring.SpringUtils; +import com.staffing.system.domain.SysRoleDept; +import com.staffing.system.domain.SysRoleMenu; +import com.staffing.system.domain.SysUserRole; +import com.staffing.system.mapper.SysRoleDeptMapper; +import com.staffing.system.mapper.SysRoleMapper; +import com.staffing.system.mapper.SysRoleMenuMapper; +import com.staffing.system.mapper.SysUserRoleMapper; +import com.staffing.system.service.ISysRoleService; + +/** + * 角色 业务层处理 + * + * @author staffing + */ +@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 selectRoleList(SysRole role) + { + return roleMapper.selectRoleList(role); + } + + /** + * 根据用户ID查询角色 + * + * @param userId 用户ID + * @return 角色列表 + */ + @Override + public List selectRolesByUserId(Long userId) + { + List userRoles = roleMapper.selectRolePermissionByUserId(userId); + List roles = selectRoleAll(); + for (SysRole role : roles) + { + for (SysRole userRole : userRoles) + { + if (role.getRoleId().longValue() == userRole.getRoleId().longValue()) + { + role.setFlag(true); + break; + } + } + } + return roles; + } + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + @Override + public Set selectRolePermissionByUserId(Long userId) + { + List perms = roleMapper.selectRolePermissionByUserId(userId); + Set permsSet = new HashSet<>(); + for (SysRole perm : perms) + { + if (StringUtils.isNotNull(perm)) + { + permsSet.addAll(Arrays.asList(perm.getRoleKey().trim().split(","))); + } + } + return permsSet; + } + + /** + * 查询所有角色 + * + * @return 角色列表 + */ + @Override + public List selectRoleAll() + { + return SpringUtils.getAopProxy(this).selectRoleList(new SysRole()); + } + + /** + * 根据用户ID获取角色选择框列表 + * + * @param userId 用户ID + * @return 选中角色ID列表 + */ + @Override + public List selectRoleListByUserId(Long userId) + { + return roleMapper.selectRoleListByUserId(userId); + } + + /** + * 通过角色ID查询角色 + * + * @param roleId 角色ID + * @return 角色对象信息 + */ + @Override + public SysRole selectRoleById(Long roleId) + { + return roleMapper.selectRoleById(roleId); + } + + /** + * 校验角色名称是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + public boolean 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 boolean 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 角色信息 + */ + @Override + public void checkRoleAllowed(SysRole role) + { + if (StringUtils.isNotNull(role.getRoleId()) && role.isAdmin()) + { + throw new ServiceException("不允许操作超级管理员角色"); + } + } + + /** + * 校验角色是否有数据权限 + * + * @param roleIds 角色id + */ + @Override + public void checkRoleDataScope(Long... roleIds) + { + if (!SysUser.isAdmin(SecurityUtils.getUserId())) + { + for (Long roleId : roleIds) + { + SysRole role = new SysRole(); + role.setRoleId(roleId); + List roles = SpringUtils.getAopProxy(this).selectRoleList(role); + if (StringUtils.isEmpty(roles)) + { + throw new ServiceException("没有权限访问角色数据!"); + } + } + } + } + + /** + * 通过角色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 结果 + */ + @Override + 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 list = new ArrayList(); + 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 list = new ArrayList(); + 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 + @Transactional + public int deleteRoleById(Long roleId) + { + // 删除角色与菜单关联 + roleMenuMapper.deleteRoleMenuByRoleId(roleId); + // 删除角色与部门关联 + roleDeptMapper.deleteRoleDeptByRoleId(roleId); + return roleMapper.deleteRoleById(roleId); + } + + /** + * 批量删除角色信息 + * + * @param roleIds 需要删除的角色ID + * @return 结果 + */ + @Override + @Transactional + public int deleteRoleByIds(Long[] roleIds) + { + for (Long roleId : roleIds) + { + checkRoleAllowed(new SysRole(roleId)); + checkRoleDataScope(roleId); + SysRole role = selectRoleById(roleId); + if (countUserRoleByRoleId(roleId) > 0) + { + throw new ServiceException(String.format("%1$s已分配,不能删除", role.getRoleName())); + } + } + // 删除角色与菜单关联 + roleMenuMapper.deleteRoleMenu(roleIds); + // 删除角色与部门关联 + roleDeptMapper.deleteRoleDept(roleIds); + return roleMapper.deleteRoleByIds(roleIds); + } + + /** + * 取消授权用户角色 + * + * @param userRole 用户和角色关联信息 + * @return 结果 + */ + @Override + public int deleteAuthUser(SysUserRole userRole) + { + return userRoleMapper.deleteUserRoleInfo(userRole); + } + + /** + * 批量取消授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要取消授权的用户数据ID + * @return 结果 + */ + @Override + public int deleteAuthUsers(Long roleId, Long[] userIds) + { + return userRoleMapper.deleteUserRoleInfos(roleId, userIds); + } + + /** + * 批量选择授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要授权的用户数据ID + * @return 结果 + */ + @Override + public int insertAuthUsers(Long roleId, Long[] userIds) + { + // 新增用户与角色管理 + List list = new ArrayList(); + for (Long userId : userIds) + { + SysUserRole ur = new SysUserRole(); + ur.setUserId(userId); + ur.setRoleId(roleId); + list.add(ur); + } + return userRoleMapper.batchUserRole(list); + } +} diff --git a/staffing-system/src/main/java/com/staffing/system/service/impl/SysUserOnlineServiceImpl.java b/staffing-system/src/main/java/com/staffing/system/service/impl/SysUserOnlineServiceImpl.java new file mode 100644 index 0000000..9a6d54b --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/impl/SysUserOnlineServiceImpl.java @@ -0,0 +1,96 @@ +package com.staffing.system.service.impl; + +import org.springframework.stereotype.Service; +import com.staffing.common.core.domain.model.LoginUser; +import com.staffing.common.utils.StringUtils; +import com.staffing.system.domain.SysUserOnline; +import com.staffing.system.service.ISysUserOnlineService; + +/** + * 在线用户 服务层处理 + * + * @author staffing + */ +@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 在线用户 + */ + @Override + 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/staffing-system/src/main/java/com/staffing/system/service/impl/SysUserServiceImpl.java b/staffing-system/src/main/java/com/staffing/system/service/impl/SysUserServiceImpl.java new file mode 100644 index 0000000..a1d2982 --- /dev/null +++ b/staffing-system/src/main/java/com/staffing/system/service/impl/SysUserServiceImpl.java @@ -0,0 +1,555 @@ +package com.staffing.system.service.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import javax.validation.Validator; +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 org.springframework.util.CollectionUtils; +import com.staffing.common.annotation.DataScope; +import com.staffing.common.constant.UserConstants; +import com.staffing.common.core.domain.entity.SysRole; +import com.staffing.common.core.domain.entity.SysUser; +import com.staffing.common.exception.ServiceException; +import com.staffing.common.utils.SecurityUtils; +import com.staffing.common.utils.StringUtils; +import com.staffing.common.utils.bean.BeanValidators; +import com.staffing.common.utils.spring.SpringUtils; +import com.staffing.system.domain.SysPost; +import com.staffing.system.domain.SysUserPost; +import com.staffing.system.domain.SysUserRole; +import com.staffing.system.mapper.SysPostMapper; +import com.staffing.system.mapper.SysRoleMapper; +import com.staffing.system.mapper.SysUserMapper; +import com.staffing.system.mapper.SysUserPostMapper; +import com.staffing.system.mapper.SysUserRoleMapper; +import com.staffing.system.service.ISysConfigService; +import com.staffing.system.service.ISysDeptService; +import com.staffing.system.service.ISysUserService; + +/** + * 用户 业务层处理 + * + * @author staffing + */ +@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; + + @Autowired + private ISysDeptService deptService; + + @Autowired + protected Validator validator; + + /** + * 根据条件分页查询用户列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectUserList(SysUser user) + { + return userMapper.selectUserList(user); + } + + /** + * 根据条件分页查询已分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectAllocatedList(SysUser user) + { + return userMapper.selectAllocatedList(user); + } + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectUnallocatedList(SysUser user) + { + return userMapper.selectUnallocatedList(user); + } + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + @Override + public SysUser selectUserByUserName(String userName) + { + return userMapper.selectUserByUserName(userName); + } + + @Override + public SysUser selectUserByPhone(String phone) + { + return userMapper.selectUserByPhone(phone); + } + /** + * 通过用户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 list = roleMapper.selectRolesByUserName(userName); + if (CollectionUtils.isEmpty(list)) + { + return StringUtils.EMPTY; + } + return list.stream().map(SysRole::getRoleName).collect(Collectors.joining(",")); + } + + /** + * 查询用户所属岗位组 + * + * @param userName 用户名 + * @return 结果 + */ + @Override + public String selectUserPostGroup(String userName) + { + List list = postMapper.selectPostsByUserName(userName); + if (CollectionUtils.isEmpty(list)) + { + return StringUtils.EMPTY; + } + return list.stream().map(SysPost::getPostName).collect(Collectors.joining(",")); + } + + /** + * 校验用户名称是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public boolean checkUserNameUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkUserNameUnique(user.getUserName()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验手机号码是否唯一 + * + * @param user 用户信息 + * @return + */ + @Override + public boolean 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 boolean 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 用户信息 + */ + @Override + public void checkUserAllowed(SysUser user) + { + if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin()) + { + throw new ServiceException("不允许操作超级管理员用户"); + } + } + + /** + * 校验用户是否有数据权限 + * + * @param userId 用户id + */ + @Override + public void checkUserDataScope(Long userId) + { + if (!SysUser.isAdmin(SecurityUtils.getUserId())) + { + SysUser user = new SysUser(); + user.setUserId(userId); + List users = SpringUtils.getAopProxy(this).selectUserList(user); + if (StringUtils.isEmpty(users)) + { + throw new ServiceException("没有权限访问用户数据!"); + } + } + } + + /** + * 新增保存用户信息 + * + * @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 + public boolean registerUser(SysUser user) + { + return userMapper.insertUser(user) > 0; + } + + /** + * 修改保存用户信息 + * + * @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 userId 用户ID + * @param roleIds 角色组 + */ + @Override + @Transactional + public void insertUserAuth(Long userId, Long[] roleIds) + { + userRoleMapper.deleteUserRoleByUserId(userId); + insertUserRole(userId, roleIds); + } + + /** + * 修改用户状态 + * + * @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 userName 用户名 + * @param avatar 头像地址 + * @return 结果 + */ + @Override + 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) + { + this.insertUserRole(user.getUserId(), user.getRoleIds()); + } + + /** + * 新增用户岗位信息 + * + * @param user 用户对象 + */ + public void insertUserPost(SysUser user) + { + Long[] posts = user.getPostIds(); + if (StringUtils.isNotEmpty(posts)) + { + // 新增用户与岗位管理 + List list = new ArrayList(posts.length); + for (Long postId : posts) + { + SysUserPost up = new SysUserPost(); + up.setUserId(user.getUserId()); + up.setPostId(postId); + list.add(up); + } + userPostMapper.batchUserPost(list); + } + } + + /** + * 新增用户角色信息 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + public void insertUserRole(Long userId, Long[] roleIds) + { + if (StringUtils.isNotEmpty(roleIds)) + { + // 新增用户与角色管理 + List list = new ArrayList(roleIds.length); + for (Long roleId : roleIds) + { + SysUserRole ur = new SysUserRole(); + ur.setUserId(userId); + ur.setRoleId(roleId); + list.add(ur); + } + userRoleMapper.batchUserRole(list); + } + } + + /** + * 通过用户ID删除用户 + * + * @param userId 用户ID + * @return 结果 + */ + @Override + @Transactional + public int deleteUserById(Long userId) + { + // 删除用户与角色关联 + userRoleMapper.deleteUserRoleByUserId(userId); + // 删除用户与岗位表 + userPostMapper.deleteUserPostByUserId(userId); + return userMapper.deleteUserById(userId); + } + + /** + * 批量删除用户信息 + * + * @param userIds 需要删除的用户ID + * @return 结果 + */ + @Override + @Transactional + public int deleteUserByIds(Long[] userIds) + { + for (Long userId : userIds) + { + checkUserAllowed(new SysUser(userId)); + checkUserDataScope(userId); + } + // 删除用户与角色关联 + userRoleMapper.deleteUserRole(userIds); + // 删除用户与岗位关联 + userPostMapper.deleteUserPost(userIds); + return userMapper.deleteUserByIds(userIds); + } + + /** + * 导入用户数据 + * + * @param userList 用户数据列表 + * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 + * @param operName 操作用户 + * @return 结果 + */ + @Override + public String importUser(List userList, Boolean isUpdateSupport, String operName) + { + if (StringUtils.isNull(userList) || userList.size() == 0) + { + throw new ServiceException("导入用户数据不能为空!"); + } + int successNum = 0; + int failureNum = 0; + StringBuilder successMsg = new StringBuilder(); + StringBuilder failureMsg = new StringBuilder(); + for (SysUser user : userList) + { + try + { + // 验证是否存在这个用户 + SysUser u = userMapper.selectUserByUserName(user.getUserName()); + if (StringUtils.isNull(u)) + { + BeanValidators.validateWithException(validator, user); + deptService.checkDeptDataScope(user.getDeptId()); + String password = configService.selectConfigByKey("sys.user.initPassword"); + user.setPassword(SecurityUtils.encryptPassword(password)); + user.setCreateBy(operName); + userMapper.insertUser(user); + successNum++; + successMsg.append("
" + successNum + "、账号 " + user.getUserName() + " 导入成功"); + } + else if (isUpdateSupport) + { + BeanValidators.validateWithException(validator, user); + checkUserAllowed(u); + checkUserDataScope(u.getUserId()); + deptService.checkDeptDataScope(user.getDeptId()); + user.setUserId(u.getUserId()); + user.setUpdateBy(operName); + userMapper.updateUser(user); + successNum++; + successMsg.append("
" + successNum + "、账号 " + user.getUserName() + " 更新成功"); + } + else + { + failureNum++; + failureMsg.append("
" + failureNum + "、账号 " + user.getUserName() + " 已存在"); + } + } + catch (Exception e) + { + failureNum++; + String msg = "
" + failureNum + "、账号 " + user.getUserName() + " 导入失败:"; + failureMsg.append(msg + e.getMessage()); + log.error(msg, e); + } + } + if (failureNum > 0) + { + failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); + throw new ServiceException(failureMsg.toString()); + } + else + { + successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:"); + } + return successMsg.toString(); + } +} diff --git a/staffing-system/src/main/resources/apiclient_key.pem b/staffing-system/src/main/resources/apiclient_key.pem new file mode 100644 index 0000000..eef0b43 --- /dev/null +++ b/staffing-system/src/main/resources/apiclient_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDKl801cqUtGl0q +qE2V/wgHNfc1fIV1eKIvGCYGbw6fhsW2qI0Uj0y0FlVR8Psntj/prHdf4N8u4i5L +mTBmPyuQqEz+o6TmK1R5NGFR8SsJKjwaRVhj+0qDrdCGgTqcKWaUkTAfvsPlhFkC +mawXhcPdKtzTR/tKuqKybXg1GjNQFQIglBP92j3iw4moPfbaxTPVBcsogcrT/AU+ +QP05Am/n6CQAwNRTI7PmRAUV+V9Yc1zK38jXoUsIJC0FMGrxNbZty4V2NuHT0sgE +12+Fk9JWUfXGWpRgbB1qrIzH2xKkn4xugWczGZAx5bPfMZaF0Qrm7o5lr5E9AALy +196QKnwtAgMBAAECggEAEwVHjfISkfZ8ssmUZzXHgi3N5Oao/QtzZqqEv2vj2pRj +sa+Hd1uw3uON5SCT4/mXbI/1sTnCmns/z3c1dRQPOgijGfExRS7iQnLphDD5UmX1 +uJ20G8b3Cv/hqQ8u+oRkjiRHeWOGruDLHpRg9OBpMDWa//ctH6oAJnJiq9Gm6ai0 +YXkthCzTdZ7YhCl1lHyM2NHJCQ1mnAQPNH8jKIAigXxmwXbQW9QF0rd3uOfsSJCA +K0o2MFAV7McCursqiE0JWmOQAeSYf6dSm0Caa8IWoBDGN7l88mwQQBStrN0pkAt/ +tK88Icrgb+4Go6gSpn6H6KedeWM5rWusq1JjqAuOPQKBgQD2k34+wWMt9e+10fkc +0q+0CcalPlWhOrkoFSkyPzOF3D37g7rJ5VEI4bH0fOPdE8wfpqq97TUIqu7zexRS +CVbFek741lGX80GDMmf+x0hR0+FekeynQMRpmagnZ2wgPe1H4kmOhUSEVugmN+mj +LF+L5VsAjqQXuuZMgrSWLXngPwKBgQDSVfnf1LpP8A9cDcWh0xKn+DzdpwCy1q9c +yKL6doevWw1gtAtVAFeniKgY/J6iKNP536qvB0ks/AUGNXJLGrsiEdy5qiWtjdzb +CU32HcJFNwibLZ5JKMQsoiwOcJVKI5VyA+Dwj0Brzmf/qpRzY2ErfumhhPggEhVM +d+ponKNIkwKBgDx0RQuV1n86QR9O78jFTxbRHsb81XnGMAdHyOXs4PD84qV70pwV +gRywWTUcObHGXNGVx17xfYM2hYdkscK7T27zYdFYmoCqv3EvNpgcu/pz/Fl3ZZJM +KtvJNJUUokn1ZOuu62HqArZ/qENWig3bn0FpZjpovoqi5Dv1/9iiJbN5AoGBAJqH +ygYVjzBtqYszHxDuNxWq/mTGbm/15G6hhYPIE5XUqnZysKSplLykXQPGjXGL13kM +R6VCEBP5sGNIXwkowXWdc/IAPKBOyoUuR9XbNUCO10bS9CjBx6cXGpEdS8FldUWH +7fou9OB/i869b0V7LQe8vT8KpxVA098TdueWtSv7AoGAbD0dukQwhvyIazUiiHbb +UDPi4FW1Z8nFMoz7R4k3+CMrcU4dh8eM3NondcIDHOtKye6oae1DQSR6bMxcjKpX +qXhk6eyS/UKRc9kd3vzg1k5Gi5xkCrJ0HiaXTtrdfAq3Wc5WNpc7Se08ri5Yjr18 +2+SqyzR/9YzqeE7GRPyQCxU= +-----END PRIVATE KEY----- diff --git a/staffing-system/src/main/resources/mapper/custom/StEmployeeFundRecordMapper.xml b/staffing-system/src/main/resources/mapper/custom/StEmployeeFundRecordMapper.xml new file mode 100644 index 0000000..ed9965c --- /dev/null +++ b/staffing-system/src/main/resources/mapper/custom/StEmployeeFundRecordMapper.xml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + select id, task_id, task_name, task_date, employee_id, employee_name + , phone, id_card, day_price, should_price, real_price, pay_way + , pay_account, pay_time, update_time, pay_status, transfer_no from st_employee_fund_record + + + + + + + + + + + + + + + insert into st_employee_fund_record + + task_id, + task_name, + task_date, + employee_id, + employee_name, + phone, + id_card, + day_price, + should_price, + real_price, + pay_way, + pay_account, + pay_time, + update_time, + pay_status, + transfer_no, + + + #{taskId}, + #{taskName}, + #{taskDate}, + #{employeeId}, + #{employeeName}, + #{phone}, + #{idCard}, + #{dayPrice}, + #{shouldPrice}, + #{realPrice}, + #{payWay}, + #{payAccount}, + #{payTime}, + #{updateTime}, + #{payStatus}, + #{transferNo}, + + + + + update st_employee_fund_record + + task_id = #{taskId}, + task_name = #{taskName}, + task_date = #{taskDate}, + employee_id = #{employeeId}, + employee_name = #{employeeName}, + phone = #{phone}, + id_card = #{idCard}, + day_price = #{dayPrice}, + should_price = #{shouldPrice}, + real_price = #{realPrice}, + pay_way = #{payWay}, + pay_account = #{payAccount}, + pay_time = #{payTime}, + update_time = #{updateTime}, + pay_status = #{payStatus}, + transfer_no = #{transferNo}, + + where id = #{id} + + + + + + update st_employee_fund_record + + task_id = #{taskId}, + task_name = #{taskName}, + task_date = #{taskDate}, + employee_id = #{employeeId}, + employee_name = #{employeeName}, + phone = #{phone}, + id_card = #{idCard}, + day_price = #{dayPrice}, + should_price = #{shouldPrice}, + real_price = #{realPrice}, + pay_way = #{payWay}, + pay_account = #{payAccount}, + pay_time = #{payTime}, + update_time = #{updateTime}, + pay_status = #{payStatus}, + transfer_no = #{transferNo}, + + where task_id = #{taskId} + and employee_id = #{employeeId} + + + delete from st_employee_fund_record where id = #{id} + + + + delete from st_employee_fund_record where id in + + #{id} + + + \ No newline at end of file diff --git a/staffing-system/src/main/resources/mapper/custom/StEmployeeMapper.xml b/staffing-system/src/main/resources/mapper/custom/StEmployeeMapper.xml new file mode 100644 index 0000000..35538ef --- /dev/null +++ b/staffing-system/src/main/resources/mapper/custom/StEmployeeMapper.xml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + select id, real_name, phone, id_card, sex, nation, age, use_unit, interview_date, entry_date, supplier, employee_price, supplier_price, employee_type, update_time,create_time,open_id from st_employee + + + + + + + + + + + + + insert into st_employee + + real_name, + phone, + id_card, + sex, + nation, + age, + use_unit, + interview_date, + entry_date, + supplier, + employee_price, + supplier_price, + employee_type, + update_time, + create_time, + open_id, + + + #{realName}, + #{phone}, + #{idCard}, + #{sex}, + #{nation}, + #{age}, + #{useUnit}, + #{interviewDate}, + #{entryDate}, + #{supplier}, + #{employeePrice}, + #{supplierPrice}, + #{employeeType}, + #{updateTime}, + #{createTime}, + #{openId}, + + + + + update st_employee + + real_name = #{realName}, + phone = #{phone}, + id_card = #{idCard}, + sex = #{sex}, + + nation = #{nation}, + age = #{age}, + interview_date = #{interviewDate}, + entry_date = #{entryDate}, + use_unit = #{useUnit}, + supplier = #{supplier}, + employee_price = #{employeePrice}, + supplier_price = #{supplierPrice}, + employee_type = #{employeeType}, + update_time = #{updateTime}, + + where id = #{id} + + + + update st_employee + + real_name = #{realName}, + phone = #{phone}, + id_card = #{idCard}, + sex = #{sex}, + nation = #{nation}, + age = #{age}, + use_unit = #{useUnit}, + interview_date = #{interviewDate}, + entry_date = #{entryDate}, + supplier = #{supplier}, + employee_price = #{employeePrice}, + supplier_price = #{supplierPrice}, + employee_type = #{employeeType}, + update_time = #{updateTime}, + open_id = #{openId}, + + where id = #{id} + + + + delete from st_employee where id = #{id} + + + + delete from st_employee where id in + + #{id} + + + \ No newline at end of file diff --git a/staffing-system/src/main/resources/mapper/custom/StTaskMapper.xml b/staffing-system/src/main/resources/mapper/custom/StTaskMapper.xml new file mode 100644 index 0000000..254d082 --- /dev/null +++ b/staffing-system/src/main/resources/mapper/custom/StTaskMapper.xml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + select id, task_name, task_date, day_price, use_num, code_pic, status, update_time, create_time from st_task + + + + + + + + + insert into st_task + + task_name, + task_date, + day_price, + use_num, + code_pic, + status, + update_time, + create_time, + + + #{taskName}, + #{taskDate}, + #{dayPrice}, + #{useNum}, + #{codePic}, + #{status}, + #{updateTime}, + #{createTime}, + + + + + update st_task + + task_name = #{taskName}, + task_date = #{taskDate}, + day_price = #{dayPrice}, + use_num = #{useNum}, + code_pic = #{codePic}, + status = #{status}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from st_task where id = #{id} + + + + delete from st_task where id in + + #{id} + + + \ No newline at end of file diff --git a/staffing-system/src/main/resources/mapper/custom/StTaskSignMapper.xml b/staffing-system/src/main/resources/mapper/custom/StTaskSignMapper.xml new file mode 100644 index 0000000..4e37f5c --- /dev/null +++ b/staffing-system/src/main/resources/mapper/custom/StTaskSignMapper.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + select id, task_id, task_name, day_price, sign_time, employee_id, employee_name, phone, id_card, status, remark from st_task_sign + + + + + + + + + + + + + insert into st_task_sign + + task_id, + task_name, + day_price, + sign_time, + employee_id, + employee_name, + phone, + id_card, + status, + remark, + + + #{taskId}, + #{taskName}, + #{dayPrice}, + #{signTime}, + #{employeeId}, + #{employeeName}, + #{phone}, + #{idCard}, + #{status}, + #{remark}, + + + + + update st_task_sign + + task_id = #{taskId}, + task_name = #{taskName}, + day_price = #{dayPrice}, + sign_time = #{signTime}, + employee_id = #{employeeId}, + employee_name = #{employeeName}, + phone = #{phone}, + id_card = #{idCard}, + status = #{status}, + remark = #{remark}, + + where id = #{id} + + + + update st_task_sign + + task_name = #{taskName}, + day_price = #{dayPrice}, + sign_time = #{signTime}, + employee_name = #{employeeName}, + phone = #{phone}, + id_card = #{idCard}, + status = #{status}, + remark = #{remark}, + + where task_id = #{taskId} and employee_id = #{employeeId} + + + + delete from st_task_sign where id = #{id} + + + + delete from st_task_sign where id in + + #{id} + + + \ No newline at end of file diff --git a/staffing-system/src/main/resources/mapper/custom/StTransferRecordMapper.xml b/staffing-system/src/main/resources/mapper/custom/StTransferRecordMapper.xml new file mode 100644 index 0000000..82a2768 --- /dev/null +++ b/staffing-system/src/main/resources/mapper/custom/StTransferRecordMapper.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + select id, task_id, task_name, transfer_no, count_price, employee_ids, create_time, update_time, pay_status from st_transfer_record + + + + + + + + insert into st_transfer_record + + task_id, + task_name, + transfer_no, + count_price, + employee_ids, + create_time, + update_time, + pay_status, + + + #{taskId}, + #{taskName}, + #{transferNo}, + #{countPrice}, + #{employeeIds}, + #{createTime}, + #{updateTime}, + #{payStatus}, + + + + + update st_transfer_record + + task_id = #{taskId}, + task_name = #{taskName}, + transfer_no = #{transferNo}, + count_price = #{countPrice}, + employee_ids = #{employeeIds}, + create_time = #{createTime}, + update_time = #{updateTime}, + pay_status = #{payStatus}, + + where id = #{id} + + + + delete from st_transfer_record where id = #{id} + + + + delete from st_transfer_record where id in + + #{id} + + + \ No newline at end of file diff --git a/staffing-system/src/main/resources/mapper/system/SysConfigMapper.xml b/staffing-system/src/main/resources/mapper/system/SysConfigMapper.xml new file mode 100644 index 0000000..621290d --- /dev/null +++ b/staffing-system/src/main/resources/mapper/system/SysConfigMapper.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + select config_id, config_name, config_key, config_value, config_type, create_by, create_time, update_by, update_time, remark + from sys_config + + + + + + + and config_id = #{configId} + + + and config_key = #{configKey} + + + + + + + + + + + + + + insert into sys_config ( + config_name, + config_key, + config_value, + config_type, + create_by, + remark, + create_time + )values( + #{configName}, + #{configKey}, + #{configValue}, + #{configType}, + #{createBy}, + #{remark}, + sysdate() + ) + + + + update sys_config + + config_name = #{configName}, + config_key = #{configKey}, + config_value = #{configValue}, + config_type = #{configType}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = sysdate() + + where config_id = #{configId} + + + + delete from sys_config where config_id = #{configId} + + + + delete from sys_config where config_id in + + #{configId} + + + + \ No newline at end of file diff --git a/staffing-system/src/main/resources/mapper/system/SysDeptMapper.xml b/staffing-system/src/main/resources/mapper/system/SysDeptMapper.xml new file mode 100644 index 0000000..72ac96a --- /dev/null +++ b/staffing-system/src/main/resources/mapper/system/SysDeptMapper.xml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + + + + + + + + + + + + + + + + insert into sys_dept( + dept_id, + parent_id, + dept_name, + ancestors, + order_num, + leader, + phone, + email, + status, + create_by, + create_time + )values( + #{deptId}, + #{parentId}, + #{deptName}, + #{ancestors}, + #{orderNum}, + #{leader}, + #{phone}, + #{email}, + #{status}, + #{createBy}, + sysdate() + ) + + + + update sys_dept + + parent_id = #{parentId}, + dept_name = #{deptName}, + ancestors = #{ancestors}, + order_num = #{orderNum}, + leader = #{leader}, + phone = #{phone}, + email = #{email}, + status = #{status}, + update_by = #{updateBy}, + update_time = sysdate() + + where dept_id = #{deptId} + + + + update sys_dept set ancestors = + + when #{item.deptId} then #{item.ancestors} + + where dept_id in + + #{item.deptId} + + + + + update sys_dept set status = '0' where dept_id in + + #{deptId} + + + + + update sys_dept set del_flag = '2' where dept_id = #{deptId} + + + \ No newline at end of file diff --git a/staffing-system/src/main/resources/mapper/system/SysDictDataMapper.xml b/staffing-system/src/main/resources/mapper/system/SysDictDataMapper.xml new file mode 100644 index 0000000..ffe1c20 --- /dev/null +++ b/staffing-system/src/main/resources/mapper/system/SysDictDataMapper.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + + + + + + + + + + delete from sys_dict_data where dict_code = #{dictCode} + + + + delete from sys_dict_data where dict_code in + + #{dictCode} + + + + + update sys_dict_data + + dict_sort = #{dictSort}, + dict_label = #{dictLabel}, + dict_value = #{dictValue}, + dict_type = #{dictType}, + css_class = #{cssClass}, + list_class = #{listClass}, + is_default = #{isDefault}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = sysdate() + + where dict_code = #{dictCode} + + + + update sys_dict_data set dict_type = #{newDictType} where dict_type = #{oldDictType} + + + + insert into sys_dict_data( + dict_sort, + dict_label, + dict_value, + dict_type, + css_class, + list_class, + is_default, + status, + remark, + create_by, + create_time + )values( + #{dictSort}, + #{dictLabel}, + #{dictValue}, + #{dictType}, + #{cssClass}, + #{listClass}, + #{isDefault}, + #{status}, + #{remark}, + #{createBy}, + sysdate() + ) + + + \ No newline at end of file diff --git a/staffing-system/src/main/resources/mapper/system/SysDictTypeMapper.xml b/staffing-system/src/main/resources/mapper/system/SysDictTypeMapper.xml new file mode 100644 index 0000000..d2d5077 --- /dev/null +++ b/staffing-system/src/main/resources/mapper/system/SysDictTypeMapper.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + select dict_id, dict_name, dict_type, status, create_by, create_time, remark + from sys_dict_type + + + + + + + + + + + + + + delete from sys_dict_type where dict_id = #{dictId} + + + + delete from sys_dict_type where dict_id in + + #{dictId} + + + + + update sys_dict_type + + dict_name = #{dictName}, + dict_type = #{dictType}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = sysdate() + + where dict_id = #{dictId} + + + + insert into sys_dict_type( + dict_name, + dict_type, + status, + remark, + create_by, + create_time + )values( + #{dictName}, + #{dictType}, + #{status}, + #{remark}, + #{createBy}, + sysdate() + ) + + + \ No newline at end of file diff --git a/staffing-system/src/main/resources/mapper/system/SysLogininforMapper.xml b/staffing-system/src/main/resources/mapper/system/SysLogininforMapper.xml new file mode 100644 index 0000000..f2bf9ee --- /dev/null +++ b/staffing-system/src/main/resources/mapper/system/SysLogininforMapper.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + insert into sys_logininfor (user_name, status, ipaddr, login_location, browser, os, msg, login_time) + values (#{userName}, #{status}, #{ipaddr}, #{loginLocation}, #{browser}, #{os}, #{msg}, sysdate()) + + + + + + delete from sys_logininfor where info_id in + + #{infoId} + + + + + truncate table sys_logininfor + + + \ No newline at end of file diff --git a/staffing-system/src/main/resources/mapper/system/SysMenuMapper.xml b/staffing-system/src/main/resources/mapper/system/SysMenuMapper.xml new file mode 100644 index 0000000..b29a4e8 --- /dev/null +++ b/staffing-system/src/main/resources/mapper/system/SysMenuMapper.xml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select menu_id, menu_name, parent_id, order_num, path, component, `query`, route_name, is_frame, is_cache, menu_type, visible, status, ifnull(perms,'') as perms, icon, create_time + from sys_menu + + + + + + + + + + + + + + + + + + + + + + + + + + update sys_menu + + menu_name = #{menuName}, + parent_id = #{parentId}, + order_num = #{orderNum}, + path = #{path}, + component = #{component}, + `query` = #{query}, + route_name = #{routeName}, + is_frame = #{isFrame}, + is_cache = #{isCache}, + menu_type = #{menuType}, + visible = #{visible}, + status = #{status}, + perms = #{perms}, + icon = #{icon}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = sysdate() + + where menu_id = #{menuId} + + + + insert into sys_menu( + menu_id, + parent_id, + menu_name, + order_num, + path, + component, + `query`, + route_name, + is_frame, + is_cache, + menu_type, + visible, + status, + perms, + icon, + remark, + create_by, + create_time + )values( + #{menuId}, + #{parentId}, + #{menuName}, + #{orderNum}, + #{path}, + #{component}, + #{query}, + #{routeName}, + #{isFrame}, + #{isCache}, + #{menuType}, + #{visible}, + #{status}, + #{perms}, + #{icon}, + #{remark}, + #{createBy}, + sysdate() + ) + + + + delete from sys_menu where menu_id = #{menuId} + + + \ No newline at end of file diff --git a/staffing-system/src/main/resources/mapper/system/SysNoticeMapper.xml b/staffing-system/src/main/resources/mapper/system/SysNoticeMapper.xml new file mode 100644 index 0000000..b0a3bbd --- /dev/null +++ b/staffing-system/src/main/resources/mapper/system/SysNoticeMapper.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + select notice_id, notice_title, notice_type, cast(notice_content as char) as notice_content, status, create_by, create_time, update_by, update_time, remark + from sys_notice + + + + + + + + insert into sys_notice ( + notice_title, + notice_type, + notice_content, + status, + remark, + create_by, + create_time + )values( + #{noticeTitle}, + #{noticeType}, + #{noticeContent}, + #{status}, + #{remark}, + #{createBy}, + sysdate() + ) + + + + update sys_notice + + notice_title = #{noticeTitle}, + notice_type = #{noticeType}, + notice_content = #{noticeContent}, + status = #{status}, + update_by = #{updateBy}, + update_time = sysdate() + + where notice_id = #{noticeId} + + + + delete from sys_notice where notice_id = #{noticeId} + + + + delete from sys_notice where notice_id in + + #{noticeId} + + + + \ No newline at end of file diff --git a/staffing-system/src/main/resources/mapper/system/SysOperLogMapper.xml b/staffing-system/src/main/resources/mapper/system/SysOperLogMapper.xml new file mode 100644 index 0000000..8d2e70d --- /dev/null +++ b/staffing-system/src/main/resources/mapper/system/SysOperLogMapper.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 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, cost_time + from sys_oper_log + + + + 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, cost_time, oper_time) + values (#{title}, #{businessType}, #{method}, #{requestMethod}, #{operatorType}, #{operName}, #{deptName}, #{operUrl}, #{operIp}, #{operLocation}, #{operParam}, #{jsonResult}, #{status}, #{errorMsg}, #{costTime}, sysdate()) + + + + + + delete from sys_oper_log where oper_id in + + #{operId} + + + + + + + truncate table sys_oper_log + + + \ No newline at end of file diff --git a/staffing-system/src/main/resources/mapper/system/SysPostMapper.xml b/staffing-system/src/main/resources/mapper/system/SysPostMapper.xml new file mode 100644 index 0000000..20ddc6b --- /dev/null +++ b/staffing-system/src/main/resources/mapper/system/SysPostMapper.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + select post_id, post_code, post_name, post_sort, status, create_by, create_time, remark + from sys_post + + + + + + + + + + + + + + + + + + update sys_post + + post_code = #{postCode}, + post_name = #{postName}, + post_sort = #{postSort}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = sysdate() + + where post_id = #{postId} + + + + insert into sys_post( + post_id, + post_code, + post_name, + post_sort, + status, + remark, + create_by, + create_time + )values( + #{postId}, + #{postCode}, + #{postName}, + #{postSort}, + #{status}, + #{remark}, + #{createBy}, + sysdate() + ) + + + + delete from sys_post where post_id = #{postId} + + + + delete from sys_post where post_id in + + #{postId} + + + + \ No newline at end of file diff --git a/staffing-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml b/staffing-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml new file mode 100644 index 0000000..731222a --- /dev/null +++ b/staffing-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + delete from sys_role_dept where role_id=#{roleId} + + + + + + delete from sys_role_dept where role_id in + + #{roleId} + + + + + insert into sys_role_dept(role_id, dept_id) values + + (#{item.roleId},#{item.deptId}) + + + + \ No newline at end of file diff --git a/staffing-system/src/main/resources/mapper/system/SysRoleMapper.xml b/staffing-system/src/main/resources/mapper/system/SysRoleMapper.xml new file mode 100644 index 0000000..daf54cd --- /dev/null +++ b/staffing-system/src/main/resources/mapper/system/SysRoleMapper.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + select distinct r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.menu_check_strictly, r.dept_check_strictly, + 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 + + + + + + + + + + + + + + + + + + + + insert into sys_role( + role_id, + role_name, + role_key, + role_sort, + data_scope, + menu_check_strictly, + dept_check_strictly, + status, + remark, + create_by, + create_time + )values( + #{roleId}, + #{roleName}, + #{roleKey}, + #{roleSort}, + #{dataScope}, + #{menuCheckStrictly}, + #{deptCheckStrictly}, + #{status}, + #{remark}, + #{createBy}, + sysdate() + ) + + + + update sys_role + + role_name = #{roleName}, + role_key = #{roleKey}, + role_sort = #{roleSort}, + data_scope = #{dataScope}, + menu_check_strictly = #{menuCheckStrictly}, + dept_check_strictly = #{deptCheckStrictly}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = sysdate() + + where role_id = #{roleId} + + + + update sys_role set del_flag = '2' where role_id = #{roleId} + + + + update sys_role set del_flag = '2' where role_id in + + #{roleId} + + + + \ No newline at end of file diff --git a/staffing-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml b/staffing-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml new file mode 100644 index 0000000..8ca2a7f --- /dev/null +++ b/staffing-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + delete from sys_role_menu where role_id=#{roleId} + + + + delete from sys_role_menu where role_id in + + #{roleId} + + + + + insert into sys_role_menu(role_id, menu_id) values + + (#{item.roleId},#{item.menuId}) + + + + \ No newline at end of file diff --git a/staffing-system/src/main/resources/mapper/system/SysUserMapper.xml b/staffing-system/src/main/resources/mapper/system/SysUserMapper.xml new file mode 100644 index 0000000..e46f83e --- /dev/null +++ b/staffing-system/src/main/resources/mapper/system/SysUserMapper.xml @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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.ancestors, 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 + + + + + + + + + + + + + + + + + + + + + + + + insert into sys_user( + user_id, + dept_id, + user_name, + nick_name, + email, + avatar, + phonenumber, + sex, + password, + status, + create_by, + remark, + create_time + )values( + #{userId}, + #{deptId}, + #{userName}, + #{nickName}, + #{email}, + #{avatar}, + #{phonenumber}, + #{sex}, + #{password}, + #{status}, + #{createBy}, + #{remark}, + sysdate() + ) + + + + update sys_user + + dept_id = #{deptId}, + user_name = #{userName}, + nick_name = #{nickName}, + email = #{email}, + phonenumber = #{phonenumber}, + sex = #{sex}, + avatar = #{avatar}, + password = #{password}, + status = #{status}, + login_ip = #{loginIp}, + login_date = #{loginDate}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = sysdate() + + where user_id = #{userId} + + + + update sys_user set status = #{status} where user_id = #{userId} + + + + update sys_user set avatar = #{avatar} where user_name = #{userName} + + + + update sys_user set password = #{password} where user_name = #{userName} + + + + update sys_user set del_flag = '2' where user_id = #{userId} + + + + update sys_user set del_flag = '2' where user_id in + + #{userId} + + + + \ No newline at end of file diff --git a/staffing-system/src/main/resources/mapper/system/SysUserPostMapper.xml b/staffing-system/src/main/resources/mapper/system/SysUserPostMapper.xml new file mode 100644 index 0000000..908a393 --- /dev/null +++ b/staffing-system/src/main/resources/mapper/system/SysUserPostMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + delete from sys_user_post where user_id=#{userId} + + + + + + delete from sys_user_post where user_id in + + #{userId} + + + + + insert into sys_user_post(user_id, post_id) values + + (#{item.userId},#{item.postId}) + + + + \ No newline at end of file diff --git a/staffing-system/src/main/resources/mapper/system/SysUserRoleMapper.xml b/staffing-system/src/main/resources/mapper/system/SysUserRoleMapper.xml new file mode 100644 index 0000000..1eac908 --- /dev/null +++ b/staffing-system/src/main/resources/mapper/system/SysUserRoleMapper.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + delete from sys_user_role where user_id=#{userId} + + + + + + delete from sys_user_role where user_id in + + #{userId} + + + + + insert into sys_user_role(user_id, role_id) values + + (#{item.userId},#{item.roleId}) + + + + + delete from sys_user_role where user_id=#{userId} and role_id=#{roleId} + + + + delete from sys_user_role where role_id=#{roleId} and user_id in + + #{userId} + + + \ No newline at end of file diff --git a/staffing-ui/.editorconfig b/staffing-ui/.editorconfig new file mode 100644 index 0000000..7034f9b --- /dev/null +++ b/staffing-ui/.editorconfig @@ -0,0 +1,22 @@ +# 告诉EditorConfig插件,这是根文件,不用继续往上查找 +root = true + +# 匹配全部文件 +[*] +# 设置字符集 +charset = utf-8 +# 缩进风格,可选space、tab +indent_style = space +# 缩进的空格数 +indent_size = 2 +# 结尾换行符,可选lf、cr、crlf +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/staffing-ui/.env.development b/staffing-ui/.env.development new file mode 100644 index 0000000..025672e --- /dev/null +++ b/staffing-ui/.env.development @@ -0,0 +1,11 @@ +# 页面标题 +VUE_APP_TITLE = 用工管理系统 + +# 开发环境配置 +ENV = 'development' + +# 管理系统/开发环境 +VUE_APP_BASE_API = '/dev-api' + +# 路由懒加载 +VUE_CLI_BABEL_TRANSPILE_MODULES = true diff --git a/staffing-ui/.env.production b/staffing-ui/.env.production new file mode 100644 index 0000000..d10a41d --- /dev/null +++ b/staffing-ui/.env.production @@ -0,0 +1,8 @@ +# 页面标题 +VUE_APP_TITLE = 用工管理系统 + +# 生产环境配置 +ENV = 'production' + +# 管理系统/生产环境 +VUE_APP_BASE_API = '/prod-api' diff --git a/staffing-ui/.env.staging b/staffing-ui/.env.staging new file mode 100644 index 0000000..e99b2f1 --- /dev/null +++ b/staffing-ui/.env.staging @@ -0,0 +1,10 @@ +# 页面标题 +VUE_APP_TITLE = 用工管理系统 + +NODE_ENV = production + +# 测试环境配置 +ENV = 'staging' + +# xx管理系统/测试环境 +VUE_APP_BASE_API = '/stage-api' diff --git a/staffing-ui/.eslintignore b/staffing-ui/.eslintignore new file mode 100644 index 0000000..89be6f6 --- /dev/null +++ b/staffing-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/staffing-ui/.eslintrc.js b/staffing-ui/.eslintrc.js new file mode 100644 index 0000000..82bbdee --- /dev/null +++ b/staffing-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/staffing-ui/.gitignore b/staffing-ui/.gitignore new file mode 100644 index 0000000..78a752d --- /dev/null +++ b/staffing-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/staffing-ui/README.md b/staffing-ui/README.md new file mode 100644 index 0000000..6a1a632 --- /dev/null +++ b/staffing-ui/README.md @@ -0,0 +1,30 @@ +## 开发 + +```bash +# 克隆项目 +git clone https://gitee.com/y_project/staffing-Vue + +# 进入项目目录 +cd staffing-ui + +# 安装依赖 +npm install + +# 建议不要直接使用 cnpm 安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题 +npm install --registry=https://registry.npmmirror.com + +# 启动服务 +npm run dev +``` + +浏览器访问 http://localhost:80 + +## 发布 + +```bash +# 构建测试环境 +npm run build:stage + +# 构建生产环境 +npm run build:prod +``` \ No newline at end of file diff --git a/staffing-ui/babel.config.js b/staffing-ui/babel.config.js new file mode 100644 index 0000000..c8267b2 --- /dev/null +++ b/staffing-ui/babel.config.js @@ -0,0 +1,13 @@ +module.exports = { + presets: [ + // https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app + '@vue/cli-plugin-babel/preset' + ], + 'env': { + 'development': { + // babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require(). + // This plugin can significantly increase the speed of hot updates, when you have a large number of pages. + 'plugins': ['dynamic-import-node'] + } + } +} \ No newline at end of file diff --git a/staffing-ui/bin/build.bat b/staffing-ui/bin/build.bat new file mode 100644 index 0000000..dda590d --- /dev/null +++ b/staffing-ui/bin/build.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] Weḅdistļ +echo. + +%~d0 +cd %~dp0 + +cd .. +npm run build:prod + +pause \ No newline at end of file diff --git a/staffing-ui/bin/package.bat b/staffing-ui/bin/package.bat new file mode 100644 index 0000000..0e5bc0f --- /dev/null +++ b/staffing-ui/bin/package.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] װWeḅnode_modulesļ +echo. + +%~d0 +cd %~dp0 + +cd .. +npm install --registry=https://registry.npmmirror.com + +pause \ No newline at end of file diff --git a/staffing-ui/bin/run-web.bat b/staffing-ui/bin/run-web.bat new file mode 100644 index 0000000..d30deae --- /dev/null +++ b/staffing-ui/bin/run-web.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] ʹ Vue CLI Web ̡ +echo. + +%~d0 +cd %~dp0 + +cd .. +npm run dev + +pause \ No newline at end of file diff --git a/staffing-ui/build/index.js b/staffing-ui/build/index.js new file mode 100644 index 0000000..0c57de2 --- /dev/null +++ b/staffing-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/staffing-ui/package.json b/staffing-ui/package.json new file mode 100644 index 0000000..9ea4885 --- /dev/null +++ b/staffing-ui/package.json @@ -0,0 +1,91 @@ +{ + "name": "staffing", + "version": "1.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" + }, + "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/staffing-Vue.git" + }, + "dependencies": { + "@riophae/vue-treeselect": "0.4.0", + "axios": "0.28.1", + "clipboard": "2.0.8", + "core-js": "3.37.1", + "echarts": "5.4.0", + "element-ui": "2.15.14", + "file-saver": "2.0.5", + "fuse.js": "6.4.3", + "highlight.js": "9.18.5", + "html2canvas": "^1.4.1", + "js-beautify": "1.13.0", + "js-cookie": "3.0.1", + "jsencrypt": "3.0.0-rc.1", + "nprogress": "0.2.0", + "quill": "1.3.7", + "screenfull": "5.0.2", + "sortablejs": "1.10.2", + "vue": "2.6.12", + "vue-count-to": "1.0.13", + "vue-cropper": "0.5.5", + "vue-meta": "2.4.0", + "vue-router": "3.4.9", + "vuedraggable": "2.24.3", + "vuex": "3.6.0" + }, + "devDependencies": { + "@vue/cli-plugin-babel": "4.4.6", + "@vue/cli-plugin-eslint": "4.4.6", + "@vue/cli-service": "4.4.6", + "babel-eslint": "10.1.0", + "babel-plugin-dynamic-import-node": "2.3.3", + "chalk": "4.1.0", + "compression-webpack-plugin": "6.1.2", + "connect": "3.6.6", + "eslint": "7.15.0", + "eslint-plugin-vue": "7.2.0", + "lint-staged": "10.5.3", + "runjs": "4.4.2", + "sass": "1.32.13", + "sass-loader": "10.1.1", + "script-ext-html-webpack-plugin": "2.1.5", + "svg-sprite-loader": "5.1.1", + "vue-template-compiler": "2.6.12" + }, + "engines": { + "node": ">=8.9", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions" + ] +} diff --git a/staffing-ui/public/favicon.ico b/staffing-ui/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..e26376026420542212ed58d90d0ed34f554fa4ae GIT binary patch literal 5663 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 + + + + 请升级您的浏览器 + + + + + + +

请升级您的浏览器,以便我们更好的为您提供服务!

+

您正在使用 Internet Explorer 的早期版本(IE11以下版本或使用该内核的浏览器)。这意味着在升级浏览器前,您将无法访问此网站。

+
+

请注意:微软公司对Windows XP 及 Internet Explorer 早期版本的支持已经结束

+

自 2016 年 1 月 12 日起,Microsoft 不再为 IE 11 以下版本提供相应支持和更新。没有关键的浏览器安全更新,您的电脑可能易受有害病毒、间谍软件和其他恶意软件的攻击,它们可以窃取或损害您的业务数据和信息。请参阅 微软对 Internet Explorer 早期版本的支持将于 2016 年 1 月 12 日结束的说明

+
+

您可以选择更先进的浏览器

+

推荐使用以下浏览器的最新版本。如果您的电脑已有以下浏览器的最新版本则直接使用该浏览器访问即可。

+ +
+ + \ No newline at end of file diff --git a/staffing-ui/public/index.html b/staffing-ui/public/index.html new file mode 100644 index 0000000..925455c --- /dev/null +++ b/staffing-ui/public/index.html @@ -0,0 +1,208 @@ + + + + + + + + + <%= webpackConfig.name %> + + + + +
+
+
+
+
+
正在加载系统资源,请耐心等待
+
+
+ + diff --git a/staffing-ui/public/robots.txt b/staffing-ui/public/robots.txt new file mode 100644 index 0000000..77470cb --- /dev/null +++ b/staffing-ui/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / \ No newline at end of file diff --git a/staffing-ui/src/App.vue b/staffing-ui/src/App.vue new file mode 100644 index 0000000..b92ea37 --- /dev/null +++ b/staffing-ui/src/App.vue @@ -0,0 +1,28 @@ + + + + diff --git a/staffing-ui/src/api/employee/employee.js b/staffing-ui/src/api/employee/employee.js new file mode 100644 index 0000000..f387ca7 --- /dev/null +++ b/staffing-ui/src/api/employee/employee.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 查询员工列表 +export function listEmployee(query) { + return request({ + url: '/employee/employee/list', + method: 'get', + params: query + }) +} + +// 查询员工详细 +export function getEmployee(id) { + return request({ + url: '/employee/employee/' + id, + method: 'get' + }) +} + +// 新增员工 +export function addEmployee(data) { + return request({ + url: '/employee/employee', + method: 'post', + data: data + }) +} + +// 修改员工 +export function updateEmployee(data) { + return request({ + url: '/employee/employee', + method: 'put', + data: data + }) +} + +// 删除员工 +export function delEmployee(id) { + return request({ + url: '/employee/employee/' + id, + method: 'delete' + }) +} diff --git a/staffing-ui/src/api/fund/fund.js b/staffing-ui/src/api/fund/fund.js new file mode 100644 index 0000000..af2fe1d --- /dev/null +++ b/staffing-ui/src/api/fund/fund.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 查询员工资金流水列表 +export function listFund(query) { + return request({ + url: '/fund/fund/list', + method: 'get', + params: query + }) +} + +// 查询员工资金流水详细 +export function getFund(id) { + return request({ + url: '/fund/fund/' + id, + method: 'get' + }) +} + +// 新增员工资金流水 +export function addFund(data) { + return request({ + url: '/fund/fund', + method: 'post', + data: data + }) +} + +// 修改员工资金流水 +export function updateFund(data) { + return request({ + url: '/fund/fund', + method: 'put', + data: data + }) +} + +// 删除员工资金流水 +export function delFund(id) { + return request({ + url: '/fund/fund/' + id, + method: 'delete' + }) +} diff --git a/staffing-ui/src/api/login.js b/staffing-ui/src/api/login.js new file mode 100644 index 0000000..7b7388f --- /dev/null +++ b/staffing-ui/src/api/login.js @@ -0,0 +1,60 @@ +import request from '@/utils/request' + +// 登录方法 +export function login(username, password, code, uuid) { + const data = { + username, + password, + code, + uuid + } + return request({ + url: '/login', + headers: { + isToken: false, + repeatSubmit: false + }, + method: 'post', + data: data + }) +} + +// 注册方法 +export function register(data) { + return request({ + url: '/register', + headers: { + isToken: false + }, + method: 'post', + data: 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', + headers: { + isToken: false + }, + method: 'get', + timeout: 20000 + }) +} \ No newline at end of file diff --git a/staffing-ui/src/api/menu.js b/staffing-ui/src/api/menu.js new file mode 100644 index 0000000..faef101 --- /dev/null +++ b/staffing-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/staffing-ui/src/api/monitor/cache.js b/staffing-ui/src/api/monitor/cache.js new file mode 100644 index 0000000..72c5f6a --- /dev/null +++ b/staffing-ui/src/api/monitor/cache.js @@ -0,0 +1,57 @@ +import request from '@/utils/request' + +// 查询缓存详细 +export function getCache() { + return request({ + url: '/monitor/cache', + method: 'get' + }) +} + +// 查询缓存名称列表 +export function listCacheName() { + return request({ + url: '/monitor/cache/getNames', + method: 'get' + }) +} + +// 查询缓存键名列表 +export function listCacheKey(cacheName) { + return request({ + url: '/monitor/cache/getKeys/' + cacheName, + method: 'get' + }) +} + +// 查询缓存内容 +export function getCacheValue(cacheName, cacheKey) { + return request({ + url: '/monitor/cache/getValue/' + cacheName + '/' + cacheKey, + method: 'get' + }) +} + +// 清理指定名称缓存 +export function clearCacheName(cacheName) { + return request({ + url: '/monitor/cache/clearCacheName/' + cacheName, + method: 'delete' + }) +} + +// 清理指定键名缓存 +export function clearCacheKey(cacheKey) { + return request({ + url: '/monitor/cache/clearCacheKey/' + cacheKey, + method: 'delete' + }) +} + +// 清理全部缓存 +export function clearCacheAll() { + return request({ + url: '/monitor/cache/clearCacheAll', + method: 'delete' + }) +} diff --git a/staffing-ui/src/api/monitor/job.js b/staffing-ui/src/api/monitor/job.js new file mode 100644 index 0000000..3815569 --- /dev/null +++ b/staffing-ui/src/api/monitor/job.js @@ -0,0 +1,71 @@ +import request from '@/utils/request' + +// 查询定时任务调度列表 +export function listJob(query) { + return request({ + url: '/monitor/job/list', + method: 'get', + params: query + }) +} + +// 查询定时任务调度详细 +export function getJob(jobId) { + return request({ + url: '/monitor/job/' + jobId, + method: 'get' + }) +} + +// 新增定时任务调度 +export function addJob(data) { + return request({ + url: '/monitor/job', + method: 'post', + data: data + }) +} + +// 修改定时任务调度 +export function updateJob(data) { + return request({ + url: '/monitor/job', + method: 'put', + data: data + }) +} + +// 删除定时任务调度 +export function delJob(jobId) { + return request({ + url: '/monitor/job/' + jobId, + method: 'delete' + }) +} + +// 任务状态修改 +export function changeJobStatus(jobId, status) { + const data = { + jobId, + status + } + return request({ + url: '/monitor/job/changeStatus', + method: 'put', + data: data + }) +} + + +// 定时任务立即执行一次 +export function runJob(jobId, jobGroup) { + const data = { + jobId, + jobGroup + } + return request({ + url: '/monitor/job/run', + method: 'put', + data: data + }) +} \ No newline at end of file diff --git a/staffing-ui/src/api/monitor/jobLog.js b/staffing-ui/src/api/monitor/jobLog.js new file mode 100644 index 0000000..6e0be61 --- /dev/null +++ b/staffing-ui/src/api/monitor/jobLog.js @@ -0,0 +1,26 @@ +import request from '@/utils/request' + +// 查询调度日志列表 +export function listJobLog(query) { + return request({ + url: '/monitor/jobLog/list', + method: 'get', + params: query + }) +} + +// 删除调度日志 +export function delJobLog(jobLogId) { + return request({ + url: '/monitor/jobLog/' + jobLogId, + method: 'delete' + }) +} + +// 清空调度日志 +export function cleanJobLog() { + return request({ + url: '/monitor/jobLog/clean', + method: 'delete' + }) +} diff --git a/staffing-ui/src/api/monitor/logininfor.js b/staffing-ui/src/api/monitor/logininfor.js new file mode 100644 index 0000000..4d112b7 --- /dev/null +++ b/staffing-ui/src/api/monitor/logininfor.js @@ -0,0 +1,34 @@ +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 unlockLogininfor(userName) { + return request({ + url: '/monitor/logininfor/unlock/' + userName, + method: 'get' + }) +} + +// 清空登录日志 +export function cleanLogininfor() { + return request({ + url: '/monitor/logininfor/clean', + method: 'delete' + }) +} diff --git a/staffing-ui/src/api/monitor/online.js b/staffing-ui/src/api/monitor/online.js new file mode 100644 index 0000000..bd22137 --- /dev/null +++ b/staffing-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/staffing-ui/src/api/monitor/operlog.js b/staffing-ui/src/api/monitor/operlog.js new file mode 100644 index 0000000..a04bca8 --- /dev/null +++ b/staffing-ui/src/api/monitor/operlog.js @@ -0,0 +1,26 @@ +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' + }) +} diff --git a/staffing-ui/src/api/monitor/server.js b/staffing-ui/src/api/monitor/server.js new file mode 100644 index 0000000..e1f9ca2 --- /dev/null +++ b/staffing-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/staffing-ui/src/api/system/config.js b/staffing-ui/src/api/system/config.js new file mode 100644 index 0000000..a404d82 --- /dev/null +++ b/staffing-ui/src/api/system/config.js @@ -0,0 +1,60 @@ +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 refreshCache() { + return request({ + url: '/system/config/refreshCache', + method: 'delete' + }) +} diff --git a/staffing-ui/src/api/system/dept.js b/staffing-ui/src/api/system/dept.js new file mode 100644 index 0000000..fc943cd --- /dev/null +++ b/staffing-ui/src/api/system/dept.js @@ -0,0 +1,52 @@ +import request from '@/utils/request' + +// 查询部门列表 +export function listDept(query) { + return request({ + url: '/system/dept/list', + method: 'get', + params: query + }) +} + +// 查询部门列表(排除节点) +export function listDeptExcludeChild(deptId) { + return request({ + url: '/system/dept/list/exclude/' + deptId, + method: 'get' + }) +} + +// 查询部门详细 +export function getDept(deptId) { + return request({ + url: '/system/dept/' + deptId, + 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/staffing-ui/src/api/system/dict/data.js b/staffing-ui/src/api/system/dict/data.js new file mode 100644 index 0000000..6c9eb79 --- /dev/null +++ b/staffing-ui/src/api/system/dict/data.js @@ -0,0 +1,52 @@ +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/type/' + 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' + }) +} diff --git a/staffing-ui/src/api/system/dict/type.js b/staffing-ui/src/api/system/dict/type.js new file mode 100644 index 0000000..a7a6e01 --- /dev/null +++ b/staffing-ui/src/api/system/dict/type.js @@ -0,0 +1,60 @@ +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 refreshCache() { + return request({ + url: '/system/dict/type/refreshCache', + method: 'delete' + }) +} + +// 获取字典选择框列表 +export function optionselect() { + return request({ + url: '/system/dict/type/optionselect', + method: 'get' + }) +} \ No newline at end of file diff --git a/staffing-ui/src/api/system/menu.js b/staffing-ui/src/api/system/menu.js new file mode 100644 index 0000000..f6415c6 --- /dev/null +++ b/staffing-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/staffing-ui/src/api/system/notice.js b/staffing-ui/src/api/system/notice.js new file mode 100644 index 0000000..c274ea5 --- /dev/null +++ b/staffing-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/staffing-ui/src/api/system/post.js b/staffing-ui/src/api/system/post.js new file mode 100644 index 0000000..1a8e9ca --- /dev/null +++ b/staffing-ui/src/api/system/post.js @@ -0,0 +1,44 @@ +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' + }) +} diff --git a/staffing-ui/src/api/system/role.js b/staffing-ui/src/api/system/role.js new file mode 100644 index 0000000..f13e6f4 --- /dev/null +++ b/staffing-ui/src/api/system/role.js @@ -0,0 +1,119 @@ +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 allocatedUserList(query) { + return request({ + url: '/system/role/authUser/allocatedList', + method: 'get', + params: query + }) +} + +// 查询角色未授权用户列表 +export function unallocatedUserList(query) { + return request({ + url: '/system/role/authUser/unallocatedList', + method: 'get', + params: query + }) +} + +// 取消用户授权角色 +export function authUserCancel(data) { + return request({ + url: '/system/role/authUser/cancel', + method: 'put', + data: data + }) +} + +// 批量取消用户授权角色 +export function authUserCancelAll(data) { + return request({ + url: '/system/role/authUser/cancelAll', + method: 'put', + params: data + }) +} + +// 授权用户选择 +export function authUserSelectAll(data) { + return request({ + url: '/system/role/authUser/selectAll', + method: 'put', + params: data + }) +} + +// 根据角色ID查询部门树结构 +export function deptTreeSelect(roleId) { + return request({ + url: '/system/role/deptTree/' + roleId, + method: 'get' + }) +} diff --git a/staffing-ui/src/api/system/user.js b/staffing-ui/src/api/system/user.js new file mode 100644 index 0000000..502f5ed --- /dev/null +++ b/staffing-ui/src/api/system/user.js @@ -0,0 +1,136 @@ +import request from '@/utils/request' +import { parseStrEmpty } from "@/utils/staffing"; + +// 查询用户列表 +export function listUser(query) { + return request({ + url: '/system/user/list', + method: 'get', + params: query + }) +} + +// 查询用户详细 +export function getUser(userId) { + return request({ + url: '/system/user/' + parseStrEmpty(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 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', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + data: data + }) +} + +// 查询授权角色 +export function getAuthRole(userId) { + return request({ + url: '/system/user/authRole/' + userId, + method: 'get' + }) +} + +// 保存授权角色 +export function updateAuthRole(data) { + return request({ + url: '/system/user/authRole', + method: 'put', + params: data + }) +} + +// 查询部门下拉树结构 +export function deptTreeSelect() { + return request({ + url: '/system/user/deptTree', + method: 'get' + }) +} diff --git a/staffing-ui/src/api/task/task.js b/staffing-ui/src/api/task/task.js new file mode 100644 index 0000000..dc71795 --- /dev/null +++ b/staffing-ui/src/api/task/task.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 查询任务列表 +export function listTask(query) { + return request({ + url: '/task/task/list', + method: 'get', + params: query + }) +} + +// 查询任务详细 +export function getTask(id) { + return request({ + url: '/task/task/' + id, + method: 'get' + }) +} + +// 新增任务 +export function addTask(data) { + return request({ + url: '/task/task', + method: 'post', + data: data + }) +} + +// 修改任务 +export function updateTask(data) { + return request({ + url: '/task/task', + method: 'put', + data: data + }) +} + +// 删除任务 +export function delTask(id) { + return request({ + url: '/task/task/' + id, + method: 'delete' + }) +} diff --git a/staffing-ui/src/api/taskSign/sign.js b/staffing-ui/src/api/taskSign/sign.js new file mode 100644 index 0000000..ec079c4 --- /dev/null +++ b/staffing-ui/src/api/taskSign/sign.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 查询签到列表 +export function listSign(query) { + return request({ + url: '/taskSign/sign/list', + method: 'get', + params: query + }) +} + +// 查询签到详细 +export function getSign(id) { + return request({ + url: '/taskSign/sign/' + id, + method: 'get' + }) +} + +// 新增签到 +export function addSign(data) { + return request({ + url: '/taskSign/sign', + method: 'post', + data: data + }) +} + +// 修改签到 +export function updateSign(data) { + return request({ + url: '/taskSign/sign', + method: 'put', + data: data + }) +} + +// 删除签到 +export function delSign(id) { + return request({ + url: '/taskSign/sign/' + id, + method: 'delete' + }) +} diff --git a/staffing-ui/src/api/tool/gen.js b/staffing-ui/src/api/tool/gen.js new file mode 100644 index 0000000..2075677 --- /dev/null +++ b/staffing-ui/src/api/tool/gen.js @@ -0,0 +1,85 @@ +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' + }) +} + +// 修改代码生成信息 +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 + }) +} + +// 创建表 +export function createTable(data) { + return request({ + url: '/tool/gen/createTable', + method: 'post', + params: data + }) +} + +// 预览生成代码 +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' + }) +} + +// 生成代码(自定义路径) +export function genCode(tableName) { + return request({ + url: '/tool/gen/genCode/' + tableName, + method: 'get' + }) +} + +// 同步数据库 +export function synchDb(tableName) { + return request({ + url: '/tool/gen/synchDb/' + tableName, + method: 'get' + }) +} diff --git a/staffing-ui/src/assets/401_images/401.gif b/staffing-ui/src/assets/401_images/401.gif new file mode 100644 index 0000000000000000000000000000000000000000..cd6e0d9433421b3f29d0ec0c40f755e354728000 GIT binary patch literal 164227 zcmeFZWmH>j*Dkt}AW4u?O0nV^CJJ??B{WLN%@&ckY+J4b9iZvx<3D_n2&|&Z&h4vq*>(t`hn@MF%=w~&6z}y zqP(U8LV`?U5=a3N2|;mT9wtG40Z~4FVLkx~UI8K0^+%YW=^qEn^=Qs!7AS2+rGJcd zeI?Ce>FVl;;^T97cSpJlAsw7wUAL8x;NutM6BOjVuEFc#Y42*{!E5ir`p+H|&0S2L ztsGsg9PF9?>e1w-!)sS*mg|}ReF=7s|LWG>1^Kt-AWa?Y_&iJ;`2>*se=X^s6*V;e z->cf${j0W%tG4-n&G&!o*yV|*qdA|pxr@VVXH)a*>a2ea<%m*nHaBr~aDL+8VEfOz zsAcKk>fmDO;K-z)@Yh`vL5eUTG)zpb?Efm}`dd2<4U~$#i>ryfskw@xG|P2QNGmHd zl!SnSh`fT5khrj-kbuB_QF#SHMF}|}5d{S$1u-QFrGK_nbTEBwXKwHM&$ed&)mHdF zw*3ndc8=F0E1El7xtW_OIXl=f{cY(etN%O~f&bXwKiZo8=ebjScm6 zwKdgMmG3Ib%Sua%iwX^&K2DM^%sxR|Jju#lhtKOd5p=PoxFf|G-tjg^I&iIIVx?hY*t zH5KJ;id*D2$!?I65EH>+P(lKHJO~&B0L+(o_z-{*-~q0Wzw8o#kIUhVHnYmIEUUEL z>2%~7cePvas66mKz+rP7m3cl>P=r9bpJ-F`m$<6F(|e{Ih=<+t0+IKfs3OzHH{*M1 zNSYT8#i>kGz8+lsvLgxoiE{v;T3$iHA@1Jj2sA+YIy5#eUJg!49+`?JH%-XO&OzFw zq!l`o2IiKPXNMP6`MFlq)dy8pH~V86+Bh3h@(M9LZkB{V|mw?>p%0QGnHXw(N zY&W=islbdV0OY7VIe`tGo`3qyBN!|l*}U&WXQjlfYz|e%m9^I%upwc0O*Q>Crzq4@ z#lt2lO08awWy`u9o2}j|nWUEw5k(CPKhQ4p2^Y=eUg3HoE>>#&cJg>Tui`~-8UNPn zN2)cJk34wVl+EUv*ko!+PH))jl|SpAd#mQQpHBSd-0<`cfbPdywvGJ=nb{Zb0TGKf zmd}*84MiVi;W5z&=@U99k{;VWlQYjsR(Un{^|^??nQCea=}2(#?rgota{6I%ywPw8+ZNrUMfmMG0Dd(DLv)qSymlC zNkBb{VvN(m=<|z{9U~(T;om9Mdz_2t%lBXAd@1~t7IFT>t(dN z$fY8eJ=W>1%33TESv4o*QXGQ`(HSmTkBT$hk5xNg6uiMO9Rr2vi6YE&o)&p`!!{ISv$d06>ay_BeL5+FPHCjZk_G$V&!#>`CD3bO89yR zguEzwWysR4D{mi!AbYmm?qI#CzsPpGN090BhRm{jvl(z~d?85ES4J#Q$t)yZ^MPLY z>%pMVhGT7v*v9bEfYi@2{x-Rl94B{Cg^UybL=KIkDUjuyE1Y!Th21;jUj4-}opT6%CyY^G5hl}1ZwL%9# zMy|{F@BO!;`yP9$_6~n`+T91eVcjvhe|}!PpuOkUIc|sxem0y9G^}+n@H+Tlcj%`G z24%M!2A$x>03I;_BIq+$2zt&05lgB3-LgS{+ZYWZ#-fSP5g?f3b1=_E$8C_YI$dP$ zH&QG;oJJ8uwwMa44`zlW@Pc>)9}<`#dRg@B!NQS@_|Cebw+MzqeACes#p3r_^#pvi zD{f2AuXK`%$Ep!Gvy4LlQJjDtsVyEq>$pb>y~zF!aAqw_`+ZXo-1jKpr7%Ffm4cA$ zuK{^0&M>Y~4=Osr!d(Mb7&mm4@6Fd>3X zB=^V+(L=ZWP{0{i`{dRr$M|XKBU_&*x&)&|_XoJNlWT-@rfjY9$hoH#+0i*#s$0S; zdegT>H9)BQMKU&CQ|~}e3utazfx}Va-kL6jv+7tiLU)bWp1Ok8KCWK>?bbp~ts;um zvYkdxl>73HWah$kjR%;|=T8AY7P9hhh6;59nHh% z$fb0gY|KHVydSWI*6+aePxTdFsDY>V%d3$HJNv?908-tEPc?Jb;SvA0u17i~w`?mv zg%g1?uH1}pDQk8wVv^A-J+dIGlpGMb?EG<>dmve}>`QzbnO3A2{#R)R>pjPhXB=nl zN7C~y#fN&6@6S582Oaip)d=X;54wQ;3Lr`?XbLIb&A)koE>{bjC3Wl~L&~Y+H$OSp z&HFRAbXpu z&V2$J!aE$bo66p1cl4hX$=cV7W~q-}s-_YW=m_>8yv>;dbw9}L)!wB0rcDr$3TMeE z0u_0!bLr>2$M7K2zj_BjdoIJ@n`7T@@!(Vbq;90h5XxqC0>S>YK-A39;e^se(-z5- z<&HSvf(Ygo1dYm#|)bu^7x~5>u4l9 z#?JE2PckM3W-qF@d2nN6@V9-p#&iSa*X3Wq_50nAp20Q2DKrWoj3)-fTE0aU{sB@5$EFHtjC(<5xetF&*)v&r1y;=_LN zC3CBZF%TgVmz%@NK1d~fFm4FUMlAm5X5?J%)&4a{#dJCIP!g!P_m&#CcNO8F{zK09 z_ij4l`q!$CQ4`?pVZ`HK{d~B~4cx(LfY0yl*S;G!h5me)#^JUte1k%KalD6buQs$I zUs3)3@&=eePjH~U9-w)coC!Cz%&4e|Jlt+?py@2V$(zA@&-@@*-~J}Q6GDJQ3&1z_ zKYiux-|xe+sl}%Ih9~9ihX+o8r8lV+@Oqul{oWUAiJZWz(}2e}1MhJL%{&Vv7YiJG5XAK=NE{t>y6R2W9rVWC$E?}u z^gNjSRj?SD|84ProQ`iUyeM;zO=iw8MaEeKRq;rNX)w{@AhB=k^;hMst5pUc!eXN^RF+ zNqR)!`>AyH(&CE4Lqu+}^Nr{bCsf*h2 z2)i+%Cbi;u7XY2=3J1=Fv-!n*uZsaL+)-?AsQ59bh;S1>3{t@pp8D3AHAWPOU72~i zi4ddoj2%jj9UF+fACHcbi-q2b6V>IT6Mr`L1;hapASfm0ZsFqz^A6?5*Zw&jf@UQ8GOV_w`$><~;$eCDCz z`R412H#{e?MevScD#Dn{!`m{^c_o$)o#gHu?N*aSKau2po^;wI?YsqcRbfwnCOV(^ zI*TWj4q%Y)A+ljfdQd8lOJ5LK5Uw}{YMMO%AQ_=T8*7y^(u8sDP2^_6SY9SOOr~bh zMC3ddrF{;$QJSa#OAVSugV4_Shk+!Psa=J^me1oQYLc!HaqGqDKYP+OY0_&;qkANL z`$~C>B>XhF=&>ysBU}2BGzodBl+!Ai8|Py0R3HRo39~hs-@;;LN+Hj!;$p(6ZAz2Z ztX#wEvTDua(!=iTU1qJ*q)8dajfX|u56hOm6vL@MhtNIGKD*2Y!o8EGv$-ZxRyNZg zIAz1i-q7TT>svq;+2c2e! zE}vH#cWa*i29Oq{$Kh`(lV(be2Qo@ToX*^ZsHW%yQ!ZCi$$4_x$r6o1sFCJEcL;z54IKUF_NJ&qe#iN&@vtf~~y?`N1LmMP&K%&uOU*B|ssl(geNIWHGP?N;axY z9-WpUr0`Ji|DUPartv)m0qPC=1Qw^!n38BI*_uewDMNHvKp`Z zb;G4xX~NBA<$b8K_PKJMC%pC642BXB@2@HvUg>s*^NewB#v> zSm&z*yqnXj{8eNusQ9i6AGE|>DWy=kUiPl`zPY&zPuG2UvSA9t+0Y}}s?;xFmim%8 zZNtqU??mq#?9rB}^j7`WtHfP_mqg`-IP8}>3Pk$#oBa*h6RMunRFV9wnY6?&P+=cb zp<^JbMU;bX>{z%9a&o5EGM3B8S93I!CFwxw5a}g4)f|4cRUany}?u;WLbU%yQzx^dj7|YKzC|1y4V?FHM_0qRDt+<7#)-VDiD;G(E;V z-R)I6#_Gjun-{TmJB_a>6B%in=nfn2S~basG>Mls@eedFTJr1KNWQkQpP{f{t9pn`G|JlEr@tFWH~wCR z_;9C6!%g>)wj&AE;rqDbvs&rQU9q{gj*z(y^OKIn7bSsT^~OI`ue~U}n{J}gFSOm( z89&!aw*HLhZr6L&E;5dnM-g2?WnDPfStoR*t8crNpTi){#;KIZ7+k>%Yj1hh|MbQ$ z2cit)UXkv7oo-l?wsA!F2R92uJs3l~834~*{Mj+Ze zkf+}76)^9gNR{Y}yq8#f&tLuiB{81aFR+DozYL}yS>10N`91*k-kiAK>07@`#d|mJ z0cTrp*NXl(BLk?#eqLa}-y0G*0uJ^b6u}JMtsab&f<#wuD`$LnWE`}$uzO7 zKEYu;@jY^aJ!fKOWP)vRVw!l8m1%NJeUim^awu|=A!qXauhEhAv9riACi+np>8WtN zsn6b1h&>S9-sEw`)Yp+I#P2C#=_yf?ab69u1h3f9uVHBe(R=TPlo756MSelgnRThRWfsGpKc2E_7jqKdd++K=kBNN_D|0YKIsmBGRXYIq48PL z?(>}Br`X-kLxG>2GZBuXgRj4X+}{p*c6{;w_Jx(VU;uxH0sX=uZG`1qgAsq`HlY6H zVi%QasWHAJHOoLYJ0|5HBn?pF%|MJ*@wDo+DrOn@=d3bg4|bF@I-qUf8D1?l;QIC2PPW&j^l#XGod=TKp;iOXjftY%UJYdWyY z&vpzon`^dz1aQZ7R8EpLK>lChM$?$mMlU!*!{w zmBW5IO2-YqtPRU789y0rbk?R#<*NE0%8;=YOx9+^7~*a8#u%6&nPF4aa8tu+Gn;fP zHJS^T{%3t>d8;sMBlpiOI2q_2=@$1qTWRMy+-0ZEex1m%6Uw~P#<007#C>#gvw@T? zhGDl|W@8E19nRVqU|=&^bpL3$=X1WxYrpsTPs^Jz{Xrf=vk&3pYtZCd zH9m(#j7Q`#2OaYi%GE2kvacCqw+cy_gxNt{+U%pAB(8j2X{f-a9ihI^oJKLm25%_Gf&$Kki_m3e4m z1QOr-VU&Rh1eQwu%@q%~O>%57OLFXElwgJBd($d=WafhxX&M z^?E_>>>n1+Md@h?P*{Y=TSt<+ddnrG8!%8LzXqUb8HMhYIc@+=K~bd$0~{KbTGc4X zMH){Y+tg`85fmQM^_~@88s5;~$w1oEMlsSkSX4J%H8znjG?T&bJ-v0lu)C^nHGv_z z60^0vba1R(^6|uf{OlZk*+lshJu`bnSRIXhhDTJ^vi^{nJ{Ure{H6n!l@EJ`aIOs% zi0ap%lXRweMU<(``@;~2PyM=fEfiogV3BBkls3X6Ac4>CIjt=6nE&?aNL+5_Xzl}T zdp#}+t~g>)Qmc#VL-~&?>ZKOBjv|v|`Fb%-n{Wh>U9E?SEi|QMnJduQtGByyv(Xo^ zV4rwrBZi&hakaMS*dHpbd^w63OXuW|y7$(YB_81#AEjqh@>a(aK=_U8Aw~mXnQ%e6?)N zj@BPLGj%o#V;ybh2aCNCj1N28FHbh7%ZE@CwargPg|3SkOHEQhisSuTemib|Hl zc^aXH0my#DN~G}T&t8s_ z$}g_u+5QL4*vfSiR(?`MybQWa8#8F8UbxB3Mviucqgm)E6P-WodEMuZV1;8;*h%-? zNA1&7QW2Hg)U5{|h2bpsbhsEi{R0Hmq2@0DC_FGK+L*!HhWvR^39 zloFf)NAGgnc`bS8>f7>^Hjt*!u_|QEYo#5p*<@L}8N4x7!kPQ>so>L>)9;KbZ^9iZ zc+$(=2UW>leU7N9mwMm$`#6c@xwp$#1YnW;Dzn||#@4CxIp1O`K;ZDm=HgHt79M-Z zv*uA@R+|{5lqKipViA^N;(GQgb#ZgLK&{+xw6)>?Pn;=JFGizN*|C(U+v17l&E*LGzvIkuB}#nV(m&|F7BxKtMZi^Xlb+aWHCDNQ z&^YWq$JT1R76aa@1D3W)Nw)uqcQ$jZ`zol9Uzkql{L(}j_7;?n@)KUB^-}FN)arkbfexg`?@ZqCaiMmNGVMY zx2h`?x&IkGf^iwy!ixzKW^P&lL1dUh`bxZB)P>PVv{76gP#(0iG1cOFv{nm8J z1ELe~<6X%W!4$Mf>CN&0hwSdxcs6032yRk_xU&9b&sQ=ZRI8zfryytlZ9 zYs-@~abv5$;M#IO-iLsDGbfPJdNVhaqii!TQgnMWAKMMvDoA*l_sYeC<>tTnX>lMb*z@XI%-RU4 zo)-+S_8L7?mHBo6gxM&|X=Mtm$^7FUTCMADp;T8}Psp?JYtc8wBNEG(=F#<@# zld`f?Vhz(Xvx_24Q>_b%-vuBs?f^w)gGY6UJBYlnvD1Kovc&@w-!<^CI?oQE92{3? zaP)7R_>3~`_X5>@nHTBq_4~B2##J5pZESs)tu!iq@0hXs!`J1Ld1QUm_T}2<)%%~t z4?$qnZ}m65MF|#i075D~8{M!B#bEeul#9pYXX>bP)Jwe7fjng+#=AIYDbMhi_d(Bu+XqGr0Pn z;vBe9+~s`g3%#cGxTjN=79@Q~TC2pSta7I{Ujx`-R4N-)dvlAxhJyqK&qx(a?#RC%;s zTG(9}?e=zGRgTZ$R-(zo)fT$FvZ;)=?x6ELnV zC|AFQzeD7-Z1@BOI}ik6n;NQ#?&DL*9{P1!Jk`JTlcx?2VEBFkX|B_TW=?~tjt zhjx0BF>St~T3B)kmn)CO;zvCJTo~>}XbIoZ@Rh|*8}m;n56M5!IG|O)sr;ZKh#Von zdeY_m_+sR$QO^Vs>JehFRtrC)dPU?c%&I12*YnK?p#ome`qrU5Z;sOln`Kp(4qXgr zr>~pNY9{ociX@VEYvQW!fPPL<;5nmJb&vMPeTpJOwn7tc^mxues%2dm-c{vX(3?EY zLvI<7kx3H8pH#Q)x)*c~;xoO;l_WtkR`nimk8~=HQBW=5pKu-i_JWO7$x6e&l;^f^ zMsIXV!)DvEo$ z@CzRgdKL-M$$K+%g8#cht`(QdgjPy74oG;_tn)EieOO^(%N7F=S27#Z^E2BLV}rhy zVw}luf$$8QX(+GBJo{o1>Zr_05S;^NufPL6#K_a$#^6cO1(Irz_1&hA#e*xeFc6&e z-4qs3oOmopVKoTmuFL`JSE%Ec>4I?~L9uu+G8&o(Iq17nmZ3ry$#)Vl=+JjJ4X1ui zl0To|hm6D$yw+c&ckt++B6h@ZmH=DF;@}jyMer{n5E&6H9WV0e7EdzaiqUlkD4LKXxAm1(>_qnPgYUSycx*wvy-eoTukEtVxI(+W}js7l$8O(|Wbojm-p2=$}%l8Ng{vFfKXy&q+|qh&fx z!=Ea>ev})Nl zC?R{vp+xq?_0}tA&p=X`F+PTk_hYq(`ucO;S>DQWp0_XbH? zWge+f-|pbz?g<2T^qE#b-xOuPA9;lQFhtWf`cYB`I|NL8`j*Dj^I-1yP>ZPI|3onQr>+xSj4CXkx%PO zCLpMAVu`Y=Vu1qXM{FQmmTeMwTx;Tpo`2wT;{5(7VNcJ&P4ZV`&&f49QwL5swTR@^ z=!MIsS!LbS6=n-Ig}7Cp1k>pivOkVNmAsHsky50v)m1lGDN*py*;Q<)8ENe3+g{N! zcWKd9roEpDY4POaYQ}%2v-q46!S%ycw-~?e$-033ZgZqrW5QEAG8c)HSx?3bFHP}> z6PD$L55Ee%WfdX%T=u40=8>11?No!o!u)9ZbM$D3uRkfnb`v$w7^Yx-2)amsU>^S_}tJT5v-> zZ*dj=APr*{BV$k;Ij)YggmwrtO&)4fk?a^@SM({G2%m&l_Ieu-RlB=veY-lg3{Fga2!c>e@JBqq zY$#urhS6>);FI;GVF}Un+Hy?nXq$)rDlZogp_l%({6vSE>bGL*lC)}!gNRF<81N$b zooQffks)24haSgwq>^kyL02+)&eQ>h5g{Wacj9D6;RmrxAIw&VPZ$^(dz^ha$ujd` z4|YJHi69>O2bG!;em|In6?(7?kKC!kd{MoVKUj?poB&VrgAupSCK>NeS#M$Y2tar< z^kScs(_cU!-aAe;3*2mWgQM#Nl_7*yw|xA+#Sk0z13atm9?WR$n268WYZ*e;&Cpq% zI691iwqJ*thhfXDq_0e^Fs~D|I73{>5en9no`ZrZZrD51q1E1FyGM5CPd54$=-Wsi z7ccvLs&C(agBTrmMhQ%b#beh?5r7=utdP)8_Ale)GJG(+stNp(;<#T2^=w*i#m39Q zSEnH(2Rwg*5u~i31DA{&sA?%GGO`y`cT>2DtE;DPYe~YH7!V&h!T6dm9?Hl-5SFEz z?sYZZnxx_t#Va&n*?Is+GXP&=x`%t46G&y|2S1vSr>r&9ntRA7#-0&6^(B5=<^yEgFQlNrn6>xbUI75>0CB_$WQhf%~GcRNP1 zBJ!EtLX~a}I(R>#&Y~JOLo-A(2impE(J$#j&ekSjgwrfkkG1X#jvd9Y$#J!AqH`8@9%Tr&^<(Hi@WFt8zu5Pp-Q#frGZ=&Nhy@hIUC zZBmIe+15_~#s=c=RT*d{TadFkXUlvsQQ34NyYy}3tv z@cM#&#aG<0@TsI$*T^5&C)Z{hggx#ahM zlis_`FAe5I+1c0Zo9ytNguElDP^IGu|fYOcP z&NY`DLRKCTc#rNg{eR^g%%;moyCgZeZe@NZ~tsf>T(-6Rlu{@+obmN3*rXdhd=S+CL{8M0fZH2vo`R-zKVgsA3o*9eyJaV%CqLY9ddJ9`xQUPX z==5nQkyqh$@$4)ChnHl?r#rHzYZFCFiA8cK5&4fC%2jTEQz;z*?|y?5to?ijY3L=1 zRNNtf5sHlOkMafKYBFlXV%{6?lnp>B7IhA^gziWMzS;1x{B^>1OGaH+Gb`ruL<$vZ zydX37=0c)2BE_&v5`HM^;cnz>gombchU_zCAnS;dspxptN<(oM4z66cjK$eR-$q;3fvLCd)olF=>JAl_Z+A0q;$oQ96$RE!QRkcP} zTi2wY4inXcO1}r(mgvwNx8V9fH;(X&j@HLIPB!db(e^BDbg`hmF#!Lf^m?DEhyEvR zwIEv#ugMN26&uIVSX&t37OlK2=UB^~2OY7{bpp_0EKI3qxqoS|^LPKvrLIq~aA((k=mymXo6WoDg&0))xU>-Rp0%Nw;0*B z?8=Fm*7ksfq&rKP^xJC6<2DMYF`oJh*7nUp9{2hqHd!$YVOvXx-_W)91%_>Rt3UXJ zf?9o{KR*|cElM5@PLqp5h@lKH2pOBBlnYE;^7oxj@j&;FcDYLQiMK4!0G%2imIY%b ze0t8_*B&&$i5-2vUhJHh0H5wQ-!t9e$hfBj-hSZ+o=9dp8kGf2#v3*5Ke$Kn1dX<> zrH4^WwBK;N@s_Ma7V?;^OHIHy;O+z!o`x15EN$^k>&rV_r^V%fj6>ifmt5vw$x`I{ zK%j}NG07vc#%YnI=kSc%SN1b_a6QKmaWocR-2-grcOy)Qi3!jDf&5Lpo8h`6d6Z3q z?~z_d5yr&%)C0=>IKi}|NK5s6+Ao9sqOC_!j*4U8yq~Q@kN(CD?p@f>;XTg}Jj8Av%WQSCJ&|!n&>}-28fd<<{DS~9{Oi#By z+^8mx7`Ns4qDZM^PO2TRhM*JeP*%6vo=oSI<+#%XyXKOK$U()A-gUDj& z;BzIn;m7z}?Hf#cDg*l4kE1{TDwZWwo$wE?NjBXrlA{`)2u7Xel0}s$a;i>->-~*O zXdq>e_*h8l^G!xxF}xpA@)>6OZ_x(fb+qyGe`g5(e=oIe%oIRfzqgA zln0mSRj~vf4PEP8QpxNJ9bDMW`qn%50cQ}f++O+h;BIoyk!C-=tA~Gpr56RcCW!pS zb$&tBi!}6MI65XdMOen$2uQk)HdtccW@hJ=M5h-T`TCVsyCLIjoG5CVZIB^u;gl^{ zBN?bW2;|Z|q|sK<05lCxqF%;(gip}%`WiBeDeRYxX$@<^gS@YvCmi+-QRbx zk6ih7@ngno`}6Kk>|U$ch#c18h+$MRWfWi9bB$W5?E!yYpBV*gyDju?{?{k587WY{@qm$Egj~ zdnF&MJ|?#`F3%YIBSCB%@baN2O}_KD!d0#z)hK){Pt-BFX-1p1%#uWX-(=An>-mhU z#qBRSFaDm#ss!tDw(_cC3BRiYbc-az=MJ2N90?rrgBMO5y~#q1tG`;}V4sU`m1WUu zhTQ0F5EBE@J-9erF3mADn;_HRjE^7A35b11wKgajwz9^PQAHZhr z;~?VH%?xi@#Y>pz@P?U~VW4o#QlP4>E;v9{c7`!Tcp$9Hp{}07nbqk+FJ8RT`VZWroq;;V{aU`B)A*pnzBbG)v84SP+K2lk9pZRW%0)0WoZ$K?Y?7Srq5_<83~EgFkhP~^M^;6JcVjKLyCw@jQ0<_+!F_HX;zzd#n97Gc%d@Jhsj9&l!C1zH*u!XOI=?d& zLM*SU4YqMLILz1kYjDJ)Jza>F`Ud&QyHZzmSDxFFQ-_mmJl{jXOhUXp6Ry8A6eptD z-l}|jXl&sBB}(@lDR{Dm`%bqYd~MQ+aLZtVjus|{x=?}d z+G0!YJJmuT<-i1NSQIsE#^=-! z(lYq*qUVpgN6+nveaP(;LlV*%`RJ%c@Sv({udZ${!_{GkEO8!Lh;knb?NO+*dLDW5 zU>^tSC`>CdkD^%lJ-6ObxNiHy5hlk@o}`=zLv=qwHfp8$+ZmOSmS!Nxn1??FcdW0K zI*2-cv7e=%FIo$mPwY|hfcor+-0akZ9v2!SL0%im+Q&*ai5V29J&y5XV`Ka&t|F~d z`-d)JgzAPg*8#1yYiyvFtF((h@HW|Eo*8?U=( zpE|rOvbB$uCzE1?KyWfiXoih1Sw+!2Pax52myOitviH$^PRhuL1#M>O-*m2r1svjj z;v-IJCmBuh9H=itf77`RBa5XrRK~sLPO>gWie=89$D}-ukNXvv2jqkW{CiM94?uyz z|A)!H7MQC4p4yN)@cO&J6ayt(Gfn-G^_ReOyCb+iZA$yveISaN>g{C_EITolLa4&K4PtjN>#!o36~NTD#!7pw)AZXSg672@;}vc z?U)Q_Na7GzT&q|b>Kbh3tIX{>uF@lV<{n={H|Ee6cYn=pHCARUqN;!YdOIsnQv~{@e#f}XL!8` z9B_7r6r&EiJrW@ji8o%(|GJ2VeJpes-q%+R*_{*eJ3zMf;_WOQp{q!PS`SYHKi3@y z$SJyB*shK*Ov(lN{Br;GfPpkCgV5NUi`Wu^^EjY~_WL3bgYv-dC?GfBu|74k7e~b_ zreGt>6s8cikI#DEGVL>=;Ve@V;~`v{lg2RKTH`#JQ2(GpG#jQF{D6GB84~kH&S?dv z2!Ae*$6b-a*=H6|TL5X$Chw9zf-Vm0#%a(^#yLqdCTecIi z$U6j59MI;=*U+$Llfj6P`mL-(Br~pT(vEGjF}JcUhE5#}3Y1;sWyY_|t>(DGr&DTw zG&FF?dM6%TMM3>aU3Fkoj{KPQ=7#wZEvJGyFP!v2&%p$#O4nCv&my^%YGDmn0;^rjc=YJ5_N|E@3sco~r5 zX)NeR&($!Ex^O%bg8blc^ff+Xf(>enekaY7KL28%DlI>s3P@ipM?U`EJ-;F!ZA3`+ zM5}u`U)@FmFQ#`^?mMHSPbH4^wyR9h4C52vf*!VM?Z0W@ws-|g*@#6ivL{5Z?;<{q zDJ>W$=b%@oxc*%KNx`%+aKOcnX?M1BDHppyVt^XzUg5jb}3$(h&hYu^s!r3~4KGHkl ze_rteQ)9a}r1`xWClZg4gWaTFhXG8)xzGp7J>+SJfe7_n__M(t%GSdm{>WV7SIWJ# zbBDna&EE)|#KG%Fhaplk%w!Mv+c|YHPBL^aN6RpZH$`g*gIP`R$vEZMD;GnHoEIqq zFR=JJ0)YTt9+gAM`)QUgepHukS6;HTTzgs6Zul8h%k56_t5+00n)b}*^3>(mAp6y)A@A5wj8sFf@x%MQ0w z8L>F4O`Y&w63SQ6Fn;>C)P_LaKT{jU;se(L)1RQEb#+dX#Ou^X|9)CmAG75BP&G?} zli+jLVrcBp|6u1Y{+nyRyU}s@^&cs0y9!;35H00PgjxGvu07I}l2D!nq+11SD=+O{ z+j)Z#IsE#OxNAHAC%POJSg29;^%+0hn+g!$NBi0FlUk^PKvw<{kq;Rtp~32J??)vi z3-Ngwy(QI8xpwW-!ZUob^GYKMY%)vAs$Kag3#}`!U3)$_^mSNbOSeHFX1Te~+~?15y0_zU)3i;NPLli0(Inmd*fM3DAv{bl zWf;x#VtM!#Y*HmP=lHv;#m!e0R+3RaPE)5KK{@ZhW=yDQ1r>+Gl<+*2nCvIIvgNAP z?jptDf()|69h69Zj*D519`N-(&zJh-5}gFH+xBA(w;#^(qI5PJI&?iJYi6mcOQai7 zG-D0STmYT}RfsilKZn^+H==3Jg~r8#4EXa(F@tJ~&lvE#@uj%9tkSe61lHdmwj7-w z5PG;w6I;cs;^l?fd1W^6XFmDhg7vV9pAYQ)TSs&=L|$z4_l6<>{>GGpgU!eCXZ!U` zR%gIAK_a6sM((s#dQ0gmfY8BiqAJP_16LOTekvL3ZYI(06KDF&#LEj&>XBE zq}%Etn-6Sm-OmX(v@E5KwYZW4qPPX*A}sxf2TQW@m=N^&ZrjU6rH1|`+(5I}Q+zXe z$HHrQhaU`SUiP;EtELEaSIlCp5v5B) zx`kor9+2+t?sfoaL_lvrL>amp0RiPV?!C`B_ukKWp6mBF%yq5Ln%8@+^)(acVj!7z zVW%h<8yu=HK{v2NOO2I56gR0F$2ghCBf2F6C--?c)*Vo9Q=GR4hEwrkKV>#M9|5{e zQczESuN8Gde`i_JgNjf!Hu$rUaqMmf8bUVw@uqid@E0xYxc+Ay?bsInm;Ioi*$QVz z&==>MfF{A4Gu5E)dHgI|ME9f3y`ZRL(iZ;L!LHu7WUkjeMO{+Q&%u%4M?Mo-3rfhf z>~PVJYkL-MQzR&_)x{TF{x%iW9b$1L{;}GAMrnmjG9VmioFB*gjT@=kN!1pO#U2dN zIw_C2)7()e8U}-}pdHdmRV@O>@Yl|>m3i3t&+!r}jUJ*pXb>s?gWyfL`-i^6s4cR4 zAJ#Il?p1rwIJ?G(SJ)r~AGID|Ti)t0*^MPz5W(- zQ`pVM)DDuKRaBhglpj}I8UH5P%#OUGs>%CKl8aq%bC=8O+A^xf?stz^>8N~xK*+#^ zD~vH@tn)euC*X>aklXsqXB5lL^uMk=PR>b-O01YPu8$95} z)n)kGYxLnX9~!F6?R>HaZJ!wF42>4ZU3wPZvbwpQ(RcAodb*{~E z`+K(v(ow6+4tjpjseyv_8j|smuVM-R8etQ$*;@hp*vKd`*$?UxJ5`u#-G)pq2LISk z=!+gY1k3uWZ_Rv_xdvYNDIBhTbiVGr{3Z68s7@*1;{83)>+5zU+%(cgPbmMzoh;%UE&#g0H()RQRj^?WV{xq?FU z928b4s9s^4=WcW{2u#y~3b0ZGCi%j0>H5lTXrCnBE$~%32&$aGzC;6UnVZVUNk1jp zlV?xd>;)FLAh!iOkJij;g-FLVh(>$x=%(uBQ5DDgdz{Uv#8dKH8Ur%sU=`tvkx3`03=dr zaAF0kG>9=1+G^Ghn5mLRb|ocZUJVsvpQ*R82eP|zP?KaJM??LesrQ>JFprE-ja-qA zn^YN(4#nffK|n=nm18bZc{4W(0`~hVljqZY4UO9I7)ffqSA92Q)n;6Ocs(__=|1AS z!E8N~$$)t&dzY_GYBsFu*JA&}Mv=35_nBWxVDDPA*F3`#nGz8#66?~+rtcgC^r`*Q z`-KaMm1cmCBl?IUUwu&;h53tw0i8IU)|LbimonEB)}_dw>oJ9SD4Y|rZg!=x@XQ^` zt(MRMi~IWPC3S6X9u{ZKi}NJu&jjGl>goagMA-h3pMvRLI~Tl_Lp94MVfqieHhm*% zIw7<1^}fdo!GV6%<%uQ%P$+4o0y+J7k0RM{Zea7p@p|p`@2j(Yd|aLspD_8w2AQoyw~}iNISyj_$C+iq;Ntl@fP<5ZKQ9=CnREGFUeq@xZ7`aavfE*T` zl&pt%WQCXOHz~P!LI{XmW_EsAxse*9TS-nueN=3GaaLVJyN4)Ev#VcvN1v@IT_`Ht zrGM;+7^KHNylwoGO4m>j_OGwXg;AMQALo|^XQJm;Hdk3ctY>W<@D9u_L>!)p#wBl@ z9f($6I{i24<0mLQ8rsGsHRVdH51td+Wkjjc!rWB-R?`K$C~IorxwbYCpat>4pSz&Eh#u2s+0~&-)gd>%==WR zln>(fmHI28RHfe|`^L@8;re<^fP50%(Wqh=@Wdn2Kxx{6`5{gv<)-24)z4%ob>4&Pdm!0ld@9Ix zp{6Osi_@p#jhF3G7kqPirt#ICfB{0vv(*o!@p4@e7Z<-0(SEnzohiKnrc9x(DG2v4 zxe#LBw0j})l4T&tEseAt__9XoX>jd)6=JF@vqhdHbNc9mC90G zSmi7W0t-4n0RlA4XjR}OeM{3sRWD^6ex)jT;i?dafb=8jIsiA2aIGcOjS=Dz;_DM< zXPtR?%qUJG;a1CK>45maha_zhl>Z>%4h8EaO41S3=}H(W2ZEG%9uz)o=F#eRKr!C0 zbZzbnL?XllpUxb5P)LU_xe1dR<6kqIKqPWbsVduGs{CDd?6>x$?wIdosv_f`8vMy* zx-D)ldvzXiv&%@a3fHL5@J*6I78reE`xY-JMt@Ej=#gJsZxp3E$=&#e*-uGL0Bl!- zXM^6s9PVp?s0^_eRgIZ>ot);WdDy+Gj@RgwCo(xQQ20BYoI`$nQ@b7=2n9 z{8K0V&Zi(uj4hl6JYY*Kb3qZSoX52}mqsk;I}&4n<*NG3@Qw=JK0H6S+|POI4~Fx<947Lly+|=W8@vN>waw;6v+e6^lw?nbWoDUi@_ng% zLUl+`OPEbliO|%|FirSPU=24IsW9&NkSbVb1?RHseY`iF+O4_<2@!Ztb>oe{po5iE zHFn(5;ARG&{~CGO&)x@`H?Z6)|cAT;Ox<+YHQjhDO+xf3cf%EI07ArJte z!@mSN`s5+H04jg{OCXY#5ucr3TE!-3VKlWugKRXy0LS*dqXLtnn%LVt4ZPFz^K%?e4v)U5AucWeV0XZF_`mYSMR zufztDch0*Dj~=|Z8FZ$gJIohud^=?H;OQ36B8RG(*raxdze1j3&YHokY{*C6GL4`s@~s59wX*AKSz2H^;8)6t8cU5KMe#2Ux~;E; z!Di$NR|R`I*gMh>pts`zEUIlb6t+F&o48HBmx#WAIDB@zbb;x&6mS70WGAh3?E|^@ zFpv5$ncXz_Ata9=m?!UyJ+!g9ZV?7ZL~w*F9F+Ej3yg7(yO?D0TuzM+amM}8JNMG#z>4O!>qv?af_{Y4F$|)iM zcp=$MPl3K<(;D^?@`?13zBhIyb!+5~9p&gmmmK6O)MG9Zl<3n_&l9UeET^0h5NB49 z4~`KS$l*Ss=P!7ujo^qOmR^~#&EGP z!W4y{j=_xEN`{OY5q0!E3aa8pz=Z|-sh;iB=N)Vjx+Q_As@X=uT$Qfb)EflDYF!y{ zJ4_48pR!vNLWJ%$TRk6fWFADjiWqN+f`ZyjyO@UFtf1>fnZI{@Rr4a$r#cY$6=42~ z`KO{LqT7Udeh6EN)Yj-tk*V5&9HY^D16)m)(EfYqD;>L5bi5H?ljK@DqAQo8s}w1)A5<1G7z6QPXYu&f6k4NlqFN($No_ zZ_AT#NsWyf@4o-Ut^C}T|LNP7A79$wILWWhLwKVP_dIA}_FQ;w1tvDu1rk90AN3Lu z&sIBt#l5Q3L6Ol|)MCX^EC?4MsiO??eG}0Jo3Rd1SrA0xWUoUrXD)g-1R2;*p#{`h zo+LBoH3Wq1)4DSCW%3iCFKY%E`OuiR=069tgT&OL^ZaSD)pC__ z{nGi!)6bbT{dKio*LR8JuSI|V+$gR6eX-NJ|NHV_NbLIRWaicNuk*hf{c9R$ATh$! z7g&@9c#0(~dM@fXb&Nc>MJfE^s3V$>ULbUUwl@QCesg6Y;_Q3xFO6I(@t^HK>4uZrZ-1v= zfZyG|e@Lbr^Obf8&@1RDPWm_o$JWPidyw~5Zw#}ZIoYQTKI*~V2nYLoYU0TO(e^_! zhm$wVna*m5e^C+1RAV-cCK#vRDsLlizx3Q=fRl!|+l(sqRvP_Y{}&Y^fC6j3a! zC7^6_LyxE;D;E(j8~l8bB5nNNOAAE9qf{rZ_|ihD%&(LC=N@lTq`Qg%`LYw22~}A~ z7JWkY@W1uZSO6sdhqMcCcITMOO8%0~U26WAh?;DZ_qnsk*Zv-+{V@ICU zzw<@=j7~j+p)CJg@FQMziXUs@O+M6f3IJK39^ZU&Uiti+hFkuTpWY~ED`n>NJ^u7my1d04 z@tl^rQiy`4!j%m7ar={Tm~KY3luA{ZjeVfwY~2v0N|1}zRP&sWSY5X9|9gJys2h)PnZ6&1(nymynbzezTn7VuoK zC561v&adG$4>BCk5p-CC9&tSQW=QU@8*nvqz(K93`f9H$;uU3kxts6rU~jbjubgXi2B?D6U_7-vu#orh&qFV{AEL!ZkQf3aW;@rRcF= z2rd#}QUn*BI4kyRoXGj`a=bzv!?HJ08_At0n^Ctyp;vE|NQeeKJ$EQ6Eb@Z6B7gB1p9 zNX7;Pcu*c%81JjR84qZCS}x$_R6#_bYHTzL1hUT&luhLs5%OkObG?KyxL+uN;QIF> zLBtUJz*qIDUIhcx_#mpf$ZCU;q_+d4#73yVuiO~HjTC0%=mSXpA{1HWZyX`U_RG~=jEz8V zT8NoQ&lSN;lKGc&cTNG~72mpnF{m@!zp@^(lG1lLL_FzduSZaasbk`DTT&W(4KThp zTAJiP+JvlfAOcE)r;cHA1krA6D)AhR6iNhche8yFy~n@HVmjU zCSvZ%-bHm!_FIH8(Y^JcD8u=nAufKD>=Htc^=J5tn<(>ZM*a@Rw$j4NJfAItykSo$ zseg^x3Jig%gogy;TA&z1VNZ&^hPb}%;g|Ek!^A9|qdottnpWWW+eQBcV(tCGFJ&t5 zZraaar#>Qg6OPU^xG}2x3>#G^3mq=}zf1f7FdUq`f-ca^aUVsCFrKH{2>KzQO9W5L zgHC|&5XICI(#^9G;QxFs?uvydpPS-zWe906s$Z)hIDXL}``GFZUQ4{|1IU!s@0oFg z(`)wvSZAdfa>@dbpU~eX*Mn|QErtag=Q9{TDd&#rjZFF4Pel-Zmy^Ne)pKSv%_ZHv zISypPD=X4I#@<MUP4B*a%pR}6U_q$?P^Y1hxWCAy z!uBggU3>=-ar?>20=Gtp%I{YIldG>RBXt@V)h>|qtFNqqNDZviG)zI*l#e4F{cEQ- zsnpzx#MGzvA+Zid@d?jw2aR4~e~Ab;VN?EPwJ~a%U5d}?=zw?|v&W6su3w&L5wcPTwPvmXQ#~G-tpT!*^pzlg z3-14~a=+Cb#WPkg{r#W&+ZCxp$}TeS#3HH$%BK$4Kl|I7CaU3t09_(gNcg~?{q5U3 z4+}^D+~#Hb3qhD#1P_C-xux_FNgjr&?ddsZ!>@+j1LvP3@6y+ObEYE$PZVp_H}{mv zCAiI#xN?sqbw0fn!r$2bUeVkq1uUmlC03Z3fA691z~-mN4{F04?_zh#TkUcw4>+VT z0BU#oqSpBj?M3ymf93HpP*}U9i+c8v_LjBK7?Z=$e2XY zP{ldpLKamIABHmDI>%8kCf1on*klcZBDm@zmMBD{CRs^<+-ZGiu?$l#5$f@@Wg5i_ zxJBTd0&z9{@CwhP2KY+SJDEtUlxKs5R;l`cnfYYX23J73)zN_! zIW;ofn(47l{Ys_?Gscq9ep+KS%Qq2jBl_CF4V7v48~P~ky*2=l5g{sJ`|`~%=hCNt zg7)B41Kn7#0QbR)vXAGxP4bXYJe2p}%Ci$;WdLM{6j$JLnT69z$d@$@OF^Y)$g}jD63v$BY5T~0kJ)I)LLP2sUz@0D2}gnTdvyNu5z9N<=*#`#!&n`Gg0`Miw-AfsVmn1XQ6JGUXqNw zP|c^w#2u zt(V;VY657T7j^MP|5F01izybi(HJwDJ4$IAU-g2OkKsht6FzCd#d3!#H8ejwPBs2s zOfGO+EC26hT~@p;|3BFKRyX3mh>Jtj6MTIB+{Is5>>o1`nc^h)_+mxXV}%Stt5h_ez9FG@Vvn4)tUbcw;X zlUgQDuOB$tB5Mbe+t3QSTlV~u+NzQ7UTln64zdl#{A4~lKCe%`m#~N@E?FLl7H^Z; zrD6Wik452b@hg*6Bh&r$QE;E54Dd<8f>Odbf4UV8k?^ z%UhVqt}=e`aUcapoO}(`=R}(eLli=bN%yMAm`;is#{~CP3jNi7J`cWy5bFv#yRj$F zFf%<+3HO`&$>6#&c;DUH+y3W4sVt#9b$=HZGNq}&FQJEnueswd5u?r=tF^|>FWOFS zi!YU1vlcpBY))NqDCeiW+01FqS&xr+sd=$ZqMxJXjCPFEcY=MXnQ2l3O2V-m0(~?Ejjon#zR`fQDoJ__S^EuBpz-^Khg@qUXcG z!tCB?cPiH@Qy7hP8ra5LpEfs~U%xJ&jO+lz2BS<&Qzqn79uD&oC5Cg6u#_N|BScR< zmmvajhpc3>r?y-$B~i3W^z9tyBB;g@92<4N#mgc|PP?5TR%$T9idp|VmM8K-)PYrU zSCS7e8Gtm>T7s;`4)W$zpI2^Hm^OAf^VX8ASvLQUPiQ8pv04GL$B5L3aBcT5z ziXzK(MgS>Goe!wCY8v+WNdhP9g&9+44u?qQI!A`bxiQW?8EsnR5g2{rzJV|Xcta4; zoAINGM-Ru3KOn&(CzGmvvq3<7Nmzmvj&BOTf6RN3GUkOmpd--job7#YkHGapAH3~! zhtfM#y&L5<#x#dp2kMi{eN`&T9hrC!~{f;x3$v=f^H}vRvK^S25&T~P8uye=Mc~fuTddxDEjx>D zO1HOG-4=gsM~HF!?p)`p`gLOgEYeOtf9?PJ;PB2=z~oPS4t_-n%Q75eJFq>snKu*) z=-Cc@?roCKK1>7!jRt`fScsE#kvfhTFkKZjQ7*hs`djUjQmwojI{Z!KYdF-PN)U;k zbYFJU$*RlXMBRNDcluvK=%2(E!lm{PPC^@&gfN^aQz`v(3|$yoJ^%p|U3_(FEoNxW;5zk}*QmP)h}mO2 zEU^rVjVVg7S)@Ot);BsEUTzDi2_7V|xrf zAsNsLN$%+PFb-`2l)W3XYDR_kjZYf}M`J(ErgsemPJUUqBi0jx?=ux5=05=H@d&&q zwe{Bi4=%Cl*w&w?d-hvFyLTnE!WAhc&(JwtfMq%~HMk-RA9_6B+;(>{AB&1L=IBp8m6_ZZM)#G2{m!vHn%-bw3f z8FHB=FVEp+`cH|I=MFt-?ew2Xb(&ih{`L4_eSc!o-Nsk!Mvs|5tP&TVpTpX|v3FEw z!uAb}{Ud)$WeOu2d$ZQ|q)2Bz<*UXNa}2tYOf3yJ@G?D$Va&AVxZLm*{rOaNleHBT zGeL`MvYV_heCEPJh;*Q9(wa|vUECWquSi~X`=OlFzA%~MmFUf@w&Io1p#3ywY`f^j zRK0s$K=wOV6*gY=^*wNB#J);JVB3Agq@Tyjk0oE3{3i5e|C;=f{zt&OU+hb}V9mha z1757q9jI;iwXgiujB)^2P$nk$DBUzK1PPx7h4O2g_W3iAbD&_PDT`(i`&s84QCX8f z&gjI+{3WPZUt52KKoTS*j+fBZf`T4(OBDeB9Welk9xqcy->c}uH=AxjS?Qz{1y(7v z$sevHKeIDrN>w(hFQ#~k9#KwLjEO8xx1<81GG5h<5M(gDe8`pRE?Uk_M}H%o5B6%b z{6QvK$AafsXh8aggjdGYda|?V);uuq!l$fAg;2K7ic@M-nTXpMTh33piA&NnL9hNI|eg31`|SV+4@XKD=@0TucRM;XMx3fnoFpm(Bu!dx9; z=7QHOlcN&5oP(Oh`NC5LQ;z)5PxZSYDKR9P?H>G>L+xp0T0&6j5c%+~RAc%5lFNxl zj&I8mfI8u!IY|J?L6o@|-E~x-6CKz-Q>!TmLX^st!5ps~*y>(W40*Rw&RLdGl;!M~#32hUsOeS0;NhQ!>OQZlY< zO>zgL8;2!7_M*PZWy*Qn@TPD?;tY~TrAaWydC1i_1XC_+SzdcT*Ym0-d4z%G?R=X@s|IV~_noz_e(^Hj2z+7XOkGY1Vgukq4sP@K4dduV@K`A4qgsai{K=0WNo#&JcVxQvUie zfW3MnJS+nGJ`m1zgK+iiHj*E10O9T<62FU-W6;%Ml4M&TEDPQJ6%#_k%mGzy3#J$q z2zZ)?`(}jgqx_`%h*wzUly?YuqXpx}B1{03kf~+obtaS_{|43FxJjRb43o9sgcr@; zWPtVh#mNWL2BoNQ;vnv~X_Ohl@2Psz>bm%Q=yAe2(mKWB_F@DXEOv2_PKk?{SOu)b z`bry!k9<7tiC!T)Sb*?0Ixa3m0Z8|%bwE{c3KJJo#LcIn@wvVJAL|J$n?v{U>j}pl zmOS!bWK}!Jqv{LO1fI33f0d&0l#y84ZRuD0!eg3TMX&->{u{;kBgP~DA;!Yn-I~He zY~TJxG0O22BmWP@Pz`aW5xJH3=PP2x2reoNj1Zs|wfcu*^enohUurU2{7I(x($EmL zu6wF(qk_t7m{@l)8Y;gC(}1|tG(C)ip~;_esYs?xPC;oIH|C9XNqKF0 zXqK%>bX{vOqS4jFrR}XN0uuCsDiAwtAVyy09yv1kxFM!_>hqnk_Z}}GLo*Aabe-=2 zEx2{TFL56>c0*wOsX(fpy;IhNw3^ei@eAPLd2=VV^S3Tv&|5M_wfpGy5ZJNR9Qg2t zqT?q#+=5I5zm2>hD|mHYn>TF9Dt=AA?3=|9mVo9^5?=FvwPM@Cg%Aa*LbP3~vBZVobPZhkwr zN0>+FR6*w2D&EXQk4bg)PgpG;xOq_BYt=<~Zppx4E)>Wp?U^d&aGic zaf9=ORMQ4JDMRxn%meTPI`h1%D#bNVe-+SJ{z>#E@Qh-h!p-E%{gPn2#qIu&@--0pFp!sUgCGcGkdSi?BbG>04u+CT=LI}heL@*R7Y9({ntnZL7RJMX?MM61 z>#{}2V7v*?vRQ4QF#d`%WrCS{09TaUu)1=rjQRGO=HYRC5`;#S5=Hd<~@y+{zj&Pl-LjeVTo_!uxA7AKKc zUi3BsrUeROmWwEO?0q98sw$CQ7Cfye|Mfc2nv-eY_LbW3CvZ z*>z-1<&wo3t`I)RTdIs45op~x8bb^TH@dNKV;dN6E$rBUd(3Y{e1IYIj?-Drwei%K z{W*G)&B7MAHE8p#X}z|8K9 zvxKNH3M!!x!{NLxh&qT0)a#2Oz>(|o*Ajonq50TRq$<(?nj9SqNy(>hH_Y3&`HOxM zDg_kA>auJX*hp~|cG|EsiDM1?*Qgp7DUxJvikzY%o3wx=9EPf{)VhaOHVVDuD&V_A zE(u=Q_RFw38CiinTDkGv|{qG=tT{B?+7-d^5b@s?8xhzoJ|e-75PlY9L8?*YMo%JAvGd1414UuWjd zf91dVg=o}>m6!!gyZ;n{_AF^a2mvyW??A%){y>VBv_6hPt%jiDC$j;LX4%34P$t6c8*YLuy$xxZb?bLNl|H4 za=B?`b;D}}jg^BShbE{)}SKkW+xj&}3fAqFfCM^h!B7BH8d-E5{Z zCvP1M2R{PdYEQ=(S1{QJJREf%tlI-R8pkN8;~>*YGVuPs#b@rr~8BBb8&g8Gqq z5&SIgo%an*~$H|8Pi(d^ z!uh-f(Cyy_R|(Dwf#j6RIN{$xzupWw)8joLzha$Tu?A-tqz zW+c#^!G5%`w@d+q-KeF2UgUz0lWDmdVjeAnOY4gf3-CtANdY32!*16A@-e??NA983 zZ={Dr-AbG+O3coawu(?a!tf;XBE5K^Qei{Iu!+}Sh?BTj53JIN7QIl-M_#rE8|GEQc+*_OaydOIN@Ynt*F{m1StLr}Bg)>eGnH={Q-kK_hX0@X`A zl~hejL}hGns;_E|_8QUj*Uj17Bq_}Src7nRLl+k!(7s2HobtNjm_7<*?%`eUJlbW? z=!3EqvbHp&Q?*M2e&9rY-M1Z9k>M&x_O@?Beuou;Uj*<6_8%Wa|ClhZOQdZz$5wp5 zD?HJ4e)zSn!_iy&XoSDC>S$E>j|{h1jfahM^I=gSTI3{n0zMg210^+{SB(r#+`gH` zLi1X=Qw#DO4OENYbce#Uja5L*g4rN~hip^ZxQ?HiOFd zVH2)_NJ%D_nP0$Rxs9ooIrr^@mhZRx@1HM5@YUc8pVI#?8E%6$X<;`@L}ffzS&OQb zaT%?O4bU3B3G5C(94o!d%AljN8|!y)2J2xHy_&?Z?W-QT666x@MD9=Y1A@1AfqQbK zxe_PFq?og@nGad#XWF{)ZKraGT-S3)(?HiBFVaXGkDp^|8!nir;(n8#zv&9RxL8)X z{`BK5GpVyNcm?>&pase2yl-_Xw6LWcCU&bW-jaUu0TV2Z@7zNSy{*+tL}aZXE$M7U zd({V#mqvj{MS^%S3lN!e5r(KbLLt>JP!A-4V)T8e<|J+jpPSn39giS(pC^39j^gPM z4sE=_LgLUS%f=cP_TUXO?R|FD;oV6h^-o{vpCSfrI)GEe&tsS=4eRc8Kb<0a=5J1w zb>4nc^N_%CPKT2lYRs*!$%32f5~tZAUb8dXbxf5 ze#e*GGv{3v%f5OA!c&JLe}$QbKmesQ_wU+EhPS{!{!@E%l=0zg*`(Ef@rd)thZ2e0 zrtMeiS&;BJ^*`ZkwsAB@(h$JUqlLG?qG{omyFl(+e-3$lG;wtZ08;yp1?GB5_u#QV zISg-stzOdj8u$mqrKBo(`B(yhRDo&v1$rC2iBnXOdXEgugkhXnOKrmDF zbBA;BqJg+my!KYzn&ui#9yB`ggEktf2GH0ab^LTHm`H=!N+_S-w4TTZMenJ~HswCb z40Bd&j$D6UReq~ciZ;q4IrW}l=jj|mzxc@uCVUgmkIwO4u48ohngl zdbUo#sfkb`b~DrV;MyVy|1_}*=@=&Yd#V~KmNt=r2SFA;U7N?{<-Q$M`Os|86lj3) zXFCAhjLoA;y1tGd$%s;$@CwJy(V*`gHiyKl^DE9vDgpF19?b0&v(za!?*N%1T-T>r zr05@hQ#;wIyydW7(@x;+^zFIv9TSn;(fd2#Ser$~yG_vcta;;)CfOhBg< z6DWW#g7`X6nfqKR09K)^1l!KfUQY%l( zf<;uM#B@|VX)xmCVXt~ou$c-qM(_)z{_cpXEP!jR*7V(ovg3y_$g5VTkRnJL{CYcr zubW41aP9JU-?|5AL9A+$5H2M?5fve&X|EEemC1DE+DzQo>uej;+V9qnfr<89oo?g5 zoCy{_z+QQp0tiSM>S}4xyj_SSmh&4BLQer_(d4}vt` zT`dpHU)yrjP4{wpgt~L52*^xOaPXF9tR6D{MVTFc@}%-d=h1s3o2HaV-=BQ^*CEgG z$6rrus(*Yo_S*e1V;U}UI%}Egc>2Y*^mQ$mey6GhLeCATh7gYXc}$3s0-B~o#A2lg z+*<3TKN!G~jZ+eL{MxXQ)Rf+Dbx6d$8(0-sRhNIyWs5DOXz3iR+;L!XzFu{=&DkBb zbywuyK$6yZw-n6;$?gQzDe`=GosC)Du`J8s*?)T8P?>293_?f+8V?nM=f7oD&uq;`h1wD1lU?(?h2-21KS^AKAfEKGBqBqN zg7ar}ZU42eVm@<&|DXFR|6Je_V*y9%5fuDoysAQ1pRF15@GC84FP#{#XZ3v@;}ELX ze~-Aa0`T*6fd8QJzZwT5X*KN4po|Y=RZ9bK;D z60M^G@w7nDhsrLepsZY#)z`hWqAoSTv$nnkB~Je4WmHP*+m}Y2T>w|?khOSmQ1kFa z1}k|mKGYoZVOC)@);agff=FoGr_Z=GA;j1`pl5wgjFqMz^=W$ltnxwpr>*n#%{1J( zTdECfBj7u+xsWC1g;Xfc)Vbpw#gcSnx}cHqM*c!i7?TBX93oLvkpR@X&QJ|aEErAB zH;SW%P%{joqF&C$oF*FTWVePajss2%V{%I1bYyc0obQV{3uS*ml6i!RvO%+zFs%|5 zPh&@^MT1?VC;Ci-Ky~k1kByX8##?Bc7k60#9M%i0476)rba(-iF8#)w9zk~@UnR0= z>z6EIst>fT+7NUv(Z3ABXwxaOsxz}a)`Gq~*r;$O&h_NT)5A;&l)ZjRrhm&(AIv+y z2J>sZ`>pYHKk1~BjBeH7uOB*!a9KBDup*%v^{=0KpS^g6TXU*qpzHIFkNLzE{WFfn z$2(Q-pu2sAW-T&(KirSFJUszBnk+sK2w;W1qmOVBvOQx%fwt;Qu3={^Wed;AjiyW~ zJ~kswLkb9;7s*M?pA3b`Yj2o&as?Ec;XkPY8KecfmlaTO_C&xU3{iYsFmauP6i7>Fr-hkU+T^}*U&n5hf|U7-aeO6j+Mo6S>7_Y&d~Voq9o{^afS< zg019JLi~YoPqsyRGo&4EHP+0jgF0c++C*oV4CDGy1N+_U=2`2?-IjUJ?cLT^d~>_e z9chZK{2WjLXn)Co*-qNX!R){%bKqiSJ8`;7JqE}Fr-bR0gY_;R%grEi(yKA9w=j=9w5f{R987{u|dAmmxOwD}rYBRzRsWXX=01R6H#>9+#YPIDRj)UUfX7 z@ZacG_3ILlVBL59Iab^cS4)!7z7qr-Du8>8=on`A0SJS4ltvZc&QfhK+iHRlmQ=?9 zfbE@~pf3uf2jXq4{G^2QGoH5zXYpCXcK~gn%OB+wm$&cY@{eAJeyi+p90G*Bn!9zw zx7MhgHYPYjme$*3^PJ`F%S$}lcYEfCU`M(6$!$bDYrj~2L-M`7Hlb7Ta^bs^;=r!n zix;7LhJpbD0Onx9tGR^>MWO>k!E3Lb&vbVPj}2SML*{YHCZWf9pMMkluokPFpHK_yagaspZ}7P!rv$*OKD4wTBP}RYWlzEpuMlN z@PGYXhY0=IXX3ZwPx(itAeoi@VF8R#l{|XsAAi^RiIl3JQ>x>4JFKH90nY)b?=Ac1 zS0ffKNj^X-h=y-ymOC9pwjXBl&wvSKA^$cU(J*U5j`uB~*&*8F% z!rT}a*ZpAMuv8rz8>~?Yqx<`;%i#uVKh__RnQik zA&gXm0m_e?B3``!#4@EmPqHMk95&;+eVw7uE@agcBOKYz4Zg`M7RtafXZ#qm(wg0L z#pnQT;$e=zj%vtA4=;F>GjT-uT5ha=DiWCZ=y`L*{Dd-lm3%F_pFDoTI-|>?G zhc7Y39a-OVDgK^5QmEktbj};HnJ(7*8qqx#<@mM1Ytl)=OnL8VXS(}2*;Taa5^;Oe z?>c7LQk`h>Oru5s<}oe`Hkit=EwPk_3}-DTNQlWPv-DOK$kY05gzo~!0P zz1g=Pf_tKVT@ekN5XmKh@411dk+^Fz$c;rUQvm<<7nCef4w#z;49 z8vfW=MmeG*0g@KUmX}80D=2DR5FM(`unb|#@#YejZ5i(Olds_i#VXYtaU_Im11w_b zI0c~L+@en{J-Br2c;s%qu$u%TU&=;#zYwiAr7*n+ofC$W5?hfI8=LB-zEyHA;U)DJ z;1i-{IG_P$6fu@S$x?j6GYeNV=(8L@mDA^j=`)UGg>mPB3*8wJYeo?*4|$4x;iHkc z-ZHS1(o9r^enfhUlHlWVy1q@0%9os*xhcP8Ns4?KE=mgu(<-d0+~=YyAJsk@5E8)d zApimcI-nqM6Z6-5jmW<=&95uDb)SJ+w4Ze5w0!Z_;%qCL_hD;WiRuG1wL~om1&$S9 zceztx>W&?|Yn`;f!>#|ajD+-8s$eJs!k!8Cq0$QUqoRHfLMo$R1*Qzd2vh7w>55~0 zHA%|{l)~ow=vXo_4KR{zdsl9e^{>5krv47jtc(k!gM&bPf0I@6dj9T&GKEoJnh<^U z$+Wig?*H2|QWB6+q#l5GqNF$;k1eG&>>)U&OYn^?a z^EbTL?|$#+dF~)DBRcTi6hqUP&0C#&)UE3hBE<&X>S>O*^Z-QmyJ9e(f|LB)2yy5z zIlDOd_|3it`IpxWZesS+5Hgf`tnyM~K4UH@|VZsM#hwCc@_cR&-s( zx)Zpxf|@_ASI~Yh`EVX2%>8tOb*ESG+1*O7;XjRCJtE@^gk5Br};J{_Zbb^i`+%`gJ?$o10|M!vQrPh0)U za4u7B`aD!K{SE0TOUWa%mxfvyDO7(4O(=#up8tK$RzUoTFEt8>7P#4dyG5hy<*55f zh42CP+VU_`y?>dYRc8ph4sZZa92Z5NbbswIm8)l(z1z*6wt-sBU#fbfFxEE?0VuJ$ zKCvjq`sPSO2G!L75*vmmCaFcbnIPlH7|vpom^Puu1V4#S=(VN-89%e zVu}3tx$E0EzJ}zji|;L2h?}FSO)ETDCLtnmj#RK1uqqr(Q1&sV2&^MxMez0VHrGSAm|)ows`+Z?(kYGm&7d^(Gb{d@?#eWr8xrJLL+8X;Y9Z;7R=LWd zX#88VIr@&TS4Jl{WXDsTagh5G;uL^{J|=&#S>86a$ungw#qa#1{JFzCP-~XjfI)Mz z&<;O!da7Yxjv@ucw=eTA5~m%_z7!gHG)*nZfI>nJ@87eh*9{ewzw-x^;Q&+(?iU{q%tk>E%U} zpCtnrt$la-B`W(C>5nrF^w-zL%i%rEIbIHk)wxTDf6quHAV5`o$M8|Iwa6NT&d9~+ zE_-G3%Ww$*-5M!Ns~jjIXI2w>-?Y7G9V}9+ydLfK3&s@NNX@sdBNsQ7|4G!L-_19rc~3zV7-LLuiJQa&*= z*;?MR#4nAxl$FFpKDeYv4Z@0@$x*wL7>~Ffs_gXsT>28L`nXiRV=m5GZU7-*UCl9w z2&`a~_aL~foT!|zrfiv-GieI@Eoal11h9&1iD`|;xXt7CkJ`Rj6MSnwpR)SaakW+U zt&^pE|2YU>)58?6QQZJZ3%S}qYIbld;HxL%t>yYa%U9lA$EikVAAgs#8{PlXC}XgT zbN~n(e8qx1q$PCzdDP{RL@&^Zt0~@x!<4M!H_C&)TRq0L5z&n!j%9QHNsjgZ37WK< zKrCFq!Rc2Tofu@hjrt)F+d5tO{FB8%q!ix6FJ3N0Sm4NdkPBwc{(#i?6=6i4aol}=ciI#8a)z{b8{n_28mtT~seo5EAD)=ppUcOqvMzh0E z?h_macYh9WJ_G}NCj_!!+C^30@O^#0`7Od|%mu-n8&F7N!Z`R7-nb9AgVB=HU9uN|KX)vLdvegEhGHR^p>VdHyHI zRGomKuzK(rlgnR8*ZcPpD5>PRLlw_fzKr1Yl~WEzC_jv$%8{*p{CAZU6fpeHtz?WiT zOE?Q{@gDc-g1uD1>>drhfe` z+X%?m#}{B24wrfM_1xv*t}G6Gn2>5u@N2A#Tv^y0I-yAYjm`}$_c~E+Mh{S(82ElF zvC7-(xsAC;sj`l)a{=fWL2fn(Ma{nmCECtg0~vthz5t9g69ERJOR8g0 zji(ZHDR1Rm;8S&>SjJFn7_lf0JzL>h6b;G6=RLL>t&vWF)v$HR7O#WG&xUUHD*a{W z5|tb+q}wBpC9_q;uCsO}MK$fbH@}=7rdJbyqUG924>v-U%rmp(u|$@itJyu3L8t#X zzu)z|M)bqv&2J$RI`^$RU~DX0mH@h2+7sp(5)Y`X9IZElGTZ9?9bK?ekd-+be(=-t z?bQ&bLIcClCxRilJam=KQ=vR8Dh3gPL0=eXVU=#ikzJz{h5!kcTq9E&Pc#47>%!miqvu9#$6Tfx8t3rvwuFYPTPe~s=6_62xl}e0#BE=TmZ8KrTOr>2$~Q~) zbY2xJ;^%sx8MSo79~~`3{OHq>WP1471ke56!%^+qp1o_!<(_k($9T_Cbohx_KWHVB z|Aac5mwS)dUcdV0fJe~>GNbBoi+{?P;RBicGJUHA?~FXO)5g*9y*^4rlU9!-?|RTd zt_S$=v*5Ng_vt=9`p?J+ZiwGV0If7V{+|d?y?rFf!vx$1>P3{I)^FD0Q>sC3{BnXY zWBft-zRv@agnECM=>IQRmyWLg zy`WAi{eyMlq@hWyk^!T~%{uZj*1pSsu+E)Y;WdEx6~;MhA`Nj-0}=~{#Kys;$$T*y zQD}TdCbveiQ7SYrt1v4u$2hN`s4|2P?3h>85GfvXwK$od z#dD>OD(u)8j%YyH=i1#Z7o`#6;juE4-}IH=@(|66agZ85kx~rpLY0&mOzO#o$Tz!w zox;ui)=G9WHF!8&c$b6k{bao zU&Q7`1(gOT6`IKq0$QTFwJt_~Gu0?AH%0LQoo%ROGoCle^40 zg}td;`9;m4B>4$urMpIUwvfUU3lIlh;b3T*Nzv>Ar2!6Zvj70DD^Y?1qFTF4i<-Ae z%h;=q_V%mLxSR*oy<}F_kO#%uLAA~OyTz1IOQlw24ixacTfE6f1Os)fYUuLnIQ6?_ zh0A;Vm4yr69VA;YB0O|UbM72Zy~E^3o=V-J`+W^(-pW?^v){v|k|P*6kN^Kz7Y`!m zL!)u7jSesckSX$h!}mOtC5J_@e;&6zA@w{S;@gMAo53CcULvexk8-@rH9q86FT=~e z&maPB*-yU&?qCCNRnml@F9yWUN!7>+&MBVUatKiy5~K@I>b|oSn&}bcem-ZG{IY-g zpj#Ay%h1LWk<3@pXV>*4IbboEA5*1mduUD!fm(>>n*{m8#Ki`GVVi;kfB zeQ($;#A6inblGq3*V33jpn|~a7c>B?%?rBh@ig!hpYfaY8RqEVe?3r}jdij4Jhr1| zu}b;2`jY6t{x?eu?_b-XN>9~Hq2fIW$uLY?qscN>KVRdEl|v7HfNH7O3K zK^OHuY2C;_XhK2fj0b5{tMY6x0Z-noIH>$M^KSq?ge?qAoftTa`O zR|N$ylD&pTjju_81Y8v<u$32c%27Ae0j>%h+Oqa+x_h&-%n5muRiSK)#uLd_-Vk$=fRCV z>`?u2#PG$(j`4q$(l<4b_hExT6og*5xrubQ0ysQ_(*96c^La0KI<_399o=Gjb4puH zxnOP?IuJIk+Dc9USsWHUDa+Pp2CKXZx9;#VHu&0oY-_1ieR67MeUnF7GgDE|nc?e7 zkIj+*SY_uFlhLt{*_l{Xx?`D`WIn%Prqoc{WyZ(%Yzd7OT4LKuwRwR5ELpzv1ti`h zVE{kfT!|lTZ`(-!PT5fQ{W}u{(K=>UpGp$*%%F|OIytNdp=?I}QqQ-+@o`3Q?})gS zoxBWL8FXQ05XW9|ev;*0NwGjOGTy$k3!eS1TT}{KE59m<51AA-&1dAZw}6@D!VVHp zm8gCE;8bPFni6QuL23n=fOVaU_}h24^>#CZTn!6*Xe-!9mtp_hwWDLJmYu?~qt=5) z%n*Fs&-tH2@V}4E)(;4=zwLLGVNc9z74!C8^XozJ0zBU5{OBh0Q?9^qR$H!q zfb6Z#DXILlds$-cRC|4~q-yNL5jg_Mha<1%DH~E~0-ijZVoi!1=rgE#@;#Zq%BCU3 zT%ks&2wr9Lu)sFu&~S+fTzx)oZ_L#^CF-FiOsZ?u+&uk&@mj<^Ur9--kYge80>(@P z7fDMxY%@wZKZsB>MN>cmM8LEgD+#2ZS*?B^kPqPq3CQBpu%GxV zbvK>(^V{hX?G*$OJCoP{OVDF5V+Ya3D;4Fi<@TkP< zC8T6!Gx1TzWe_K#iX(&b^)pMV{5{JJkQlwVm5QdTvt{!KT^d<8ry}%#Vl4s)ZX6sp zgtWOkK_{jSN$Xr2W|mUF3MshqN@%-38*Yqh*@a0KmofX};6m@(a$Q z^1BaRuyVSvM2HNfOu8vrQ`e8_`3#fTw9kb{=#XLe?N*1c_%|L#LN(OnXg1#rsxo^z*A?D4Lg325pe5!y5Rn4~+{`@^R+?Qye6Oc(E5z%Zf z+~4lWbi`l8XkrpStky;?1mCRA5FU$FW)*B8G7Isx2h5$5mnw=6yV&dk4vR@_A0DFa za~>?A{fp#AS(=W6KScZ7jTvY>-JW=TMo04?@l2hK#iVj9^W@@4sAQiH`a9HDaydA8 z+`+r!=2HA~&j%Kt-*wkY$Mbf%x6f~XDgJEoM*?^x4SZ45GayWURb`HWf3i3@hmkle zW+8yWthqao%7ua|_?Ul(o~1qVN+<9U+yIL8M3X)@RH5D#D~xZ-e4SUIPz6YVy&$zt zj9)$T28-pKO(P0L_ah)yxV75Y>1EcjNs#3A8wUDQ{?zA*uOD?Yv#C~|7%>{#vNNU7 z=pBc}={C;dq^A^z8iF{YL;wWZjhkH=@4Nk`@3`yXvby@xFmCe(GpH7)M;tjb^Y}l4 z$Y#g2-rW^4R4?5v%y8M;EkgZ;UsTjs{0pyv*wM1PumXL)iPFe-X~#tn{Cazf;HK8< zGW_bf87uOxwCkR#{<#?Q+L7ECt3ut$IWD3)Z|#HI`v18AuLN-(HE$$Y9sLu(#B~ke zc-R~1-|$+(_PcQKxwNG|%>RDNO)x=K2IzWBh~z4|g;-1D^*q|^Y7m9RR2Px+wwx5w z$PHry?+I)9_C7(46yxDNJUNbh;KPp|utlIwiMX3~yN1O_2r;E?j`C-58K)RvW7sDY zBq6M7KPP^?tXWI+%0onu^o?su{YaYaVP9q2p z(jUZF&PP8`j)>^1AH@C-5v@e_s!M$fIhCFM01aVn4`_)3;^t0;M{65Fb@a6uL4CUD zPe_CY!V@C;j$?vq17dGMn4sD@RyRxl@BuOUiE&q@FO(E`jqaoVZmIylSI%yw z8{~qv{$1e*1&scabj>5G8HTg|4O-bWfqhaAbjnH5Yk$(UCklgiVgPEs`=4qf5SY+C zTkVb|KpfGt5!<#76HZ<_2d3peq$`JRM8X`Ziy>Xsl5bvVfn70u&5Ei%mGzw=E6*0{JrVOk#F~7J}>yJ41&#WQY7}mY;b&D6)vqQ50gEt#j_D;i711*V+26SF=>$q2m+o#EN#N|+81-Nb>LQfNvSSu*?Da8}(J zhnZZICMvzE%|qix2Dv0@3s=`Ryu6r72&i+~t>sT|(p+Toyt)2Gta-fh%;ApMy+V;^ zSWOZXkv3dw{0UGWFB7xazBrvB7OoF@@v9GaNOIFPpHZ)zM@?2*bVqeKK8l)Rc=Scd zbRL&(q0Qq0x@3P92JIDI<2wSmof?Ryq^BI~q@UkwEwfr4)4ka{`pja2H=YY}_r`aj z7OCQRa)X%6`M~Q8uRnWmVzZDvZu~3f=g*53edG$^)u0=8slm#vFaB1wf&Z{Ln4X`w z6##G~IeKjvRBJt$BL-;nT?uA8*p>}psx&YPjjS2_J>yCJh@(V58y>8h%F4{5tz^2H6y%A&mGX+1Vl%~@ zr7w@mbj;N(94n%B%LTiaJt)PzA=QjR_cxLiLc#K^K+x+{ct;R%glW<_YKbqt?-HcC zlbfJ!xm%EenJ@nhT5A(PZ0$#TfgTW@H-MgNWe!A zgz|A&DulWZa1&MHc)$CI@?k%?XGd~W&qT2Vk4^gSdEDbOSV=BTFh6qm?NLPVIQtoO z?WDq31m0J9?O**v29}so%@?A-`T+*4T8$*iMeL9Ag@d2?0c@x%8u9J@yWUT;Pez{f z+eYhJ+=NJdKV) zo=nk%`TS-ue|i}4d7cc5u==U>Js5=kZ`L~~VCJNW;KH3l1qX>;cDA>*Z zDu3}I3&uu4Fikf_F2jeXq@UPFwd>u+ch09srhqWgK#UK%Nu2Z~N)h9Oc6tg`Qvhl@ zV(y`@$iM-L>d+8O6ezDXLP?!6J}E1kF(vvfAP!ZOWF2K*kXc;i0x2_B_o{Akrtxf4uFMu=RayBfQ{dtuk>K6q7D0-vgn_xWvnl!i0!@_R!>J=thu6YUyn78P`OH zi6YM5$1v8!evrRS5(_0xhPze+&!L5Ztjg2Ml zAoY*;J3M}niIP$T0(87=VjSLH^%!!KWH6cCHE=M#7d_tDY_um}#*Nq6cQ(TCa5ud$ zJwW0YhtPg(rT)7J?i>0;YM^D4PDNXjoldNeh9!El#9p*FnjBi`nSHXQ7bl&qv^aBi zx4o=q57p6j`K^l8UpUE2yy0{!J@nQ1(oMj^VFNn))rZbsH&BN1|5bGQ+45YsN7;25!S)GAt$iF)qi&CJGA=O!IxPFge`u z-T+L1kcO=mUVI7P%4Uj5k_C(S>#UNkH0#FQt#tc-_HEaDio4Hn2$@i3$$FUo!5!~X z6gq=5vKmmg3!m?@Qg{W%Td* z76}oe%QI+9O8pyb5O5yoP^U#D$!;y>5!qVSu5Z0IA(}gtrhdK`V6b;tNq!PF`;7q0 z$6nhHvOFI#{7747 zO+RcAp~FA$cCdXDr^!O{VeI))dvA+)x@T1$3z6dT1jB|k)`Sd02XCLA=xD(B%K^fM zWc=yylX$IpgF1XQ)>$E_z7HHZY~;a@EYNh~2LP=-T7-z4?6h2=Ac~6RMPV@VQIh90 z9r~*!u2Rp88P$>B+AD!hzt3g@+*ixS^1uB64ow^vrBU&gEv4?uX^-X0(#yi!%Cd{7 zS}PLrv=OD51Q?%g`_z92Q_v1V>#3?^Dof1umks6u|;;Do5zi zmL)m=ebYpQftRzt%Psa1N%66%#w~v>)zNWyNwEOEu0NJC(37wf8S)qr3CJIKIm(T) zsIoju8#gav$Y6T+<+xcKN18er&}%dHE&B9CoU0cs9vRsRd-k~QQ zA25dVPmdu3_CRpK=Q-BupoICA6v{EDiPddQaLDxR&gcGp;>@E@aly;y!=q7vz#kW# zSNJ#2t!WvYunBN=g!yuK{4c3Q^Km}Gxx*wIzW58| zwT5s%gwI?<&yCYFUsXOGyrm8KMec>tpUZ%EGQ+lcw z!M>LouJg+MFs?{fQ`NX3;Yk_iA#sJ-Y@;*dG+R!yBN28=@q0a85|31Dm&r@s@U9n8 z&5S(>#pQ*E2K4O5M(SB+Pr+wA= za}2umrA&Xkv%{nK+xo3rIabHdmDL7{W@WzTb|bI_yk6HA*mALy*wuZ=Tf9r=D>;|z)vhIUXH(k%cF@2|l>5%~2s?F-RbTb*g`c zml1e1C-fhr=YKX${{=6}(rorXEJC&wwnAxm3_1lH^?WytM$Nv602@BXLaNvZhevxM z&^tsAej*C+J|4l*wM=!C1~D-S=sO$o8W zO@4B%SxJc{w@=fdM96ng|BV4$*l2N1z)6io!AXaHOGsVNqqKop>AoxXaG<7IW_9S- zH?lrXBo#KS@uXpb-=_k-5<3{u6BM@z=d;SGPG~A^v+riuSFk3=qRu!TxG0oFemK}% zkec8bR((Borl^Brpi^J&%xVq_zp02pTqTL1u$J>^yMQ-!4wPLyYFL|&*<|9_9O0B68UgQS2iR6f4+AA}(75Hc~&! z{wM;ac$b`L{}WWk|1VJShHR!JocpH~xU zJ>8ftYAVt9G49WXF`T8&i1-~mxBlkV5@M?ZfIdQoguYa>Qwnqpi;WY8yfFY!2FIso zF!@CW1ZC#M)A(BgNb}1=N!_hHV#@2B)ZPQN>RZhVQRXFWUAkmdO?};iPYaR2(vRct zf&Pg}5gO7?D?shnMRpoYMdZ>38_j1IkIj8Xqgkiw2uuN5?^7I3hPEBnJlUXCaL~^|dtAwQCfD0fs@Po2J+5cW2U=eP-`uGz zeVg15X?q|2uvYmpM2a(sNVBo7^$`$_cl5C3X|;Wwm=yYXo!t*h!8Q#(p>~c!hHBUh zUvFI$qr&%3hP9i+DG%pgmr{-Zg|fxMX9V6V+bmg)X|cRL%2%dvwBAhX=b31KP4L})$Q+sTWO z<=D;tYm#bZ>MIOEDEk5*!07hy@>pV6P)1BK8~C=hsin}OR!CPV4-8h6NK+ry1E^6i z0aS<{Ki;f*1tuuKL!a^?Q)CbZ)+AUlAM^1#q$JU|aa;5R{dI8B@P0s(OS(15!kln6 z6_#QdC+RTR4@2_(N)2v`b+fm&N#ycjAY^Qwc@;cTSWp2AGAZC zbzbsxnso~2=`Ry&osbj6v)btE5Zd!1?s@=uVwsbXCqxh8llgjR=Pw0Fu<8|;1_|wS zXves?xE$lf+hTYiSiPJzpW4!t>pGWSF7!+&i0#%BJ$v|IY4Qm;rnW~9%;)5#`3+Xz za;!voL=4ij$r=*}+q=Z`zZ-RleY;HuUr?Hg^j~`Bz38_r4XW&(@yffyvdW(C)l6ht z7kUnHA{lBz`Q3zGWk(Z~ilkV++xsiKMQA6Vx4|*5=wX^De(Hx7#O|LkEt?{Z--U|t zmyh#+hL`LHppMI3eY~#ARI_b6fnyh{|D1kk0sk94@t)d_2%-4!7d;V+W_}0)$PEy| z1+XwXnd0+Z2e~+2eA7QjA|9Rlk-)rbr#`LhN-itp5Q8LT0pM~Hc;n5j1*x45SQr@` zq6G2N0}6%4#EQ^F=$i$_rKT|?_?ri&=fpv>EWkFoB|bFKR-TyZ%LIhwyP770e3z)= z=FZnNl=YQfANnOAJx)afqlWHCfaBOCPb(4#?fAODMmpq7oU*tfxZ?DAbC0pWXLf&& z?9jXYcmukG`F%$xgz zW4ep)sR>)9A<^MKzY#POdwzW4hknz$wyPH6Gbrv=x7VReTaz7iqj48!>P z+14WjF^l9#k*(tODDm%X3*iiEFoqyT#OwTMUR20NoP_6~Nd#Pi@?)$D21$sx^-4CA zbX;~Z^dyLV>p$tqe@#Cb-fkoBn#8bg2tiYvtY%R&N|kQcA>H_CYayc0b+-5 zRWn4;n6&s8u!P;UAi`#2N8#PG-jgokps{A(d7H>*6*2Z~2>V~fJ72&Z# z^#^Z-;AR}Zee6~cmBBpK{G-cq@JW>RN;_lw{ImMY)7Gl0{z_##0xaHX8>*j6VgnUK zGzU^$3``k3?Rx^xj|dJb`OvlJLiYoEi5$8505D-;t7fK{k=2ikuF4M1pG8-zko>oF z$brkz1AhR6K09Feo+u&Cgrw8!x^9)7g=$hz`^aLS7#Q$A5b#a>ec%%eOnhZAyQ3E= zv%PXL1P`!T`^1SF&6#7X?#TbF^5{X~q>dlo(V?)Dmk;IDasasm^};I# zTa4rV!!zbFxiQP8=xRqBQ}39EB}+4*_mP)L*+qB%BSBvTg9(lQU>D^(UX#hON`LKX zqdA3$4ZwU_o`aZ?rM=Iks}Q4kOk;~P;W9n7DegzsB?Ki8WI%l#4Fr%{6LwhdBfFGRccMGmz_5!Zx11Iy z;jt_aaS5PkeFCIV)tIKEu6~aRR{MfRa;4!=q0a7G@q8;t!K$TXmsv!!&EaDE{mZ*qSl|@qfBVfiAqjz9E=y zc|e$OyK6cgKAj}ovruc0fruGl#z=ytQ#2d(k}!tR46=~Y3n2e#u6|FJp)i-6UvEn? zUV#v9Y(&#M(-#;162BjCcK1>KJuDeaD4f1BWlA!p8BQ}r?YwvS~r8WeFZ4&#~Cinjx@j2;ItM6x{0rxDn&N%Xq<%RDvHTZ^)+aEX&ac2qW8C zCzo2H+%bxta^K6XQ0GS%1t)Rr7bHyhsd~u`iDnEzace^ig8y-Oi?E@2k@n4D<`0AvrOT6ZjfA^xMJsYi_A*b zqPj-03JZZI+ZIz`S-Wm$e78-nNmsx6paFW=V$`5*;_H-CbwBaZUs~^`lKY#s}@%fEUEyr@dO9n{9p>x$s*AonTFA@>5h7NcH z?tG11XNc1fNhcjf{h~JiV>}4w7NzsCwqQ7!&v+;U-@X8pDEMh%q~uIVDhuu})y`JG zQvr~P3$e|_+|A;+~Uywe+tR*Mt!Dv3>rIHA}x8^}kI`zx44`;o^NLJ>Xo%Wah;{5&uv`Xz5$;x0nr+#I>|Jio=tY~ly z60md^Ta==>`dZ3pl&0O|dkpINUKI_8&NBbX`PA{gN5TiH--DhdyX!;_L|^@X(_`^X z(E2FC;4>-z(ka9^5y0c8Ln2*g}?7lfRhOnoLOdM_tfbdR(^T+Z?hO4Qu)P3mKCb+K7)=kovn z$TqQ;flTjN}X7YiDtlX$aKsY`=onE1|hL3&tzpp3j z2Mngu+DSI1FOCotu{C;RhRw+Zdlg1BQpk4(xWxo>tuO!c*}T9!o5H_8o7|yo&kzdL z?54j)QA6jL}<|m{ZMgEExLF(GfIvCw+WJ54LY!uzZ~EN8AU3 zB{h5VrYVfLd-|C>oBR5QXa@Ft``mT@3f%gAMoap2D@W~B5_ zE6F9x@&wyfrk91}G(^^_La9%c`x{V-Y^X>r`H z75nOGixop(tZYs^N3Hu@a!n;4$|d53;3|DxS{zcJ8us<;RHZ>r*aL;e^4U7`FPNWM zW5s-v{rXU*LQ~~po7>sm;;`#VK<9t{%=AW@Ym8F~X%x(yF{5(5PoHB)yKr6JP{yBU z(^|hINV2Q>j=4sF9U*cfPCkeqj_KF@fg7RFe|J-d#jmD7=V=;0T+dKm%QV#> z!hPE8o#*3x8r#mk!UWmR7fe(FYkfHhQnk-E?>lt9DM~RPdRz>#bV-@c;KWYrP6+Q_ zEq)te#1Bt)SWMl@cDtwD2MC_(V~@$1dQ(b*0=evkX04g`mpZ>0!Y;2l5}_!RpU~DQ zli1@3m2|E=@_)$!Pz^<(T#qFnDPO&@xT&1U~rN-{*pKas0O<2@Xd0|V%PVB=r` zXaQWDm}k`oIQ`pNo2!hCY?DrfJJ#;s5ft{=d2|3@6Lft79UE=mzal8m6gD57WNR=2 z%5qhTSV?p|=9XWQ6cHenAVQkeOm0qjeiw=-tIZ_VQP_ytUefAy|l^H7FWErKNB~f!I>wTLzV26|zo6 z;M<|NWQz=$RH3sAiy+mcp%_*VTTqcIl~7J;9Q#J7p!&y0TAQ@HqU#nC)_p zL-92y0I=p=eB%>Y*4^56g{z&J|(+_eLXrFalzh8bJYQ7{<*mg;q zEldseNo!|0+xE!MhW&25k=}iZj;><-6?8niI34WsdlM_;J$Jq<)h%)zKP1cNdnn8h zAMYq;$p)abgEF`&QKl!@bpWDV?mNn*`l1Vpjl#gW_N!n(qlS@jwgsDCSmS2#I#BD! zbE%+*Ntbi@9Ny1Ug9vdcWxZtz!2v!@VSxO&r)~z!IM@OfQn3o(aQ-gv;Vw1;A zfjUFet9YtGEj@|AgJ$D+^elMIlf8GRFvWE4MNz!vRI`*Di6F&BtWPC)!4Ri*Vk_%c zNt0<9-b#p8$m^|-H2LCm@_u1KdzZOT1IIK}J|nVqx>yWGwHJ{k(6ke;cfC?t5<6F9 zncVOj&Q{qn#DOm806B10b5ggI1*WJtaMiNMB<1R30?w3lMKLTqp}4(5S(vGN=M)cRd;;rkw*Ykl+@n1&EJlOMcUztGlc z7GhGuY{*=|43LPIQL=U@yI~=IeDy9I$t35B5`;~3a245zmQ`0P%JKe^#JXcJ5;U&u zba;_v5RHC69Ykl-IOCNO5kG!6YjN$qebuN?r$juR>zvJyjbNhq{1f5D)iAoIsWlM0 z@LVvH&DGNH+K=DX6kmC}Z7}UL;{zWvME%)7NhIC^xrJ=5$2~J_MXR+q53lzt_dkgq z)VE2B%A1z)p^vi4CY*`f_s7KYy9l1bzp)Aa5QTk)51 z>1a;iB<7ZX#J!RA>qIP~O5%F(v!2I~v1H{ZL`NSaWI??HJ`y*%XQLfI&-Sx#W5^}; z@vHBAzAt$Noe}vJ8tr={wRlA*5{j?FNAjxezqR7!oO%?KxZQ=!bim@W?p>vjr%(oN zpoTFL*lk>XPYMO1t&W=)+^Hi=f&&F)a`u8|dhW*=D2nBy#^c=lAlR=%WDejULVzy; z%0Q9km>%0JNScNXQ_pRHq!@7Xz2&I|gg2=&Aj_NaxXc{<0rGkG7u|S*o47cSuE(LJ_QwjqX@y9`Vfm2Xm027gtIRIA&DU?(n zM?!Cad~SJ)$CZ%_RR7qm+IpJ!x7v*Y9@meA4s_FM2~E&3#cCV+hn1!$oc3>_S_VR6w4vjT-%S!_yE@3pEC?7;G(9x zKvyMSz=mf5UTB5@%M*L$D3%0&rcEq4Ub#(RAYJkJa3U;`UEFDR)hOF~ zf3JgGijBvgoL zJ-4~%_b!v>mky;|1L8f3*4hd(WC@DZCM9sb2UOD!{YsbczN+egLo9k)0~IF;FnVvQ z?L`OZLe$mNCs+~CDJYacd~55uxQrj{%a8qr1JVNXm3)y}Z+RL^a-Oi5zh|H2E_hU` z1_S8W{Lm&HY)sBF1sZi&%=d1o6pA%-+cj;xT{?1U9(-Bpm^{3&C3@L15n1W%u`;=< zti8;OR3GKrj?1;oN0I*!6C55Z%-hVpqX#r5cr@vFu zO6y?`GUoAw&A%w=EeB4YFI+APfR^*KpA`RBWtBR&3_cx9nf*CU@q3H|-%FF59M3?d z`;P;^u((Ye&XM%q^@v{u(jUwZ1D{G38CXvv@BVwOkV-woTtvv--5(TOAXSIb`iu|K=eXR_x|(!X&!A_@MPh~ zt))(3Y6_)iZoQMGu|6;!WJ|&n2@=n4H1h_G^VwCTN}}LB-omQu<6F2y*gkaX%f9xw zghccdU}czG_QP+Y)dz~z*@&UUi6yW5iW8Ezcyo8;p8GIR7yDb$a+zoQ=fEje1G&qK zXoFJi$>CT)Qa8VVd3;SnJUYGZ2f=Kp=59Mit`NO&@Aee`2=?+8W=0bop*V&1n7-goskEw%x zX>pGr>$z%=9%mMEXH2u_y6L&Tg$8BqmEXQn!=4FSaA= z%`W!?rtrh*s-9jU%I!wj#a6S#L~g8a?R#FN>j0va4EGvlEaz9tjqM>kkfGhuZM#sA z;XwM$fIv7>V#Bup<&Kfm~baAqUeLOB!b92{gyJRYtwK=#~4ew@N~e(>xIx9v+Qtiv?J zRj~O@TYj3&!`kn&7FHMMl&_Ovu5|9%+`R2xb-ymDeZwcvD=TE)Zi^R7HX>`G1Fp@} zktQw8^9tVfSDVSz%|Dh>;$e?&*B!Z@x6l#>c<=R;Hc2S%1>11n97KJQyg5XYdv^nh ztQIA|wPAfLJ!&Ib5j=_cy#)F;&7j{67-<812Y<5D#(XVdpAP&90@|X}aStER6^Ans z@A*zqcITA=gZ{76y@CJ3*IW2S9j@Ek-x&rbs1b$^=>|bjNf|;)KpI3qL^>3a24NVw zyKCs~kWd^#S{xA&kp^j%7BKjYd+&43KKt{Y_n&yybKmz`*Lv5zGaXYP|NFs{i{P`W z_FR9&kG=;RyY_M*Dx^QDB#ygoP=Qoz&-eSYCEjWN9)#I{<*XDrq!JKzJ2)5-i$KDN z4>C%$fOAjx)Hb?7km{H}k8w({$QoN#b0p#p4j{|j3*pJMfM4+fQ}6C!$*~qlF#tr% zhYoM?FM@Nr1*g$TI5V0PNEw$wympNwmLFI^-(D%pJgQD>wcdgX37a+)D4!SnINHS2S~DglvK-r#{bgJrzkR_&oQZm)0TmDNxq&J<5_cr9$jY` zmHf7pSh&k2VS)y%_-M0a7y%|(M=e1#ZOT+`@AXSt0}|@ZDGy6}fm~k=YLO4nYim|F zUP)`qnk7+eyj+qQ-qXI5o#K{3Vb4UiH%>YJtl;b9lKhsHYS4fI0&0X~4@%S}Nxnt} zM=jI;M(TNzc@zYiZ&C|w-$hH#p@M$P^{H)@zq^K#4EbzRe)(>+o~$27-lYR$)u-YU z8)>Kz=C6v{7B}BZQ{c+EURKbN;q_A|9+n>oS4jm6_2#Zy0XOL?SaH$A5yrvZTE~wJ zi-8Z6Wk*o(kPuheHVMeoGhJC`M{Cf^*s1AyNjgf{blFLx(3re72xV(R8}$*D*qS@d zQ)>2f&*&cgjg$!OU<>;W(|eCS(-YEcAN|z4XIfR=l=-&C?&j#HapUEttkqr1htjhq z>C?>>^1Kcb)pf&7`X=sar9;*`rk5zD8!ork+IY%FApgT+`QbkWugfexWK4bCG=Jk? zXx9pTDIN^QeHapORf_E&$Qh$Byd#FWOaw(ff?HnAo=NJBkXY(kbBcclb0%U* zzK^_-sMFX<+9;5#_gaswEQIhk@!-r9uL|xbR@3mUl3QA*j+KSX zv;38^w|s@Ns_WbYsz()1tH^n1B!p|*SGt2FCFVt_7`oAfAGtImhQAyV0 z()^0+4(_7K4teJ*d`vJynDxVB;l(HZazmBv??D_cth1dr!(rc(lfHEZ^b7TOnemjM zNg2>+B~lah4K7~JZjjq8x>J8u5711^1nEB3KoQ(65dge06cmx5pCAP=eRUAsbvmR< zZ0s=Z>aYDba9)W66obvP2E<#>LZTPwMbuNJ-Km$$+5&y=9|Yx5Scp^89_`wVSC0p1 z5ga_wco?OYs7BD&>%dhb9dg&}QxAS9O2W-{K%T-DuO*yGD0!NkKfC8X*PPWW0Df?) zg|OX}^e9OB0d?tOvz_wiHt1OlRJeD8%XyJ9Vy^7y>&;K`tJ=OZaf+7VK`u{zt8Nf` z4jM1oKlN+LNM#p%i{7fbOm`hbv@6K&THlfXxqCU(lJw1H303H%COrfa6+r*i3;aQUJ3_Z*84Oo~8 z2qG~QMR=7E^6HcWcAvBBQubb`fL0;mFGRt*&q0qnpS^@v9&mzfQZ8pZ6@q}2qnX1vFm%sy@#PXGa zL8UezDuN;o9-R_`SlWw^rvTGa;)iv-XkxPdPr>`|j>dlsiyC@O87Y(bUsc6hA*n7I z?7C>MK;|7=umP#B%{qL2NRt}%6dGq(3NGmYYvsG=nC$Th%Hy>eBCn-B5$U^pZ5VTn zf+I+f$9{ewOIw5jlO2{?KC9j_F8tCUbvjj9J}Xn5BlSb**Hn^U2x-Dq3Ls8Mj-QE) zaF?FUkebr9@YWX&J$mEAC7jacCgOK1f3V%v2#&8kz}3!P4mR22=i-lGxgp3$Si??D8*}$MBX{F*5 zwD*0sQiJPKSda&%np?&Bx3QCEW_oa`Td1?TUe*-*5M8|G?;Z=^s7aYBI@0H)Yjlt$ zW5aK)q~OFVft^{N$Zz^U{1mUvgEJGTQCnEpZ_uNs9iQ%dO{Ygp*;;us&Dv+5v{Y!< zI+={lPJb&b@pP|svA^?qwv)cC?Kj@uxpKx_Xuqk(&=fkbJ@S9(eIxtkChjsfWV52rrB%YfCPl-#^iXQyi@^kCX z)6use9;yUZBDc3XTIBO62}l1kZ)`}Y5JJsD5uic@hb1I>()$NQ!|3CavU7BOiP-DR zN4X`X()m%wg;`~_bzBv$w$;V;ZKYKH4zRe^7q1ggG?fldYw$xJP8MnQ0A~2TXGgyW z&8vw|Hoa3GG49>7E9l84@0Qgq1^T{q@5RCG1K}@kH)amcgb}d$@0jHyII8Du9*4pb znGma@;>Tj=efp}=)w_uh3=Qc)_35}NK6Z8HX$uL5vQpxq$^|oPs5qCVV~XmmqT7LO zXQnXpy@w+$la7BV&*X09*YdKw%TebZFnFc@Q=wpXk8{cUlj?iP#;vUq8?OuRCrKwd z)@DpM)G_AP^@XTwJ@MU z`dBO4g)SkrSw6p)+{Ml+rw|bTdGG$_3 z&CRrY?1N3(xW2lQ7=r2`N#?bI@uZ9@`eFg&Kx96gSKk-vCtx)^mZ>zbS)8$Dlwpfl z)|OU+Dixjekx|w(@FDD?-O6+2*TTQ#cJvHygxbVc_7<>kZLQ;E`|n|aXW5y($+0IL zAwayUUK*!FVsr8MLScW zgJn4DrBBbR$xmQ84#)xaQKf4m-DZwV{4Na=bDAsf7$=b=kY z;-XBnHqp+&RuzXB^OtOArCjL+iMm(IPWL0bs*Q9(Y-dUnoOmgih#o0}xHuMsG)I@b zzQV)-?q@K>;pGtKRuat1poS+r+-gafKH5STRUZ`jjRq-1g?X3{z^dCMd^5tRXK=UC z{MqGRn0&$=Ud0%?YB3IC3`^kUG7bdOKVvjPhs!Xu0m5AVjD#1c*NDAVvk>G zgtU5b#r0zoEtK+-Jk-H+9(%cC?~kyVZK&gKuCxpGL%-X4_zAz6mh51+ZZ7jN<}-cv z77$Y+2{a%tT1{09j0mAbBBM5*nbh@N47`8&OPz!gcuuxi5pzobgi8T;ag?#Vt(R(D z%-0&T-m&bQH%=7&wb#d>^lSg|V7e?FTYnw)&_g}G7qH=Ak6Rz>5(kb%Q4d6Zd{_*Z zUz`n5s62X={RDihe~j{Nii|h+;u1r7MS@B7)T1w46T`$~ z3n}dX#qBjj><=~cvC=ewa+Pe9yL%|@E zIc|{>4k#&_BN5A^2o@ipy*087zN=!xWdx{3D&k@phD`Zb$b!{1-IM?C!S8?Tpob4W zQ9YCm6g`Bwl|4c7@Us<^L-&qNw?qc}=^A2NYJ~iy8|eh36k6e^VC09%GT;E%HHNj> zB^4L#t$5UlpeOf#Pc2$dWZ|aB%;aUEDyx9v3nKYxwc7?w#Pm8tFRhRBHpJaKS=;z z?^Dq`9T%X$;5c|3sdXZi^A2!j0{w!>$DQvI`P|Etzc^gc01Q#*l2DQg0jg4`Fp$9Y z2$L_MyJ|#p>L$2Iivwdsu=sfGDz4? zV{y>v{abcdAk4ZWO0{R)|F`Kw8U-`;lLcVbK_SEpvp0>oLI8?AGch~I-aF!+E|8Ix zTUvH2KeCW2Gp@Y8L5Qlr)c~j|Y3%H}jB2qfs(sm4PXF4TCbq7BEEthu_KYTQ^zF1e zQ-Q~e-j53o-Bs>1#Z!wL+OQS(=*i9RcbDH|*5>zq$c7(c<~mL<#6-{}yaHMB7?{D> zEQ3Ji>rkXd#Un;oMn@!2P)ibunY|tRLx3XGW{*=HLk_=?sj@%d=}v8BmHxGPz^bKw z&6#gZwXyJa9_+Z%*+M*qn!5aH*;Gmp~bmCDDIJ2^;{=^ zv)9rk;x)9|#PrT1KCH zZ@xKnxL{}V108s}Wa?h9o>QMHUP439j-jJL06iny1pr|-WrKtM5Gehx4rrX~c<+ z4S{30+XZ-dc8DJj`s+DO)lGIRW-uqSE`@_7_msWv zmsRFxAtyA7^E5{U2eWwtItl}xZVN8^ZhR742@g&tfU>bSddkVcE)JWps2iPq#X9E| z^N}fLej91oP9~M`7{Bd`Lb||DTS?VI%vF{ARG{q+NWGV=Ys9&$zf$G; z3Spssxh8)0ho3frbOLgdxw|<;mZmSF+<YQImEylm*OZRFE*a1XxouwmGgPd@!;x)7jg_tf=A*pzR_Qw%~2$PGj{yn zZqI`$?|$!QpcdXU@JKx08BHO`QFrq5_#KE*=tgV^$`vRd!3D*iqh=GV~{!4%9>mV=%cOM z^S9e9g1@eKaUqmkMbe^7LeeiaKxMuUO}n-V6XGM)GUteMcL9;KIFQI*6-kiC6upT) z%n1_Jikc(gL77+lua>3%bN`9q%%UM>8oc{Q)#)^*R0N)gkq=LnCNs?!d8C2K@=TUS z!WPB$Ki;{e)0F6f>Jf($K;o*&(hQlntKJ%zo7qXy6p3Z06;Xp~)&@B|jCR)x&NSW9 z(Ye!-oX=2+TJ#jnB>H3AV#VTP5XNg^1j%yJ%B?ZxtNcmY6&vzX_r?Vyn+y1J`I)u_ z2R++pq2FD;zz!YB0xb`3Zq41dB%-98Z_ElOFj&cQb{7al-O1qI2`aP>{YdZ8@OzqpYsz$awyJ_Nlcno- zi)1Jv#Ay%vP=^ltcDP47c)O?E%o8x;T{d|xJ}tyfhoJwm4fo12rU^gB{){b^e;a9( zGD1`CZeC3lm_68eo>mzhP(eAsVA2tuk`aEJ^PVpUV28L73UgJu#?N$*-D5iT$yAT6 zq9D-hXMg~2I#~c0;{){d(=LOh#{G!`SIVk z!vn%UZigYV^V>8GPuZe>^RTZXwH^e=xg6m=n4fDUl8`1t3hn;_`9gObszanvA*%r|krD2++Tq8YSY& z)De`-fF_%9d*Hi|!mKnNDt0I*=jV}8(F*jiM>=ZWzQl}r8h!9xGr-3wy#VKi%1XSS zn^IU=rB-ZXksDs!)O;(m&axrDrR$|E?1c;9*!k*B6;*;KakCmR@Ghpd)DQNS@G%PU zI@=!z>z`SEGBg)JV?4gHZ5H<>U}1Xa;2vr?daCj8{PrwIITZu8KYxyYP2IBMy= zW8<mYI^quiT#ebI#@)-9PPqh_$rpzP+xz^CH8j{t5X5l3W;<>6?%2oPiW) zW*=`V!cD}yvf@7V=ZJc*TkAjDv@E`9d#m=!b$ZCAR`Ytz&6up_X3|b}cNUMwo~<#t z2ftZ-thi`SPegBBIi;Qn$#V9nvkvimK{T(*=J$4be+A!kQ+PVp<-12d_@W{H&j+#_ zlb>10-2evQ?6bn;hP#zQ;M0-Qh&N=ve?#YBVD`qI3kWSEi~|m*-?t2*vL-PKRi1nw z>_<03!x)Z6o+?6rc%F_uYGfZC~kL$M_fmW71(&b zn#iSu%2Nk$5)aylJ2_3j7o2iAQXL$nYi!Mn09SB)iRG2c;^ne(kLpi1(Uj(6u+1lw zVg+?O%IICQ_sT*AA4}O^_Dpx~B!5f4KwnO;c>Wl=O zl7EC0rPI9sQVw=AQzB~Dr!AJuiF-n&S^3N=RV2|eiq&=JKsB~#LfyGmcrJS5Qu9Go zSiQ2Arb9xa9RN31&U6#cv6J= znj6&L6pDT+XVIWbN@nGP=7#Qv6;F?_Dozz-pz+c|9FVnd=aLV9z3uFVP**h&}h`_-``fU&Y+SQMJ^=_;?DDS`NJsMzrVlHin!QuS9o_ z31f511OMV}K;>h?;BLfg9>cZEv$~`rV+HVaPY{_@k|mw`B2Ao+%1)MU^!-c=IzisP zn^KQs%;h-gTVMkhm%Y$Y#BV&^=u8ExpCYK}(WBpD$SztRs|fMbRYd3z266NTiE!Y; zuT%_jL-gz-D6BdEqnGgiQ!zCKfSA%>00|98E2w=U4U)+DL3JxQlk|I9gBIpO^4=W@ zr|)SHb^N(NWw=}wkO2_~gf3TxBTlc9wxjHLr`$l4o!`^g7}vQf9kpqfuI41U*xlrf zd~2JoN9nYtB+2Fod&CUNbReR_KVh_8+212W=fGm~j(xsuh53Fi8!Ssq1le1Mu==qL z`3^YLYSth$JhJ@O!%y;bE6=FwQw3C}aJpAsUL+TAs%$7GB@&)Rql)WxH(?-Y{m`<> z@Iz+M9X%N!&CAUh?vTxCcCKTBMTHc7p1u8LLo*Jm3s4B~X~K2iQ<3rHP%v&#vsU$5 z#ACuKpI0KT3r*46Oord!b%Ks%jU=3Wps8c6rmP)_Fu5@mqWZhsxJNUpCAl@VA)vy5 zA?c%NlPB)_D`E34-B)M7k3t?A*=rxmjGSp0#Cx)0Cu#Pkxv$p zGeotNx|SsW({1BwD&|psXMWr4MP)r4v+(j|51}x<0Q?*HA+?5@-Os)mF9jj03Is2%5gS>V*dxby}obdDU&V; zN$-IAdv=`SdJ*$;R_ z6pfz|K$S_HGY#nrG);?wvdSA8#i}B008~&@XBQtLrP_`r(Cy`$PO4OQn!16vrTIAf z+WzsW`0n=(Kwtgzf*r9c2sXC3Za1^??8TRjZ$_wL>{`e76D0)GCy(Ca9~biamDShc znDHS}E0i_L?>KrR1X*{hKfL4YkKvv$a_=9%tQre;z9cmBl^dVPqIPjZ#PJ|sDJj&r zt^f3@?U>iKOVc*1>UQH1vYcnXe8o453so+djH0ep%BRXflRW%rdX%tK+4}O{8$t?? zMP3+_+Z!Z8v>v{>5ki)-G}7V};~1-n%ouFn7@GJJLI2&r%)iz4)y~IU%jUWz`gKye z>ghL&2dVPSyAo?pT;F=M_?+dM2=mZ+i={J-etr+!F;OHicy13H3ek9d)w!N{#p?El z$97#%3`K{x@^0R$zV$LgRP)T<@~+DoG_7C;o#!XKDgCgx!jjG3{@dIu2C_wqfII8! z-cNwUKkVniEL1Hoek_cH!w(my>S=Jwf!;s$Kxk<2Z+k6_0V@G?;ZNolf}nd z7_gK$*i;YZhFPs8sgqS=lOYIrR5C9zD@%@M?)Jd~la^#g5sPUn3!-?N7L`d2FW6=NKLHp!iE?ui;V@8$~26+?%VSp+#lgPFPh`^I6=ZT z%RMDa!3ZnyP#)8dB+K9kgov(%RH_nq+7`pb+!%S(`4E{g^sh$AB2>Bhzc)&X`Teu$ zVvu-tR20B~wwbM8A&mzv`B*)yV8O6L(L~0>B`PFgo^?yTSF|@6wDJ?rE-Nl8;)e!l z^7OFNA{B*B#KU2~<|uk@tBKhE8G9v(Ewqw7&o@pKklqUGXwadeQ_(Z^dF#o68Y=V*T&UZP(~2quG=D%59tXmFQ9fkZqFV_1qc z8Z^@r45WjBrM77tv$3J^t#w9PJJbt)A8T(V)yqf;qqfX=Iu?#eDCI>E$+NfdH>T>N z>1wPg$#3VTqXEBH&P6Dq&&Kbh8An;`pmt|=g3P+POuIJ1aCCNDvn?*C)P;#Qedb-d zFev?)i$*Qyp6S0I7})>>u<{>@x9ccP#l_t)^)F{BKBt!xL{vPU34t?HxgH|cy4LJz zU(wYpusSOu;q>ojbuGgtrvG`tU&X7BL8TtI{h%EDO5Ci<(le>~-vVH6y2Q zhjUR8RrUZ??Z}6CM5XJq?up4cPpY>dPk?D?e%*fhjRQ^W#y6YAR4>Ap?FG$a@A zogF3~_9hAyH@Z0P*|sYR-5np|Q<-%9K}yn=q>ETO3B11*^7F^S zr_P5q zDDt@i1nGdF-Q5yEx}G>XrlweK!wMB&R`wO?gb+S;%(tuMaM_VH z2861R5`&k~J1I$C=Q}w08JXLqec7EP^|l^J=O)q3&fNMWrLN5jN)~`)moCoO7X(29 zO`v9>JP?TJfG-6|$ar*>z+^ayZ*3R&t`zXT*B!OCBlbx}@UmZMefKj6x>gaSPy#?8 z1rOa`=LYzalF%D1)xD&?@BF5dvVa)?plFfUFpxSc`AYrZYExchJAT>cf5B=fWiv8e%UQv_+qp0Bj-6h{|={gKuJMJ@TMryd1`I(~}`uL@=aB1}*ukmSJu5Rwq>Flosq4ZE$i_Y~^dVny=?hoLTd3_!$- zY2c1Sk1CD{z2(W1$ELCG1wCNu3-MpMp+>z9#?R!E{Dz`Ko zedmy_(e33gJHcSVp8Uo`injp|6z*W)&vb$_zdzfAF)o3gaCrbTk`Gk1(fByk7Esam zQ5*>3gq6`W#PaZhShl2ZDS~_RzsXi22vBvEs>7HTWgEGt=fO7?TAq)mSZE8IzAi9J z0j_?rW?39En7o7|(RgJIo+GXQ9Cbj!p0=bDf;76qd>kfn91NJxPEuou4qiJ)qozEs}#9Wl-yX|1%Wt+s;RndxOdX^7OWv1S;Z8IU^{0N6h@#_=JRpDbm9< zEtLQ&_h;cr$thwee^-Mb`ry>Od=Er=fH5p5v7n;TpeV+arVLxv)GS@|*fcwrxbWmb zWW2Z+l+gHUpbD1h5EuMr@LdWjy2p;jx}5MS?DdETtbcYngo#+kHrBbaZIAe}?zOnJ zb7-kWLIIr^nI_rsfYct@=vLK5R`d0luYQH?8f<4D?BeZOD93B+JL=hF*r@D5#} zTx)-?*rAS4yGSl^py9e@N^5c>AacJ{HH*bjEGqRopHB3!x$4nb%0oi7vJw54a@sXq zzGlX_^9U_*86cW8tmRsDGQJz|%r;3+o*SAMJ(6>WPl;t0glNHaJgXc9I zTowWu@@6kZ{da`ir0B$S^OhWCLTh`<&yL!VI=6LudY$Oj^Ns?N7Gp75 z(N|R0)5e|ez0eU6X>tj#3#RA`V7dAAV-oKVdWN>aZ&Q6g={`0Vc0k%2Q-m+(i#v`f zFAJzY(2yTIUjLlob$6f5|8(L@Pr=RHh4b?td-aI;0^h!X^SHs)3l;$X$M**%2oJhw zH68##=+);gf@uZXIp~RL30%l5gi+-(o2h!C2=kw%Md;nkS?dgPHaaUK0mB~E~j=!$o1WG`5o(3n%YaTpe=8VTYO0pC2E%sLVHnhfrPRFY~ z*33t*riNu^U;$-TU!^qjiDlaqL6>{$Z1(wp9a5wWy`HTsX|<8(GcIV0^b5rC-qBV-wp7 zzJ_ck9J9FtABtb=n ziG1^_nQ~>|rSW^w=LkbQ9!9ss`BjDiy%*eRVgx9H+4_a+*)~>E!d~u2y9J}JS^!Tt z=fuJsU&H0d(ao%sV|t`ynJjzeY-s$I+Y|z^stt>Esd!R4iGc9uBwV{j{d8y5AvBlU zGp_n*MY>^zj!r-FQBxY2TZO>SBY1BkP30orKyb-Vk*qiSA9LOcLbmY8QO(c14+S(F zdG1i_ODgM9>)TEdJ)zGWSBrXEr{lXByg2pmxNpwfOZ}WUsGhSV$^7h)!(0ks6Bp4- zIq4d{7?cswZu!zP%*|7;nefcRKRep!a9(U0 z`H0;i&Aztg!$Y!10Bu!i1*GkU;RByg)sjE;w2b-uunS%mvnR{m!v9!KzVC9qTv(6r ztAHCF3Kv=j6aGrik89KtexJ;F{~IbeP$+dL@z0r3e-1!`P?vbT4Ch!7hy1k=k&>;A z1|r$i(feM6*B2m8%iPaBuPJ6id?*v`-ag_$uu6r3HQk{5+ZNRHK8nY1ahUv$70F_T z%q1Vp!%L`T1j6ezwfIt)cqs9-9WF&TyBGc+4c8IGW8l9FSyDtWG6PiBUN?39DFtHl z@)j8yGa&ku;!n{6AcIr9;D|2-U!Mapc-yN|qnG^n81VpNqYq8khq~|LNn9h}NRlbW zLuMX9NtV?(0sTZ8);_lKL^ZbfV36BnFe`(vqDUDM=5F(dR~|hqB&i=}8f!znW~zD; z#~GZ@S_~7_fJ&R~2U(#?srjVUb*7h7qK?p&Fde_mL7Gxz}&C~-A4Us3@#%SFR#;TxxE6sYj*v4ap9@Npu zZy61sdC>sn-a9^_)Zp8tSoP9)?}TDQ1r^9{|9opp|tIuK{G*6sd=<*9N}$(^4BGbO|SJ#E2& z_5ZlaRar~BrT3)v{@1jH+u}_E;)hBg`;Bm-kA>KmCLN2xcy+NkD%^<~H25o0N1G#G z7XX;Vy}u&GO?rER>WJv!eDusGEIdM<9(K=Mk>>iN$mEn%F24ZRyBKUzT7H28!X-`* zU~&(|RaK*lG9T-^Rn)Y!O8aLSx#d>2b-$*se_)pr@_Mih0qd|Qx|)aHr&7iCInp#w z%%&iwrXAkoeO~n$E%6v1Sle-$AM*&_-aWKkZ}6OXcl1;L+lCkFXrF~KbXGwY=A+0x zv={#Bi5DQ?qJAj?{4kJ$G}WYW6^>XyN+UNLdEg;G_Ab))B+pO}+frD+o%bIRU3?IwX&Z!qabPd0u zYKrl4!}dK#L7xXaaAzaN8UWe`UyVk&615lOhrS5nw8j1A58KPrCaJrajKKVTzpr2a zq9qD8j?PaHW#<93Lf2127dK4M4j^^g590L5>OzE;M`|3a@3FLW1F7^B4Tb4!-U(B3 zAy@@5bM-w$GEp+FNN|He)*<|Vl2@qtG-p=AK~1Ni$ZLU3iX`?+nZ-g(`VWg>SN}-C z6C7+di<9UmrLl2ZRa_W^VinXjHARXjO{T{Ewi%xt9D6fvMr!n?S$WM2J~99+uE#m* zTia2w58Ru`_432=QxSW1?emr5-S9cWNKK_AOnT!66$qClz!kGitPYA$iS8>&Wwv%K z%(OEbDif64-r~pQ@9`sP8D)eJrO6yiRk#)*Y=zwrqPnK-fIz%)9Bo6`uf(qk-zN$X zvAdGEC!~E{1;W>T7T*g7T^83>ylB2Ih{u2;;~Q$42@@X_!4n51_!r@O3}T98hPt$n z`RPmOx}Po1G$e4wraHCB^vNr1fxCCMp*<(Mk8htAH3nZk>h&Y(6lMjuB0iI1it!IR z?q7PLptU41z=sWs=ld>onxYxY;Z056zcAKPWgu|6g z%bP7X^lRrOFw|_DFR}CdEnh1a?Dpco3w)=weKUq{@~&N_V|-lqNta^jbT#pvtNL21 zLZQ^$OdYs=&HhQB??y!Vp7h0L$p?O)tr{TyT%x#sd;}=(68pK^^6|gP(Zs79+LIsX zY2@bFYuf)1C@u$qSNxHs@+^Pe_x|05_%~|Aq{XY_*j4oJ6IlpMVr1-JQ9bI3~`<2w)b7I zOFa&F#S+R`3do9;y(eK1D5f4Cx^<-rG+xwBH+U+_QYG;kV-EfU<*c5>grB}HRqGRDwlYV21XR)ffZ)~Nb7B-RVF=ZFax1t zhbLS2N!lcmAXllm#XmuDa;=d1t(DC6NCKqIkd()wQpbD5fVHHh96jZjgVmfYVm_`= z*RImf7?~`SIj*c`+17g^(_>fL{2!wb6xagJ{?{l}X04|qVu1LUTk-;*`X=~qXn+SV zFbw&J%7n?p6IEt(K02E|q5SVo&*8)M&y)>`k$e9bh4@DrM@gjmpZO3&1Bz5GmI^co zOc-&e$43uyy$eXj5qEl?egS%cvDU<$oVe0zcW}_k>J3j3hpN>bo8g#%He_RZq>UN}YUs&37M7;NDo7&nlTKVkx zWpw}4aMmnji%4oV#v@zjjeRiqXi_N^SGq>sSs2RxTg4 z-ZzN?3Kup@QbTKlsh2J_pdd>;W3lAIRA9F~JJslTpY9_#(t)#ZBXWS}Q$zVgsC39| z0JAQivZ7duKB?4!({Sbeeaa&k^dI)!&>Y$+qLW?yhq=MOHj)u#5Y!(V~Y;!C}CPfM;MG0+&az>9g_=H4@rz<{! zUrl#=26ocvrhIn^1-Ic?nWx5=*l#$rQKU`e?)EQ zC9Rdo>#YCH^w1r}TF<{Ed-%0JN9s9&7r5rw{A<&QOd9c)$>?rPc|Pz`3*OKd!7C zdV1aJz?X;C>lvMhn#$qJ_E>U{Ytq!N9?z?b8V}#gqA?G^$fJOiYK3ds(I1R{?lr+l zHXDvm59)!|2#Y(HZlFkVU5{s%T;861-c6(Q7Ibos*H}aq+=FLQDy&bGX#BB_g>H zLa3=G1aAmn*ndLPpTvZKix<1WU9bmkisf{$godippLM?u#%_N9bx2UV^80Agj z8TVOla4h0?VAtLNl zMZ(-FLM{?V^JzdyWV#`u#s5Cl4xqe827VmtVO7L*5k4R({yxecrA#)uH&DD>4{?=K zh8Q_W(kx&i9Ywg8`|-e)12-Up#payitd~mYYLu$hXG&72x_mD(KGnR0_Y#vTlTvcL zR;~?Qy?VGjmwR0FToKiYI-s|r3yPHk3DatHm}&Qf(N*#XNVsXu%LVzALprK=V6`eiHO?P8( zaNMi&FmErmTy8_-o!{(X{^?lxtsleh0?!W%07?fQ2nXRiycq}6u25poWVE?D>D}3) z3j4PNH7h^{d?lLZ0n&>l{&*Y5e21#K5^Fs-7eSYQ!XLk1Tqhz!5*c{`ydD<#YndnZ zl`@0=TISiL1=y+oB17H@XSd1d8>Q~~--B^C7zx00(3s1R9=9i1X6Q8pPbg1h?q zQ8;_xX>b2nJv~jgJq?Cvna_m{IsmYq(vM4_1MfeN5EInT5U{mp^X*&v&sNjCXx0zT zY(E`)!|Kk#s=m|lGBWbRwVvXOkw?1Q5PM0!l7?+Rb zGPsDgnhDdrnksa=iQ)^5L2IU0thKYQ+5}J!FAWl!Z{$SLVX|xKwbHXRQ4I<)-5NF2~^I*4+5= z8H0FdgNJsYh>KLN)wNKjo893vtCPd7aa50mn3`KXt;^jGcchCJ2zpctqN4TgOjFMH zb_{S?2+W&2+mL6Xq+Txb=WVm;Ry#M{f&+qGOuK(c=}g|tyy^YznlIHBONBw}IJnEJ zZSIcMyFah?Pxrt4C&likAoUWoCTJv_>Ziqr0#p>K`WU7t0Ki-Xk8unw8BnQ8^n~=O zz(_HuZR=%fay!#y6pNpaW~5vq|4L+HUd2i@&n>+rC}W+#Pz*0C0Usx|5*ZREIwGZ> zAVS!Dq=Ke8Q%_P|=USs>(aIzO-)9?a;5w@JA^^0ZW9cov$4tm%?*2_)_eXq^wpr5- zQGA>%n2z6nsN|ZZkS;i=YOONU-eZ`)O2`OV zmH*KkaAxu)lN2EDi#8N~-dRR)Qm0rFifqA8@9kc2Kr)rS`hQI46?Pl7uKo(Ae92J9 z@#cn-YsWVunW46+Z^PC0pVIfMHRtIk(69FEmL7BeIvG{!2Ic3_P@$2%DgJ(3oP$@9Q6~n_8SuvW0%F`TQ)!%>gHAh}^7j+YtS45vU_#ns0t1jv8uW zXKSe@kI%jkbJJ(*p(!gJU-BdVNMEcK`QrqN<8H`oiN?iP5(}g~(CCrNNZl7>z7gN5 zcRg5gWd&bMj4MIgxxaQa^b#3O^8+cpXz=i&IC@FVpWXFHih|HHt$P3eQTNt=QMX&a z_{@+q62s6b(xrlgAc8}uw3LW+i-1Tf4k_K;-Q6V)NVkXxNOyxYh;lyM_r3S_-t|1^ zIs1Fg>-#5MKU{0Q*IMrw`c8~t5ysEntw1DtB!=-EbbQ}usCGEJ`=Qh+CdqqV_Oi;^ z4`ET_?l=QD&HZy?{Xp|Cc2bHME{Nt8%PXoKb>%#0=wj0CpZSQV5 zRV7W2Fueq;iz|WAm@5RoS~<~xut0kN$?VsCv-01@)&xPl7H$*)ro8&5G4=KiWG~%)eErl2p6LnO z6Bs+a1@07VFan(*-~#Uz9-Wr%PKFz=t8AZ=QCMW2mGfK`;h0)nQ!8Bh*c4Gv*YchV zmfdKU{IVL|^FA)2BdojkVx{%6Nq#H*FL{=t51Bh~8&^BXB#uC<497K=(5%mF(*R3rs5Id1Wh zj#h9hx^(q|bMJ&mxMm4+1MIMuXiF;Em^_yMJGY^t2xC>{laoPsYt0M7z#jp3%fzlB z4%(00D|SZA9iY!8IIGHx-t5d|My#Gzh?qV3M9*e1VYt+9-bTB95tg{b{zWiK)B+k+ zGZ3Tor7y-Qa4om;(t)3m)5+F-TIq64Fm!Ds@1WWP z!`*3HyrFE5V8-Sd$;|t>v?6`U^W)7w+(oa#!~SBGP0<5}tVkJ<5R(WFUV6g3I?{;= z1@aYr5HKl2Ux6p%)3~dKYe9ZOujVuO=tE_dFs`TP1K^y=f3sFT+8YzV}SobFrv~*_BBtKpZzr^)bOY0%CK9=>jo@UDS4JpT)8S zc=pyPUna(&^KUkANR@>h=@4V)&8Tof`}X-5D|F`r&G|-@k`ym%#(sL))b`*$#syE! z*tM3IS-uN3!t*jOzcdb#Sh_WQWIxDNiP z%icNc4a`iF_Je#=i99g83p__y;*84SN3rLM7(z-d2GliBT6jNXR4dAEQ%2fZ z1c1?b>7Xx0?$6rrqHiT1f3@qnc{1hr<=M%!%WBEVKZ5g8L4pgu(8trEGCPmIL~4l& z4aah-v|_o7m$PD!(jV7eF2VFb;7q9FFgLi+I?xU)Y?Y<~f~O~s-e#Nf;M~%Zv9;Xb zbXP=yjcK-B-l2Dq0xKa}zyYUqmizu-XxwBuv1Zp)JtSAU>;uT6u34mVW|tdzyl{|Z zeYQfVBG5M=q1*x53Y$8uJ@793!9&{po2Y5BXNSC&6~z6DVXMntG>l=cfB~J36D4sQhH^H~;cTjSk_+7MyIGt8 zlk-PH1HKU%((WkyzKzLflFzwBX8FZ@aGrjeMl}9W0p>m$YlWf4DQUB)v7AbDZZDsf`aRyg4 z`T(^2YmLr?Et|+D3yrS2TL0yiEX!2`M}X+jHrUZX!mK@~ZrPQ1riMOt5J_OzFkin` z?KUvT-aKbUh|H}8YV?e`eR~IBwqR=R?)TQ;;wHjS3Zec8a36{mhIuGydujLrYx>C7 zZ*+l(+4TGZ7ueH;$BxOsEmp{69k_YEE{762z&NOcByTX>Qe|ZLgCmD=phf&zPJa@U z#XZab^_)TX`|g1k>v!^1LL^Vd?^E#>q~<89SDM^eXX?)4Ms6hu+M8(4w z5x19IYpKfY!;c-LZ%5UI+iwb0e&Py~jT4}ql(*_DT4YgR^yJ+dKfg6Fqt?W08xhG* zI8hGneV$svAC1%6{9AfIwgrDiKIB3G zTP}c|xoX#pyzyGtj4gRe^U+xFrEU~tdtG)M2q)PS!;y62hJ?9jarCM6RXu9&hb zc0Fq<&QDkMG!TsAQ>=aO9rMhBDQH4~6`U$6J6NsKB8Nf=)n!064>I>4mGotL6Dlpm zo*Up(IGb<3*{6K2KZTn4+iTV^&JfHJib;9foT}aC_3u5;(|2WYGV_i&N3<=r=; zKRbfbF1b(cO?MEY4%E{~x3pRyR$=Z)gSq#jooFx#m+r{o(+kYn3K&5;28LoRsCrHe z!i4thnbgB3UlZef$O+!!^upHyqtR~tmqo- zBN1`v%ImKQ0qCED=EQMmyc5d#)~+{_~zE)4TzY@33+i(fqcOIZy-- z3N~1;T)~YeH65weA=d8q69y1)0`Zzm23vr5qAQ7|Y_fv)J**p2BdW-)4^9w=SYGL&zbO452#s@zsYH+1jz+^F5}yY)C(sILpxKUz~O? z_x=5P`WFQJFT!GcNHqVkx-!LD{8n9!@RjPn7?}XKL=+f1cyHkaITE>uL(XPrtO?@| zN8-?i4~s!oNrl8C;2P*y2sT^7QwaI19CY{()dW&Zwf(o*>M+Nir#NuI4pY?Aeaz*+ zBE23n0izanxp)UJar2basesjFONjPzDpo3`fi1M7;c0^GkM6W6rAG#A9{v!jfXqmk zEIS}spi)aaGTn&F9eM=XkjolzD$t=D-dlT#t*2u3u)w3d&=!8-r&Syyy>C_8e7vz) zhQ{XHDsKn!ynm^#`vb6NP$=N%ahd)pHymBSXpr;_YO+ATT}69giIF!OI1I)ROi$Xu z;h&saYho$x%WOJyg74yt-GPBy4zaoR(3s>ld#$*v#d~ddcenmcb+xoJ+HYgYD|Tq* zsB6CS?pD`@L+za}ukKU}tiIv}G7)Sx%S3VB*$j!2ZTt84PSPx5;cC<1WbpLmjtYLij|djr+PflWRiti3^S=WxViP$At;0tAh0iC%|9;0pFdGY`keT z)!LZM_{Dj(#A`-|Dtz4@SwzD$@3$C!5`jl^)44Z{FuK7vzxjj0?DOET@qAqRBgdD{y!-k=oMpp`>X8kqWc_VR8FmqV+iGV-)xuSBl!{N5kH(9=HhV_2` z_D{^|ay@Fu?cQ$byMd}Yq^Dn|$0?+Q6R(B2wLhj+e%txrmO^MaF%z6MuDZLz?}137$*oR-nwK|iL}2kOmKt?s5eNt#E_18VC||zVLn{q+?T;Kth3nh& zzi8dA%J2#3$FF5L61Ggw&Bc-WN6ZPJ5QpcK|8B8~2NET?_Dr_qH;`+RK_96|<8@~` z5g<&ueHQm~20$6#LOS_ffd#QSOy;>bg243ZN+?7|`AQ2!N#+=llpId> zR9^Q@LP}1qbDDu!mSlB1R!!%BKfeeMC8@x>cy~x@6_b)6wrrqB zg41A1MTBSK{cTP#$nKWyD~$atvZ+&xor{LCF1Gx~cl#gv9B=G)0|fGBqoNC6O*$_uJ{RD^zyU*bR!bOUzkh zrew27Cxgjhr6&H16!WVxT=L>4l_U;)OU^5d|yYE3b|Go@! z>EA7m=>tIS(6#;U8}7g&;<|azelN{~zWu)X&#;4jo-X-=fuP&kS%4+<&5<+gX%|A|C zJuNVvFzDhrLVM}zfc5yzwi6EK;r7XlA+e5FkAQcuK(O1v_Q^sp@tjlcJ;csN_gnXA zfkk%i8L@G^Y`o3x+Z*rdFA0L4E1C4Ay$LQ{d;NXSIhTC&Sss|C%tHt)e)#NsE+~Pj z3FiUJ++ET}=gICO=rG(A^2&JL1@iubygNReJItLdR5`5?M^)fG7I^q%(EKhQ?wfaH z6G0DJAUmm-KN^Z0ZZ}iWo)&QI&7=XT>r06nV9Xuf55R@$!6hX`HN6$d$pN~H8D1@+@EWqL|#P$sB9>LOYkk-jc z?n$XU!dc3sFpPg!r}L6C&{&c2G}NLHhI>22Y6}G}9p}K^!w=QlO8RE8oFlwY5j2q% zT|}btuI0x!zYfmWl34R@3C(Y=*l?y|uP?GPWMQ&TU&VxRY02^HJIFPNld=lSb-Yg? zfH-EyuqEUPzCS8=O!C&_u=c%MT2UDj;%z!^!Kd)}4A(xODP;#lepg?#&yri0dddiT zxAdch?W{QUXryIdeZY1?!o_F*5rKh%kN#lcUY43rCr^h$*<_|aLuw2V0XQ4{%ThTo z(Ddrq_cusA*Slax&(v*#P)+`wS6FgR63qyL<7U?)+GXY|u4;MXMz~Fr5a0x&|8@8D z{-oDjo2vr}ov9nZEA(f5_Cy~@F?@Nouz2*!L&bs2J0>MH?JgN2SRLWz13>B&lB_p5 zc>tvLEy>o*y&}JBX4aWC%;C7`5?|&rRut9kxu7JEQU|m2Y7INqjDo`e z3l8sFje(gv%%J=%idx(>Fpt`KPexBh0$pB@m{m&t^n}F|hlz>qu##6e>TazUBl^!&Vi*nxQpWqdU4(& zD2+7OZr})S60hG%>EWVqr1-dZp41@}BFU@8_Tm@4(qiG4J5Foh{z} zg`Zq}&szze@zqIRe`hly$JodBsY?`}zd}t}#OCwEry(!Lq@I`XmFqv=wjP18skBa5 z#ECe55ltFkz_9D0y&K%L-hVt`_5r_jhM#J#F4X-4e%7?X;uA22`{njYNH8Z|eYn8v zkNsf(+k>ae@mU)up`@eR4)b@e&zxK?(?;8#uRj!MS;XS?-l<#@m~puWuKuF`ef_R2 z!P)A2zd_V;?$=uvd$|C`bF(?@$N6q$oap^+#{0_1^-f0R!{S?<=!*zi+~?kVqnp~` z;dhOSSzEOScJ5K~JJ^je0!~lA6V_z~-e2qQQ%1p$p0Dc`dzX(ytep6Kr9{2-Z9-n8 zlVeTtLm`)+M(Kl@9&iZ4)my35Ar#tJ5LpgwQi^m+Z0>iC(^hidi`qb%vLKh~4S7ro z6iiFD4f9oy7Ce0#mWPy}YTVSq_P>FjH7r4eK&!P(8W5$aNHQvMXhAJ9@jU6Js6>gh zREv!W3&$mh$2fxY`oZKuYf_iGp7z1Ql3=Q&wYJ-(-$Ly445=+mQG$~ZK{qiq33j`? z=n(0_RYoZI_wKF-kWC0Jy~&NLqav82a)i?%J;FT)#4Nra^2u7W9B;2%A@rNq-KCf~ z$F&{~Gemgxo#+esiS}zsBU%tWW=GRtG9E#)$PHLRirUA3^BUt5?5 z*|MO{apf=Lh+VvzARGZW{?q7Kwf`nWE_(nIr(9cMQz>=<_$o!wCU?;ovgq2XD0=u0?{t*WBOmePZe~ct?iw7^rD_0pZ;{%`dR;7CR|@gs0qfwrEaB9t8T>1VZIsVGIv}ymzHJ!!Qw!U{b%_;9kec>5b#ip0tNnnL!gA1t+J@z^gPV z_pR07WVjZ?aU>_6LXA}!^!|$0z1K8u7d}ig3)W>$7!BL058-HF=i0(8cL-2b&gbx>evH8jMQ!GiayC+jw+Hu`lJ|nzdEa zd_bnkVaxVng_8Y%uv3{MtYs4&Z3snZ$~;P6<_*WEHt~LzF^;n{)i^LBy=Q0xoodD5 z9QM55aIiX@rI4oduJLGdyvllZ@ZFyxg#Y(jSO)2D^l>~rZe76G9@L6ODyRj_A57fh z5GaKKWgtVk1qh>&Cp{AeUo%7cCj(sxXJX!88;jSBe8~X5m;VHZpFq_+}B(QDq%hVMLcRmvyhen&6FxN^9}^8DuW3olJp|pob&KtBhr8 zW2;gMDO_?18=-UGuAOq)+^(DRsj(%Rn`Gpq5Ya$T{QdEcfMTY7YM9gSP$O&)XO_m_Vc2uNSyGU)ko=~K*y21TLXN9 zN+-cqqsY4tYesYQL--4HzutfOh5s?WQ@>Hzw8Mk|XL{|Vc-C~~Bx(EW)~Od=1GW9O zNqX~Bc)&O^`%>LWV3cEbx(>jRp)RxZFk6Qieu~g~Fu+$4S`NCKdS{80PAPMl&2K03 za+%I-?X=tHZ7~{)+(SQet^9+&kRN^Q*6{|p8l5{%^U0w5R=lxxYoA`x;Q4Ci6=^Zk zICZVRz}@a*Q}|p7eMMS)wHE)B-erO;lEQ6wBJQ~;xFt-VZ9_*URXA`d?e_cQ_j#w8 z7MfwFZWsGu+z-xa?IN;l&DaUqkkWgb=rcQmmUBuFB(N>vXQ5UL9bdSVyafF&$0^2E z#GEG)Qw*f~r3ky;ZPZWzsJ_5$t?p3Q+Rp zK?Hr>(l;}QR5H|zsaH?iH(Pl^jI*=o02dBn5BX5{DdX$PF(@QjqXrH{UI_ zFwAhWe7rr`d(!(F*xkm=buJ=u9vo3gT#V=U*V%E4d7_`tEEfc3%W3Qn2ZdZjhbpbh zGiBZeR~(LFC2A`?&b;lL3yFlg_jEnh{H6gbzj18k+6EH03)p+S!cr5*pw>I$_u&;2 zKQyLK`JtWnh!4{bHH~}?TDv#m+02yG{^EEUsv5N7t7rY)O5k%<4IGl|SeIQxGf+FV zqRQ}{!Z;<5&T@|>6SRm-&AlaNc=F}fRM3ONK{em!>4Z;Gr7`kF14q_5UJ=mFN)t`0 z`u>Dv#{{LwC#~L(A`6lz!I+kpA#cXJ$(P=BFud#}e-CfM@v)zEijs4pVCSRs%<4k8 zqDWr-2<1`!oEpdMPi#TBSd5;0NRnn<;HX_mNzwId{~Ij~zxbaCk^g96y2pQwxcS9; zLlmPJV6u4FT1}2M9@mtI{O)u-d0bmRP-5%c_w~5E7We&j$>T+V+chGLe_F<2fC&H8 z{SrB%y_@&UU9J9l6ERR}6_>p-p5o4g`(Cj%OLTK!K|Bdjf?R<`SKY5q3N*4>lRUdu zf8W-gCPD1E%i!+!OMWhdl^O__7Znf~WZ`73f$$HGijEP6g&HA9_+nGj(g}QwlTy<2 z^52kTnMC9klvkJln>$=s8DKmmjvHnMqHJhx@3@=k@;s-re}ENMY=@{H{5;Uo1H|Bb z7@H{|`)FS}yIhXDFgdldl~z6RqHcQo(4+fJ-_bd0ZO;Led<ho_ zXm88iA$?n6>u{+8yR zDoN=F{O+(HdsRapGDNh_l3tLkKfH#2+5LipuTX@Lu^^J`{CS>c(tK>2Q1nreOwnb1 z48OZ-fohqJapvnPd~3Z_+vTMu_fJ~7O|Q}hpLOuq^*5UxQ?(?3O=22@d^z?M%&6PC z@7I7Rj9qVrD zYlKgGddy%(KINYh>PN|agNOV=77vr(LCYjee80^&vVf~+iCszbOfFhYbi&X;MzbKt zTw*&TCss^a6YPv_7eIoqqkDJ7T;BuQn>Z#mykc&r#JXw^gR|3OycooR`{8x2SR2dc$cSfcb#e3GIyt=4nm|3&w6$3E9(>a)Ch&I zmkJ(ow3VSJhdqm!)^v*r-rYfMRthwaue==+|Lev1|BLST4;N?N;Lm*w$CAYEBSC$z{O% z`Yo4wYUfU?ywY~V(S+^s+&ZquU=v()$E&32!GHibH{oUs- z8;#V;KThV9-`qd$XZ%^;KgCP``jnn!PV{>ZZ}_{j0OO8#C!fLRIfrl*{Pe3~9g~K=s(H{umbASzp5#oUz1EP0N zgWu+Y>CIP2fu-N~s7_lC#M=TYoQ z5!HMPm1j~tT3TbjS6G4Zj0Q!I!`>~>@)7iy6mzs+|Pf5t1zX%@gGlM~hj&=>-L*W>pDao6UIMyDHk6 z^(HOhcl2}aHT#;*5 zDyYsoVB`{s7^T~=wp03}93vCXRZCU8#7irw5R;X=U2J{+wpLO#Q*46DXL3_7kwOE3w!%Jknns zQJNkq#Wk77;uZX&@iM%`(onGU| z09kJ>dm&-3I;gh4$@h()dOGRUZKfWXxr>a7bJlibZC`4WH+?j{=2-vY$%PwE<8UGD zB@q6y@3#5)dB%=w`N5O5VE4x#18mivt+(0s)%H#AxScf3;g`8|Da`CAo;0sLEOYzP zH*?&0@@_Ar?A5Bm?D^zL%jrOw$4TGp&-0V_N)6e%pQVa4Ah=neF|wD${d3sDr>*eN zavxU3dD!FAHi|*JUNW1)CmRM*RGqi+=4*t_f0bragCHO{IQQ52lf$O3(2i^94_@w5 zU9v!o8|+k4B!N=%zw>e@)p3Ks35&+xRNe#e>S>Q^0@ zgG|yHh!=Qr)qxF35Kc-U1c`faY+O8ls80mJGazC$og`cxlnO+wqOy}!uOe2f49Ic} zKqM8_&F}8REKCsoEghYFFx*lDL`>JvFcU$YarwtDLu9RXQBC8sMK2xv2Ip2XCi{%1 zSGUtYZ5a8@>>PQZziqZ3U%XE87(0gsW9$+_+%Slh3tv(u~9E$$ANX;*@@SNarH#8t8bDB9gH-JHX0t^zav3+JyJIB z<&v?tRUM2*_SA0DZ}ZD*_F^Jc;f`lh!6m0Z@tfgVAb$9e2T4+o(RDX@7BY?bLq?s8fcBD#NZRn zTQGz%aZmfaotK>s&<6`mW4%3-rNzV*piGHS+J~4%YiRa#M-OkaX@_b$t()G~^mf6;-h%=A*Jq#%YHV6no&1(j8(MQ7uORQ7(WBK-1L)N(1Wto0 z)<~uxQN#oYN!32pSUapzU_5ceDxspXdzPTq3g1`aA?D5-1Abth154Qu9s`+Zwc1dQsZnJ zH?p%@gfEv5!Fk&Jt?28mv)w+tY8VUmN}3(+Nv=Ixg{Vj4Am9*+YI-oE#f=BPFb`52dTbe4 zam2lF@9UMMxU|}BWVL%fWRo!vskJt$*m6&r;Lm5`79Z$Z?7Z3eKI8E(eP9R;_vGRG zOmJIU0xI+^fTr*UTqM2#rZMcR(r-le1h-u+B`knxG?SvvMdFfB^`n|5CL?xNcPDG? zH;8#LiI0E1^i7tzP?vsVNV|nNVTe5V8XhCbk*utEB#(DJgp__=uv`3|TA0dx1{x{S zOd^5(i1_v_YF-K%IkEguL~l0RLA@Nd;~llMDHS%Eo?a2@k6{^wAhySH3am!qI?0ha z#E&OD^=n6B>!+e`X`OZJ1M%c7?M&QK{QX7@2MOJ;vWdM53Se;cu;Km{URw4WR+`@u zokw#8vn;zwcs_xAX!7obS;{^)>P;Ni%eya}-UUk`PMJ?$z0YqssBO!Zc0RRAyS=Xb z3R@%1g^4ZS5jt#xn9G2Nuz@>WWiZ$d)$wSF_?UZDL(ML$GRcoLq|+uoM!H2Olf7Kc zk#hstj7RrIH~)j`PyUvA8IB7$P(p)v1vy z8-wi=6JJE^^<%L?zf{{)Wa>kZJ4H3;E^{~W3D9WcdhvSgIM23RuDay zcAUUirt5$Pv)20O3@_4ZtCUfTk2;gNW~8x!!8SpyXZ>-YP5w3M$3+9DGa&JRVzsdRbIni3C!wR6mUPQ! zpD_qEu)wjSSW|8)_G9WA#JP69^GPz6t{fkzX6)|VrYXEO$JOGy&4`4tI-E>| zl|`Lv0Mi+kydIs$h7X@tvUKXaPMhPCyvg=qWWW1@DTe=Xu*nT-bZ07qbrkQqB!f(E zyI`t=kQPlLt5rhMr~8TVU5YDrk{X^8-6_SrHLP%Jmm`1BOANB0`}74fkr<|<7S>AP z3P4(D#w_1w_*I#6g#d`adA}flL=MeOU8}z$fZZfm;0Mp}bQ*@C=RG!nVscH{{}f~d z%96dY?e>0dFHWs_vhs0-+kkD+%?>1?m}(=y`W9UYkAICI(7RIRJcZ$c93JA5{ie(j zuzT}Rha@^FIpsQ;t{Nf{$eeYt3w{D*&X)S)7V0Co%WCUHVFYncalPx&t-K`7PeHP6 zJ-tjYM5SSI-$*OLkWtI0iL!w)qnDF&IiFp|=U1W!U29gieB0d!!nY5cE8GzKhv!!7 zuAsB;5T^>2{(-xmxH(%uzMw(dThXoUR-B3jM8FA+?v!@cEL{kVMB&~VVRm;Ev+U)< z+1twHZrf+tjmZfJGwLWl38Q`q9`iwaV*B&zdOPLj454eaLjI#Uz478n;#2Fnd84tI zN8IlM_tz7j>Zz)gLv!`UWA$4>+RkLAssd(TQxzozU^g3h*?nLy@VN9N8l%O*@RQvs zj^S}CX($d}Nq*3E0sS07hdxQwN;Z^D!@^f)&>g!S8zPeRPXggb<0z`<)5OJ(>pq(@ z*4lg^(|A7q!}DZ&7VUlQy3&6H0pu%VVQRt?AXu7n2DI^XRlTFK>9G~I} z0w)=d<+0ddqb;=|rZWQBDdtl3G-+DPI(jMgWL9e#{w#%SnZW`ZYgyrcMgU-*9!o-r zSe4e~w1wf;Q08!5EBwMci|d8FK8cX@@>F_GSoK(9A&j)S&>BWN)vH+gJ~wa$x1H=? zvA+MW%;5he0{AG)T5>p|cz65olZwpEqfrg5XGfp4%}b8P^qjYkz8Ji{d0a~u{j7H4 zOKQpSC(Pn-5Dc`q9eiY3w-4|CNYG#;fJ&o&&JK1G8tk_<(g zXC(*>TF&5p@9PfP5pW3z9^j?<)hid|xp7eRx)>kh75wsRH!u3^T*ezrKo17>Kb^Q| zfCi_gdtxx5&QGzMtL(vE6#WL6tb&O=B_Wnu()W9Lh|r8Yq_Cvjb$-d`J{M`Z7hrq0gCaB)zZu&HmS4#kG7 zeMf^{)ueLQ$YayhBT4PGAABZGw!_4*d;049F6wq68bgF;@mdr=1j7*p0`d$3#&|gl zKcX?{qm5yo$AvjycYHa97c=hL$x`fm!wAbpFj6OoYw%k|Mw4VPQ~LHOTG>SfZDh0Z zP{>KTqQkR%=yM)OnQ*~Lw0&Ft(`H0xeh0GvT{6gc?NDJE+^Jj88%Owarw^=C}D&_ z%GW{=xJ&1u<>zpeWpSR!Cdmyur(bRUuPQy_PnEtfP@}2kud`ll#~ad8V?%yhX z#6rXs^^qw3u@x}uos!JicL8*nwZ~1fb|rDNWnZVGmCt}#&-{hrvo}7z;$)tRxPHMQ zLb&dskx_;)0_{i9iP7GgDM{%*FiIVQgpB;xWaipw1!d(zxfRt`uwtFOnkIt?9oOd8 zwh!&P^&Q=1EjnF2gUG&|p-<^SqhACA#=lPSOis_)&CV}bE-tSbtgdfqZElb5?i~ag zj~&i^JpC?nt_dnVh0@6G4Zialy||$#%h*E>ZKPmn$~KK{HwS0P+PQqB?BXO7z9-?c zoF!{Mka(#g)T4&g5lfLp&kg;QAWn~C&2m3d-MlYVRJjGO5kH`hUqE1hm~IoO!)t1Fv* zkHWY{r&wP;|G}S_Q@_8yVzDcnu}ei|9^!qCmXiBaMa&!v7h9AG{-YIy>60PF#65sw zk-#ocMWVUvU#|Awz8Ab>F;}}JjIDPqc-xWp1A)5pWy_*FFzZQ&OZ;|gq-ZY#ZjH2K z>pS+o-gV-SEswuxB|h~@pE7qn)WmBxhf>)CEyjgQm~r(>Ue!M4Ta6ImhSU!EB(K^H5QfsTe{4@*7y7u zm0n5R(=(Y}M+}0Ar_u((bmX256eO5?4g-D7pKs;C3rD$-x`i*|5xj5#gYUuVvwe^Y z+{iAtTRJ!XbuHXV0%nDAMmUB|aykwLIZ>52T|TbQz+OZDo%T7oEzH5WZ~YDu7YO)X zZ%7E9&j@2bR~txn$P{IJFAu~^LR^O4`^4JiYc$48(7^qO`~8rPO~UW!6LW#Iw0Xv(5+KYj`@t`D?>B4u(x z7SQBpb|l!u<%#zGV^2`W>#^588(TdjR?ark%RK5{lx5KgZ;d``aoc#l8|q?mvGdbs z*XWD&#kcMtjf;3v#gfNUM2WO}`wZOW{43-fUmBq?aeMCG*qR~YkUVGl7JV2d;ogVW zY{=L8I&a=HoH1!MGhxzF&;p_Czc_T50TEqYpp@V7ro7Q_4jnd|f2%^TcK;I5)t&9| z8{Yh#@i1O|yf_Zv&GM_8&lLfC0EpI&mheyXJr)THi zFMj;I1UxcnWXscAy>W?CH&BBh81@2vem+| zg*Y~x@2 zAw4hmXz)+*c~JH@xwXap1LI9@;L#P!`UG%EYPErG$StTq76#JO5md41Xn8g^JF(CL z6&Fc=a>cvow_oc|#T=mFxIs}8DwfwUf6y8--#jq2^ogs}pr?(Ow98X)`W(T|5F$Ca zV3254szV!E#tpiVoqx|$tH}m)3paHh|YdB z9Ut)Q364)^hrDRFRRvtuF_Qw~T8yd~V5MUk;WR#uwSOiA!GR{7@V9X+&%4yd-OToH z3$n#S5y6hu$Ea)B|8b(VoN3Q^* zK%#wk;piB7Y&>)Z0H3whu&8&qL11#fc9g#;9-3bEcIdcwFvAm&F&v}XKLWx|zyrEP z&0M|+$8^cg3XzDnP{ol!d^DCOmDKT3A*bxgj^^z}E{Tet!S z#3JW4(8OS+&*{v>FB=U$S~lkMRw-DhSwAd%jJaMyd7%Z1{I@O3d~>57G7h$XZrn)CdWFpyzK zSF${P{{y&z4MZ2$Q4#Uazvq$VXp3e# z>bV885pN~{lmiilkkd%ZMG$%1qDku$$-a_?6~4)Q#Yc%qd!;T1K_m`U(XT&}6NCeT zfV2MgBd?=MEztkiup-$y|E^*EvmYtQ%UI^leEdIYSgsrZhdza@>Z)O>!5aUQ4Qqts zFF%q|KKU;{a;m%HzxOmv@?%29$iU&;$V+?-NBT$7&>bY&ljKpl0U^E`DG}y1h!{$hh;rBv zj)7W(zm>vESCJsc<6eM61ROJnFz8>ZKyK$+7>U8^yCs9M=f~SYgoq_$V&ouTqD@uH zXcQ`kH_UWRK%kyMnD?F`W6WGUZVaA?c!6Xjm*69>_>b`cEHGv98>V>b9>{rqf|23Y zL_QBWuSYL5fz}1zsvnF{2|oj?nT>q7k;+GQ2FBnSWLJ*0r7BcTQmd~w6~%)mT83P3 zx%mdswo@u&Io~<=33BWFfGm7cuRRyD3OY51K-ty`$Sa+~LFu7x-ixJH^@7Nvua5Ft zRGqNGfvCb*!{Y1-wsdPFn##n$5J&@6UvV+iVso~BY2yR3T#8ZwRnMdoUqZ-vu5B&> zQw$)f;XD-7kPc{@E5_~i`T(d`)2-VB!SBm03zl$&Ao<1`2B1>xi%tBN(?FB*Rz@ko zHlN#%kek%M;>0T_H^iUB9UMS5Z}nfN)qjE$H7pZ;cca*Ld+T5J8&0&SWc?i{-Vapi z{|zUm`F=;4S$qCFoXC7T{a2i5ms$1)PJH3r@K>D3!r5_!6F+qI2UJK54*d^tBF7(% z@YioQz6=2xp*It*YdhoLH$vzz0e}-#?{xpyIMIPes12==#7r+qnp7hm7@<6niQJ4X zhGNmCJE=TwvmUKyqA35|`>&?e|7YLs{pBSH`>&1g-%YE3xKRM&j!X_x3iub$O-BRJ z6Y)poIokY5(O8TIYnTI!NgFJTs*GrQMaEAGZBfj zNTOr35d~@xJu)6pFzX|DZoErQwlOh=om3>moGOADpOkxUMchD?2NcaZ{*ejnOjn(g z%9|O^0(GCPio(|v=RrqsBhO>SUGGulLrG;D2@~$%ZCGSnXEFe#VRIFRC#c=m6;Di* z*03bOs6X=5=5m7)CEIg+V@o3~vGgsZdUtM((=5)kMH-gKL4=v=@R2buk7~G>9OIC! zC>#kSW_yCMnTA`dO*IsdIGN(<#i9l)=bc%#lNe$(C=K`Z``GBOGBsbuve2;`jW=v7 z_5oGddl!G}#Qe^+i|*ellPW#{}{I`q)A583}G`T!N6rX~3keZY#r z>c2J2{n{HX3|N3q`X;dMpAK`bh=5=RkUBWzmtih4EamTpx$6;s`J@0^t+H1kYkp0q z+S1zDl}FJ1`!FZb@$r{WYEd!!-yY`v*(d!=Z*0akWa5cp17F4{_OzqfRz%*lZ`F5e>2SK+{TmDfPXbCfnu0Tv90YLiBAzaEw;T& zs`F8=wB3dM!%FG@SD*ARmN9|t=%=@shP5={j@&4G+U$;KFyYcCVCIE5B8 zpw5N!tHdieyF#8YujRwR&nlrNFgI+?uvB(7I9t-IF@v@HT9apZE+S0pBB?O zK)RO6uy&y~z^^78l!wF4(E-w8fDz>sowIMKlve6kOUkP8AhXDyxptIBvhc;_#31I( zCGR7IJ4(Yi9K|519<7B6m`^~SzTg~j>YJ3sKohNnV}2#T_&UY|syd5y$0<5XZo+9g zwJETnULBMV3*Tt`xLtAccoWcnBi(O-q5i_8Wek!9-mNq@^l}I+2doicm>OIhamTsn zU0h0>mz+>aMm!a)394ZmBG`L0_XCEY;*KENVc(4h>~BuJA$StKZ<<7|lI_rWY?Anf=QgZ=o9Y;?|R+JjmA2s*l@yLxJ3`~Pj2<+p#Pzdy#w zC@5MZ(vQg!eJ?0Z?d(pGdYCi(X0qJ*uFNnQmYR5hBveh>@qxi?Sy9LdQ}psEt=KvE znIU`jJH=)cC{hMj0POXTH~l5pd)PJfw5fd<)a6xphjmx!OqrLMBch_~g;Ce#L*KyO z|C4`ap;ArBU|9?{d?%9f_C!n zp__@6m0!_KLEq+>i`UwXm2X7&saAJk(aqS@n*h2ga_jp*Y$iJceuy22qOD66M^^s? z-TduuXY=!8F=dBRc94G}D0#=f(_7bMi4?EaeC7+fnX-cTif;Dy8?UI-DqBijPnzwX zDAsM57#^CuIa&2fj)e+l^srq(ZL-P;#xA_Ye3Zi8=(-D#xn;X$b< zYS>kCnNb)v5~m^bqIf`F>=KFXILKP^l7-)L$&r?{plmj+q0+1b`yN!ex{Ew4Gd`p{y5_qwXS(U*jxpE=@{-LR~ciU0#(SN7am*45#yf&Vy-Q2a$^pu{c-e ze|X(8&;Y(ZB-`+gs~lE?<7yzAL_=RT-zKOHP{mDMi;FPmz|*NZMnr5iA&=D_GJr&vbmm<`LEQD*LoqBM5=$tcKndRng^;8iETO>USX7#pTehE2 zP$AMIZb_(U-z5}ODEoE^1tVDWh_CGUq+-d`S3-f4yW`2?QrN(9-Sssrp`f;~`TC7H z$=lx&3V-33`x!CqJRn%j^!1^5zLfqod@N5Xn&DiYi*dBq|E}y z-J=>ec4^I)3X40YX;ezTrZqiaGhJx+Y@x_hhv`1nwwFPm7U<&8-y;|mLHgA1C(Me$OM|yiFpoubmem_P_PP~mUz4r0(n7I zlem*P6-PiEl%^6nsDXPyB9}tNQkoBy%6H}c*~}B{qe~=iU9Xo&JVr>^as=K`_F|45 z<><}iznT`5&hyE-7bI0wz((q}Zat2he%^^)K1cniwLG3ncu)#g(uZD9eslo}Qsm56 zC|4HGhr*9^f{No`jTT3P^@KJ3l7Q%2RP{wBUeYWmpQ9Z^lQw~B3Hm`g@=R@@>eGW2 z5eQU;ID#qcISmdHT^_qKHvobn7lz22m?*qba)+nhJcq5%U0A;E&FcCr0ANseg1%=3pdWp!FXrq z7BGCk;|oRiIBs~bjx{MuRL2AH z!JipR(TT3oLrTVfP0{JuA{2$9(zQ#6Np$auUa@vvx%bCHfq(E2^Q8=WLW<-)kpzKn zqjaR<2>P=IqNWg!;`QMZbX zQ3i#@Ca56Lrs7Bhyf+Tl1l|ieiC2J5QX^qkjn+W115imM+ma|bnjJU&a|L@)A_U&j z8x8IRvW`BnVU|guY@RXUW(btU8B!~DJa9<6h9B5B9Qa8Tqw`Vv{LG``1y%?YIs^|j zT6luMWp;@+(niDdsEcWS30<(o9gCyhrWydHpJ@|P4Bu#eQr*Cg#a0ycCPB`4Np^+e zCpaK=L+P_z>ZGWS4rqz={!xR4JIKJ8?>`1`UBa~Q+o*Zr(y=#c9)Z4$8b)%gU(tQM z{L7IeCLv?z)}UVKmHd;yZVJQSZrLV&LU}dc=1{K2;kt8znckJ{*ld9++>Dxjw^-dZ6;R9 zaklj0z!~9VetBf#NOmefYR7RFq1uWE#uFJ*!Bt95mr4G>TT^xvN90~iRYFB32OOE&{_`hZ^qgQ^+F=-|N=L9Z5=bfaPU1 zmB26~lJKZ#OY;~kHkcThoF>Mp=bVledKhNr7um%X140jn(#o33(5v5t9_r`YJ4Neu ze->ab8z>z9S?D1etTgg??`PoyueEeMM+0&*KWYW{Mzm%J`)cHL1 z>NPm}qulJDGex$3B{%yH;D6uCOs#@~Ud=h`+|v?|5~om21mjSPqfA8D(esCJ5Yh<{ zsDO#NqOA1Q1qDfdK9C;ws*qGXuhu9dDZC?)nG^>!NNlWeHf=mbD{zoF$*^`}k<4J} z0<*k|sb7(tg+-@@EJ4p;Zx-Wq%Dzm-$-$spYVp}(3V*Kx;KCZRrdTSlYOJ&1AUjAL zKcdx1Q&L%cO(xz!f}RBhcM*nz&DR1}m~cGCRSMG(qh)85{Nsy7V;~=3;QA3ZJ0DVt zSaeA@hreB|2cm}S(0(`$yHdT~zfze6?^~%pANAU&dWtX5$KE9(!B73lW_?#Z)s^n5 zo-)nDUM_8|)2t1AtkY5>2DF#KA^Lvm#IB)O)sy4p_@v{M;o4Ejd#Wb|l02;Hi6O1D zLN4(eF3{YPT)sylOI-ne2H&>+AytB#odqLU)l+W9Bv$n#Jo@1AY;ce4qbJsOORH-a z7oYy2>gn(Q3`MuJ@$Af%3uyMfrRjXpum)M3&bA1khdC&d)IVr$0k#AU>VPq@uR=RVgx}vz-lj1~|i$ zd10q84LuQzt1Hl$qlb8 zg)CV^?eAEyT2|GSu*Rf!cVuTHI|_x*n{dcMWarq{N?y4jIkXev3HnOy7ok=^6gelb z9^rv=zOP3GK~;JCFlXDoFWM!Qs{CDP9}59?J^BWIeSJ5iCmLRRY{C8&{Q61S7kV+` zi?q**ASu;6B`wn^BMYOSlN%2^pI=a_T2dBKbgrVZR{CmPqj*D8t8mM;_7m4{_z+_| zelQ2X2E|q18Z{dF0)BaP&OAH`-hDUdMJ;}l_9fB+FY(`%_Wivg|6ES5aWpVp=+gOX zrFF|WP|;jo*e>{W$d3V#_E{gtQ4V5@A_!!iq!XzAYXV~h9FE@?82@vMyyee|yzJ5- zuJsrI(;h>r&QY-u@l8hP53eLg2$1zh5onTPTFp(Q1U$`Kv>!nsCZRs^8o_bIVR7h#0e0Gt_Nl?=d>`<0u zNvHmHzK9X0K<;*Ss7upq$nA|YLXt5|coBRNXVK{AmH_n0KmEC^b4+F5j90aF+ zuV$+<{oit%Z03h{_ZLmM^u2JBFV&nSKIE>*<4dws?{!X+4ouYOt;`Bu`zlnGQ~8D~ z0YX(f)7|}L4_ESu%go^k02maeyuw|fYKFV6bY-p5)w(p8enaCm$=0@{YMu5Q--N0a z*|$c=QtZcfg{sWW8cs8hXMG<%SrDTHs@a)#7gzeVQ1$Os^H-s2fZ>21GZ>nUV*iAo zV(wJVQxc{>SGKapZB7mt0}M(I!kARu6)Ts&=sHTJ-9KIXen9(3IGN1dMu9}1640N@ z<^MU=9QkL}{3Wn`_Z-Go2IVWRMD=X6cO=?x8#pAV3U54qReVX6Yjn*Hb3mcdrHe z8vO`L+Fzh$o!@}Zb>Wu6FYT7}7r-ZAgaKZo@m~}&-jnHHDZaQpn8rN#i;`N=H74E? zy$gJ@i>7C3XJ+qLQp-^qVk&ESfp*)}d?KmE9o7aYshNm%+X1ejq6c`5=HDDC2aQ$s zO_Yw_Eg_ltrldB00PGZhrlkI}0+sVeDDPuG2GG(u`pvFm?Do`-4D^^iM z`cT0+5@BO`vc1i11$U@#7XV6X<|OAe!c>9E&%$L%v?EouHifI$!>0~(z(9@9sv|sZ$L5o>#M40-#GuSz>+m$ z`9Z1Qi2u7v{Sd~rEfKlA7a#LUzM>sx$ijdIXsm#3fKlhP{gToZ(=q~5w6d}Rw1ble zOChIwSA0V|j7qR*2cXnXZ0+pn)s5H%)-&>e2KX;4_4n78Qv^OPDF?qCiZj2@l?LI> zHEvRH2#-Z$r)aa}CH_#ds4xmmnP8!mAtFEbAnhW{ZEA8K0;vI~5;Ycvm>K!9e}Gc| zzXGgt@70&E$A({^I{T~!0-*}awT9Y#y$8gUJe>kzDJn5NC3SIs1yKR79&&KP{t7A@ z_|~DmUzFM>LZ~4R8X=hmJR(@L0JPc&9t(&9yULj`)gj0 z{T1{@%>FYQx<}2Z1SPA}d-JOLgNM0~IhYQXUIOl_KlUP^3Fl^OBsz6D6fAJ@-cjSnLvQk2?U7Axf8;p(=X5B$ zztW+;UX=QIgnp%F*cT4k5|+vvI!rD~#z_}#YV32I*@*z@mWFPp3L*QS-B=Y28F>GQ zZG3dq&t@YrjkPWBzSDwtifkqcRJZ%+#_BHIRbpWTyFp;h8sclXRjJfr`i0+h4I z^V#7O8mwiGA>t`#8pX|}8cu!JJ{y@=r$3~3ru5T;_vTg=n6rnf6lWG#uo%>mDsN@c zM7gVl>4`k-4wq)EkNdA!9{)K7cSTW5(5RepjqVVsor^j8)RRIJ-cUl z411vK&)cFBEiWB5jr(K85dbYOYG2D+E%+_!2`kt`J+UU+lGi03@i zr$)}RM-hl3MSVP3oE7@w4J3B*CQQ)_L+m_8(qZg3aZaT3XUziK*>ZK3XdH-8-sSda zo)|Ix1!re=Vm#&i89w@?(D6Og^Zx_?4!}k${#nJ9SsaE#n@1CMb(D(KwPe(^#lr-? zz8az%vIc;PgG_b0h(4MW-$%}3x3ahUw=%Y}-xk;?IR&<*yzqwnd2pghh|xLlad^&xxh=Xz9TbV84((Vc*n%va;ar)^D0@O1{5yae@c{^e*yS z=L&yRx(}lMvaG4%?G~2vpt;&NyyF~S*}yNHhx6P&7M3qjSmenFy_l$YKFWk-yEvV+ zls$-=S7jHX-se0NAgljk%+-YL>1g_{7664++~_roUDjL&_mP|bD(f$$MK0~qvQj8f z6WK24ToI4<8;H{&-a((0>qW~XYif5zLY^!rvhX;_d+utvpLqa$O)-la6MqcBp)!)t z!6FG~3Bq`nvPnK>%{>M)O!lOU8FIRNk zxAw)Vx3<;9_!CC_gZ9BxkHTp%aOtg;h+9K&zqe}FrsEwa>{MTtq!!Nx3X7=@dKnlC`e zzgEPDNhM@cmeu2r7pdM5i5d!EpDb6eFwNR@`Zq!-{y9~q`Day@hpz#L7VswNh>1`6 zX)}j|#lxLFRZ}2*v^Zwpp9FhVc58!42Or3I`YvL^URL-B+Fxike`WRmnT!xPh`};$ z9-NF{-k!d4AJBehUHq{*0}4Pp+g<%Hki>^2CZ&c&qyg>hB6wF8xV!pW_?B0(bM0AE zjO?0fiLV0U#V_q_FK0lhWp5Gdy1vV}{mq<#-xM09#K5jKMU2PzK8!fjFCL(u2~07y zz??jNzN;q=wJ@BasytUe=C`0sb;6fGirA$Dk&{GBL8D`09a*Goz!tUEg;pxlbwJ(v zx6)4jIfeE+=$KWHHWPBgFNDD*wnL7fWKmpR_z;VR9<%zy+#!0K>Fx*xdghVO$L@dqJYWD_$Lv2!MN{CvWoK)5XgD21NkMS>kVSgzE z?4MI^8h=!7D?=J;QKOw_kycuFHRQxq8Hk`D(v)!StGbj?3`?-cNa45GEq@mggA^g0 z5URb}`1@az*gC`g0eStG)~`Q}c?tkU{UYW`gc7U%+waQwnq$Ko^V>cDZ^t|tv*NMw zc>8a3qTqpeaY8_j&8?nrNnvBIcw;l^7zqJ?YWNa^94(8=&YEm#ZDAr2^4uH}Ug|%b zp7VQDh^Hf1l4gv_ zUzX@zU;;i;wl^h|V&;i>I9KC}DT1>d>px@&F^v+MlR!m_gcqUoPIm3zyl8;ZA^|7w z+r0FJ^9sJJu)p(?KUrHDIKM)y0IT$f8`!+WzNxUc`Ej(K?pT4)0fD06pk3bklJ~Dl z>sx}Dkt23uHZ~pSX}-n>@ZKCg9YBH@OAMBmygYn^3;^{@{O^3VCy2BHG9&GQ`Q0bv z7{R}*rCXobdDv>Kw8)XnwwoZfM4TdcX$@)tS{}&|%i2POo9}L37RSp34E>8#B}Jp; zp)7!wj+}Bp{vbr>==nXv&;McG`@+wqMPX6$B$(RmN1&oe=o~Jc9kT>JV}}p~M{!aL z6scXhBCRV~Q!;PQ|9QYTO5$6NA*pij0uArx7LyosAt9d$XCvun@B#^r-&c7y>Ku8$ zs=NukU5HF;SJHfw2HZMZqdQEMaoZ9XsJxF5K>r`@e+M`?tM+o@r>`G|`Uz)y7WvxA?u91n-u%W4mM;~;pt*%|av#YX4 zudjbt?I!k3i6Tn8b64gzkf4cGTxdU;7lQdOWDc%8<(QE#f0j|8RK1B6xK&>L0A$x) z2053pB56AP7b=b-`c2QrTsm+{Pn8@1_qB<(&b>~y{R>e*f1XLQD{#}1!J9fKI|hC{ zU2Qs&hpS=2O#wqbw6NxMKM>GrFl&Dx;v~nzcCF8lYzAGb#}RmQMD}^^R}-&A7m{SV z37O6fs7;t!IVc9E}XbXkEi{ZR>BLLUH6~g z`2leM;a{t~-JSoNsrnnZFYUX=zf#;d!zuQVV*t4Bp<7C! z=xaBc{2HYXMn!kUm$FLHXTn#?Dn8)bl-KYqTJIj5jV=)+w%!NVQ3Jhp=LZy}Ec@Qi z>tc;G<#z&=P4z2Wx7ZLEU*(Z06?=O{AhL|B?6G4OqjI(T!?$g;HlFG4cGDU?uLOna z5}2r63X6&54T(#XCk7{_C4sbIcIlYV$lQX{`C1-@WnR(cRs5O2D_1a~zKPLDx3Rg& z_uBPNgSM{PRGq86L+U*@3vcM$8o47qK5sJ}xV57xq1#+l?hxjcwX1`=W@9C~r@}|w_MFcss3}D^Y^Y9G}4U^PSCJv8@ zJ!KV_m}KjqnwtDAm{iQ9px8E{q`bn}Z&#wPa^Bphz9k3L+}bXZZd!DsCl1!#I~W!@ zbc-|Ce0byzE7)Ru;vOCG)P?DpJJEM%7l50)iwnzUk5_v~pRK<%eE#aKME|=FDgz&H z%$a$;KLP}k!Vh%Tmhca3^pyuAFVL5eJCSy99pto81UuwcL`U&^MKW&;cE#15-5~>q z5tB&?ahnY#>N$T2CWWsu{bz$oGnvIZ3E1e7f@Ub(fL@y;FT4>gwIV~w$8CetXSuhjoM9$Ayr*di5{?a=ttp8RD@GiWUQY>+0%~d zmnRQDUwc~Jfyeo*ribiEc-2C~(1N`_pY1cQrV(;(uJE8AFmwnIeYk(qE(@Rd-u>^4 z>{;untq&`mNBEttIp=>646#Sh{KA` z*EhCBXI<|Qs5HLX*~b~xKjbWDaqZ?POUrrU+hcd*O{VTXFunh9Ru@PNSDjyMyl1?; z(r`z2^7%{UXRqE0-+I>uGVT4aBjf}2elsF}-4Aw-TG2`_E6D`0o55y!$d63SWO(4J znKbTT>c;(*s|9j0A&EOE5jY3)&6ML?o!+G5GVN(q)N|N03l(vC-~UWjZ#5Z&mO2Xj zgqa+H2yzs%@$Yk^3_0$t=_E8LO(*$Q!m}=EB)b$%^vPUcH77N~M)Xq;|5Fwk^-G7h z^(&sv$P*jJx?d}{dvKOx`uG_QAxGxEm;-v1hM|5BZ)J^t#y{%WyV_PM^RHef{`7zG zm-u#_xa?pM%2*Fl5{|uWVSJbR(lI2je|ffbh@{|+Is;A zW?<>dtb&?4Cs=KL^QD$+ZI`i{>s@PnL_1b}!QXh^@>Us9lb*u(G%DuagYt*PV+Kzi z7fx!EEUfZXtYuE<6FqyLiqXCQD(kM!hpkTx?>_VA9sq{K4JRce)xt#ggRT%{1iLCl zpy^o^hv1ECx;C@Xk<^mm^$U&wTARzYW4EnJ{9`=t-`t1x3CcKdNXQwe=udWsp!5sf` zGhzgED%t6~23#TeD?2g0iuD-ObC>V>79T{W-hbhUKN;}i<1ITtKuMtE9T0kjOjgSe z*#D&|;}S0hC4Eh6SB=EvXMhdz3QCi_$|_@Bf$-a1tc6E@R|C%0ij9KM?%Yk`9KNMf z@H|{VgU6jKC!$p|&aeba^uh>IN zP^ zQiy{^riSDJ6c!$NWe{gCL2rQ zS*H~gXR8}%mQ-eWeeKH4EwyE>*X`QcJ1^|zknBcYjoA0-RD8`ww)Hg_yFdG+Jwpd% zHCOo%z4DB0`FUlLa@fY3w^tXGUc8%oxn1nnzPa(P8iT!|0dU4hh4x@1B^=Qk($PcTe!?RSj5=^6tgox`qW!+cB@?jUa)a zCP{Q+l9q>F0szCDrX>m2CRWcXEaEFLjw`OHq@yj@0eMz66z1gWtDCT45nwF1vB(A2$V|bnk5TQ zh8&lhES(d*03RiJ+LfrG>~$ivnB`EZ8Q5RxCRuPug9s$_VtH(rAfwVD;rTq}J3h+Vvys-0--Wn^o(hl>;)4W@6rV-jl5D{D$dYVR?J)kMKWtr7FB(+M@h<*Krw&fEY^q=!a(+i~Tmp*10?4%M1{lnVdf*2}uptV<1eu!i@kyzk)I`&8 z`fc7|O4(iwWht(BImESlkMNrCOLn>)GX83ADo>M(hrMw4?AeT7z50pQ$D*V^Jb;t; zK|;&gACIzx4LrF|x$BBo)CXc$cJ(8y5jZLAra+KMbJ_Gd^=<6A&}y!Z{GO*(_g|qgPlU{BcZj zhFR@iqg1%;xUm=8f_=zQ=}fcO3N=a#5&eL54->B;G^Wkb^giAD30- zzlYAxoO8Mzm*u&oGw&oT=1|u8a&h${w0Y#S272rCP=wX_oI}3suise0ecq>SWC3TL z-6eKFz!5nN;%O2+rGJzFraO?N{ctXv!a``k_XL}6mmjUqSVtIJ5t}J|c9Pd9thxer zG_s0%l!1_cTsJIA2!zB$M;l!bQ;>_ZXu-qGnml0fLVpQ!yq7yZE)C&*j zSXd7xbGWQ7MxXgCw3Kj?+IT7Lv`8H^l{wV&CN5*MCvE1(QpzYWohENlb|b2$3)ig+ z21?d+L0b~Ty;WDV2w?jCxprJbEQF#{PBih?&Jak0(Cd=Rdiif%KzZ(LL#4zBj}M1& zOwhue>5+<#9c3wappMddH)k49^W3bZZhV(9C#a*SgTD6Wt(kJ}o4B0aHN~#R&vzQ8 z$M5*L;8UaR0*z-Grh}`H5GYP#(+p1Ag9(+xyb0#(@g#}zq@-n&R7-1#B zmP0Emf=jaW%^L;(E_(`Uoa-dQ6+LxwP=r|tp+;mNa39w4Vi^^ypJRJ}vwSV*LUyD= zJ_r6Knq2Pwk6j=+7i!vWg;|l~WZvl&StD$Lh7hp8&CG!7eBG)pc|!D+j9}ngsOyA8 zOpObXhNTi}Qf~KLD7o{SQInL5Z}0IsMm5r)s-M5T@7T}%?t#nQi|-zKELXZyzy*e0 zKC)v{1zRypBeqCm%C2nnv2C;nQLx7#-_L6*e)d~T4A^vE(moq~YFUX11m3|xplVL7 zloVHeSgUAS|M0Y?pXcMV`n&cYpEoa8eOzyQxBl@(2mZ0`jUI9b;D{V+_4do*lP|Vk zjmjMR^m;WAGp8x^lmof*ypW<6o=36SBk4Ye|XmP;`7Ii{$o4aukSkS zeA-&B-ub-!?gele0)YYH%XUDhHqbCd41^qeFnq%g8Hs_i%61ayZvf{)F?c5jI*GhC z0_YLBFd5k{;`EI`HpN^5oq;a0){P+E$XtY_Y&X@+MzGLuE|L2{H|>Xw5ELR086w-m zK(!evtC&ZeGSI^!ycwn%nMYDA+smQ98Lm5=N7gjZ%j2~fVT{P9=$Gv?;!lrLqTN8@ za&({p9wVy%6$pp=9pnQ=w41x)eMZN3Ek_~|ZWr%}e$jbQC;e``0{Oh9e{w9GF<_M9&D22DnF0WzW{Ze);=(wMmO7|MFj7q#; z=5q0|$DT8XKAhRP0LgGuaTjzfnOMygLK340>BWW4-`UO85!0#=B%c*dUItL0(!0~fwYRDaWs(SF5+RU0`^V?EMJW28d+EJN=nfLvS!(3 zHCHcGSX9?GH7f>Ym}Molbab9{Z!-sl0VkSSX)B#TaW}`iw0bW9Cz@Lbh+Ri#W^1mw z0wMpJqMDiS33ADmvvvhMwGUe0y-&Dw# z-Og)$ldjEqy+vbCv?1u^5)H--)9~DY*gDNj8(tk)KsF%SD@YmPi8xgo(07_mr!lP| zEU+`M56Abu zXF=rrfxQn83`H>^uTa?>Ot~P;L0Ayaf7ZGXN;Aq_v~4xCiUL1-zj_K3D!g`>)UYG8 z*aSupRMy{VgND`lfSytp(h3ISlk$SZ;WvcI?U3dc)@$5&Of{Lc3|GsNNQTQgP_|=3 z^ISVLJ1rm1LYf|>*`CGIcwHKo4Db8->a4e^2^EmOWCLMpCelrt)fl{X5#ST%_PnRPs zo%AtUyaUde;^a`sedkFv1<4VrSJcN<#{621^PctJVg#KD8i=OlyhKSeF?@9tO>wc- zKt$|$^tgHe+bqWTUE<@E8Z8n+w@D zAznKx&eac2t^V9|52OKi(kN7IpQoZ`!7uVCHZH>>ac&IUXXv@O&B6Ap-J5>E7qk7! zRY*(%w^+kh8uyOvi;(qJ%NL*ikM-O}{`AdAE5&@Oy90fKt(#Gfk@?iivi-s{o6#P_ z`Lyo_`b9r%#-I@e^!RcE5>zi^Llp}c$Om_OZfs-$6RX^yy#7m|=N7P>92`{kdYOPh z6tc<44XLM(6VuLWanP|kUSIyQUy-||QMTX~t6 zyxbM-@{wfItE-GMJ%?53y1lkcc5B>7X8g&H}EVGUi;!175eW zr55E?b@i?_mJw+U*V@zwysg2o*6Y1}r$UlCK~eo9x7o?UTx&KyIk%*x+Xc~ z=F{_dsVc<3Yx&vA9S@&}&tJva1%hW@e|Xd37x589HFE(Eno3&CstX@i{GZ^%s*U}VSb71@&?44&1~ zEFzZSw@8ncbp34jM%9?wXFC2o$Ma3XyXCIw!C74j&sw;UR|ZW!x;?RzfxLSgb?^A* z{6GSy(a3(0K^a)kFemfMX){pw^{2L|MU=}OX2+Nw6?4FSdN{y0~Hg2 zJx(q2C@x`^v#EtQSux!Fu%4{I=vR{2VYGLa5s`v6!};tL?4|jqUD%cn>tySR<7%kt z`xlPZfH+Eqw1BfabQH!N_()zflg(i};h;)QL(tRmY9CCw0|75^%8`AWY8c$C&9`#6 zRv5{P|kh>gmwau(thR=zPMbKZOJmHIeNx3ea_Ue|~GrQoXK(}d2f1#0Bggb_-|+*NxII5HVVWc9W@jn$q#kaYG4__y zkPcrQqVss;ExY>*jEi&ilu|cHa3KpaTj&xCf|{Im7oQPDDhJG7gDRf8DUSLKz7u^d z%Jo5@>9hCC*~`YKb_g*k(N6bvTY2jHTV70Q3A`VkHZ&`rW`|DuTxMclYyZvqe1xi_ z9~9+hV4gPw@ClD!^gxEuPP#%aY^Ap-aU(fluJ0&p-cz*XLXR zy;lA*u|%7#>OzpbsWS1GxSVH`@J-J@a5C= zI5VvNVU)|hgDw(~>=rSLIn~rA5!gIxpvBJXRmLo$Sg2oa#5w&{W)P<6L`{e?t6f6u z3-d8t(`BS9*-sA*`l^|q~VYP+t+En}CL*52DEWZ=^ZqKxUkJ<7;k z=60!aY`Ras(;W=!x%Z^;j_1_eazj|aqmh;MOxlS>(Cmx1af5;22k$-w)5^Ubd?ll* z(k9_dz|kXl_Fk*)0meMJ1=X07VHCGPB1|0l{TxRKUAJY`2gKt@fn|NdiP!{K)@|!2 z-tiaRI(+=@WZU53NmSOEfOJ^cM)7Dii4@ftuj6zQK8l`=)Av|V*GrUAwDZHY3Wfd7 z1qn{zpQyN%X;7UWv`V4^9BqutJBP=&u18>4-FDG3rP3d*#a#0IntC!X$Q7obR91Az zsMm*PfpqR7??M*=zv5@UXD`)^Gu%O5&)##*D}bnz`qE`>V@_SriD)o}hh~n}nl<)a zWKguf){(sN_EU!A0UkP3F8z7$H^EDz`3gD8*LRn7+wYngv8O|R%L^ZAI{ZaH&A^8r zx5FBSP3JgdjjX=}I0aiMGj6_~B8Hc^1KN(qHSLaju1!m2N)Z*oayq6^8`K@vUkp6@li4AB6Vo-7Z`NiXH+*7-Gth7I~Dbl!b3&*Kipq zHo%pnXadR_Hj0jpN?VYl4Hd&9Rlf>0REOP;HE_2utS&$ic@aroubEY39a`@MsL+s2z)Ugi7-d{10giLp`_k$q^sc%8?L9;9e z7l^et329t-JNqP}Yn<9C-{o%x5UV^}$4AnkKul2HHvWT@mfM?yOo5bgH|Eb};)ma^ z^?OAkobdhOpcZ5lJj1WJDL^OipNi9ARCC@_O-Z@KCj)ZH`OfO zbiU_qTq!*&5CL@kzL_A$`z}pRE|(C)+~<5`PlgC0aiBa~v;NECTTgHdO**D|SnRtW ztCdtr!1~+79@qc1ZJWtE87tEm)!+&rtGuEu6ws1w3O!ZnVP7 z%^r0xYdp0_ykL2-{*kF8g?@XZiaKWdXziVLkj{c(!R$VqwL%CBNfb#2gzK!~lmp!3_KF zDGZ8f=Vbg9aUr0vp3T;D>0JF#|uB-}9u*&nVZfLZirOmGeU2D40fodVaSQ@8w z4h{)jCblyoj=Fhgf{V7y)tIt=@?oc5uML=Z;L%bO_lUa@?7{Mj!dcJx#f`UFcLOTk zZKvM~oG*BDL`YVr*)A2v!IW673NkvtxTc07GCmzfafgYYgg3vR6YmrYFaqRdLl}V( zu za^uvNY~sqxLKX+?=0JfL?GkIQMkf}pzqhq^Sh|`K<@p(ro=R#JESFyxdlDwlT*hgz zaRhgGVOockeGQCv(&%KR6LjN>$H0*h=HSD{nK%7$1~?Lr{muwbX>WUfVc>STk(ey# za_4#};_*hd(Kfqm!ChZ>qanY8AD&w(`>JiTV$MJ%_&Rs+@o0rG-Zb94;44I43G_%p zJl!Y!C0fRsWZ`d3+bM_bpMpb1cA7NR-Hh+vo`p`(=$;R;x0wXB< z0{O{lAqlTDWH0C7VxK{vaJe~iCb+D0SU+%*@?N*9h<@qqSP9d#%!6RmD)R|^)q#Li zOP0g)gep@V78!BW8%2Z{#^I4!2uR5i5m*skkR3DJ5`f{PmtUa)MqLSkFOL^9NsRoA zT%mxm%_>WJ9&)AVa(pRUNs)_w7uX_RKcbX3y3B^8rDx60R~WMvRZ*vZR|1#G5Ls?3 z1ez`5ZeatI_zb+N;ygD!Rl&7vTdmTVQVz3<9WXmvY`G1sAu0gesU%)`YPza}v+0qr z0N0TU38$(QV@+FGeDB&gkewS}Y)H*Z34ZaU>g-X28wH>T-HniNj}9obiC_HsMTp}v z%owym*G;%H-q}r@bFZ`ia3I&qe#)FWz5sk#>II@v!6JvFP-@KLQT})DaR!Czy{B&m z)L+H}AAg*CDMs8E1v)BqpRYbrG{dPLuJo$oQjDoIVb7gnJZjvj0^KZ0NOH1W$h2zg z^}Nbh$0)pM7dI68o^|sl!6P(Wm2XblJ-(s>(Rlhv`LWOC?j~1HqujSgp$JDA{2+~f z&IhNceM0BVQm)Y~2+Br77Q$jsr%2PEc6jWxJ~HvSxopKtv{in|{qU1DKMgZa03%oC zSZl;$V3w9esP7?%@_S?%P!GZ z^h03i?e?Pxmz{Q!A#F!L@XOo(K#cs+|K11~pVgz21tr2z!-sfBK*$bq=rQ{1N7`1^SIAhEPQux#I5yJ)<&eIA#mf< z#fH!XZ=;C6uca%0Od~tDei{DajUVzSrTmYIoU-U_)2I;{wdC4IUm$vn<*N@(k9-s7K0++w>jo5s{b0w^G+uM%b{mpC=v;kMlb53rHEdot;FN%W83Cq# zCR?k3vG@$yL30ffD;!AlVQa`-Rrl)&Be7mXjL$6{Njn`tc6F7lcr;(g%R(T$o;^H8 z!9+Og!;^*aB+X*HE-xZfdxf#d1rm58SL)TxAqL#}JCqs?%123=4y2S#$67xnIOm~K z_UJl+^!nJ=NzSY7L4^4Brw zF&yb?h+C*})vdBoe_o{iN!QD#-I0M&E#1T#SzXE-JpewF`auGN1Ix6)b|OT?)7rcc^Yrk$7o|*Rr(!& zSDFsYc~Ch0Y=8#45X6Tho){f)-jU5egpvivl>AUMuSsZUWa^MVc^=!a-|3E2|8O1x zNk;gQ1t7(NHMx@k&Oap^4&sEibVr>eU?+&Xp!m`ZF3k}JPhfvNEg7b6mowjs= zwbw_3jys3PVu*NY22f%zNSM_=ihu75qTW3XgC_sAH>-qNq&qQVvg? zR>6O^6cKd&f$Qu>H}g@%Y_jrp`LS*iTBH%q%*)(O{LM{2zJQ}JmxUp`vnj>2~E(FF^Quwa- zZ*?zA6!4s!V`QQi_A0EaZGkm?RO?((EswqYVr}8`>5X}W%C=w)oo~eEkW9DttIm!r zk>ApyHzXi<6tOK^1y)M_iz^ZF=#uC23~%Af{f}WE8Ibm3ESd?JozKx*IWQ95Ga#x; zA3VdrXYv=?q5oU7==}d)%m3r8U+-qk8E&-${G{8avRo5jFyy}C(HG7rL6W(H2OzJF zg~F!APLlC@UzqO}E|t6eb?bjOc-tp^GjnY^OKcL|5iPPlYp7b`d!Q?bZVIWMjj{B}d>X>OJXU-v;W+1)i-MLFB z3t}QIpAf(gBE(IkAQ|8p0mQvJ5l|}YxRE4h=U^nzh88lpKo$WrPfP(QsO)NOV!mBr za9vBQJ-3{F)3weny{PmX#Q%@H_kL?~-`fSBgg}ZAB3-G{yMRbXLy-=mAR;2YcLAkK zXi|kxr4xGZRX_|yx)c>eLj`4;UYK|FN58>Vfr{mc@jhg(m7gRlaR#*w&kO zgDB;7ARpaQVph`xI@*35n8*#@d_ns23;%hWoGWaOwJYB)*x5QSrbq;|TFzHi3_Rc> zm2GlDTZ9X0XCeg5oh8h1YM($9#4`mra~HIT<7{X3Gefw!65aJZj$!Bam7fl?;W zF>8$xLT)cgnqQ){=rqI83n$LgQavD=g@5+9y8<@Usjzf(usBZM$O1vRqB$!{y-Vt7f2@f8ClS>YTp{HR7qD~M zC>>Ljnxb54=5EKo$3;iU#uKg!UnGqv- zcIX%hqh(BdnQm#pGsIoKqEb1H-rP*Gk9?@Whh-e8*6D*>l!eoIWfIXvgQVe}{B97? z-ig1G%L}lTUu<6DXCWc;#}jLj{$P^I7XbKgJMv;HYWw+zaK~O4PCv!E;kx+>cHY=l zlG^EXJhpZ!IXbxY7WmYuo~-eMwg$DHs%EDib0B?cG5!5jW9_}~LqT6b2CQRaM;4s3 zpqCp8W{oHh=^j@{m{D7&j)w-pbwm{4G#5w+J@a?is##&)3A<=EKSB0BvW_Sygwkc2 z^hG3Z`=`N_hL-RVv1g*z{WpQ1R?*7coqLQ>O9KUVwekv8IAH0p_lSp6D0EW6{eACC zmrSkYwj?HRV9G`O=Pgo|M4tO&d%6@}%48K1U!}<8n3>3vZAmZMSYY!drh{A_>hY zK4MXCW`V783o^F(wpyeB8(#J1e%n2L5q>)aZx)%|Bc@S*!I8`V!VcruAPB=WFn93K zd%HalPW#$%iMQmLYvj?p!Q)8V@ps2$i$~#I*k3>21w+VE0f6lPeLKwhzZdRnY52}T zKWWnStBAbtfW(FE=yh&stw8oZvswT6NPy0AhYsHv%P?^JK;<|!tUX(!J1b?%9Z z*R*cd3y|&EQy&cwhUfeuFTui(%ABZ@Qo5sar8%IwO#J6z|1)b&S$ej`wfv8|f4TeP zt$xSj7+sWEM~KN$6DCVI$2tPr*VC-~1V zOTgpIag5VAcGL9?7Z@diol{wNNHt5V^Xz!Nm*0-Qzw=} z#}GtfM{nOv7MhGMh zSl<1*_j&Wf;m=$lb@Z)0)iEk*}nV<_h+{MH~ha> zoX-=0{dp7yFSE2iHdzRw+^y8=H~sJ-;D@0WU>x}J2i%Mn;)x|3D}q!{C^dz!_tnrJ zKixjSHr08rhN7XOK?qt0UUWF~5n&Ea5;b)yl50~09?h?)#~gERVa)8ID0^ZK@EYl! zhu~ZCM#gmRV9v!W*1aTBUd-DzPngvWRh^aIG6NA{ALZHZG%x)M;BHyvFj39OZg*ObkzR7|~&>ViC8 z@QtbBs#$ZCAjT5cYkFFz`0MQS!To63xyB8;R~EUr`LTpd=&u6^w$T@1$V;-ncA8k5>xp4ar>*$@ z3Ifw(H!Jw^K6*0X=%rX^w>`0GmQ6pMQ3uZI$WV#q9rdwJX4f)v>Ej9X27ocqauNv5 zZN*QN%ml%`G1@pbG2<R&t0K_Y0F-EFV!!4hdU7c^NJTgINRQBdPn*~yG0I^Vd!B&s*j0- z%~zOApl1c%9AZeUs=h6e_>VO+!rX*?kC*LqW3zgU@ejH`Df^FvufA2lyPem!oef#@ z^)v$(-wwPxwb|f_#}a2xKMP-%0!B&K1vt%c^D{The$Xo1bPf3Oy59fi!3~6Kwa?4y zymsCXtiQSsm(KV2ALX)*{`wx&N*O4zI~o@gtnltHRF7L=w;$azbW0Qrq|DYW%^1xt z$RmZjf_QYXFd@TM8Yg_nZ6X0lfOjeBZ+XMT)Bb~2sp-@ChYPJllIj)6Tc21s zY>XM1+%EQ?oYPxme6w!h;2!_3i#zY?!hG*TZ{ z6Igs6uAMPXE$*)kg&c`yPW6WL1VE;)%|uwgKc~f{WP&^#&+1RSu6F!@GotPjIvKhA zB-5T`=@MuKs@o>MWYo#RUYX*w5-S;}VmWspSN2L<{gKwAwGeO7wQ;)3Zz6o`zVMHR zYPOAdYKZ4gl^71W%QK3XX6HG*TN`ZUw=gae>Ux<_bKvsoiMR5%=j8zZdApEmgS=&d zoryamfc`zf3CNvujl9%NTBiVu7a8Zj+F4QVn+h9xCr5xhB*fJA*dhb2Fk;_YF93tQe4ph=(2YR4+j`p zG(tGFwpk+>e~n?$?6GXDQQ-}CT~RT31c!*2QG7n){H#=etls`Ihluzux}I>Q`_KXk zp4}R&gwwyw^HEn7OVuAr!ElQxd7}Z90C?zIY@&|u8Ftzm>Gm4wQcNO+=`A((AsKG$ z96ZUclRiUPyxXPA+z%26pK@%EM0j)WA7Odug4m}+asVfvu!7j4qL5G@i*begvrPnI zabZ^N3iF*`bM~Y;8pYV(&>w=q>O#sKW76S;MitX*<+UcdLGV6M7J%`I=t6{=sKgXX zC3r!`8kuPZkmMeH>O3Y5G4qXsNMONsmp8tNPHH{r2cNm%T6lY&jOn|=MpH6+A6l!$ zL0i8PgPWlB79EdDz*?Ti7VVDFn@$*lLr}2`;f1Z1f?vffJw2SA6SDqJ2jzyuuk_VY zqQf_8&@*UtY-y?x5j7Ca(vGy ztA~dT87XW3>ZFf**nDNN>M0Akf1oCmn7-Y5n3&|Kc(~%4_W%jn=?A~2a6sdtoD^cV>rCwjoZ}$4K@q z$KDDbb_jZ($Dx2Z^xzop@6n$HgVTTT^q1wGp#MkReg0aLa0QZ_4Q}7(4;g_-5VHx$thIU z4WO%Dz3YhZ?dhFaXqor`dHZp-_I60m*xGib}!~j@!uLW&fT^i zOp}s#w(`DEJgP*3?EIm=AF7!o8oeN%Hm;*qsC(I8a9`ZvS^!&!(U(%|;#a^yll#Qr zE5cM^WT=FUW`nV8lv7`m09|usSdr}!SLHj=DalsF*v?&|I^=oUg8QXVO-KDX^?kSk@lQQNyp(%i=Db zG-8K3kR{0vR~tNNBz1hd>HnooNcEHui2jOD-n+$PrVj#* zAMjC!j_1f6-+9@IJAA^Uc#K0t=@Bsdk!GeLujCkDA<*mIS|o5!23*)>UaH)OPjL*- zBd8L*HAxzn)VlomgRK@KMSle^AOk_cfK}Q|4H|gy2x>(s8LMlBPZ*Y3L_=C4I1-)- zmUhSMb~NP2>Vt{{rFIoynH*;o84|~fN80egod!UScs79>14zB)7Jhz_t}tV%(YefhBIF6q&9MswHrE)gC& zWYU4weF%)z7;re7Pqk}JSz=P-P>%A(WkAU@@i<6T`n;W-(7uBrv~q3j7AaZ9m=kT9 zhJzX$KJ%937}l@TCwLidcy<6*Uo_|JRI&N8vY`l^z_6NH;L5U7_TET-9c@=%}tQprl0>zfich9PBZt$U0yE4PaLKyHDZf`Hm*C8&I zcka?2_DWe4<8__;I`5fRs={G%0q{2_rtw757_NZxmRUC>o2*nF-#}pYx2+}atCUL- zxs}(iN!qvP#Y<}X9k)XvUeO}N51H-nCG2UjnER9w85n6)SpH568YzPDGK)3t=w4*? ztW-MwWD{{IY#}3GyJ^|r9^kZ=&4<0uM{wPh@v5Ot#*#icb*W|RYYqB`P$Okv%y#d; z$WguGB*-6BZ&X#ljXYS@p~u6*9h}#4OrySW6;xk3Hy@4P{vI}bwQFWy)gtg$mC(IOArXXPRXJP#-sByxUlVyvVUZhx5YDOY+~Zppk2@8 zOyA4hV9Ev}ZcJef0E+fFNd>oL6ZHI4ORZc8 zZL%(=@S7I z{{dfOqZVnsO=;o2+Rl$N4PgP-XwC`0ZwMn9zjUZ(_+om0y_&E6HMbMufZ~0drt1n- zd&?g~0O!&EAZa8)qTh#h^K+P)Y4Zt(UXp9xQA9I|uwtI#ksEEd(?ra@e|T>O!dAA= z9S7L``a-X#XBA2EXz8Qa z%p*Et46jI>$vcb)x5?xM#o{V<918A4_!uiUeUk*>nzS2!#DBOF5~CPv$w>+0K7)$q z6a2;&t0U2s>uYF({Dc%=8skC=86eeD&B)FaramQ3DFJGEtHThhgzdtNM(^A^!1Xne zWu)`VTi0o@yZGW9hIm`<+>V}Gii8OE{1pV8Y1;0596#@BK@;yFchP7M5}Skd9OEq3 z#h>9T&05>$D}y^5QI?<1(olu_wU!b|$rp_j&N7*lsZ=VSB+^+$YS!=4GvJAJ!)Jlc z+L$0Ccx7@CUhug7#ih0kD25Z)RfqAsk87AvCODyxnA>M5W*zoQt7CNql-u~n%F|kF zVop_ayLCm8upY^DvjP+B;nftd52ZEtHB0Et;or}`>V&~Df?-bstqn+ePWN@Q`Wp(L z+b!{AnKLI@EHdAPQvlytdp%0*^Vq~bfFN$sTA`A`eD!X9>cwa*z$RX#^?dXO*-wR0 z2XcA%%LuVMq@%ym=NmX=G|hpAz%$r>$jzIupk7{$M-SiXF&W>JyX{D~>1i2AcEQ6r zu;~67*ka|^S)X^EUq6^9LK{haD6-NsO!g+47fe>*__S4osdRUOZl0~CF(adiX&Th^8~fg zT74zgXs&?f2gIL9qd%3@mi_tDF*jm)m+d+(4kk+ddw%SZFH^!*ciJ&wp^4w4z&8gZ z-jK2pPolu*{dgVBfVq;BC@|nA3s5poF`@mVf8 zd8K86c+2eanpzv>LW}CUmM6L>RhtNr*3K>^^g}C%E2uZ~3N>0c55F9|=@}9A>TQcq zuPr2LdcJnz-kXKxQkGG72ytaA#q0gu{*vvlIF_dm{0gjo=PKPCjP4g%)lL5~BmH^cE)Ni>7pb@y4mcVVLcJt@M%9-!Dq96` z3&MqkZe-1Js@)Svd^gnOITR}&CA6h&a(DTt(h;(ns2-BoRCkZR)Q6>A9^xiO# za#?Z;Hwbz6>X^AER{s0b&wAY6k_Z!x@ZFE|xtC|oJw4#NUC?&9c@}xNxz{*B&wlBd zFCV1gYv+SsqDpg=D+4#pjzz$%7%_xIV>}0uDa4=wK&P&E1<@4+&oeOHXV8p*CxL4* zQZU{;u|w_J4=_}fcdh_*u%9hL0{w~|d2SNGK9YV|&w-{UD>aRg-nUzPbm>RSqS*Sm zG&7C3 z6TSKKi;-~Mw>)XGfZH;`r|vXw-tdnny!n8<14TZqF<3}qt7fF?XP|g(m9!lsgGew8 zY@l`tnvJZ|qd53WOR~$>oXHvR0E(>QY*=ovu$V%aq@nJ5B{!#;gJWwMwgLk*9HGgE zittVrEXEk;V;;EHSUK-!$WSJ<4?0!RG^|x~r?~Hi<{|`WSa)gT)xlQz0)$hmNEl{J ztwYumq~h2!4K2{~OP`X@!1enO5Y&g;VW~$)r)#^-#oG}XR$A+ynyd}wx_WHwwC>Wf zL=*2au%C~ty%)?0l$pX`-4$bIi*x#L|AMWI*@!-k*3IG0dqB{OuPs_>quo1N4Pq*K zMZ_`d*A-E(^|4R)r7>m>MxjCW$6%|8cvt{*w{YylQno=3CD~nS%+*jh~W>H5=OB_|2|9@ZnE)MQbc) zhYKGauM|9XIr>`^c*L#@!?x+mjg-6O#~Ykz_Vsfh=Ntq@*t-<=uFG<_4T*x8%AN5! zKZ<}2%AO}JYtr~nuV1MCZ+teaULuW&(yz577RJ80+#X4E=hS5!d;L}X(`kas_7F1- zIaXu;2AeOxoe9)>U?6ZxIEWToNPgzckQ=7{w{*d3_>i@XhyRNPbMYKxs8M!zy1NmV zT&(&F*8a+j>2)Hh;$OU?f5-q=WxLBHfjsu#5@OP%Tzl~Z;EFQ&?{y9|Wo``dl`I^Rno*@Y# zwEb0xQ$k7(AvrZ&H`6&6taG?gaIGjC^bDEbi!=A}t8Z<)8r)>z6Vcw?BZERzHX~}D zzZl`TH_!|`8J!$OJ+tZLU>yuKUBf_?xw*gJ}5nRZ+K z4n44+AEA&7LVS7+>EX^*lKcXk@m0GP16K?L3}&W=Oqm`rDg9dE8PD%elvF#m5s$3n zI+fyrZO!~v$N3^7$js$cq{q^g4Ed0hh}6^I`G4wITyF5SQm5BW>d~T4blGdX^7yB= zv-)FtqCoH6&uJ7{6Sa(;14vy8p||z;8TP{MMw*LHR7anR($JpQFcsyB_!3=Dcg8q0 z!v@+Ues}h{o{4nIphncBj64mLOqIKjk_N1Uesv|21B zrFO9v4^>CpiFp2LqD7)VQw=Lx<~pBlyivBe<>PY!$R!nvSoPD7Z45kd@%HRA*c9gk z5@N#LwLR{Ps@Kv3>02vl{h1F?G(c8R!gw&0mUrytxlmsZyF8TlHe=q2unS?ux+&!8 z5lYqaFSGfAXT32BLX!D%Nr4no04R`VY}-dB>(s3AR}@tq#a5JP0mNh}L2Nf^(LAa* zgL{DtWDwnYF7BV|?PTX| z@9&W(ui)ytw!NkT9lc(uw|?_^Aw zXHp>E$<8q`ksyhcAuZm^k0jq}t$c2NFLe_C)eba}$+)A08BYbMLY^#fVy>gG;bglL;6*~UV5(7-@b|M2C z-)F>!mc>7NOh}kpFzUWLW*3|q;V{eQ_Un$ zHEP^chT?^-V$k|Gm(D$GgM98Ybdmx7yJq}~?DgyChqK>cb|Xpw`#q=i^qKgum|5dH@@WlE_saG8`c61at1~dY`^|OPZ}sTdscz>qX$@Gf8!&gqSc>!< zD>$AallvHx(-SSvi*AUh6BDdo#F0Ogd4=hQpS7D)?#Jos3^uWGRD z1Xnf-lpCdXZCLw$uS31#6<#%ZL|YVZl0CF3=KkHwQKIuQg09Jz!FBw(9IX|$qI<-+ zU)DV9{pmRq$zg>Tx;Ey0o!7?{OhuGJj&ojc<`^Qt%)4yeTGnBdJ8p_w-l~K zF`PYOC71hjikU?OGW(D!lA~h9LI5@?`tdwp0-Gg;NP^kyBm5#*_Q0`^;N+1_m|Tb- z<$UryL2G*9Jw#su{~oQPatjqN?H1XUY_vQ72`?LSW{JV34!@L^P>~j#;Y8+Rnn@&< zTBdj=SQH}wY?`gmeVLWzoGKy`$PP`oZb<=QOXn32Zkk`o_huI1Ewu0^lokctN*^uC zoGvN_E10(-Fmk7;Hw6dEqHCn&nS)r;+~6gJ3LXZxAh@li&08BYHyEhMyzLr@8XtI%IAUT^vw|trhQ)>}+2j zmvx07F1_mX)h}z?bnaggEj;)6G?AnO!ND~A2qt(G)afS`vr0`BNOWePRoXCbv%m_3 z^>TX4G4+{8kdyXvq_%grIK-2a4aS#LkPJE88GiV}nJ7s1LUpYoe3bgDnFvHG?(TV} zZL&(wB)RhBeYdOYH^iNo#eYsVoTsb_o^&QBeqp(GOnX3$UEjGl)nZ|IAE_5zb06dS z9gm$RJbIx#BQuxP^;YfGqqCE44VBH5As@#Sp!73E0L(dXLZRi!4KwUVmFHeTLnSXn zzFCA{!1*|(Ys!B;UT%qZpj>=!u{D%x-d zlHQ4iLv}^od=&kR*EYk2csvQdKkFIcrUXOVfe_H!tvPaTL5(mj&PxyZx7YADuuOyEQ{o{n^ihI5jUjVR% zDnU-Rf=WCG_b`r-(~2se!C{o`*Zc|#P$2ZmZ^%yhd`gKU^*3bqp+VSOhEUOX2Y|NE zJMNxW0nO-y#3X5yhn~G-GB_^&=uUceenAAmB(Jcn+yWI_5?@hQf0YH{gl}kVlW`9= z3(Wvec-|@(`|#&O-3G3q#=|e`1FM}NUazJr44%CSdpBRu=L5O9u#(u}+qt?K)impD zH@aYF4&LJkh}!8V0tnj*a36u3r7)emh*b!7tBuE2p^+AO!BVvg_1Lqr4`STl>4u5%MkR>QvAJP+S}9&V9$LFfMU|VEUL5s2 zWV~fGl&#(NJF=@Z{o#afvE&FmHAmcShI7kRfA?)QSRJgSq!?3ZGgxLN`V|`m$c=2W z*JZq!n8W#fxol8vJAuX0uX1oFZfnhRk16iwfhTu_M8qHE0PAzi1X=7J*SHVUOh42qyuk^N8$Gnc`z44+L7&J_gH7 zn=QmPFpXJKKodkb@Sh^ai18e~{m@u79cm!ynwYqCGWDHEYb7I>TbKwFDoWBdU==MyTvn7|EONe>XtE1{;fI=fa(CNg#wmX`<0wbm+LJUn4VSV#q5 zPpgRs^^6gi-O|^9lC}EGt+Cm)NGjC4^27=Py*h6?j~n05hYKmZWJdsv0tT8>b*@sj z9FPElV}7nKlVKTyZ(VtJ+pf;M0P9NEX;+3c74>TR?~{HcAzi-lu1NSPa%G|gO@+v* zg-4|kJ+An2b2v=fsIT!Y^0Sn0+NF}AKWvz+8R~usgD+)ICF8?I0sX{UP z4W(ykjTKSD?0`1O3m;DaGVIDXSI?+i&E`ojvu-B-@*bGmdU{P^*cj{$_l@M^++9wZib!KJjf5;5hmZcZe1&MCsq*6si7{SY)H(IR*) z8UmT)`)Ve|cwSZb$){9X(Ds?>wfSwC@OK)9osg~LMap(uAj8G}Y!f-kwIU?TgfNouvS%GF+Od@@Vw(c!de9cHp7G%>;EEN>=e}8 zfyjJ`6V$G0SUY9+WC1km|KexD5z>NBs(IuF-NAZ)%@fa!i`!L?dnet+po2@-=JrXC zCMybY_j+PfDk0YabtY5K10>JQSmI4=g39aam1qLYY(UhO^>+Z!?OokGl||+dptfhY zt;q?Z`r=i6<^93eZ%aFz$EQC$?)3t4=9YZYy@|^kAv5=%eBQm!Leu9=^=a?B-lPve zbBKf`ZkpBvAqsh0F6tO{g=^ET?U2>xVFDZ$Zp}<}cRh6>myT+mziZJS&#QNArj;*R zI7Cggr|Ykt*sm@T=&(j}P4|6gmiW)oQ;3G5r*hw-CjH^p?O$X&Pf7>yjf}h~Wlyv5 zjJRk$adE1(<8@R_xnYuNe1M!R6~Azvlj$V^#%7yoJ@s|6dlTwV&|uf?x!5j z$FUFS4-dpYe3v>lm-An~I`zSnmhe5CZ0+-#n852}JOmwB6dPF06U)gE7C^rFo0Muc zAI8vO6Y}6RNVia8?w7m>mv`f37vkK-EJP+V%`HTW=%faR$c*)~i=OJTnS1mCFzk(z zLwR6hX~_7r94H7W3uuY6rKorbrkec3dh8P@pm&`wI+@R`la4n#McNwx>c3fY72PcG5I$O-J4()8?R zIh6`8+|+e>g1pBz3l|n{oeGH|Zu zEWBJ))c3ThpvrT5yC2(>6xH)P516Qp6$`G#ked!5N;h6M(a|sL_KCl7+EcpF7V5+R z+uzt5m9K~Fj|uug>J4d`J}Zy=l4B874;9{ry^;{Q(>TFzCR7KB(I!o( zt;VzWfXL{Rv)gL$2^>oVO_SN5)NKO6n_J5dBvj1ZuK_nBz+xTgsO$F}<3Zz0qF!=Z zc1{>ehJF^IsMw0m!z?DWq`F3j<-S!+ZF7rEUZ6!#3Rr~9gDST=Q`I#o)HLG1>d(0`e;mME^eWhecsd z1{MP6552BS*%gM#9~N67!*)e5c(uGEIiKIh!ua9&ceMnSez}t(WN~%PMUYV8c5g@2 z+bH=_*-iTUT*w;968I(!Lo}2iD4+kBztF13ot>nWah)KwWUf#6G8fZklys)K(AeC@ zS?@DgK5z2gQ?|`R@Qk~YIVxA?${k~Z{qu^a?xF0DPS4Gfm= z@ZUW6^kPfSBJhFruN^##|M5K7poVyWnL9>Pyx zU#@s{`LX6vSsM(XbH(5yy2BzIU)6#PwVN_C;Q#n3 z=9Zjd{a4h-S_E4-xpFi28%MPP3dVsQW;`8LJtO(vmt8kzLqGcGgGm3!Bi&s1I=PFi zy?gYSoP-93OO%ha;a6lIL3=bcf8K$f4Y2`+EZnrafKD^#f;STS@}zHNJ=yL%V-Q&x z5baSLL1zcm%8d63TyCDO-mDf9NW1#nCde)L8%gfK^>_dlc022U%eqXI#3!y%uR#OZ6tDNX`Of2RuGu* zYG+Y)^{+{U@-;U%pKn0>v6#)GqlyRI5%r-kH*3+yZ>6op_R_|{wAHhzA#NFuz~-da z=U<%G+Wi)TF(`Kdo)Il~`KkX8A`x*Y5>bpJTUw+jyY4HB+8|JO0D zCcVTNTY7)!v+olT;^?&>CkFU8mI@Id@mP4$gzTN%6>kL|<38Xqep?vrs(n`^3^YN? zIT>7y#)D24_5`C7EcZsa+`bE9xoKWxWf)i45pZC4?<*!488&zbI#EiOyqv4VW*9B;5C|Q;jmxVQ>CzIJK?T#V@`i`nSRh#~vNmotEdn&Z1(!kecluxm5Hz zMWtD*O{T$yzTEh#uiqfQ!&IV4BVg!jz&TKT`JIHdDu3k+-g14Gw#-3;$-&S1AnYZd z+f^UkUx0+1UiNzyaR$xzoUl%&0b^5tHa`wvX_TOJye-(;u==V*@8lS7Tz^wz`TH?` z4qo8YBIMQOGHWY~Cwnk)!FE9`j^lBf-?s@Q`vcj&GlUStr&mG}qrx<;h^-k{in!}p zJ%`&RO`6x@W(`P$=bmZ0QflC$NDlYbk3~$M>uv16r8dP?)jVbhYGyDDJ`R>4k09I^ z01nyc$rCKHP-vZ0orh-^+_8Z&`cv})@XY3rP!8WZNQ9hms)gdGrwER4u`X)h(Z!CB z7O_8o8jiSw2n463Bzj;Ja`~(}8j#}urWLPKMvcQ4D65kv8yni@C0`X8_{1#i4>BM& z6r$D%AzC;KN|e5?LRxC$z)6QONO04)+b==1jXo-n(hu9?Af6^{Mx>s3Kxe8vj7=pc z1*ow`(~6k!pve7ud8uP9BBKiAjLQ^@Vmf_-9{?+l-@(RmeYD_XpCtGw3&>LJ&QfEr z2uSPZSkS!+#q_Qsgzr&Ut?4GtiJt5reM59h{(ETs%lq@4$819e(cO*q%9_wdAFJ}u z&8O&s7h4qO;8o0rx$B#45-q6n?Ym{%YwhwC(OVQG;(67~UpGk=o<3fg-a^AqB@k^P zfe9j%l;zu7)QuWV+sxGO6t*$6mNvv*><|9ke)eL8-2t{!Ny3Mq+U%W)^-JJNQ(tG8dp0f`9!_CYn;!iJnB#p_Jxd@)B z!-W{h&BKp)RpD=oNjF`-{R=Grhm+;+$M|2!@jsQM{bvk`9O5r45P^r^C*aCWHHGuq z9<&&yQ-i%t!{b5-W*nBDrw@0jyB2%%rm`{Va0Cg|ET##G{jKCYAylpsnRu zbA_!p@p*M?RCn)CQDa@%@OT{EfF02F@@*)=9U?qE7r-*sy*R&Yhnlc|v$AQ|>glqz ze`m&{{>#xV7OVG5-@#oK)$mkeh$`YGB%;QgBFuw9CbI>a#}r9(A-#qHp5GhCDpe$k zs9RJCysHMX(r3iXAP?98|Kr-|i^epNp$aa*h{ zdwAhsAFrEm-&2@sk{zF@*B{=AjdHg7-+t>XPEa`RDE-B?(H9cH4Xor`B71-b`He4_ z{y9EmR1JY*NB*$im%*k#8ez!}C~(a=z4^kHo}o&y$}|s9}%x@9AfK zw8uQp5}Q258yYFsG(`en$-bFVUOKy~mcS!YT5wLsLh@r`q4E>sc(o0+Pp5UrL_VcV zGvNx2%{I^3q^)2gm!uu4O0@yogB`9%sMmaNGHr^cLg1`Z1IxB3V-YBfRew$kZQ(Cc zbdDMzEK`8^3nh7Ia-SFZxQ?wCLM>=C05h=Qw?id}72zPNPBK}=g`NOE`tUOuXJUth@`ao+a9moXJQ&z zk%ny-S&b5jyKme=<-4Y=;-Z7w>@#*eNM)LThD?(83raFAJ`eah>;Luh*AF;2SUns{ z?{YZ*|0_tvc(RlLFx_Mvdv8Sqs|ZloE+I{cWrHwp8=??n5H6KXeP0ep(^yIiYRVZ& zW@a%*vwcO8C-t+dt&<`=b)rekecs{nA9g~tdkm3MGQ)AXmW;x}#J&mSb!A$%v`Yns zt=CIqB6;E1kRpJ-j(iQ?7_E-I=HrKSf-bk z*ir|w4w;2+ei7$S7AXT+VRPEm@3!jg-D5$&-bEWNdvGu~ELcA@Jm!%TOXQ8{lSN7g z0|1QzC-1JXh}=rgDJ;5(_rGNV!YU8S*8EInbyIP!qi=J2R-;wJ)2`SjPHo-&fwfMM zs{^CnWmXkq6P|faKq}aa z*Ua(bd4d8nNxiddzlciL#p$yeNjrG0&PWEmejg9fd{wG1D?h$R#G5i8In<9O#Fx46 zXe5(A%cX`>e^d#(sD51}^2(i&xFMqScj<8?BT_t4f}FqTt!5$cC_x>SoC{Agd}xr2 z2rZ^^xP3uGh&pBQ6-U8fLIdtb7wXEjhXfl_;MM6xz{W7!E;xeqv(P+v;wcu_;L^?|7U zmQGZ*rEiA)KI8e&)}VwpLsu0{#r&0bR+69FS>c$!vwxK#_u+1DnevG?7USh@wpQ6JBO2DumLUxTK z&dHLwNa=*LxRY2!j2WKPdu22s^$S zp>8Dx{7}=4U=e?7MWr|x5uT(jwHjolZ2<0Ru!|6giSkT@0#>EjxgaRLh)5Tysqj)z zIxjIYBvoJLdNBoyeoa?$;Ld;&00GS2!MxI;*fU9F>vXc?b&;p2yES zXqsk0u8Ko5haM@Ew!||8VV30uNV)Yv%9ZnW+bPcr+xccPo8CPepi?=w2M=(b_>B)?Eid_y9B;}HBC~CNTx^3 zrDMVUzrd=h(3jWxH~(^}PFbBy-q{sb9!xtm|9SH6{|2n?{=swozwuIiyc~223qZ-t zlFF$N5HfwX8#mi<16JFmFszxC?jG=X*E$4d=U|^XH;1-T5l09^Y%f^i5OH{bx`-m= zLirh5#CB)Wz!*woW(o#BnY|l(6p$mskO_fYb-0V@oH)-ylK-S^0^k+*xZ$S>-uHyQ2Ncmx1TcK>o>nK zMnLD%04S25$$T3e=0&ll#3O3i&wA5cDDz7Z{n%oy)H{uQHZgX`P0Jtq2}r+iU%a8ShQMdE_Fvx3z!VI z)PC%fY*NhDl1^J36dkar@;2+T$-rICX%{@pzWS23lL`Bx^INR~# zsWAmfz9}8MM9ik_=^bi{1OZc%AIm#S$u3HxJORFq09bL`JR&Li)gaeL?pS9Hd&rzV zP;Tl9mGZNl{ctn-{IgrY(U-kI_}J~h`kh}p!KS!2rm-AuSZln=ac~WJznLKV(v(Ih zmBGqXFrCV|H|$uL?(-l#t|Syr8$%?*nb0W~Rt!c^oS!5wpn&ofZK4Irua!`cUeF<1 zfXQ%wdr_tq~|Kw*pEw zJQdqr1HAtj=Is;Q8$MCbUPvuh?2X8M1=TYw9JDR} z`MUgn0tSEjf*p_;D;Mk%2JCmQ`ZSmd=z#q#Z-XE$QGSq0g-jF6Mi#XpWw@G&BeoRl zsk_n8wk*&#z_lAK`{~}B*|n`6o@zO%?(ubcBIaR@vODln)om9EH@V82&hGLF~pg?by-51R8 z@T3%jN1a`8y~V#nPdS+i1wLQ{`)~L@2njXQ4hoBm(nMKD$Kj)FZaT-OJobcyr)K_- z_P)cf>FilMkPrxFAyN#uh8n6ZfD{205RoPX1wjO)N)hQbQW6L)AcWo_^w3dMKvAlS zfQuEeW2L!*iv>m3d%giR?(Xlt_bqpK@9*9JU_R$O^UR!?XXfOt%65Q-7FQ;xRxxXh zgc$L4%|{BI{8~3QpyyRSXozPtI}Y3}3b`xUJl8Lj4lgQ5+i zm-Bk#Mpj=IXIIw;{_Wt95;Q=2~zW^GQo@2Cr0Eq$XqVm zqRgo5=W_2Sz%)Oca0_Hwtme-}5W_d!Hq+kKS1h$k*v?$WByR70;a!8njU(EV;dh>_ z9cx*&hOp&G*1EfGeowY0nY1C9e z&9vAbuxvHKCBf{O(EEJnx?ucfohp>azxy2xd~~_AMccZsi+!8wxwDJ!=AI0dns=T1 zBr5!J=HWu~DL+m|tnwJA@W?X9KmT?A+Mk+wUg&p0VWKE#)N`VEiDKSPO_Y+6 zijxfLDzC}1|JvW*72Ld*z;znH`Xf%UyonwzBz~^PUuDfLT~5r?8n8f{daKVL({GGJ z^opgEn@4p0xLOBw55;i|ZC-nCy;b$On8t_;(;<{Krw*=t+5S}4`EbW%^`c1A%fpMb z6Pe144GOvDyG1LCfGeF(XiNi=A7TsTji%FrQVrthM(cO)h0Pbk6Bgq zT$yaRKD38EM^f|Dc+0|q%7%-RCu}1e&OCIgzkW6T?yPBtpw2}wABuOQP~-4o2W*Yv zQ{sdK_S27MW|?zj=lLW$!;5dd!4>|k+-+|_GssI&%5{99(asDI`+in+4K5I=joZM zF`wqS$9^~8w2Zv}Xg26M{2^OewnYMSz-v-8CBfXZJg$yMuSmXPRUYgIg@bxR7?Yhx z^VS{g;R(3emm$CZvn#cnP&LGlKQJhC)#rI-CJ}$9f!dn%Q?Yi%4TSBKJs)aY(m~rK zIBZYVrxd+nug%R?hl@7Y4hfBr&l?N??s`?*!(4)WHgKDD1Zq({<1&=C#3IB*IJ=}&xF_fM`i%R?+^>BcCwomDqF->1lU$5^THv1W%USszgOg~iktX`u-4m1WYbPm+B zK@c~T<-<%jV9y)ZhF@+{4Eq@rKK0Z&_(0(^&3BPZaak1;7h!0}LyAuUy(GFU^?+u2 zj#ab+M{d!sWQXkHa=rYD>U1%;!kPxP+Qya?UN09|=CSs*RW2bN=cJksCU*7rxYqZd zzch46tZev-{e`PHtghc2GyUoIy*u6`_lv~(Tm~K$i=B1!n^PF1gffKKCZZY0I zp0<1bA-!$#)00Z_z3$l47)84Q;sq_mH>)>1l{-e%Q5TlBfZclPd?8Ju?-?pQsRBd8 zk9@vta_P8RVYaH;=DA4$fpY~Kfz$UcwbqQ3>csNmj88DHRv2a~+7F(nyxtaveU>LrIdq&p*VWzATi@1qL5-vF;*bglb2vQp z%JmyJM{jM*+#5I+bj|ww{VN=_$Ns#7W&(Gf58eAYXvFlzobQy8!0ej~&lZCp?Rok> z_6d(8-2pDB`1IQBP8rIIsmaBwg!1#rA}U_@298x+Oq1A7TVr&*@=_+yD%ROuI$kxD zOK=%1GHR{9T=@SPr0M^AkX}pbCUc;I2%H=mkLC5aQDEZ-*F$m@nFELEh9h*HRi9#T z1hN$uYCIb+V5S$`mO;9-$f$Xn80g^(tlZfQ zco#IB@}w^NSS!42-?#RMq1lCTg^?PmhLFe@lU1qDR<09KfSN#>kfV~)H+ znfM|Iq!nO=X$`T2S>Mpu)SOw@(t6_LskZhG@#Ck@vOwC`fBr%?r^*%5pcRNu)5g+N9dpJ1k#2t?c8FqW4O79}nbAq!*7T2OW} z7X@Xfqom^}Peu8)*$M!Rd7tRY?C3o&-gDv7pj@y4ZRpC?Yb+uhyKVI2o%;_Uj6He! z?D@px)HDlYbFY5+2V>v;tn_P50xuekH=HYrJ@Rg5n~o!cal4-vsflSx?}jPIVIx|^ zF`s{UO5rdF!boW9Vm4Xm>hK25>Bs(RM;I4;@v2WJJWXOi(hwW9kd+{n<8e1ecGYVM zi63_hN;$z#gxSXD5)*fm*-H%JFcj=GES&?!^;zPVqpqGM9(CW~^!1}I@Id+!SN{-B ztcCs1@`VVndksiP!G|r-0v%}YCa7Y9rmvHp!DK zqZh-`XuB(S=BOjlqpQ<|J4Iz|z~kCx(6nppZhP}fR*k@0=$?lzMtyhBvi_+cG!e;J zxp_oPzD(F*dXZ0InX6@`cTNon1Fvgpma1r}5|{kePh2u>4KOWc$uy5?1>rs&`Vp%V zmT8@wGR6G5>Muk@)Jg&_=_?6bwv;h$EKp1;6Xr7V>C#-cU_ee8k%Mch+ouV?Z122L za`%?-&ygb&h2XW~A05L6!5AtXL`@1Y2QZqrUr|U&sfmNSZux#vO-}ewdk6X=7%NyAXUxI>72q zb35YIQH#!2jYc!wJ9F&=ip|MW(21#AefZ8ZLL82M3Fdj~NNj#23h!O)f=ny-I#}%$ zR=dad4{f3?+vG)RU}eE#F8KR9F%!QAqx#OP0Gs5vD*Lvl3ZTmajd9^QR)Ufimq>16 z+vg8W+YNXKN;ewIkGYz2Hc2&1-B5qPbzAyP6y?C~<)bpBCIj*}fTu$V#xnVP+LtDg z%i}|gp5An!+-V9cgqq;qje$QQ*j+n~YjAk6Ei@a4kuHo#266GRP-YP;APY z$XK`%Bcpebp#xeXD_@E1P^uq$!Cn4FM)7{jtQ7L);N+%^2EHzEWZDD8cdw^twJ=#^ zq8-eBlV6WaHzNPAWsw&uywrbJMX`8QwHuNhTtl!Z4o{Xz#wJ&kfOZ@h$ z?Y+e^m*_v_H|@Y&%}7(*q5@;eVMaKnGPt591Xbr+^qX^9GV17(QIk_vDe0Z|Yr4ey zEgkAW44)S>DBr%2tr<`AzvP{vO-~ivVMwSRd%?`O@)EtdIj?3iH5f4vZXY9b`*bR2 zl-l*HxkpB&Z_YPG?TUnAxO8B`GU;whTDnGgWd3ptFLA1%R8?;?uFc78pcFP!u)^@; zQB7@rfxoj5q6^BBh4Rx@Xjc)VHC>pBFzDDGTDS1`$VmkWVAenuiX@c@TIJg|OUGdf zr*+!LOOzX2pkuSmwK?;!LlFuKS98xq9k8DNU085(fqXJ2*A9ut<=Gs@2NaiANMXV& z{mPh*rHQr)zq9H`U{%7BRe&k5PxUSg*)220MUi5Din^)DhR(`>@Or`?DqsKG23r%c zKGlSKq|Eq7??$ImfmN$_+NYfaxldN!1drE|<4qS=7Da0Nv2vfKV3iyJkyw^GJevi7 zV{|biJKQ?9%!gjRU$-_{m)Q_f+7bd6{+(^miKQ;v_95KC%HA}>idF*=Y&*nak`RmW z0v6j8E>Y~%n&oKPJSHHWw`HY3c2gL)=)>;kLAAYBHRzW?o15Rm?6$h(SRM*Jbmowduq|m>|9b^`SyJfSOwFHBVAZf|8;zIXG8XaC^n$k@4^H zopRoRn11eTsPYH0w-+1aQqxkxmYg)xCNEj5Fe%ubQR3p{FYQy|ZE9Z&a<|$Bc#E%P zbXsiMZ|qy5IqH&qlT!*e8a;TPXc6z>ZHX}Nq zg0!bPytLLEF6Emf{KxmX?5pzA;lglTgEd{IC#!*B+6Q!jVJvpzV(~AgOfb70_^O4B z(r`6etT`-nDkTsx7rx~e{FoLp!Y+Rv4MO|t2aAs)qqXc~G{S%*d`o)6gK6+AmaisL zOUkr)G3BOCdl=Q$m;kAS`e=0Cv6#A(AqQL9!`aSm5cb6rVwdSekz^dKL>#uueq0Mo z?3`AL?@wrv#%Q7ppN$^UEUiq&cxkQ{y3r6qyKK4!Qj?Pgl$VEfpD;+GQe~9>zLu)k3|}7jl>KmXj1qM_Xt0^kZF5TTJIo~ znl0|OX>O>|onFws#5l0`UZi{kgt?%21;^jnRaETcSyEQ6C@daY!K|&Ui-hwwkaU|9 zTfBZ_+aXr0Ph37T(sFiGUZZ1lEmHr$TdKL7lcT)HK;`kLPWT+W-bEtCwi)k^IZ_wU zrNm=%^Hu7IH1bZiMpIYG#Qq(`k;a#2ptsCB=Pzf*cC8S55CigDyquAR)}<7g0!E;7 zNHvM~VBHba{wDYEq(*k~9fXlN4zUhy`9hhjM5NeoxRpl^SsCUDz1z*5CNb1n1T_J2 zR$ig8eP+!zE2VQj$q3yiwDbzY^Piu%6TYu-=%qM5mFs%kJj=M>MO6A>dS+&bvqzR; zhP7Y*K6GITHM~4(H@qs!ad&O#&a?)0Us$qhHQ=_mFHUMtPsiJ9U$}orCp-5g$l12= z!wp~s%iIRtWQR0f1OUy_$omK)_NB>7g~2WY$zHjIGNc~9?z0ncQU{ZVASl>Tv@o&p zmOH-WBFi=wulnr>q{?bt;^rPut09EfJ)DD z4$00-*=`zw0j);u%rX+Pq%!>QQt_|lm{|>#?Igcp@5{3Rwq0&~neN%BTDPZBM3IF=szxV0c?-x$WCkO{Wy{^ z%ZgvXX+ivw_GAVAEqkDR(>Em-%1!XrCHoAd(W-b}`?9)v?SO`egN){=)O_(%-*XD& z8W04R;~2R0;$etuseBKQn5~QA9CR-ROtA)C~Bw zP1aoU*zH!dcP0ApCcMu~(bU36k2-VB#Z8C^GSxLSP9B}8>J7bWSP)djeo38zq8SyH z8XNLxRR?y|f2~FWm399n zHIl(Uqek*dXN-}sB3zRxspH7?R^z?T33Je`0~OWj zq78|VkZ<4ZR@PtjbIh>wiFapb%$!Rn$A8bvUm5TZDyn~d3GC{halMd`?@=E`+m6t3 zafF+bE?s}c1*R9b_LETbqz;*f!iUTmn}_u%32~zI`{u9an-quW4BOeL@Bcw0FmP-^ zJ{PIvFnsP!0iRi?#;JR⋘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 GY5fOuZZib{ literal 0 HcmV?d00001 diff --git a/staffing-ui/src/assets/404_images/404.png b/staffing-ui/src/assets/404_images/404.png new file mode 100644 index 0000000000000000000000000000000000000000..3d8e2305cc973ad2121403aee4bf08728f76c461 GIT binary patch literal 98071 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 literal 0 HcmV?d00001 diff --git a/staffing-ui/src/assets/404_images/404_cloud.png b/staffing-ui/src/assets/404_images/404_cloud.png new file mode 100644 index 0000000000000000000000000000000000000000..c6281d09013e0a2c5f8e699a0a6038d9480291e5 GIT binary patch literal 4766 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 literal 0 HcmV?d00001 diff --git a/staffing-ui/src/assets/icons/index.js b/staffing-ui/src/assets/icons/index.js new file mode 100644 index 0000000..2c6b309 --- /dev/null +++ b/staffing-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/staffing-ui/src/assets/icons/svg/404.svg b/staffing-ui/src/assets/icons/svg/404.svg new file mode 100644 index 0000000..6df5019 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/404.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/bug.svg b/staffing-ui/src/assets/icons/svg/bug.svg new file mode 100644 index 0000000..05a150d --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/bug.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/build.svg b/staffing-ui/src/assets/icons/svg/build.svg new file mode 100644 index 0000000..97c4688 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/build.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/button.svg b/staffing-ui/src/assets/icons/svg/button.svg new file mode 100644 index 0000000..904fddc --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/button.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/cascader.svg b/staffing-ui/src/assets/icons/svg/cascader.svg new file mode 100644 index 0000000..e256024 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/cascader.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/chart.svg b/staffing-ui/src/assets/icons/svg/chart.svg new file mode 100644 index 0000000..27728fb --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/chart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/checkbox.svg b/staffing-ui/src/assets/icons/svg/checkbox.svg new file mode 100644 index 0000000..013fd3a --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/checkbox.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/clipboard.svg b/staffing-ui/src/assets/icons/svg/clipboard.svg new file mode 100644 index 0000000..90923ff --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/clipboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/code.svg b/staffing-ui/src/assets/icons/svg/code.svg new file mode 100644 index 0000000..5f9c5ab --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/color.svg b/staffing-ui/src/assets/icons/svg/color.svg new file mode 100644 index 0000000..44a81aa --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/color.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/component.svg b/staffing-ui/src/assets/icons/svg/component.svg new file mode 100644 index 0000000..29c3458 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/component.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/dashboard.svg b/staffing-ui/src/assets/icons/svg/dashboard.svg new file mode 100644 index 0000000..5317d37 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/dashboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/date-range.svg b/staffing-ui/src/assets/icons/svg/date-range.svg new file mode 100644 index 0000000..fda571e --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/date-range.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/date.svg b/staffing-ui/src/assets/icons/svg/date.svg new file mode 100644 index 0000000..52dc73e --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/date.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/dict.svg b/staffing-ui/src/assets/icons/svg/dict.svg new file mode 100644 index 0000000..4849377 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/dict.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/documentation.svg b/staffing-ui/src/assets/icons/svg/documentation.svg new file mode 100644 index 0000000..7043122 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/documentation.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/download.svg b/staffing-ui/src/assets/icons/svg/download.svg new file mode 100644 index 0000000..c896951 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/download.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/drag.svg b/staffing-ui/src/assets/icons/svg/drag.svg new file mode 100644 index 0000000..4185d3c --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/drag.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/druid.svg b/staffing-ui/src/assets/icons/svg/druid.svg new file mode 100644 index 0000000..a2b4b4e --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/druid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/edit.svg b/staffing-ui/src/assets/icons/svg/edit.svg new file mode 100644 index 0000000..d26101f --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/edit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/education.svg b/staffing-ui/src/assets/icons/svg/education.svg new file mode 100644 index 0000000..7bfb01d --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/education.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/email.svg b/staffing-ui/src/assets/icons/svg/email.svg new file mode 100644 index 0000000..74d25e2 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/email.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/example.svg b/staffing-ui/src/assets/icons/svg/example.svg new file mode 100644 index 0000000..46f42b5 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/example.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/excel.svg b/staffing-ui/src/assets/icons/svg/excel.svg new file mode 100644 index 0000000..74d97b8 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/excel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/exit-fullscreen.svg b/staffing-ui/src/assets/icons/svg/exit-fullscreen.svg new file mode 100644 index 0000000..485c128 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/exit-fullscreen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/eye-open.svg b/staffing-ui/src/assets/icons/svg/eye-open.svg new file mode 100644 index 0000000..88dcc98 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/eye-open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/eye.svg b/staffing-ui/src/assets/icons/svg/eye.svg new file mode 100644 index 0000000..16ed2d8 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/eye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/form.svg b/staffing-ui/src/assets/icons/svg/form.svg new file mode 100644 index 0000000..dcbaa18 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/form.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/fullscreen.svg b/staffing-ui/src/assets/icons/svg/fullscreen.svg new file mode 100644 index 0000000..0e86b6f --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/fullscreen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/github.svg b/staffing-ui/src/assets/icons/svg/github.svg new file mode 100644 index 0000000..db0a0d4 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/guide.svg b/staffing-ui/src/assets/icons/svg/guide.svg new file mode 100644 index 0000000..b271001 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/guide.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/icon.svg b/staffing-ui/src/assets/icons/svg/icon.svg new file mode 100644 index 0000000..82be8ee --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/input.svg b/staffing-ui/src/assets/icons/svg/input.svg new file mode 100644 index 0000000..ab91381 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/input.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/international.svg b/staffing-ui/src/assets/icons/svg/international.svg new file mode 100644 index 0000000..e9b56ee --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/international.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/job.svg b/staffing-ui/src/assets/icons/svg/job.svg new file mode 100644 index 0000000..2a93a25 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/job.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/language.svg b/staffing-ui/src/assets/icons/svg/language.svg new file mode 100644 index 0000000..0082b57 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/language.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/link.svg b/staffing-ui/src/assets/icons/svg/link.svg new file mode 100644 index 0000000..48197ba --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/list.svg b/staffing-ui/src/assets/icons/svg/list.svg new file mode 100644 index 0000000..20259ed --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/list.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/lock.svg b/staffing-ui/src/assets/icons/svg/lock.svg new file mode 100644 index 0000000..74fee54 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/lock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/log.svg b/staffing-ui/src/assets/icons/svg/log.svg new file mode 100644 index 0000000..d879d33 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/log.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/logininfor.svg b/staffing-ui/src/assets/icons/svg/logininfor.svg new file mode 100644 index 0000000..267f844 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/logininfor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/message.svg b/staffing-ui/src/assets/icons/svg/message.svg new file mode 100644 index 0000000..14ca817 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/message.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/money.svg b/staffing-ui/src/assets/icons/svg/money.svg new file mode 100644 index 0000000..c1580de --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/money.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/monitor.svg b/staffing-ui/src/assets/icons/svg/monitor.svg new file mode 100644 index 0000000..bc308cb --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/monitor.svg @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/nested.svg b/staffing-ui/src/assets/icons/svg/nested.svg new file mode 100644 index 0000000..06713a8 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/nested.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/number.svg b/staffing-ui/src/assets/icons/svg/number.svg new file mode 100644 index 0000000..ad5ce9a --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/number.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/online.svg b/staffing-ui/src/assets/icons/svg/online.svg new file mode 100644 index 0000000..330a202 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/online.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/password.svg b/staffing-ui/src/assets/icons/svg/password.svg new file mode 100644 index 0000000..6c64def --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/password.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/pdf.svg b/staffing-ui/src/assets/icons/svg/pdf.svg new file mode 100644 index 0000000..957aa0c --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/pdf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/people.svg b/staffing-ui/src/assets/icons/svg/people.svg new file mode 100644 index 0000000..2bd54ae --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/people.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/peoples.svg b/staffing-ui/src/assets/icons/svg/peoples.svg new file mode 100644 index 0000000..aab852e --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/peoples.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/phone.svg b/staffing-ui/src/assets/icons/svg/phone.svg new file mode 100644 index 0000000..ab8e8c4 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/phone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/post.svg b/staffing-ui/src/assets/icons/svg/post.svg new file mode 100644 index 0000000..2922c61 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/post.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/qq.svg b/staffing-ui/src/assets/icons/svg/qq.svg new file mode 100644 index 0000000..ee13d4e --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/qq.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/question.svg b/staffing-ui/src/assets/icons/svg/question.svg new file mode 100644 index 0000000..cf75bd4 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/question.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/radio.svg b/staffing-ui/src/assets/icons/svg/radio.svg new file mode 100644 index 0000000..0cde345 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/radio.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/rate.svg b/staffing-ui/src/assets/icons/svg/rate.svg new file mode 100644 index 0000000..aa3b14d --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/rate.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/redis-list.svg b/staffing-ui/src/assets/icons/svg/redis-list.svg new file mode 100644 index 0000000..98a15b2 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/redis-list.svg @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/redis.svg b/staffing-ui/src/assets/icons/svg/redis.svg new file mode 100644 index 0000000..2f1d62d --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/redis.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/row.svg b/staffing-ui/src/assets/icons/svg/row.svg new file mode 100644 index 0000000..0780992 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/row.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/search.svg b/staffing-ui/src/assets/icons/svg/search.svg new file mode 100644 index 0000000..84233dd --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/select.svg b/staffing-ui/src/assets/icons/svg/select.svg new file mode 100644 index 0000000..d628382 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/select.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/server.svg b/staffing-ui/src/assets/icons/svg/server.svg new file mode 100644 index 0000000..eb287e3 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/server.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/shopping.svg b/staffing-ui/src/assets/icons/svg/shopping.svg new file mode 100644 index 0000000..87513e7 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/shopping.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/size.svg b/staffing-ui/src/assets/icons/svg/size.svg new file mode 100644 index 0000000..ddb25b8 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/size.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/skill.svg b/staffing-ui/src/assets/icons/svg/skill.svg new file mode 100644 index 0000000..a3b7312 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/skill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/slider.svg b/staffing-ui/src/assets/icons/svg/slider.svg new file mode 100644 index 0000000..fbe4f39 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/slider.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/star.svg b/staffing-ui/src/assets/icons/svg/star.svg new file mode 100644 index 0000000..6cf86e6 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/star.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/swagger.svg b/staffing-ui/src/assets/icons/svg/swagger.svg new file mode 100644 index 0000000..05d4e7b --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/swagger.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/switch.svg b/staffing-ui/src/assets/icons/svg/switch.svg new file mode 100644 index 0000000..0ba61e3 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/switch.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/system.svg b/staffing-ui/src/assets/icons/svg/system.svg new file mode 100644 index 0000000..5992593 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/system.svg @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/tab.svg b/staffing-ui/src/assets/icons/svg/tab.svg new file mode 100644 index 0000000..b4b48e4 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/tab.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/table.svg b/staffing-ui/src/assets/icons/svg/table.svg new file mode 100644 index 0000000..0e3dc9d --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/table.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/textarea.svg b/staffing-ui/src/assets/icons/svg/textarea.svg new file mode 100644 index 0000000..2709f29 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/textarea.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/theme.svg b/staffing-ui/src/assets/icons/svg/theme.svg new file mode 100644 index 0000000..5982a2f --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/theme.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/time-range.svg b/staffing-ui/src/assets/icons/svg/time-range.svg new file mode 100644 index 0000000..13c1202 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/time-range.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/time.svg b/staffing-ui/src/assets/icons/svg/time.svg new file mode 100644 index 0000000..b376e32 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/time.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/tool.svg b/staffing-ui/src/assets/icons/svg/tool.svg new file mode 100644 index 0000000..48e0e35 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/tool.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/tree-table.svg b/staffing-ui/src/assets/icons/svg/tree-table.svg new file mode 100644 index 0000000..8aafdb8 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/tree-table.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/tree.svg b/staffing-ui/src/assets/icons/svg/tree.svg new file mode 100644 index 0000000..dd4b7dd --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/tree.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/upload.svg b/staffing-ui/src/assets/icons/svg/upload.svg new file mode 100644 index 0000000..bae49c0 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/upload.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/user.svg b/staffing-ui/src/assets/icons/svg/user.svg new file mode 100644 index 0000000..0ba0716 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/validCode.svg b/staffing-ui/src/assets/icons/svg/validCode.svg new file mode 100644 index 0000000..cfb1021 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/validCode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/wechat.svg b/staffing-ui/src/assets/icons/svg/wechat.svg new file mode 100644 index 0000000..c586e55 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/wechat.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svg/zip.svg b/staffing-ui/src/assets/icons/svg/zip.svg new file mode 100644 index 0000000..f806fc4 --- /dev/null +++ b/staffing-ui/src/assets/icons/svg/zip.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staffing-ui/src/assets/icons/svgo.yml b/staffing-ui/src/assets/icons/svgo.yml new file mode 100644 index 0000000..d11906a --- /dev/null +++ b/staffing-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/staffing-ui/src/assets/images/bg.jpg b/staffing-ui/src/assets/images/bg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..611192155cdd440fa9781a6728588abf55aeec46 GIT binary patch literal 986646 zcmbq)_g7O*)Nbe~O*#^qfMTI41f>O}OOuX-j?zP$M0WROV>#q9;eCPah*36l`*PPk=Jo7wzE@vxzR`4|nd)D-xMfXC`ZOkPJNsSE0T`*S?66X?0>A(=uLOsrT4hdO-$EaQ zRX!C;O3*Nv|Cz>@QvbnM5Qcd_Ob)npV6*`gCFY<5r;${1rK@ai4~F2pG<9`dkZx4` zXW6rdKxW$rv53~Q>;y8nq_Chp^kar)CBod^a35DFut<=5AuZ1~Ba(>veJK2+)c1tB zA*3+y;yg^Mb;~b7qm;Ey_j;_E`ANds$izjF_~W;4i)CIJMQMqq0h9c9_ZH_HmZ>E8 zs!y&x1T{}~{r08b$q)78#uh#qezQ={|AW6>RG~KOFXfj#uZ`3_MiFB)>=K}u6frhB z2@!3&1O$m2v9s5xOC(a&j?F}^$~63HxnJh3Dpp0Ew0O~-lUJWt_vK~Qf8}2V{qNqF zk5B>F@uZ7Q3NP-v0`?EG!;&UY7EreNI0&=Z>Mr8ScsUPtYzICHmExZ!*BO_dpw!z{tTr<-^P(R(o*QHOc^gerWQma92#z<%Hyk~0uv zqAkp2PMt0eT-a3rknJMC*?O)nPm4pLjJH57MutP_JA8dP8j-$>;g5&70tE7s(|Bzp ze_W%^l!W(?l>oi2x(-y3IE&_}#!aTE3*@dMqr#0rMtR?b=I!E>)Rm5J5#0ihU;h5_ zGc+wIhsqDvaDd(Nj_;`|{ahwEnj>7P-<$Miw3D^?K9@#A=tH&mM=<=Kj=ChB9q;8O ztz%r<5%OsSzx8+FuWvGy zIm`CXI?a*i5@SoL@^9zL^6qiJ)-09et1Y?1ATcq_TvCGedN7P z*Nmx$tOC4P6tLorDeKr42N?+h-{ICAN&o5mrZuB7jRZn_shq-~D1A0A&FS08nLP`` z{!$X()=19T=n3qPuZ32W&c8=`D}L-&D2*OgZSZL~G9Air{g|GIjI4GP38_5JOniBt z@qrV!->*vmkN|riNaY-dq2$4SrE*YSRzVq=#=j@MNTR!2>la8natYwC9orfPlJEQ$ zdA=U3+Dtrbfq5wyuGv24W*m6`vv^xu`drwUJHWA4vlnIX7E^T0!&fW5ZDmEvL z*VBN+$Crz`I=q}g1;mT2KraDO6D#z=ZyaJp=V1}{g3N{8JXnk0_G<^Gv=W{{Z&0jh zg&!sj(qsl?_{Z$)!#2T<3ysSy#tbeCqkftbku8*!?q0&5F*FM6C$ki zy-8>NJH!6p(cj1hdn0vk-Rq=l`@|AP5h)69-&gCizQJR16Ni8K3wy0ub|Cl(XeYX1 z^!{88E%&YbPiw8sT@m%`>Nm6CDd|*;tH5u57~H|oGh@gefSxz170gm+7hIlKNplma z>)95!MRLm{Q0v=2EVSyXfAr`?>a(V)?6YHZAntYf$x#qGqF&sF~W(?s;?TzZ1#W)k+9rV$rg>jjHy0%N1 zTgWX~uX|=@L3-|O_Fck16p}6i@0{V|Xpc9W&@;(qPv;~Y51W^X6U%&`+|`hek-G)7 zWz!ZrclG=L(cxNGVQCuYg|F~)9%pJNh9LC8neSEMa=9;+Z3En?a(36w(twUpTH%_C zy%7SPmjG{PbXWj>`YZaHM=bpSH;n)Lkw3|!3`k;=4hk1aJ1Etf5Q$6t(Y}y~b3mvB z-!9G43jXfmh;7|d%+Dth#;$9gJpE&|BFaX83L^$D;T-RErl)mK4i4jdP&sSo)p=a+ zr9LEm^1hY{Txm&G{T5^bEbHhRI2U9Q z>_Q73qruwP?#dU8IY&wC^R40j!99>TTh(pt1Q2p&Yf4M3ZK6dT?YXZaSO?-@ zZ{)T;5A{VE+QP<|MM8Lhb=aS!(C~P$QC%J8&t`NLXOrLKcCmAuNtKiV=#jYgS{!i1 zldTi0pBqG>MwLOmzlz}Ax{!8@9vB_!i3KsWg6&YP{hx0@8fbnMSeSu}@EdWlJdIm^ zBbEDL74_^9rup5eZP{kD8S1@bJ`1BGVdEo>9A_vsV`(zQ!kt;=)A77}FXOEeDE`}w zfY|pV?Cd4B(YhwyNMzB}g;mD;XB>B(DwUTa!n(tyP$Nu~RpJbp;m|!&GdTz=u*Nan zG^rL(9*%&PPc#nc?FGNX;(Ohu>D5e?n=s~sgjSNE6yF`ujJho!lu9J=G}v!%BZfNj zsmYzm{LR@Y+%Mb-AMx+TiJSA>PtSeYW6=Zf+(M`mG&s1-%kGuLAg-%|`e$w8j30OE zYpaWk>B2c`i?@2M_%N>!%m_4%5O&?2P3y}&^^qcf!jDCs2UV#g-oFLM5@Tg3sqEg) zq|*7+Ao-T4kzXqajOSlZ_sYP{YPxAfN0_h7kb$j`?DYM)N31WsXg=peger?R^cvG> zWQgynKa_16cD^68$eVUx4=dz%4R}9w^kr)8@S2*=obkP>q-sv!&SDWb^UFx|;FN1a}+$nmEj6 zzwIsxoE1p9h;TWzuD4CxlydTVvI60f7kG&&QVc+4>p2F#Qe+^jpuA`of7{^(JoCgk z7|x|-+`7JGcM&T89=tyrtN2V#+C=O1Hyu4ObrF&O^cL!Bz>#W>-y_>Ib;{7lDfX-@ z>pZO_Xw7BRNd^h*H6r6q4n4ByjOPWMvo7q5W^Ui4pQWWFqdsjB{f2#0&fmJd4FmVr zi7jj1vXEHYG^~-2=_oZdFfcNQnhm@kQ1=dzEI4m!rY`7fqk5@GyVp|00zbs$a_K#F zo@i${DHWnspL!kf9#t8Ya5B_kl$J>Tn zdvMBrk77?_zlH%Td2^cv$IG0xaR3CKEoPe9jI9FKGl4&r}eyWQ~ zdxQjMKT4kBcxP_2Ce#%JRtcBwO_LG|WoktX#l%PuU)Ygsq@(K6^cQvoP89^fB zMd^J+TCuL~-YDFfcZ5xB_v6N@W%0pUPzsa&pz?(C^b?$d|DUi8!{+Sd0Zc5T921cr zkNf7|Pq_mCQTe=T9=wWPn}fr?L=Z!5-@)B$0AR>Dgx=|TdJwWbOr>Ry=x9zaMg2hJ zjfHFTC1B%soU%m1L`<90K%|uwegZ3q&CVUF@7e~#>bhH1Uqi>jyle>YU?87ee5nn}@1(7yrb3UehUeCn8U0O-gAkOvCG!Rrn*Ey{!fw4yji;XkmO& z>p|zz4!jX(PZ;T*(^F#hNe8Ra=hYt7rL;~s&)jiy%P&6s-$ox#_hO6{3b6^Kv`_oE zlpu8b4GAKQw0IGrxFqKIn&B>4l_Ave={8h^zrF4+i!ew4tdjE&I9X}RY4$AbFj6DH z|D9Q1PKp#&AW)z(Er?gTJi{5!Aki$yfIYedi13t+wa(R!LUvO%?BNHyJcFj?>srm{ z3nvE?f#=8FvbUjG(iGi0un`1v{zYL9+_(u#Ncb8hI^BOjza8Wx42e3d$5VS>wnEMk%BNO9-)ZikJH*Xb8e(r5u~1QwURasonU) ztZ}AfcoGW>%Qs9_KS|{mD7KVw?}42L?da$1&`W@w0FUQK16_$1vd;Qys$U`Pq5I8b z3F3-a(%!umCI_1Gb4&JASNy-h@c@eqr>)1G{wK>32oOj&BX6@bB4}%difO!xu7?Fv z$Z>tcf#zo?*v_*1yOr_vZSjx-|`;V zpe7Mn?CUqP0W?%S7p;9|sq>`NKvMH=R%?T@6il%&*j#bsnVE9gFD=AoxS~hq6G5mL zP_*EeTuP*FL$A2)l)G*3azr5o>HPRPx#UyO3Oa#3g`H9!iSwj`=m; z`MT=Pi_swja^}p#T_gv$i`(scJDZZoNY~}lb|8qoo^mGkf~Hw=>4iaJBakq&IXnNg zX@Kjx1i1uTcvDOH{rM#z+<^W-S$^#ZNyK=0-b^0+%GEXeFSY#Z&Ez4cz6uUZCn>(U ztZ&8iMRKp=qsfa)0Gh%4x%l+Dg5ME#X{CGCwf`{p2%gp8%ItTPNBfBGC5^WP{PfC8 z9MyQ3Htt-SGllc%!#F8#G5$07imA>}k63!QbTm^ci0f}*mvsAF^zf6zcNS(Ww{oGJY)1i-`U1EO=sL?fiO{|Y zZz+fBhax+})$ZVy!ojoFpr?}640AvaApEF(XUBpRqin`6Fs%C0lsI<;nD`cblHWgjt=P-1A?ZgTC$Qsz30JWwO4aJY3#@~C>)Ut29iPwt)m6Aa_!FKN&(6a8`akSOO1XfVe<8bOnJn74PA>sr zZqS2nOt_$uWbb$5*8>1fi{;@xnFA8flqS4c(|m^#wd!P4X)5P@m+zCAn-}U>ZUxP)(P?W5MO8Y@n9nb~gP+0zHKOx!dKD&l* z^D5n*_4)dGg!76Z>jUZAoIO+)QR5P|p6-m=CrEK#OvW~`*y1bd%ReUofQx_e&AWK=|#&-f#ISF&zDF+c#8Ycj}XpZoOd^D&HQksBk$cxCc-Z5PHe>w+VM zo;tG3oA)m!r;F$;pF#%v^%E2$#GrrXH@3=S%Z&Ai9D0rf8RmKz0u~zG)xJ@e82yR8 zGPSsaRrI((_7%`7Y7kDk><)Y|3v1p{0&NhT^9`=G zX$l?6#hR!0ROJ1e3wfL(qvP0lZ(oeO;bvGX8p%5sNlDULU#TDA^4iaj7uN558Suf} z>##(>x7zgU_I(N8DyIOk`ttkJU+pU~2N$ijBT|n>gH$QECZz?jCqrHJ98lwqhV7#O ztC|t$yPoCwh9g#PPb{&U_Xu^`~zj(A}?cgPW|qHs&Sw z(0Zml|LpSu)kqFGoH$xBm)pW$(ZQxy zrnfctY)2v23u-s^ZM(PG-~%b5g-&PK;my?}JsG~(s5L+MEEE37bDz6^j^5q1N@vT1 z`o?=F(N|8@+P57_<@=e$QcNtZikcE+=#Pb@sd7yBsK%g;F9#o80@!2{L{3SYS>dh9 zjU^`LdfLXEnu_%6i7{G(=8>SrR&S(${K4w$>bJQbqVDBT!vQW3K=8TrZ>^G=b=Cg~ z)yJ7R!$L`|W992(U-Iqsx~M3|2n z(JXy^oqIR?PVH!!MV5ZO)Qu5wZ>dMe)kv$MuI{}KBxWh$$>cRYjlmV_SeKp5YdiT6 zv}cGt^n;9T`0p~%y_VwxZ2GFU^6o=j2cu#I!*|Hay$up9)jqktz8+TI)owdffq=n% zeT?3nOQV~jA3=;wzO=}~{TD<3CcOEmF)4ljtf#QN=|v<(zR4l=w#3o&36|bn7ld~7 zR%H>CEGiOrD{z?K4hd8GPXSB%3v3GgU4OFRF( zAbF7|)P%qfVCV?6%12!>V_Q*` zlTbJ`OsurB%NYNNjN0FO%1noZg+Gy~v|@z`N2m%0V(f=z4SHOre)RSHK^RHZwQAMy z3-{;9&qDvbE>@*(okXCdz-cG_Dx$Gk643{AEw_}#_ct5=n+$sJExj9$-$LxIrPKi9 zL^mmC=zMT3m^351R;{k@dexEFsAdo&heKAgTiDu82?V1t=WVq;c9MM6CE#VeEQ`r> zkJ%w$>~l@;HNIr~BT;1C`@vs-(+zfX3Bc2WtKE$f_2N32bk4{DsCe#4wSNjchoQZ0 z{bzjwJlH?FK((9}JdDtW-gK`h-6gB5$qpLi|JJ9Ha*O>`NYZ+A9eoM7Os+W7Jj}wn#T`1Ox4Uh8P>W zSviOCL*2RnKUh+eymn{$pBfhU`w}2|08<=C)E6gwL@dwigl7=Q%VGm#rZ z^YreSI$bXeRN*mX+&%z(QLst}Ve0FsRrylJViS7gsLabR0S(~t@`f8vlE~2H$(gP( z{Qg=z>wlW?>8@_={;jO}1`H>1Y~*Be`n%}-iU)<_spDhoe0!&GFk&ml<6i8*C4gmS zqpEi6l_KB?#yjVCpbFJEqu1hzP!#;a7L#ZDVYbYc5=N(!LnpICp5DC@M+T`bl#)@ zu*>Sh8yv7w26hDdNKtJ4{?J`&1{=uezKD0x%&#+tsanQ&Toq5#Szn>-&!NcLlYV87 z#szygMu+y~99*&WFR!$u+T+`N<{iOOCH*axU=q3LJ-Ga1_HQRIn^UH-G<70NwyKPC zXTid8!-P?7V`IrcbFb2O?7rYt&b&fwkmpREkoK@{XPP~a;=G!s=x(>HbTL%Ee5Z$h zlGADC=#2p~swGP(V8Zr=|-hekH0N8Plw4g-O+`>6pB)9YZ4j&Q1jhJ%*l zo*r}rks4mH$f&(U9YR42S%Np?OD&BV#jP1$Ck7n;Ex0j%a@M#RI1xmNNmFky#EXmO6v8cZQAF0d5o!;IH^2%|?RVWT>Fs#}&8fK>IO2M6bSc};b1Lj{V%b5ci* z!W4wePKqYN;RrER=rbr3yr+1fanQ{kxMzRSgRqg*a&>|fr5V-N^D!?UZ+Vhs#-2qv z+~YBi)LB1Yxk=Px6!^1}dP3TInF%`}T>>7Pv^5GkNi2}G`a=A~T%aVydSt%L+R=p;U#X$ydkVzb=>ckOrk|g`-Mu8U8fHRiS83%! zmD*R@u4%6KNYHJ#4l&#yYoOs39v-GZyvhn4rO8RqjbHu4VVurX(D-!Rp;All;i)&> zqYFbEx@eg9#{GNqwrvSz?LS=0)i+P1H{`r090ltUMtj96*<+PkFkpyR5C#{W(0{{l z9(f2lByEgQ-PNUC>G$~-7O3+0KBbxiZ%?Gost#;qWhu;k&W*mLM5pI~PcuL4&&fnh zXjIv&?~ko0BVfS|C+LKgr_+;aWYKfKQ~UnH+ke}&oFBZRjuCqPqP`nPf@DhuyBhE( zh!-9ybB}p?MpwJmR{#Kg?vzmN&P2}@${Aqy6ABJ)PVmn_1r*8|7R|J%zaS) zjV)%p`9l+Nv9fbu=;(L6o7u|B{H#r3OqB|d z=-Bi@s31HqMPpvFCnUoeIn0z?+#q_Q#%&xvc+$uvn6)5N0~?soHI<#aGvXH)y!NEX z!1eTjS<55uixn)!0{qvfnd8WJ-M?`JAZj8)>n;I}BX2V=Dl+|=ax#D0T_C?WBbq{t z4r**YrSJ|mO~`H5Dx*ILL`eprW=81Y3p$PwrC}(=s3R|zJ;kP-7(*<)=)vR2RCxNY zCgZ0Fh^d=tDb?+ANaku9WFxX`Xr=t@2saWwrhhAuawY6m(mm0g^3@&K?(XB8+2(iz z1)PB)wY1(^HobH7axK=aSLpL6PR>S#&-T~}Q62HU#NrV!e|GDlwgytJ=E zrhZU3)dXNCL$-r3m5L6GWpSANebOm8m81F^)r&i;9~%BdE&g5X$@sAt{@QF=Pk7Ar z=2th8>)aK0fE`Up)@yR8jOeR;ni8}X5!iCFfrxR_>WCDlpoT_-)k4#5Ev2ST zneCVnjzZS0#qxvjH?tzz$ILjsIt}08N^rt2*PHYz1lzuBG`lX;~acH>+#=%PU0s z-~mkU9-nPVm}^=b2 zz$=bRlpIEDocnVyUeU(4yWcaQr|P$9Ohw^n=vmOYTyZ(D>{IUXQS+YXubAm|+{!uX zN@XcviBLC+E6hGT#SAm|eZK!jYpQt%HFMDWww2dk0J7h(HR&CiA2maLYWu^zynQ3o zBSELlRYY{(e`OoN%0q93e1G9`IthP~{VWo2q8*!hhFNNvwH{LCLn%FBt&SWuV>9x% zhcOf)R{AM|G*Q8j^5NC6FsXwf>tpvnRn_$p81wv=wE5w>;vXN2zMULrEKT==%1l%t zNs$t-LkPrhuQ_*0te%y}sWlE}B#BVEwn@dN9)(~%Iy&fgv3S*JLAmrHtsUBc94?CA zl*F6I%KjENka^$qm5a2u<30&}CI?{*%J~>2Hucfo+GkFY#?}G^k!xc>*cIB!lxtg< z-W@MqfR6puo+-S>=NPful3#G#m8OjMcFmToU{QSX@j>ep02Q{akc64ZKJ5!Uo}0^W zHXTsz+g8hvs*rj{sac=2-b*E_k5b%Ju*_6HNwu>6Mvtnnb6y84-Q$UEP&}eTNOs!^ z^4*;D08yl$l~Mu@l*q3E$)6!!NTedR-*F33^Vj-*b&a~XU9};z*%RDzHA#_|PSa%< zka(UHnA&cXdX&oTA*>T zFE-?zK5{c;_#Y!Dq~p^BgC*G_H(GH~*;QRffATQSYCz*$bVV;Tw@@ghbYpFSdp0Q| zd+)JVZ%)kX|5U{W@TjrjLVi7U@+7eM&t6?$|<*osHy--TR#)eipyqN9n1 zb1ol4ZIq~hA;!ykR&uNzi$D)gF;Sf?=@j6lCT+VGG-s-h& zM6x!nrtdVOT~n!7RP+U1&N_mi>$#NrQA1B@)HeR8C2CG7)#fe@QmHl~pZQ9Um5N>v zMTc;0IXizVEKspHO~O!1|EFIqfOFDW1<>VeY8&Q!pOkyoB-tX`KuxuF&~VW@vHep* zV(am0`S>p1XuXv5e=h8NN_%{R&8&ZF7NR$VSM3j#E`avX2E_~p{y>G=GR?L|+*%{H zqL5FfBQx@!@{=1y5XWApHo`rm%3UAo55J&(Dd%mpTZ3w4X?zaV`KM%5=zoa*8e~} zQ6;1F;g|WK7g4j2t%6-yc4I1HY}C#(Qs}=dhCAY&$D;!0wIu_e635qG$lvex^G2

j9FqxU0Q4t||Iio34hj2>&Ein^^jKsNjf~zILX8eq4FuGz~*QB(~Z2 zTEm2-=C1_+=rpJ$u;`~w(=WAwYohwYTMQW5_2b#t0Q9p81M&Yb6d#dsBG11DMrxHW zOM8#XtGJ>O7%w(AcgGYv-tvNvL7&l36^;CG2n!g$ny`VVehYcZ`qggcYHhRhF2D#{Rq?gXkD8iQhg-H;XP0a2Ot5QwRC?g)NN+Ack@Zmb%*XT0Z z_AeF#+lCe4ZV$@y$j$Pi$E$^e(XZi(-bf)3aNVj4`=2wRyjtL?aH?2FyKt3g+VjxR z3wUfG1MBSxoi$)Wj$c=c=;0-RitW9GG4+Pr17Sm|hw*wz%t2IJOWhCaEJtrkNz7H{ zM%@)Jjp-VUk5>umCO5Qq@=m<(>0;Z^!KMW%MI&St@gr zznY@Sy@5%F#|-GRzu*5WFP3fX>fhFm2P-o8D`IH#vOF9zbthsR7i?jw&E3YT^^&|T{TeKS{)BnlfDY%{Ilfw=Z%ZoQC3n8RXC;CIhO^DPl54VC( zFW*|t+S|O9l++f6qALbI%2tPZv{?sbWN8Y$F{jY6vk=QYh3yT%gKR!I=o}Dtyy@aU zq%u?swP!E#FMzvzF3BX~a=K)F$P#}~}oE{S?1q(*vKZREHsXl$$xA!OXFkcdiLh0`(!|v{-$~po4Hjv=J}~Ql zqT4cXv63-lc3yDvg^h0ILT$@%8KHYdu;}yVo&ewOS@;c`TQb*1yX#s1Ot@G0*Nox7 zt43ud^n)uON3A`@zx}KJLOc*3k>#k%zR_2z^!0{RaV6pY#^NQQ@PVHZqy92LGtt(l zDmQYLO<75q#pa2eo*`UE_vHg9n`E(ko5&|Y7J*hbXSs>Srx^|0+`wkkwe=@N3=|(1 zTm)>{MmIML@|9X#+j!<={5M_%0ex6l-t1c1^Ey#jyGeT4|M$AMq%L3~x?j zEAT@3vxR(9*-A+!nm_fm7j;!stSj<|NWq z0m;|44X%i7*nBc7UT@G@V0D0ckXCrQ9jxF6>LeG9S+0h{*B0t7taWp_x%*m_)jQjU z3R5!RBT$ifMd>wonv|e=m~_aqO!`S0!kV|nY``uq@%w;@mRPEb`_D6f(Inuu#aY0) zf)m^G(gGo>u9L-;4`gL&JK^fU!IJC78%gugV>J;DZ1h zBt~CP-np7!I-$o`zas(imZlsBrd`7pNVA79A|<*HzLn@P{RAa<5|$2C9+#}%nEMWl zX%%QePIWd$WyyAEI-MmQ+D}}dX6RG+=SEIXkdgd5(U*YA(-jHG2k%>ws=uUJ!K3bn z7#>=Sn}AijaHDYU7PtAJ)nvrbv0~K3%+>|1OtnVz{-Yl=J4YKcTZk;VVyvG3dAk&G z6SkDBb1ZaEAW$((CAh9@?7Ng32>~mwx=UWPVa&KAbJ%qj*zx9e)~KqfFLyzwuCn~z z;o|`I*u?48Di9jC;)C8AX8QazG70Y+;)j~4+KRpRC0h(mfTrTo$@N<)i`+h#P>(Nv z{N^}=390PaFE-=KWJFw(hqt$Qnb1|~)K3^9LMM{)r z)u014j=1K&hG5EzX{v+`7v7;->e~drGM+rVk-HL?M`wJeis$Zlzp>EKt-$#xxF27k z>qi=pUK2&dQ-7Hh0aabzw2&uh{PoSdEAg!(po$t!->EH*-=dEE^@b)gpPt|1)!t9% z2rdk6vxM8@@4CeLdbn1XslD&RuN0 zxxcxYw`x{j;-6K$42&TX#Cw`d_9K{C6K7(G1>U#b6? z6&5OozKbI~|1Kn*nOYst{7qiy-3Edw@;uBa=@bkMtt|#|>ZFah3pJn)7v=s1ZZ5o4 zC@H@d>nOa~U9j?a(xil%H*Wdwy9U~``T28y9_F0ES;{c_RfG0@5^`Xh;Rcj zOtq21VIHpd57ZThIUo`9opYf1#TgUYdY6D2R{2q$!+`q#D&+NsJ#&u28^eY3)g-FV zq!Krl(Bu%OXG|1F_biM%t_Ui&ko_(1aOrOelc^)d^7AZ<(`PZQp1xXMbF;1- z-rj~i5Iw4~nSxaL)1Q}sBgsL2nuk(mT-UY6+hX3Gx$K_NPAN8XR+movOccI@?^v<= zSK(xn6oSb%J{sv~JmYBlYCXTL9E4?Ar3sP0qV!Sm*~66lKmSZ_&aL_@L&t{8p8(H< zh~cab8T3S*0-SYaef-+imi5la_Z+yA6Glj#n7nKvs3wx8#$ zGdXcBZut?i6!Te(BRMiPU1D`#QoRuTp@82PR04&(zklqkD*_MLBl>P_yqUE867xn- zLoMR@vh$;GbGBagE8LXLSSqnT(>X`#$h1iYGc@d6qOi8j8+Ng0x$b&@n(pH}&ZYLQWV^QQ+yU66*yb>ohPjNa@xG=6lN#|Xr? zq~?8Y|K+mhc=Y&}{{r+s-!7B{o_G}BM2=B<^{=7~X^5=r~G zC>ri7GJ}RRhru^D!r^z{N9y0_5h9U-R!mx63?_3O;SoA32@W~z0B?1>bA?NQwWW-=dnVKS6g9}WJNz<{1UJueM_peKt(a!>j}2}Ni%+j@eBO> z8_Ny1l|SfbrN5v8|3Pjx%8=X@5+OE_4D@n1xcHzy%Je=uJhNX<`qeG1Vufhf(cjne zu~h9wBiUg_vk#yv;QfHfe-C|DQ^qTC^Z!>LOYMYlYpH6##vr2gkt(-5U5Nq9e zn)=b&)5VzZ_g4A)U9}@av)%*gTJN_0g@eP`R-EYKhr?SoaLGf;$L+Hv{WOi@^02}S zl2FeLeZi9xbQquHmUs5fLD$J8KxsEUOCGnhzj&H8vR_S}t8%}4E3>-vp7(cE6AmEO zoJ@wI?1Ci<+P`I9b)I`|AGNHwDQBv4RETt9h}g+1jog5+Fj!rQk}6hcF5c|j58$|& zeXxBwlc}zR?7rz__<{zr@d~J2S{^-uf}V#uR#|#3AOZR8OKT(E!RQ%_`IF9*PJtrD z4Vc061e5u~X>#qGv|wbArtZ_e-<(~T#eed9yIY7yD~a2&U(9ME_oz*Oei&l$YKqs` z8StV|-YFEq;u3U()o*^7>os_bkRzNU8oSy49v1~4J9@e|a?M5|MM!^-J)XVA$%ws< z!^wO`NRatY~{A4ZUesZyR&Xulk{yu8Ss4|@vn8-zTgM+7$4r_^PtK9}DNZ0Lh^0%Z3zpTxOj2D-neVslflT3pA^>>u{))$d;dj)!l4 z>IBQ2`{V)p4+Lkpf7@CLe`b$t)e^})Mk(Yiyc;+Vlg<=}rZ_A6`2V&_lG)nkM`hrv zYGWn7v8OmxeIs4;0|gEcyB9g=7He1GbFt@Q|4>i;YXXo%SY||)yo2)Y@Q5yQc&nU` z_qF4hwi}?U$sT?s6biCXy%hCkF1PjEx&&O2_K2}zP1#Z3y+f%v=z^TB?QBvQxdKf+ zT;KjttI-xpV0OKdPbDodXG?9AXJKPtqe6ZOm6`^FyA+`I0zw1QsLsmkcRN#HgV20_ z5&pc}O5%rjgJwN@0!nbidamS?-x=c&xX6|w3W#z3mTIeFHM^>a#1>s?%6Q~=?fFwF ze5}R~0IKUhDj0P^NYk4|80AWNO(0?`r(m(GGpH3xt>u?!YXRgOY6zTt4X@2 zLuXt<5x|&5KJt*D3eGqM#hopIwu5~kb9>1Ara)|suj>BQh&d(xYmipPEobFwNI zUphAU&Yxg$M_~@G&w~UNBR-!9v<8XZVxTOoeo+vu%hzsj_(zniB9A(Hd15&MYsQc7 zh%1A=B$(P=eKzs_Us?Tol?+x>_$4?^K1D%q7q8pvue1bws!aI~VBKi@hX6B58PtY< z2MSc2%`GC7ZW}~rjFX>SNY%M=>Bl5^>M%9TLb1o!AQ(p^5e@Z;5?-sgEvEq!$g z22Wh_5N9Id_mSfy9)mIC_EZ94dKh{<@NnNY&Rq2k==BjN zd2yZD*!hjcg=;+lEG4LmKn|u8o&ajr+x0p5&t4z6zJa&jH4z=nK6VnEdE@h_F6qVK z3uPF+@$R`8lgaOOv!iRWZF7%3a--|wblES|Jq2v9b@T6n*5Bl-&+PmSR_XnxHj`3LC=zTFBC0V$aKEcV`g>~7Oxm}F*! zZ)$n{Tdyer;OmNI*`u9F?*bWvdj<-)onV8!pJObxisje@kGihSAo+WDtL_zi_078g zVa;XHYjY}W5ic!GatSx4*ExNgrr5i!(R#PYmb4^@*$5Wpvin6DO3RR)DMq-V6f8hlC zM~6=muuosVnQCvIqsA*IaXqWrCByu~HPpfoh7nO(_9wN)X*>e{axCst3d}CJaYCo=eP1inD(YL zqhHm3C_}CLouiru-iVwpr9&SbeEm-^W=-IqS4bZpFdBXVTEW+$!!!DZ#WIeBTqG|| zS`?Ablg?Xv{33_;p*M73Zdxn&aK| zyig-Q&cgls;Fo}X^6p1-j-3qgbX6Hot#I&`d5O07Z*MQDwq|_e#=*IdUw(qy>JqOV z-%UAQ3$`2&v3#RsxV^)iS? zAF;d@UUgiRZ`SYJT$U(wZmaTYPxQO~ru4@F?UpI|_ z;;Cg(!GAu?%1t%#-^z&ZMD4c#*e-+$^NiNEj@H##Dc6_DiGudXa`|oOOk2~hadzT= zaE<84(tifr6x{EV4<3t+i>=>oOZ@|MzitV~_>nGbr8C+Z_K+JX>0X*0SVgb!FfBHw z7Qr|yhG#BR{syF&Z4Y~Y} zMbYW|0CCaiqXc!E;j>%=sIs{K(P(C1#-tt(!HiJTB?UsMKp>${J7T_J*BqCK&{k!I zrJo#)YNm`w&(Et1_^oxQ+#cQ&-edtU&TgI}27~VJHlHg0AXP0ohkn>pl2EY@?VP*> zoZe+TIu+;|pskm_@3A{cwhq&Lq^N;!`U&Q=wn%7vA>*-a^*+Gq``1p?gORTa&*lpm zC#<)wd*tde>C7mv0{wuYgc(k5&*q%CiGlx|7XSnT^XKf7{`nszS=H4c|Egm7A2e)N zHOI@OiF6T3P|syB-xxQ_z*ctr*Wv;P-t>i^Z{|7}D~Cy4$r-kJ?V-=Sds^==@9G6$nVfFpZtUF>4t!RS@ zX?_aKe3E~y`~?t5sY2jV-vf+EOsN;WT}0Sek&%*!Q(@~Na$iA`mlMXx{rXqOf%qC2vqkD1ZMe(e%~Pi2pFgRzVvY#uD_1lqhx9fqw2rWo+h z4+P;~*cKVR{w6qa7iNdvP} zw}r=n@V4Kc9n#U&W)&+0yhEY)y6k!wcQsc_~J~zHSKZbhzJv9<^kt2*ZOqRU%j@rvrs!Vc! zkF)xEFsWH$npi3U5<={*yZ2p9i2j$ih6Qj!>pKs2*VuF0m-OY0&L2^CW@eCUixJ;&zLy$;wALM_4#Sk4+_f} znF~X$dq6fUpNil7H|g=VCG%-AXOTuqlEqEgsg%?U$R+Ei`gFu8iMt@>fVTT{1D8)< zm!1Zoo=ujA0N9peU@m-l@A1Rh z?6R{ic>dW5g{1-FYlcDy=0^AW@WS_Yw`-)Xk?4|AWBO!61f}Nq&a0@U2ZGbiFlF`j z)LO2eQ;pke3l9ysd@!&L&p#fb_CHqe!Fg#Gzb`F?xBSKejkE@zE6wKYNqfPICVljE zRZmQZ^2UG1>g#YFBsP$F4f^lT^&G!oB>`3-l1GM<xPi3Uv;n-<~)CFNOu6` zV{Ux6`SSXBp007F?gQ$vwdRRtST)FahI0;=hk4qt&r?*Zf|>$)br*C z)$o;PAnkQq6Kn0~%-idI_8yQ~m=k_`*k6#}>wFn#>U$$lDW){vj(x%sI%>7L52J!V z-#W{}8IXtzUNe||lN1|pNPNh>q%nU?=_brY!3OAm{%*b8{x{ySi0ik1P31JwO|Ew=Z-n1$S(uWR82p2d`EUAN>9 zEB$iY4;8S41mSq&kNfo2Vwt_~-ouV>nS$4JTio3B@c#G4iM7v7zhBe(b=wJ!L}A_p z5Pd!y{{WmN+mIZHzt_tJ6(K2;w+P?ch|hfJib-rmv+cnQ`?31ymlnR(@xS-@U}gCc zrpEk@`FMF>uJ{vsr^plY7QkComdY*Ej(qy>&-L3D<1y||ZK4RaebebSg4%N<0yZO& z!(rYa4!o{M&ii1OKn9jKV08un+o1gozos@$pcE0l+bF;7`X4TsSx7ipj0j8x{#~9v zhE){7nZG|f{W(|_9rsHKvSg_y0`Z*F9R%z?MRnLTM@sOG*P!OW>8X4pP!=5vBr~AaD?|S#(&QSUKEBj*R2*! zcUVr}c6#a`g8cX8YYun9{QL&qy$AtaueiAS z{l6@2+MwGY?lUdl+v>i$R^)WVZ!NyEXP@3uEcAHypR>zZ*M}uAA)Q zIO!E6+Vhtr+o%AJysv*An;5;6YGOg!;{5t=e-X~-%gYT-Skyy{rHMaBsr~P^G`qCX zNKNZ@u*L8nzn^tS`SjI*qF7q^qVuCT94|=6+Mb zs%wghN}*&W?avvH)-`vh%(B@sm85*SKeeLmQ5XcV=*~$NHuMDe3u3EORGaq|I;!6O z00F;VVEA7B0AXQHRl8?mb}FZp`WyB2-p8gHR?g1O;dG1gQP-Zs@)qm2E`47W(9Uty16~DX7lDheC=1_dNTyy}5aHw_IPcJ_)JL9K|}xPZE>_x=9+| zLTo`Jk>q?f@i?MWys^r&E0knnz+8=InZCn)xnIW}(1B|OJW@Hq^s zH7(TGhBh}ozdsJw#C&m@S4&TrK~NxI2}s}}BageM?-#1?&)3TwqN&=lX{M2YmCm3(|+`fZFK`3Hgg0&1(kY;V#c#XUh5XY>AvIDH@ZUy1RZ6uv5&YHX@`ra>5q zp8o)>>M%y~6LLu;+>7mF5Nbj3m|Rpf6M3l{Olr2 zAvg57^Yi&0o_OPJwCruc%{Cd}AiCT$*ln(gs96U z`R~2}wE=F*UN;A0;cwIG`-~lsx&f=7Pp*Hpk4|8CtNau6h2P{IB7Jn_TMdZMC_4f92)= zF|8J`UZVE!+v{R~x@3+(R4};HuE1^6r`#rczQtOcHTuh?uq? zQa?>CYBYifEH7?Dbt6gqzJ~ZC$)z;KZq2>r9PfT&_!xC`A!EBJI!__DP08`;w~i$! z=_u!n;0p`bZP%@b_CKZqw;<|qajMrG`UB>A`1%utMz?PL$AyPp zpSK~6ejmhiRZRluVg& zbD5krfJoX_0fA;C-2jqU8*Dxsbj6B~C#hr-RzGD*4Zw0y%Jc36>C2uUGi6z7x7kqD zN=}BUlV#MR=R)6MtCjY*UYLoNzIu|zW?+D9E-nG(ru{FquekFVX4|pheA|H4;rYbTaTgF4nEA(Y>y+x#DYR|(m4yC9+$cP zyS6-T>s2*;Alfn%ogr!Co+G?o+E2pU394PpD?Mv(MDKZfUzy=Ekud1H>_QyT*9Wd!ZL{dVeoF!5_UcLBSJ8RUQ|Zd(#M za`PLD4rftzQc6K$flkErzg_LN-G3|X(cbZU8@23JNz+P!Ojv1Y8(^BI*}QS3Q&n`+ z(@`nRU`V7MZ4=HNJcl8usuD<1Td@S43=P2Y9IyKFIEi|7Nf|B3n~i`L?wjq?sP!C% zAJkOK8-Lo=$sA>LNukQ>9FFU4z8^iX(n8Uu=T~cX4o2ek+>8BRt_Q|b;rDkaC;_4> zTTC#Ql)D+XZAvQLFI85m0-1=2pJ)o0GFtj2G>t_!Y-!e2D8Y4evHnly@#V|qfkpOo zm8$hHl(}IRi>i~oo5P?x_<3MY+5`t%Gh4bYd!uWCVm@d4;Cj(OFYkUK^~;eL{`k#Z zbS(@MLR3kFgil{FaPgbHtPeSk2282cDt(6MtMkT3Mv~{Q}0rPeWxQ_aCA2Dz(Q;9G<9GtPJ^o4=eSOKQp?UY~3Yiw=%<4LDqxpQ%H zy*C@}&i?=}L5DI&G|~uyolHf5Cif)u=ke*(-s2BbF0RW6lA@MHR~AyrReS)|usrwi z{P24_dz8q%UJXTU$$OrUk6@IE!<~(_3u1gwjnYmhv6QBE*m`Kpsb@ zm!QRPQ>r!9h_^CsLBE;hYjfOk9dSK0Q$Cc^%Ny?cS7hh01IE|s%g+pIQtDxeL}D?0 zMBi2Sz5F?E=g!za6}Lq+9W+r)NHo%07yy}%`@W{tbuH>y&zeY+z5dpV@unT5is4$! zgHEe~Zew%mIeudUk=Z6D9fi38^B*C&{qU~A*s3cM?A9j4so0xen*0U!w~h+!96DkM zdu{cQZlkUBbmz~hBc<`ks;Y{Vwhpq@V-r8q7W9sBpo>5@n*>Fs-?Q2sF%C5`Vs&q^ zu=Bp-bGJUW*x-GkQbG;bZaS^Gbv{P>e6T~Mq%CdE{$4*Te0p-g%5Qak@$&ky+WVYk zs+-9ZIiE7yD&0LVjXs#nBLt}fjC=ZPWf+0pH*$NnAR<5}#T_tj;80kF3r}?=9*?usZ8PjL1#MH!9oo+r#|xYHx7*ZF>{uLFRh;e)xS~ zTlUEdTmcQnqhLrq0*+dGaVnDxJ?Q(j2Jp8u8N6X%rIZMfG@!mK)Y5rM}hnrcZ2j#~GlIYA>cU&EguN!o+ z-}C;C{>vmPk_V4b7f=bf78m@s{qQ719kl?;ckr`b_WJO{vkSQnJL|T~VP)%Y@pFUl z+Z}C8dJbdMdTE55kbN|&t4}DwcaUeKBp`#FXXmD^5OdlBTEtyPGI<+%epj{d;ixJS zF4^FcDD80Xu-|dE$8U}B?c;_9Mx}8e1MfAd0Z)eG=;0F7%_tDdJG3X1cPs_G#>bzD z9$;^cRqSojbj3Yg?bHlQAubt^g61?GYhkx*;EpG>q;}M9lFz+@>;<~?zdt`OjqqfR z5r=nCy@HE-&3k$7d`ZIlEfOlT00;$07d9hpL&WcYm!2OaaEC%RDs>heZEaQ?+gBm$ zgweK&AfpPxu=O{2gD=0PuByQFjwb&A+vV!zG*7e6pbChLQIXx#Va(hDcH}y3@x!Wm zH#?Fs;Puh3l~P*aXz}|?r(0;HB*rMx#_}L zoA&uL1>90_M-a^js)HrXWutJ-Epk)4Q;TzGilMMld)_`42NlZ7St-NCFw<2Vg$z)G z+1TA(R`+dNk<8eGk9ct3x8572;n=87P{}<75T}ln(G4YA1kmlecUia9=U_ns`15Xa z#2hV{RA!a**-59&YhG7sNvvt3V!)os?ohV9^r_!(3uDrF{{X_g7SDy-t8c_L)lnra zZA)ros4`RQ)J!aEi{ZZ#@td35hW5`*6oA<7UKI|gn5U%R4R9H?uX&E@M(Qp7yt-}h z!$u-TBn?3Hx9q=H#g?r*StNN-MhhRgTYv$-URFB|{ylLPVOZRhUg_~7$LH5;{@rop zH~chI(ko2fnX^4HC*}2+af4oqYk#VeZBY>ot`ZD;VrRP=j8)P}3$v4}{ubNo(+E(? zSxMBJ5N&PE?k)9yJ@ECSEhqui7E`!AJg@nWD|NNqKET95zr1RgOk>&N%3kpF5HvJBp z^7`k6GrWaVk;=r|sJ-{a(lt?4CUU-(jP}3RSN#6kL~e;JeYM^Y`dJSq9v59F;rU>| z8Kjb0cv!%!bfSV*HRw8cdU%WDT6GNq$Fp)tBi^{^em@Sln9DP0a@u-|a{!g9f8%na zmfL?(<9+d~VLGX&ahpDBu7n8_$I!-tx{`;W>Z(f(nTxR;VV`Y4&!MbUdp|Ai4_%Mf zme>^Tt`U@i654}or~3Z@PF`{oJO(22K9?QkP^78fk=z^D+kT!K+Px!*9EG`C?_+D9 zpHJ=Mgm}Hpx)`Mq?L0$&Ur3zshHTSSaUw)d$|tk?=|aAyBOs@hqFDh(3u`iR)4s0f zJTnpzVbaI*Hz)Ju{ROtxAAs0xx&EGgetY1OBNSNz*a2d1)PB8p{+Q&})mk-GQw-f- zmT_b0+gn1D6qNBcFTrMCo|3MyxOPzK%&8;;d)vdG_42}5)!SNvz5otHdXfEaffm>s z9)rM+oV;K z{LU1LNC#0;4=Z&WU+DN@OB*q=kWYX(`Gm8 zZ!gMNf^B{J1NwXp2X|{L0?Ir#`2PT1y)d|x2eBjza{k=+{deCLMKsijNl0Gw z#Y4@aBOJu=>QtBudUMaFJ$0rBQ)~v^(g#o9d}1pbTwE!+^8nt$-(EcM_Bv*j?GkDr zY9z1&PWSrT8zrgaAjfmcz~AT3`*p+r0Mk;_@ltYMl22=3=j(BOWR%aT-e2*2{q)vJ z5r`(uHGUMxw^T-loUv#~AjJwS?@>+jHNqKkP7u9E&mAZtaw} zsUKcg&s{w-6378JxK1x`cEk>d{&W8TdPLEfrO-{;PULd6{)g+0G_n*ChPqzmMXi4u zZ}T^|>PKM65mek>--w%zMBnx6wlz&nH11=88c6`VC?4n>$vg7p(0cB-u+Vx>#l z1WS?Uyi6KlQPXfz2y)-QZ%!jXyLh+%0AN3^6Rp&etix5We!F>i{BT(!XxO3dxHfg% zTl4kX;p&pZ-3Q~ft@(ad{|)=H0b)tCn-dB0pLEG#yQSi05*A8=dX( z^Yi72NOO$N3JLPKt7VHXsc|gy!$)T$uO@4*qyGTe3`LV*cD??u`FZ+V8#^9^jrnc* zdh+;VJ5B9xYdm|A@-Ob_ka7>X+aFCkh8X6CS!A6fl0Hg*AFkazet2uCh!+46y9;dI zy*dNsgpvuql?8k`owmQ}{dwVNSZ${J7QZdYCNa#W4IqWajua8UwEv)|i)TjpWo`7=KZy%SF^=R6g zvFu2eB1o3t>apI-YySZD-;g%d;plf{C?=EsCN1gOALQwE)Y6EzOML^>AAfB}DuKBL zZ+?A0LH#d+$5T;E#p!A#h1>rCEK(TQj}2?2`r>+gnwBi4mogc>4D}T<2IPin?Tk&6Q%YrDA{YA1H_JD*;79);WAvK91j8V3gF8)XGu_*~kRgFG0@5kLR~hwh_}%!II`hn__s6 zN8Z{xlcuAzUh@9{hrWJUmZgU#IeuX!WkpO`iiG|f6gM!;_aWAA?I}F4kaqe!rN&3u@9gBwtb9=KW9pzekzGin7hI%RZi- zzpko|NnUe{1Q0Pmuk#$dd6ECil1PfQQg@(M%!brpK|9<)P_o za`WfU;pOngu5D}W;fqdh!uf_tL6v4TlF_tT#7#9UboB`|(V!O{yldW#pTPCST&=o- zZ)*>)+X!|yDduJ~RK`8yA$)}3(+Y-qiS>eQ^#1@p+D;S!YySYme}VnZ7pIqaf5&0; zf31!+rG~Bd7Qdl3=55z)zree8Wq^fDn-wQ>`GLQWU5}lx*K=!f zf|izwNIJ@K5q_-UzGpYplqvBkho&U65f^EA#}A{%g52+5FVJ-Q=i}poM!Oc~Hoo3u zeR9Giwzjt`n}2^lA3SI|8xCF{A1=RE#ciQ)%pAOp$2^z6?WMifKfUa5U%SqZ3b6vk zes}WbJa+5(VN8Gvi~N7a8<+1~ZTtD-3$gP3et+W{R+O+2b_n2qo{`S0T7P)_KS7Cn zo_Y#up*CYiwba%sVI+a5jgNOrZRP8TY#KAS;g6q8FV5cUu}jAM@bBHv{f-}dx4YE6qD{eMG=$mz0klT}npT{>q;EK5&A z*pm#gGg?+@z13*fyrc2@Vg}`&{IBup=g;GTuA&H%!)OTa#A64~R%D!f+kI#I9@;qE zfZUIdE$`5OOj&YO%i*r0Y{mmuMkk2XQmG;3r!Kv+!r%Q9NNqdcd+u>oy@(v{K97d` z;KEr2ti+MJ+hV80ezxiJ7}dAqcDy$2HCIhFmSU<(%#Iap;e28IQ0knm!!=0O~K2aRygc6(mW-?Vr>ab6%*TWu!xLAZac&+n15s z&k{<`p#u=0`?eZ)^}pAa*vV#+Uwj+h`k!|r&43)PcIC^K8tOMUI({FQkJjAq?;rSv z*NT2N)f8>h(M>Hobkny>RXKWSwF+W>wQ}GTaBFheaO~{La6@$kM{d&(NPBvE=wImHI;9k8iFLGdUi@kX>3S% zstGG3g})8HJ}~)KWl@!8bUB?e#Pu{)FjdC0BFPI$Pa?}7Z5wx5JxktRPM){LqmDSr z4lQhq)A06D!>1?8AHd9ikBdK=uD)KPZ*Nad{Bx#JNwgG{^nm~}O{Onmbdvu7%dqqt<2y(GV~k;I zZEd`NFNcrx!ZAlZ4@v(3sF&u#9k}P;QCBwf;{-wc&W^8WiUKz}x3%ss`||xT9Y@6c z@vLSg4O!}{z+HP7zo*h2Nn$1X=|P*<*MIMg>MVBLbMFE3HpYOzG6%2p!oao8%m*`l z*m-|X(`-FnhAxGfjs*Ho&OLQm(GWz^pmM@8Z0tIC+smI$r1;s?w8$ioLh?%r1S={= z#coB)y}jSB3^GOll~H9QuIBr1f71TE@i{@B*5#D7)O5Xwg1#=!aV$$CfykKH?;Cje z0f+d0oz1T@by#K>1*bD?iGQJ06%ReL9OmWAdiq3OB0>WZWfuUIK*d+hN#Cy4<>P_t zupoc!$ol-R&-22sZ~?b=;CR^Xci;2z>y0w)$cy#)^yz-SKcM^$ilnJffohl3SeWK5 zc($%s24c)Oo)~2Pduw;Sfi@nVxWnmhpYM%@B%51p_B;5S4=-Qb;lP6NG^N*4{tIq? z7WLoLuP1Ho%_-1RO*a5KMy$9(Se{;2QoY$px)9CSxBRE&^S*Q|A@_@4pd79EM=U&w zp`r`{IvGk4x8l9OYx&?PdxFIWHX_^Gpj&&*{{SCdu`ifp%R!c9d6)4VzO(qENdEw1 zrI<-qLSr_yY(xE~Zfd@`+2N}x+uh=zk>>ChnLbcHu9UM;Cn4O;&%N~m6qmK^Zb<9r z`e7}o1ACv(mHBy}o(hpW8{bI&bJvlzuhZ(|0wDLb8-dEio3*|-_+b@P913^ioauedugo%z>wobdo*TQ|mKOl@9RC1cQ;gEUDJsgX$dGJ( z58}7b!VUMgAZ>CDkEi&+c%K=)R?QSuxw&556w^&KHP+Ke0b!{EI{;2KMIh9{E5RMJ z-S_)Tt!rN&$o~LLC+_~WV+xfPzcX%Ke>1m-(a>9fZ~0&H>+;3}c9J}R)t@QEdVAXe zH_>Tn?vIb^akaU<&5z-}n-k}6L;dl%z-@`sZMhT6bM$bcS9P|-nE>~;>GMCgfz?Gc zwDnKQ$mjGg^YzrxrKOS-N0hCkUh1j8t@{3!^}}r{dJog|!nI#va-(Z8B!WCSd~A2Z zZ_d^y!s80vp-Wqgy^ee4EyguIbNt4(qhO^-B%LLB6K+S-``lt-sq&BEG03ydbAPll z$xO@lJ&3-R4d{7z^6|u4f>WqfI?92$ZzlEW`wU@o*^7X69Ywz#myp%h>i%umdT42^ zDz&<=94-4t9)#LaMMz>ZpHHrk$^#Mrz3jkpPfuQ69+=h@sdTdGH!Y|&&&c!o+i)

!x3ny#fWJMv1<$6f%V_v@kK*0 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

  • )(fZlXd7(vE`JK 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%0AUoPO?>4jUq$3sPa^G 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≶RTrZ_7=#9Q?kv#-0|k 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

    Sfo%N&|PD8Yg_vYT@ZIce*Rr8Uu5 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

    ^|P%$H^tH6%6>0FB{LOQP!hz(EhX6@BV0c( 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≶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

    OCCi+FMe(LnF>(6@z1<9hKF;ho8 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

    #P)iDDub@X-^=`AoRU-$G(j-A0^O18aq{?n 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

    Xf0C}`D2)&pa{-0p5M&eoMGi$@9yVuh{Su^LJRc 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

    ; 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�|;%w%D{Pi9@sR#QOgL9aQ$0+C4j` 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

    Wc$pS$&`~BWqqBZHiON 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¬+Kjw$I?Eqij#thsL$ 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

    uh_*%t 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'-$c`eeZC=T+Dr-W|o4M`MwrqXpU_H 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±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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/staffing-ui/src/assets/images/light.svg b/staffing-ui/src/assets/images/light.svg new file mode 100644 index 0000000..ab7cc08 --- /dev/null +++ b/staffing-ui/src/assets/images/light.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/staffing-ui/src/assets/images/login-background.jpg b/staffing-ui/src/assets/images/login-background.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8a89eb8291d5cb7d9f37ec4f275deab911c9e28e GIT binary patch literal 521275 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¥}>uauIoY!`8n(7niSl_m2d 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

    LZs5vs<4*dn)6_orH;Y;`bzi*q=#N#x6 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

    8A%Us3k< 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𝔫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

    &!CIz1Ns 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⩛TtXwH2N8q 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

    Wf@+FD?DGvA4he?g#aN51zy(O$Xy! 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

    Acrih5KDW9ugPSk3y-@mXy^-HnY=Jp77llly?k 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 vPok;F)*{# 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 DPqhcR literal 0 HcmV?d00001 diff --git a/staffing-ui/src/assets/images/profile.jpg b/staffing-ui/src/assets/images/profile.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b3a940b21cc9dcea01e62d94e243eebcf76d96bc GIT binary patch literal 81131 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 z≺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 literal 0 HcmV?d00001 diff --git a/staffing-ui/src/assets/logo/logo.png b/staffing-ui/src/assets/logo/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e26376026420542212ed58d90d0ed34f554fa4ae GIT binary patch literal 5663 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 div + > .el-submenu + > .el-submenu__title + .el-submenu__icon-arrow { + display: none; +} \ No newline at end of file diff --git a/staffing-ui/src/assets/styles/element-variables.scss b/staffing-ui/src/assets/styles/element-variables.scss new file mode 100644 index 0000000..1615ff2 --- /dev/null +++ b/staffing-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/staffing-ui/src/assets/styles/index.scss b/staffing-ui/src/assets/styles/index.scss new file mode 100644 index 0000000..2f3b9ef --- /dev/null +++ b/staffing-ui/src/assets/styles/index.scss @@ -0,0 +1,182 @@ +@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; + } +} diff --git a/staffing-ui/src/assets/styles/mixin.scss b/staffing-ui/src/assets/styles/mixin.scss new file mode 100644 index 0000000..06fa061 --- /dev/null +++ b/staffing-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/staffing-ui/src/assets/styles/sidebar.scss b/staffing-ui/src/assets/styles/sidebar.scss new file mode 100644 index 0000000..abe5b63 --- /dev/null +++ b/staffing-ui/src/assets/styles/sidebar.scss @@ -0,0 +1,227 @@ +#app { + + .main-container { + height: 100%; + transition: margin-left .28s; + margin-left: $base-sidebar-width; + position: relative; + } + + .sidebarHide { + margin-left: 0!important; + } + + .sidebar-container { + -webkit-transition: width .28s; + transition: width 0.28s; + width: $base-sidebar-width !important; + background-color: $base-menu-background; + height: 100%; + position: fixed; + font-size: 0px; + top: 0; + bottom: 0; + left: 0; + z-index: 1001; + overflow: hidden; + -webkit-box-shadow: 2px 0 6px rgba(0,21,41,.35); + box-shadow: 2px 0 6px rgba(0,21,41,.35); + + // 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; + } + + .el-menu-item, .el-submenu__title { + overflow: hidden !important; + text-overflow: ellipsis !important; + white-space: nowrap !important; + } + + // menu hover + .submenu-title-noDropdown, + .el-submenu__title { + &:hover { + background-color: rgba(0, 0, 0, 0.06) !important; + } + } + + & .theme-dark .is-active > .el-submenu__title { + color: $base-menu-color-active !important; + } + + & .nest-menu .el-submenu>.el-submenu__title, + & .el-submenu .el-menu-item { + min-width: $base-sidebar-width !important; + + &:hover { + background-color: rgba(0, 0, 0, 0.06) !important; + } + } + + & .theme-dark .nest-menu .el-submenu>.el-submenu__title, + & .theme-dark .el-submenu .el-menu-item { + background-color: $base-sub-menu-background !important; + + &:hover { + background-color: $base-sub-menu-hover !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-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: $base-sidebar-width !important; + } + + // mobile responsive + .mobile { + .main-container { + margin-left: 0px; + } + + .sidebar-container { + transition: transform .28s; + width: $base-sidebar-width !important; + } + + &.hideSidebar { + .sidebar-container { + pointer-events: none; + transition-duration: 0.3s; + transform: translate3d(-$base-sidebar-width, 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: rgba(0, 0, 0, 0.06) !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/staffing-ui/src/assets/styles/staffing.scss b/staffing-ui/src/assets/styles/staffing.scss new file mode 100644 index 0000000..6e971c2 --- /dev/null +++ b/staffing-ui/src/assets/styles/staffing.scss @@ -0,0 +1,291 @@ +/** +* 通用css样式布局处理 +* Copyright (c) 2019 staffing +*/ + +/** 基础通用 **/ +.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; +} +.ml10 { + margin-left: 10px; +} + +.mt20 { + margin-top: 20px; +} + +.mr20 { + margin-right: 20px; +} + +.mb20 { + margin-bottom: 20px; +} +.ml20 { + margin-left: 20px; +} + +.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; +} + +.el-message-box__status + .el-message-box__message{ + word-break: break-word; +} + +.el-dialog:not(.is-fullscreen) { + margin-top: 6vh !important; +} + +.el-dialog__wrapper.scrollbar .el-dialog .el-dialog__body { + overflow: auto; + overflow-x: hidden; + max-height: 70vh; + padding: 10px 20px 0; +} + +.el-table { + .el-table__header-wrapper, .el-table__fixed-header-wrapper { + th { + word-break: break-word; + background-color: #f8f8f9; + color: #515a6e; + height: 40px; + font-size: 13px; + } + } + + .el-table__body-wrapper { + .el-button [class*="el-icon-"] + span { + margin-left: 1px; + } + } +} + +/** 表单布局 **/ +.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; +} + +/* tree border */ +.tree-border { + margin-top: 5px; + border: 1px solid #e5e6e7; + background: #FFFFFF none; + border-radius: 4px; +} + +.pagination-container .el-pagination { + right: 0; + position: absolute; +} + +@media (max-width: 768px) { + .pagination-container .el-pagination > .el-pagination__jump { + display: none !important; + } + .pagination-container .el-pagination > .el-pagination__sizes { + display: none !important; + } +} + +.el-table .fixed-width .el-button--mini { + padding-left: 0; + padding-right: 0; + width: inherit; +} + +/** 表格更多操作下拉样式 */ +.el-table .el-dropdown-link,.el-table .el-dropdown-selfdefine { + cursor: pointer; + margin-left: 5px; +} + +.el-table .el-dropdown, .el-icon-arrow-down { + font-size: 12px; +} + +.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; +} + +/* button color */ +.el-button--cyan.is-active, +.el-button--cyan:active { + background: #20B2AA; + border-color: #20B2AA; + color: #FFFFFF; +} + +.el-button--cyan:focus, +.el-button--cyan:hover { + background: #48D1CC; + border-color: #48D1CC; + color: #FFFFFF; +} + +.el-button--cyan { + background-color: #20B2AA; + border-color: #20B2AA; + color: #FFFFFF; +} + +/* 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: relative; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 200px; + height: 200px; + border-radius: 50%; + box-shadow: 0 0 4px #ccc; + overflow: hidden; +} + +/* 拖拽列样式 */ +.sortable-ghost { + opacity: .8; + color: #fff !important; + background: #42b983 !important; +} + +.top-right-btn { + position: relative; + float: right; +} diff --git a/staffing-ui/src/assets/styles/transition.scss b/staffing-ui/src/assets/styles/transition.scss new file mode 100644 index 0000000..073f8c6 --- /dev/null +++ b/staffing-ui/src/assets/styles/transition.scss @@ -0,0 +1,49 @@ +// 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--move, +.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/staffing-ui/src/assets/styles/variables.scss b/staffing-ui/src/assets/styles/variables.scss new file mode 100644 index 0000000..34484d4 --- /dev/null +++ b/staffing-ui/src/assets/styles/variables.scss @@ -0,0 +1,54 @@ +// base color +$blue:#324157; +$light-blue:#3A71A8; +$red:#C03639; +$pink: #E65D6E; +$green: #30B08F; +$tiffany: #4AB7BD; +$yellow:#FEC171; +$panGreen: #30B08F; + +// 默认菜单主题风格 +$base-menu-color:#bfcbd9; +$base-menu-color-active:#f4f4f5; +$base-menu-background:#304156; +$base-logo-title-color: #ffffff; + +$base-menu-light-color:rgba(0,0,0,.70); +$base-menu-light-background:#ffffff; +$base-logo-light-title-color: #001529; + +$base-sub-menu-background:#1f2d3d; +$base-sub-menu-hover:#001528; + +// 自定义暗色菜单风格 +/** +$base-menu-color:hsla(0,0%,100%,.65); +$base-menu-color-active:#fff; +$base-menu-background:#001529; +$base-logo-title-color: #ffffff; + +$base-menu-light-color:rgba(0,0,0,.70); +$base-menu-light-background:#ffffff; +$base-logo-light-title-color: #001529; + +$base-sub-menu-background:#000c17; +$base-sub-menu-hover:#001528; +*/ + +$base-sidebar-width: 200px; + +// the :export directive is the magic sauce for webpack +// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass +:export { + menuColor: $base-menu-color; + menuLightColor: $base-menu-light-color; + menuColorActive: $base-menu-color-active; + menuBackground: $base-menu-background; + menuLightBackground: $base-menu-light-background; + subMenuBackground: $base-sub-menu-background; + subMenuHover: $base-sub-menu-hover; + sideBarWidth: $base-sidebar-width; + logoTitleColor: $base-logo-title-color; + logoLightTitleColor: $base-logo-light-title-color +} diff --git a/staffing-ui/src/components/Breadcrumb/index.vue b/staffing-ui/src/components/Breadcrumb/index.vue new file mode 100644 index 0000000..1696f54 --- /dev/null +++ b/staffing-ui/src/components/Breadcrumb/index.vue @@ -0,0 +1,74 @@ + + + + + diff --git a/staffing-ui/src/components/Crontab/day.vue b/staffing-ui/src/components/Crontab/day.vue new file mode 100644 index 0000000..fe3eaf0 --- /dev/null +++ b/staffing-ui/src/components/Crontab/day.vue @@ -0,0 +1,161 @@ + + + diff --git a/staffing-ui/src/components/Crontab/hour.vue b/staffing-ui/src/components/Crontab/hour.vue new file mode 100644 index 0000000..3216c33 --- /dev/null +++ b/staffing-ui/src/components/Crontab/hour.vue @@ -0,0 +1,120 @@ + + + diff --git a/staffing-ui/src/components/Crontab/index.vue b/staffing-ui/src/components/Crontab/index.vue new file mode 100644 index 0000000..3963df2 --- /dev/null +++ b/staffing-ui/src/components/Crontab/index.vue @@ -0,0 +1,430 @@ + + + + diff --git a/staffing-ui/src/components/Crontab/min.vue b/staffing-ui/src/components/Crontab/min.vue new file mode 100644 index 0000000..43cab90 --- /dev/null +++ b/staffing-ui/src/components/Crontab/min.vue @@ -0,0 +1,116 @@ + + + \ No newline at end of file diff --git a/staffing-ui/src/components/Crontab/month.vue b/staffing-ui/src/components/Crontab/month.vue new file mode 100644 index 0000000..fd0ac38 --- /dev/null +++ b/staffing-ui/src/components/Crontab/month.vue @@ -0,0 +1,114 @@ + + + diff --git a/staffing-ui/src/components/Crontab/result.vue b/staffing-ui/src/components/Crontab/result.vue new file mode 100644 index 0000000..aea6e0e --- /dev/null +++ b/staffing-ui/src/components/Crontab/result.vue @@ -0,0 +1,559 @@ + + + diff --git a/staffing-ui/src/components/Crontab/second.vue b/staffing-ui/src/components/Crontab/second.vue new file mode 100644 index 0000000..e7b7761 --- /dev/null +++ b/staffing-ui/src/components/Crontab/second.vue @@ -0,0 +1,117 @@ + + + diff --git a/staffing-ui/src/components/Crontab/week.vue b/staffing-ui/src/components/Crontab/week.vue new file mode 100644 index 0000000..1cec700 --- /dev/null +++ b/staffing-ui/src/components/Crontab/week.vue @@ -0,0 +1,202 @@ + + + diff --git a/staffing-ui/src/components/Crontab/year.vue b/staffing-ui/src/components/Crontab/year.vue new file mode 100644 index 0000000..5487a6c --- /dev/null +++ b/staffing-ui/src/components/Crontab/year.vue @@ -0,0 +1,131 @@ + + + diff --git a/staffing-ui/src/components/DictData/index.js b/staffing-ui/src/components/DictData/index.js new file mode 100644 index 0000000..7b85d4a --- /dev/null +++ b/staffing-ui/src/components/DictData/index.js @@ -0,0 +1,49 @@ +import Vue from 'vue' +import store from '@/store' +import DataDict from '@/utils/dict' +import { getDicts as getDicts } from '@/api/system/dict/data' + +function searchDictByKey(dict, key) { + if (key == null && key == "") { + return null + } + try { + for (let i = 0; i < dict.length; i++) { + if (dict[i].key == key) { + return dict[i].value + } + } + } catch (e) { + return null + } +} + +function install() { + Vue.use(DataDict, { + metas: { + '*': { + labelField: 'dictLabel', + valueField: 'dictValue', + request(dictMeta) { + const storeDict = searchDictByKey(store.getters.dict, dictMeta.type) + if (storeDict) { + return new Promise(resolve => { resolve(storeDict) }) + } else { + return new Promise((resolve, reject) => { + getDicts(dictMeta.type).then(res => { + store.dispatch('dict/setDict', { key: dictMeta.type, value: res.data }) + resolve(res.data) + }).catch(error => { + reject(error) + }) + }) + } + }, + }, + }, + }) +} + +export default { + install, +} \ No newline at end of file diff --git a/staffing-ui/src/components/DictTag/index.vue b/staffing-ui/src/components/DictTag/index.vue new file mode 100644 index 0000000..6b5b230 --- /dev/null +++ b/staffing-ui/src/components/DictTag/index.vue @@ -0,0 +1,89 @@ + + + + diff --git a/staffing-ui/src/components/Editor/index.vue b/staffing-ui/src/components/Editor/index.vue new file mode 100644 index 0000000..8981d76 --- /dev/null +++ b/staffing-ui/src/components/Editor/index.vue @@ -0,0 +1,274 @@ + + + + + diff --git a/staffing-ui/src/components/FileUpload/index.vue b/staffing-ui/src/components/FileUpload/index.vue new file mode 100644 index 0000000..c7f6b0a --- /dev/null +++ b/staffing-ui/src/components/FileUpload/index.vue @@ -0,0 +1,216 @@ + + + + + diff --git a/staffing-ui/src/components/Hamburger/index.vue b/staffing-ui/src/components/Hamburger/index.vue new file mode 100644 index 0000000..368b002 --- /dev/null +++ b/staffing-ui/src/components/Hamburger/index.vue @@ -0,0 +1,44 @@ + + + + + diff --git a/staffing-ui/src/components/HeaderSearch/index.vue b/staffing-ui/src/components/HeaderSearch/index.vue new file mode 100644 index 0000000..7d6780b --- /dev/null +++ b/staffing-ui/src/components/HeaderSearch/index.vue @@ -0,0 +1,198 @@ + + + + + diff --git a/staffing-ui/src/components/IconSelect/index.vue b/staffing-ui/src/components/IconSelect/index.vue new file mode 100644 index 0000000..8dadc02 --- /dev/null +++ b/staffing-ui/src/components/IconSelect/index.vue @@ -0,0 +1,104 @@ + + + + + + diff --git a/staffing-ui/src/components/IconSelect/requireIcons.js b/staffing-ui/src/components/IconSelect/requireIcons.js new file mode 100644 index 0000000..99e5c54 --- /dev/null +++ b/staffing-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/staffing-ui/src/components/ImagePreview/index.vue b/staffing-ui/src/components/ImagePreview/index.vue new file mode 100644 index 0000000..3c770c7 --- /dev/null +++ b/staffing-ui/src/components/ImagePreview/index.vue @@ -0,0 +1,90 @@ + + + + + diff --git a/staffing-ui/src/components/ImageUpload/index.vue b/staffing-ui/src/components/ImageUpload/index.vue new file mode 100644 index 0000000..2e64c9b --- /dev/null +++ b/staffing-ui/src/components/ImageUpload/index.vue @@ -0,0 +1,226 @@ + + + + + diff --git a/staffing-ui/src/components/Pagination/index.vue b/staffing-ui/src/components/Pagination/index.vue new file mode 100644 index 0000000..56f5a6b --- /dev/null +++ b/staffing-ui/src/components/Pagination/index.vue @@ -0,0 +1,114 @@ + + + + + diff --git a/staffing-ui/src/components/PanThumb/index.vue b/staffing-ui/src/components/PanThumb/index.vue new file mode 100644 index 0000000..1bcf417 --- /dev/null +++ b/staffing-ui/src/components/PanThumb/index.vue @@ -0,0 +1,142 @@ + + + + + diff --git a/staffing-ui/src/components/ParentView/index.vue b/staffing-ui/src/components/ParentView/index.vue new file mode 100644 index 0000000..7bf6148 --- /dev/null +++ b/staffing-ui/src/components/ParentView/index.vue @@ -0,0 +1,3 @@ + diff --git a/staffing-ui/src/components/RightPanel/index.vue b/staffing-ui/src/components/RightPanel/index.vue new file mode 100644 index 0000000..5abeecb --- /dev/null +++ b/staffing-ui/src/components/RightPanel/index.vue @@ -0,0 +1,106 @@ + + + + + diff --git a/staffing-ui/src/components/RightToolbar/index.vue b/staffing-ui/src/components/RightToolbar/index.vue new file mode 100644 index 0000000..67da293 --- /dev/null +++ b/staffing-ui/src/components/RightToolbar/index.vue @@ -0,0 +1,129 @@ + + + diff --git a/staffing-ui/src/components/Screenfull/index.vue b/staffing-ui/src/components/Screenfull/index.vue new file mode 100644 index 0000000..d4e539c --- /dev/null +++ b/staffing-ui/src/components/Screenfull/index.vue @@ -0,0 +1,57 @@ + + + + + diff --git a/staffing-ui/src/components/SizeSelect/index.vue b/staffing-ui/src/components/SizeSelect/index.vue new file mode 100644 index 0000000..069b5de --- /dev/null +++ b/staffing-ui/src/components/SizeSelect/index.vue @@ -0,0 +1,56 @@ + + + diff --git a/staffing-ui/src/components/SvgIcon/index.vue b/staffing-ui/src/components/SvgIcon/index.vue new file mode 100644 index 0000000..e4bf5ad --- /dev/null +++ b/staffing-ui/src/components/SvgIcon/index.vue @@ -0,0 +1,61 @@ + + + + + diff --git a/staffing-ui/src/components/ThemePicker/index.vue b/staffing-ui/src/components/ThemePicker/index.vue new file mode 100644 index 0000000..1714e1f --- /dev/null +++ b/staffing-ui/src/components/ThemePicker/index.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/staffing-ui/src/components/TopNav/index.vue b/staffing-ui/src/components/TopNav/index.vue new file mode 100644 index 0000000..86a91c4 --- /dev/null +++ b/staffing-ui/src/components/TopNav/index.vue @@ -0,0 +1,195 @@ + + + + + diff --git a/staffing-ui/src/components/iFrame/index.vue b/staffing-ui/src/components/iFrame/index.vue new file mode 100644 index 0000000..426857f --- /dev/null +++ b/staffing-ui/src/components/iFrame/index.vue @@ -0,0 +1,36 @@ + + + diff --git a/staffing-ui/src/layout/components/Navbar.vue b/staffing-ui/src/layout/components/Navbar.vue new file mode 100644 index 0000000..1ce8963 --- /dev/null +++ b/staffing-ui/src/layout/components/Navbar.vue @@ -0,0 +1,200 @@ + + + + + diff --git a/staffing-ui/src/layout/components/Settings/index.vue b/staffing-ui/src/layout/components/Settings/index.vue new file mode 100644 index 0000000..bb3c9ce --- /dev/null +++ b/staffing-ui/src/layout/components/Settings/index.vue @@ -0,0 +1,260 @@ + + + + + diff --git a/staffing-ui/src/layout/components/Sidebar/FixiOSBug.js b/staffing-ui/src/layout/components/Sidebar/FixiOSBug.js new file mode 100644 index 0000000..6823726 --- /dev/null +++ b/staffing-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/staffing-ui/src/layout/components/Sidebar/Item.vue b/staffing-ui/src/layout/components/Sidebar/Item.vue new file mode 100644 index 0000000..be3285d --- /dev/null +++ b/staffing-ui/src/layout/components/Sidebar/Item.vue @@ -0,0 +1,33 @@ + diff --git a/staffing-ui/src/layout/components/Sidebar/Link.vue b/staffing-ui/src/layout/components/Sidebar/Link.vue new file mode 100644 index 0000000..8b0bc93 --- /dev/null +++ b/staffing-ui/src/layout/components/Sidebar/Link.vue @@ -0,0 +1,43 @@ + + + diff --git a/staffing-ui/src/layout/components/Sidebar/Logo.vue b/staffing-ui/src/layout/components/Sidebar/Logo.vue new file mode 100644 index 0000000..394c6ad --- /dev/null +++ b/staffing-ui/src/layout/components/Sidebar/Logo.vue @@ -0,0 +1,93 @@ + + + + + diff --git a/staffing-ui/src/layout/components/Sidebar/SidebarItem.vue b/staffing-ui/src/layout/components/Sidebar/SidebarItem.vue new file mode 100644 index 0000000..82ba407 --- /dev/null +++ b/staffing-ui/src/layout/components/Sidebar/SidebarItem.vue @@ -0,0 +1,100 @@ + + + diff --git a/staffing-ui/src/layout/components/Sidebar/index.vue b/staffing-ui/src/layout/components/Sidebar/index.vue new file mode 100644 index 0000000..51d0839 --- /dev/null +++ b/staffing-ui/src/layout/components/Sidebar/index.vue @@ -0,0 +1,57 @@ + + + diff --git a/staffing-ui/src/layout/components/TagsView/ScrollPane.vue b/staffing-ui/src/layout/components/TagsView/ScrollPane.vue new file mode 100644 index 0000000..bb753a1 --- /dev/null +++ b/staffing-ui/src/layout/components/TagsView/ScrollPane.vue @@ -0,0 +1,94 @@ + + + + + diff --git a/staffing-ui/src/layout/components/TagsView/index.vue b/staffing-ui/src/layout/components/TagsView/index.vue new file mode 100644 index 0000000..96585a5 --- /dev/null +++ b/staffing-ui/src/layout/components/TagsView/index.vue @@ -0,0 +1,332 @@ + + + + + + + diff --git a/staffing-ui/src/layout/components/index.js b/staffing-ui/src/layout/components/index.js new file mode 100644 index 0000000..104bd3a --- /dev/null +++ b/staffing-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/staffing-ui/src/layout/index.vue b/staffing-ui/src/layout/index.vue new file mode 100644 index 0000000..dba4393 --- /dev/null +++ b/staffing-ui/src/layout/index.vue @@ -0,0 +1,111 @@ + + + + + diff --git a/staffing-ui/src/layout/mixin/ResizeHandler.js b/staffing-ui/src/layout/mixin/ResizeHandler.js new file mode 100644 index 0000000..e8d0df8 --- /dev/null +++ b/staffing-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/staffing-ui/src/main.js b/staffing-ui/src/main.js new file mode 100644 index 0000000..3752ade --- /dev/null +++ b/staffing-ui/src/main.js @@ -0,0 +1,86 @@ +import Vue from 'vue' + +import Cookies from 'js-cookie' + +import Element from 'element-ui' +import './assets/styles/element-variables.scss' + +import '@/assets/styles/index.scss' // global css +import '@/assets/styles/staffing.scss' // staffing css +import App from './App' +import store from './store' +import router from './router' +import directive from './directive' // directive +import plugins from './plugins' // plugins +import { download } from '@/utils/request' + +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, selectDictLabels, handleTree } from "@/utils/staffing"; +// 分页组件 +import Pagination from "@/components/Pagination"; +// 自定义表格工具组件 +import RightToolbar from "@/components/RightToolbar" +// 富文本组件 +import Editor from "@/components/Editor" +// 文件上传组件 +import FileUpload from "@/components/FileUpload" +// 图片上传组件 +import ImageUpload from "@/components/ImageUpload" +// 图片预览组件 +import ImagePreview from "@/components/ImagePreview" +// 字典标签组件 +import DictTag from '@/components/DictTag' +// 头部标签组件 +import VueMeta from 'vue-meta' +// 字典数据组件 +import DictData from '@/components/DictData' + +// 全局方法挂载 +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.selectDictLabels = selectDictLabels +Vue.prototype.download = download +Vue.prototype.handleTree = handleTree + +// 全局组件挂载 +Vue.component('DictTag', DictTag) +Vue.component('Pagination', Pagination) +Vue.component('RightToolbar', RightToolbar) +Vue.component('Editor', Editor) +Vue.component('FileUpload', FileUpload) +Vue.component('ImageUpload', ImageUpload) +Vue.component('ImagePreview', ImagePreview) + +Vue.use(directive) +Vue.use(plugins) +Vue.use(VueMeta) +DictData.install() + +/** + * 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/staffing-ui/src/permission.js b/staffing-ui/src/permission.js new file mode 100644 index 0000000..0af16d8 --- /dev/null +++ b/staffing-ui/src/permission.js @@ -0,0 +1,130 @@ +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' +import { isRelogin } from '@/utils/request' + +NProgress.configure({ showSpinner: false }) + +const whiteList = ['/login', '/register'] + +// router.beforeEach((to, from, next) => { +// NProgress.start() +// if (getToken()) { +// to.meta.title && store.dispatch('settings/setTitle', to.meta.title) +// /* has token*/ +// if (to.path === '/login') { +// next({ path: '/' }) +// NProgress.done() +// } else if (whiteList.indexOf(to.path) !== -1) { +// next() +// } else { +// if (store.getters.roles.length === 0) { +// isRelogin.show = true +// // 判断当前用户是否已拉取完user_info信息 +// store.dispatch('GetInfo').then(() => { +// isRelogin.show = false +// store.dispatch('GenerateRoutes').then(accessRoutes => { +// // 根据roles权限生成可访问的路由表 +// router.addRoutes(accessRoutes) // 动态添加可访问路由表 +// // next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 +// if (to.fullPath == '/') { +// var heardPath=accessRoutes[0].path.split("/")[1]==''?"":accessRoutes[0].path; +// // 当登录之后,直接通过ip地址和端口号访问时,跳转到第一个路由页面indexPage。如:http://10.12.7.76:6090/,这样直接访问。 +// let pathIndex = '' +// pathIndex = heardPath + '/' + accessRoutes[0].children[0].path +// // console.log(accessRoutes[0].path); +// // console.log(pathIndex); +// // replace: true只是一个设置信息,告诉VUE本次操作后,不能通过浏览器后退按钮,返回前一个路由。 +// next({ path: pathIndex, replace: true }) // hack方法 确保addRoutes已完成 +// } else { +// // 如果是点击了一个菜单,然后刷新,保持在当前的页面。 +// // 如果是从其他页面点击,通过打开新窗口跳转路由。如从当前故障报警详情里跳到实时监控页面。 +// next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 +// // 使用next({ ...to, replace: true })来确保addRoutes()时动态添加的路由已经被完全加载上去。 +// } +// +// }) +// }).catch(err => { +// store.dispatch('LogOut').then(() => { +// Message.error(err) +// next({ path: '/' }) +// }) +// }) +// } else { +// next() +// } +// } +// } else { +// // 没有token +// if (whiteList.indexOf(to.path) !== -1) { +// // 在免登录白名单,直接进入 +// next() +// } else { +// next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) // 否则全部重定向到登录页 +// NProgress.done() +// } +// } +// }) + +router.beforeEach((to, from, next) => { + NProgress.start() + if (getToken()) { + to.meta.title && store.dispatch('settings/setTitle', to.meta.title) + + if (store.getters.roles.length === 0) { + // isRelogin.show = true + // 判断当前用户是否已拉取完user_info信息 + store.dispatch('GetInfo').then(res => { + // 拉取user_info + const roles = res.roles + store.dispatch('GenerateRoutes', { roles }).then(accessRoutes => { + // 根据roles权限生成可访问的路由表 + // 修改默认首页 + // console.log(accessRoutes, from, to.fullPath) + router.addRoutes(accessRoutes) // 动态添加可访问路由表 + if (to.fullPath == '/') { + var heardPath=accessRoutes[0].path.split("/")[1]==''?"":accessRoutes[0].path; + // 当登录之后,直接通过ip地址和端口号访问时,跳转到第一个路由页面indexPage。如:http://10.12.7.76:6090/,这样直接访问。 + let pathIndex = '' + pathIndex = heardPath + '/' + accessRoutes[0].children[0].path + // console.log(accessRoutes[0].path); + // console.log(pathIndex); + // replace: true只是一个设置信息,告诉VUE本次操作后,不能通过浏览器后退按钮,返回前一个路由。 + next({ path: pathIndex, replace: true }) // hack方法 确保addRoutes已完成 + } else { + // 如果是点击了一个菜单,然后刷新,保持在当前的页面。 + // 如果是从其他页面点击,通过打开新窗口跳转路由。如从当前故障报警详情里跳到实时监控页面。 + next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 + // 使用next({ ...to, replace: true })来确保addRoutes()时动态添加的路由已经被完全加载上去。 + } + // 修改默认首页end + }) + + }).catch(err => { + store.dispatch('LogOut').then(() => { + Message.error(err) + location.href = '/login'; + }) + }) + } else { + next() + } + + } else { + // 没有token + if (whiteList.indexOf(to.path) !== -1) { + // 在免登录白名单,直接进入 + next() + } else { + next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) // 否则全部重定向到登录页 + NProgress.done() + } + } +}) + +router.afterEach(() => { + NProgress.done() +}) diff --git a/staffing-ui/src/plugins/auth.js b/staffing-ui/src/plugins/auth.js new file mode 100644 index 0000000..6c6bc24 --- /dev/null +++ b/staffing-ui/src/plugins/auth.js @@ -0,0 +1,60 @@ +import store from '@/store' + +function authPermission(permission) { + const all_permission = "*:*:*"; + const permissions = store.getters && store.getters.permissions + if (permission && permission.length > 0) { + return permissions.some(v => { + return all_permission === v || v === permission + }) + } else { + return false + } +} + +function authRole(role) { + const super_admin = "admin"; + const roles = store.getters && store.getters.roles + if (role && role.length > 0) { + return roles.some(v => { + return super_admin === v || v === role + }) + } else { + return false + } +} + +export default { + // 验证用户是否具备某权限 + hasPermi(permission) { + return authPermission(permission); + }, + // 验证用户是否含有指定权限,只需包含其中一个 + hasPermiOr(permissions) { + return permissions.some(item => { + return authPermission(item) + }) + }, + // 验证用户是否含有指定权限,必须全部拥有 + hasPermiAnd(permissions) { + return permissions.every(item => { + return authPermission(item) + }) + }, + // 验证用户是否具备某角色 + hasRole(role) { + return authRole(role); + }, + // 验证用户是否含有指定角色,只需包含其中一个 + hasRoleOr(roles) { + return roles.some(item => { + return authRole(item) + }) + }, + // 验证用户是否含有指定角色,必须全部拥有 + hasRoleAnd(roles) { + return roles.every(item => { + return authRole(item) + }) + } +} diff --git a/staffing-ui/src/plugins/cache.js b/staffing-ui/src/plugins/cache.js new file mode 100644 index 0000000..6b5c00b --- /dev/null +++ b/staffing-ui/src/plugins/cache.js @@ -0,0 +1,77 @@ +const sessionCache = { + set (key, value) { + if (!sessionStorage) { + return + } + if (key != null && value != null) { + sessionStorage.setItem(key, value) + } + }, + get (key) { + if (!sessionStorage) { + return null + } + if (key == null) { + return null + } + return sessionStorage.getItem(key) + }, + setJSON (key, jsonValue) { + if (jsonValue != null) { + this.set(key, JSON.stringify(jsonValue)) + } + }, + getJSON (key) { + const value = this.get(key) + if (value != null) { + return JSON.parse(value) + } + }, + remove (key) { + sessionStorage.removeItem(key); + } +} +const localCache = { + set (key, value) { + if (!localStorage) { + return + } + if (key != null && value != null) { + localStorage.setItem(key, value) + } + }, + get (key) { + if (!localStorage) { + return null + } + if (key == null) { + return null + } + return localStorage.getItem(key) + }, + setJSON (key, jsonValue) { + if (jsonValue != null) { + this.set(key, JSON.stringify(jsonValue)) + } + }, + getJSON (key) { + const value = this.get(key) + if (value != null) { + return JSON.parse(value) + } + }, + remove (key) { + localStorage.removeItem(key); + } +} + +export default { + /** + * 会话级缓存 + */ + session: sessionCache, + /** + * 本地缓存 + */ + local: localCache +} diff --git a/staffing-ui/src/plugins/download.js b/staffing-ui/src/plugins/download.js new file mode 100644 index 0000000..91bed5f --- /dev/null +++ b/staffing-ui/src/plugins/download.js @@ -0,0 +1,79 @@ +import axios from 'axios' +import {Loading, Message} from 'element-ui' +import { saveAs } from 'file-saver' +import { getToken } from '@/utils/auth' +import errorCode from '@/utils/errorCode' +import { blobValidate } from "@/utils/staffing"; + +const baseURL = process.env.VUE_APP_BASE_API +let downloadLoadingInstance; + +export default { + name(name, isDelete = true) { + var url = baseURL + "/common/download?fileName=" + encodeURIComponent(name) + "&delete=" + isDelete + axios({ + method: 'get', + url: url, + responseType: 'blob', + headers: { 'Authorization': 'Bearer ' + getToken() } + }).then((res) => { + const isBlob = blobValidate(res.data); + if (isBlob) { + const blob = new Blob([res.data]) + this.saveAs(blob, decodeURIComponent(res.headers['download-filename'])) + } else { + this.printErrMsg(res.data); + } + }) + }, + resource(resource) { + var url = baseURL + "/common/download/resource?resource=" + encodeURIComponent(resource); + axios({ + method: 'get', + url: url, + responseType: 'blob', + headers: { 'Authorization': 'Bearer ' + getToken() } + }).then((res) => { + const isBlob = blobValidate(res.data); + if (isBlob) { + const blob = new Blob([res.data]) + this.saveAs(blob, decodeURIComponent(res.headers['download-filename'])) + } else { + this.printErrMsg(res.data); + } + }) + }, + zip(url, name) { + var url = baseURL + url + downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", }) + axios({ + method: 'get', + url: url, + responseType: 'blob', + headers: { 'Authorization': 'Bearer ' + getToken() } + }).then((res) => { + const isBlob = blobValidate(res.data); + if (isBlob) { + const blob = new Blob([res.data], { type: 'application/zip' }) + this.saveAs(blob, name) + } else { + this.printErrMsg(res.data); + } + downloadLoadingInstance.close(); + }).catch((r) => { + console.error(r) + Message.error('下载文件出现错误,请联系管理员!') + downloadLoadingInstance.close(); + }) + }, + saveAs(text, name, opts) { + saveAs(text, name, opts); + }, + async printErrMsg(data) { + const resText = await data.text(); + const rspObj = JSON.parse(resText); + const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] + Message.error(errMsg); + } +} + diff --git a/staffing-ui/src/plugins/index.js b/staffing-ui/src/plugins/index.js new file mode 100644 index 0000000..d000f2d --- /dev/null +++ b/staffing-ui/src/plugins/index.js @@ -0,0 +1,20 @@ +import tab from './tab' +import auth from './auth' +import cache from './cache' +import modal from './modal' +import download from './download' + +export default { + install(Vue) { + // 页签操作 + Vue.prototype.$tab = tab + // 认证对象 + Vue.prototype.$auth = auth + // 缓存对象 + Vue.prototype.$cache = cache + // 模态框对象 + Vue.prototype.$modal = modal + // 下载文件 + Vue.prototype.$download = download + } +} diff --git a/staffing-ui/src/plugins/modal.js b/staffing-ui/src/plugins/modal.js new file mode 100644 index 0000000..b37ca14 --- /dev/null +++ b/staffing-ui/src/plugins/modal.js @@ -0,0 +1,83 @@ +import { Message, MessageBox, Notification, Loading } from 'element-ui' + +let loadingInstance; + +export default { + // 消息提示 + msg(content) { + Message.info(content) + }, + // 错误消息 + msgError(content) { + Message.error(content) + }, + // 成功消息 + msgSuccess(content) { + Message.success(content) + }, + // 警告消息 + msgWarning(content) { + Message.warning(content) + }, + // 弹出提示 + alert(content) { + MessageBox.alert(content, "系统提示") + }, + // 错误提示 + alertError(content) { + MessageBox.alert(content, "系统提示", { type: 'error' }) + }, + // 成功提示 + alertSuccess(content) { + MessageBox.alert(content, "系统提示", { type: 'success' }) + }, + // 警告提示 + alertWarning(content) { + MessageBox.alert(content, "系统提示", { type: 'warning' }) + }, + // 通知提示 + notify(content) { + Notification.info(content) + }, + // 错误通知 + notifyError(content) { + Notification.error(content); + }, + // 成功通知 + notifySuccess(content) { + Notification.success(content) + }, + // 警告通知 + notifyWarning(content) { + Notification.warning(content) + }, + // 确认窗体 + confirm(content) { + return MessageBox.confirm(content, "系统提示", { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: "warning", + }) + }, + // 提交内容 + prompt(content) { + return MessageBox.prompt(content, "系统提示", { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: "warning", + }) + }, + // 打开遮罩层 + loading(content) { + loadingInstance = Loading.service({ + lock: true, + text: content, + spinner: "el-icon-loading", + background: "rgba(0, 0, 0, 0.7)", + }) + }, + // 关闭遮罩层 + closeLoading() { + loadingInstance.close(); + } +} diff --git a/staffing-ui/src/plugins/tab.js b/staffing-ui/src/plugins/tab.js new file mode 100644 index 0000000..fcde419 --- /dev/null +++ b/staffing-ui/src/plugins/tab.js @@ -0,0 +1,71 @@ +import store from '@/store' +import router from '@/router'; + +export default { + // 刷新当前tab页签 + refreshPage(obj) { + const { path, query, matched } = router.currentRoute; + if (obj === undefined) { + matched.forEach((m) => { + if (m.components && m.components.default && m.components.default.name) { + if (!['Layout', 'ParentView'].includes(m.components.default.name)) { + obj = { name: m.components.default.name, path: path, query: query }; + } + } + }); + } + return store.dispatch('tagsView/delCachedView', obj).then(() => { + const { path, query } = obj + router.replace({ + path: '/redirect' + path, + query: query + }) + }) + }, + // 关闭当前tab页签,打开新页签 + closeOpenPage(obj) { + store.dispatch("tagsView/delView", router.currentRoute); + if (obj !== undefined) { + return router.push(obj); + } + }, + // 关闭指定tab页签 + closePage(obj) { + if (obj === undefined) { + return store.dispatch('tagsView/delView', router.currentRoute).then(({ visitedViews }) => { + const latestView = visitedViews.slice(-1)[0] + if (latestView) { + return router.push(latestView.fullPath) + } + return router.push('/'); + }); + } + return store.dispatch('tagsView/delView', obj); + }, + // 关闭所有tab页签 + closeAllPage() { + return store.dispatch('tagsView/delAllViews'); + }, + // 关闭左侧tab页签 + closeLeftPage(obj) { + return store.dispatch('tagsView/delLeftTags', obj || router.currentRoute); + }, + // 关闭右侧tab页签 + closeRightPage(obj) { + return store.dispatch('tagsView/delRightTags', obj || router.currentRoute); + }, + // 关闭其他tab页签 + closeOtherPage(obj) { + return store.dispatch('tagsView/delOthersViews', obj || router.currentRoute); + }, + // 添加tab页签 + openPage(title, url, params) { + const obj = { path: url, meta: { title: title } } + store.dispatch('tagsView/addView', obj); + return router.push({ path: url, query: params }); + }, + // 修改tab页签 + updatePage(obj) { + return store.dispatch('tagsView/updateVisitedView', obj); + } +} diff --git a/staffing-ui/src/router/index.js b/staffing-ui/src/router/index.js new file mode 100644 index 0000000..f8e1400 --- /dev/null +++ b/staffing-ui/src/router/index.js @@ -0,0 +1,183 @@ +import Vue from 'vue' +import Router from 'vue-router' + +Vue.use(Router) + +/* Layout */ +import Layout from '@/layout' + +/** + * Note: 路由配置项 + * + * hidden: true // 当设置 true 的时候该路由不会再侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1 + * alwaysShow: true // 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面 + * // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面 + * // 若你想不管路由下面的 children 声明的个数都显示你的根路由 + * // 你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,一直显示根路由 + * redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 + * name:'router-name' // 设定路由的名字,一定要填写不然使用时会出现各种问题 + * query: '{"id": 1, "name": "ry"}' // 访问路由的默认传递参数 + * roles: ['admin', 'common'] // 访问路由的角色权限 + * permissions: ['a:a:a', 'b:b:b'] // 访问路由的菜单权限 + * meta : { + noCache: true // 如果设置为true,则不会被 缓存(默认 false) + title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字 + icon: 'svg-name' // 设置该路由的图标,对应路径src/assets/icons/svg + breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示 + activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。 + } + */ + +// 公共路由 +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: '/register', + component: () => import('@/views/register'), + 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: 'Index', + // meta: { title: '首页', icon: 'dashboard', 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' } + } + ] + } +] + +// 动态路由,基于用户权限动态去加载 +export const dynamicRoutes = [ + { + path: '/system/user-auth', + component: Layout, + hidden: true, + permissions: ['system:user:edit'], + children: [ + { + path: 'role/:userId(\\d+)', + component: () => import('@/views/system/user/authRole'), + name: 'AuthRole', + meta: { title: '分配角色', activeMenu: '/system/user' } + } + ] + }, + { + path: '/system/role-auth', + component: Layout, + hidden: true, + permissions: ['system:role:edit'], + children: [ + { + path: 'user/:roleId(\\d+)', + component: () => import('@/views/system/role/authUser'), + name: 'AuthUser', + meta: { title: '分配用户', activeMenu: '/system/role' } + } + ] + }, + { + path: '/system/dict-data', + component: Layout, + hidden: true, + permissions: ['system:dict:list'], + children: [ + { + path: 'index/:dictId(\\d+)', + component: () => import('@/views/system/dict/data'), + name: 'Data', + meta: { title: '字典数据', activeMenu: '/system/dict' } + } + ] + }, + { + path: '/monitor/job-log', + component: Layout, + hidden: true, + permissions: ['monitor:job:list'], + children: [ + { + path: 'index/:jobId(\\d+)', + component: () => import('@/views/monitor/job/log'), + name: 'JobLog', + meta: { title: '调度日志', activeMenu: '/monitor/job' } + } + ] + }, + { + path: '/tool/gen-edit', + component: Layout, + hidden: true, + permissions: ['tool:gen:edit'], + children: [ + { + path: 'index/:tableId(\\d+)', + component: () => import('@/views/tool/gen/editTable'), + name: 'GenEdit', + meta: { title: '修改生成配置', activeMenu: '/tool/gen' } + } + ] + } +] + +// 防止连续点击多次路由报错 +let routerPush = Router.prototype.push; +let routerReplace = Router.prototype.replace; +// push +Router.prototype.push = function push(location) { + return routerPush.call(this, location).catch(err => err) +} +// replace +Router.prototype.replace = function push(location) { + return routerReplace.call(this, location).catch(err => err) +} + +export default new Router({ + mode: 'history', // 去掉url中的# + scrollBehavior: () => ({ y: 0 }), + routes: constantRoutes +}) diff --git a/staffing-ui/src/settings.js b/staffing-ui/src/settings.js new file mode 100644 index 0000000..6a0b09f --- /dev/null +++ b/staffing-ui/src/settings.js @@ -0,0 +1,44 @@ +module.exports = { + /** + * 侧边栏主题 深色主题theme-dark,浅色主题theme-light + */ + sideTheme: 'theme-dark', + + /** + * 是否系统布局配置 + */ + showSettings: false, + + /** + * 是否显示顶部导航 + */ + topNav: false, + + /** + * 是否显示 tagsView + */ + tagsView: true, + + /** + * 是否固定头部 + */ + fixedHeader: false, + + /** + * 是否显示logo + */ + sidebarLogo: true, + + /** + * 是否显示动态标题 + */ + dynamicTitle: false, + + /** + * @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/staffing-ui/src/store/getters.js b/staffing-ui/src/store/getters.js new file mode 100644 index 0000000..8adb1b6 --- /dev/null +++ b/staffing-ui/src/store/getters.js @@ -0,0 +1,19 @@ +const getters = { + sidebar: state => state.app.sidebar, + size: state => state.app.size, + device: state => state.app.device, + dict: state => state.dict.dict, + 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, + topbarRouters:state => state.permission.topbarRouters, + defaultRoutes:state => state.permission.defaultRoutes, + sidebarRouters:state => state.permission.sidebarRouters, +} +export default getters diff --git a/staffing-ui/src/store/index.js b/staffing-ui/src/store/index.js new file mode 100644 index 0000000..97aaef8 --- /dev/null +++ b/staffing-ui/src/store/index.js @@ -0,0 +1,25 @@ +import Vue from 'vue' +import Vuex from 'vuex' +import app from './modules/app' +import dict from './modules/dict' +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, + dict, + user, + tagsView, + permission, + settings + }, + getters +}) + +export default store diff --git a/staffing-ui/src/store/modules/app.js b/staffing-ui/src/store/modules/app.js new file mode 100644 index 0000000..3e22d1c --- /dev/null +++ b/staffing-ui/src/store/modules/app.js @@ -0,0 +1,66 @@ +import Cookies from 'js-cookie' + +const state = { + sidebar: { + opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true, + withoutAnimation: false, + hide: false + }, + device: 'desktop', + size: Cookies.get('size') || 'medium' +} + +const mutations = { + TOGGLE_SIDEBAR: state => { + if (state.sidebar.hide) { + return false; + } + 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) + }, + SET_SIDEBAR_HIDE: (state, status) => { + state.sidebar.hide = status + } +} + +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) + }, + toggleSideBarHide({ commit }, status) { + commit('SET_SIDEBAR_HIDE', status) + } +} + +export default { + namespaced: true, + state, + mutations, + actions +} diff --git a/staffing-ui/src/store/modules/dict.js b/staffing-ui/src/store/modules/dict.js new file mode 100644 index 0000000..7a1b2f0 --- /dev/null +++ b/staffing-ui/src/store/modules/dict.js @@ -0,0 +1,50 @@ +const state = { + dict: new Array() +} +const mutations = { + SET_DICT: (state, { key, value }) => { + if (key !== null && key !== "") { + state.dict.push({ + key: key, + value: value + }) + } + }, + REMOVE_DICT: (state, key) => { + try { + for (let i = 0; i < state.dict.length; i++) { + if (state.dict[i].key == key) { + state.dict.splice(i, 1) + return true + } + } + } catch (e) { + } + }, + CLEAN_DICT: (state) => { + state.dict = new Array() + } +} + +const actions = { + // 设置字典 + setDict({ commit }, data) { + commit('SET_DICT', data) + }, + // 删除字典 + removeDict({ commit }, key) { + commit('REMOVE_DICT', key) + }, + // 清空字典 + cleanDict({ commit }) { + commit('CLEAN_DICT') + } +} + +export default { + namespaced: true, + state, + mutations, + actions +} + diff --git a/staffing-ui/src/store/modules/permission.js b/staffing-ui/src/store/modules/permission.js new file mode 100644 index 0000000..8c4eb31 --- /dev/null +++ b/staffing-ui/src/store/modules/permission.js @@ -0,0 +1,147 @@ +import auth from '@/plugins/auth' +import router, { constantRoutes, dynamicRoutes } from '@/router' +import { getRouters } from '@/api/menu' +import Layout from '@/layout/index' +import ParentView from '@/components/ParentView' +import InnerLink from '@/layout/components/InnerLink' + +const permission = { + state: { + routes: [], + addRoutes: [], + defaultRoutes: [], + topbarRouters: [], + sidebarRouters: [], + //修改默认页面 + indexPage:'' + }, + mutations: { + SET_ROUTES: (state, routes) => { + state.addRoutes = routes + state.routes = constantRoutes.concat(routes) + }, + SET_DEFAULT_ROUTES: (state, routes) => { + state.defaultRoutes = constantRoutes.concat(routes) + }, + SET_TOPBAR_ROUTES: (state, routes) => { + state.topbarRouters = routes + }, + SET_SIDEBAR_ROUTERS: (state, routes) => { + state.sidebarRouters = constantRoutes.concat(routes); + }, + SET_INDEX_PAGE:(state,indexPage)=>{ + state.indexPage = indexPage; + } + }, + actions: { + // 生成路由 + GenerateRoutes({ commit }) { + return new Promise(resolve => { + // 向后端请求路由数据 + getRouters().then(res => { + const sdata = JSON.parse(JSON.stringify(res.data)) + const rdata = JSON.parse(JSON.stringify(res.data)) + //修改默认首页 + const indexdata = res.data[0].path+'/'+res.data[0].children[0].path + const sidebarRoutes = filterAsyncRouter(sdata) + const rewriteRoutes = filterAsyncRouter(rdata, false, true) + const asyncRoutes = filterDynamicRoutes(dynamicRoutes); + rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true }) + router.addRoutes(asyncRoutes); + commit('SET_ROUTES', rewriteRoutes) + commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes)) + commit('SET_DEFAULT_ROUTES', sidebarRoutes) + commit('SET_TOPBAR_ROUTES', sidebarRoutes) + //修改默认首页 + commit('SET_INDEX_PAGE',indexdata) + resolve(rewriteRoutes) + }) + }) + } + } +} + + +// 遍历后台传来的路由字符串,转换为组件对象 +function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) { + return asyncRouterMap.filter(route => { + if (type && route.children) { + route.children = filterChildren(route.children) + } + if (route.component) { + // Layout ParentView 组件特殊处理 + if (route.component === 'Layout') { + route.component = Layout + } else if (route.component === 'ParentView') { + route.component = ParentView + } else if (route.component === 'InnerLink') { + route.component = InnerLink + } else { + route.component = loadView(route.component) + } + } + if (route.children != null && route.children && route.children.length) { + route.children = filterAsyncRouter(route.children, route, type) + } else { + delete route['children'] + delete route['redirect'] + } + return true + }) +} + +function filterChildren(childrenMap, lastRouter = false) { + var children = [] + childrenMap.forEach((el, index) => { + if (el.children && el.children.length) { + if (el.component === 'ParentView' && !lastRouter) { + el.children.forEach(c => { + c.path = el.path + '/' + c.path + if (c.children && c.children.length) { + children = children.concat(filterChildren(c.children, c)) + return + } + children.push(c) + }) + return + } + } + if (lastRouter) { + el.path = lastRouter.path + '/' + el.path + if (el.children && el.children.length) { + children = children.concat(filterChildren(el.children, el)) + return + } + } + children = children.concat(el) + }) + return children +} + +// 动态路由遍历,验证是否具备权限 +export function filterDynamicRoutes(routes) { + const res = [] + routes.forEach(route => { + if (route.permissions) { + if (auth.hasPermiOr(route.permissions)) { + res.push(route) + } + } else if (route.roles) { + if (auth.hasRoleOr(route.roles)) { + res.push(route) + } + } + }) + return res +} + +export const loadView = (view) => { + if (process.env.NODE_ENV === 'development') { + return (resolve) => require([`@/views/${view}`], resolve) + } else { + // 使用 import 实现生产环境的路由懒加载 + return () => import(`@/views/${view}`) + } +} + +export default permission diff --git a/staffing-ui/src/store/modules/settings.js b/staffing-ui/src/store/modules/settings.js new file mode 100644 index 0000000..2455a1e --- /dev/null +++ b/staffing-ui/src/store/modules/settings.js @@ -0,0 +1,42 @@ +import defaultSettings from '@/settings' + +const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings + +const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || '' +const state = { + title: '', + theme: storageSetting.theme || '#409EFF', + sideTheme: storageSetting.sideTheme || sideTheme, + showSettings: showSettings, + topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav, + tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView, + fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader, + sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo, + dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle +} +const mutations = { + CHANGE_SETTING: (state, { key, value }) => { + if (state.hasOwnProperty(key)) { + state[key] = value + } + } +} + +const actions = { + // 修改布局设置 + changeSetting({ commit }, data) { + commit('CHANGE_SETTING', data) + }, + // 设置网页标题 + setTitle({ commit }, title) { + state.title = title + } +} + +export default { + namespaced: true, + state, + mutations, + actions +} + diff --git a/staffing-ui/src/store/modules/tagsView.js b/staffing-ui/src/store/modules/tagsView.js new file mode 100644 index 0000000..5fc011c --- /dev/null +++ b/staffing-ui/src/store/modules/tagsView.js @@ -0,0 +1,228 @@ +const state = { + visitedViews: [], + cachedViews: [], + iframeViews: [] +} + +const mutations = { + ADD_IFRAME_VIEW: (state, view) => { + if (state.iframeViews.some(v => v.path === view.path)) return + state.iframeViews.push( + Object.assign({}, view, { + title: view.meta.title || 'no-name' + }) + ) + }, + 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 && !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 + } + } + state.iframeViews = state.iframeViews.filter(item => item.path !== view.path) + }, + DEL_IFRAME_VIEW: (state, view) => { + state.iframeViews = state.iframeViews.filter(item => item.path !== view.path) + }, + DEL_CACHED_VIEW: (state, view) => { + const index = state.cachedViews.indexOf(view.name) + index > -1 && state.cachedViews.splice(index, 1) + }, + + DEL_OTHERS_VISITED_VIEWS: (state, view) => { + state.visitedViews = state.visitedViews.filter(v => { + return v.meta.affix || v.path === view.path + }) + state.iframeViews = state.iframeViews.filter(item => item.path === view.path) + }, + DEL_OTHERS_CACHED_VIEWS: (state, view) => { + const index = state.cachedViews.indexOf(view.name) + if (index > -1) { + state.cachedViews = state.cachedViews.slice(index, index + 1) + } else { + state.cachedViews = [] + } + }, + DEL_ALL_VISITED_VIEWS: state => { + // keep affix tags + const affixTags = state.visitedViews.filter(tag => tag.meta.affix) + state.visitedViews = affixTags + state.iframeViews = [] + }, + 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 + } + } + }, + DEL_RIGHT_VIEWS: (state, view) => { + const index = state.visitedViews.findIndex(v => v.path === view.path) + if (index === -1) { + return + } + state.visitedViews = state.visitedViews.filter((item, idx) => { + if (idx <= index || (item.meta && item.meta.affix)) { + return true + } + const i = state.cachedViews.indexOf(item.name) + if (i > -1) { + state.cachedViews.splice(i, 1) + } + if(item.meta.link) { + const fi = state.iframeViews.findIndex(v => v.path === item.path) + state.iframeViews.splice(fi, 1) + } + return false + }) + }, + DEL_LEFT_VIEWS: (state, view) => { + const index = state.visitedViews.findIndex(v => v.path === view.path) + if (index === -1) { + return + } + state.visitedViews = state.visitedViews.filter((item, idx) => { + if (idx >= index || (item.meta && item.meta.affix)) { + return true + } + const i = state.cachedViews.indexOf(item.name) + if (i > -1) { + state.cachedViews.splice(i, 1) + } + if(item.meta.link) { + const fi = state.iframeViews.findIndex(v => v.path === item.path) + state.iframeViews.splice(fi, 1) + } + return false + }) + } +} + +const actions = { + addView({ dispatch }, view) { + dispatch('addVisitedView', view) + dispatch('addCachedView', view) + }, + addIframeView({ commit }, view) { + commit('ADD_IFRAME_VIEW', 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]) + }) + }, + delIframeView({ commit, state }, view) { + return new Promise(resolve => { + commit('DEL_IFRAME_VIEW', view) + resolve([...state.iframeViews]) + }) + }, + 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) + }, + delRightTags({ commit }, view) { + return new Promise(resolve => { + commit('DEL_RIGHT_VIEWS', view) + resolve([...state.visitedViews]) + }) + }, + delLeftTags({ commit }, view) { + return new Promise(resolve => { + commit('DEL_LEFT_VIEWS', view) + resolve([...state.visitedViews]) + }) + }, +} + +export default { + namespaced: true, + state, + mutations, + actions +} diff --git a/staffing-ui/src/store/modules/user.js b/staffing-ui/src/store/modules/user.js new file mode 100644 index 0000000..cdbab1e --- /dev/null +++ b/staffing-ui/src/store/modules/user.js @@ -0,0 +1,101 @@ +import { login, logout, getInfo } from '@/api/login' +import { getToken, setToken, removeToken } from '@/utils/auth' + +const user = { + state: { + token: getToken(), + id: '', + name: '', + avatar: '', + roles: [], + permissions: [] + }, + + mutations: { + SET_TOKEN: (state, token) => { + state.token = token + }, + SET_ID: (state, id) => { + state.id = id + }, + 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().then(res => { + const user = res.user + const avatar = (user.avatar == "" || user.avatar == null) ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar; + if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组 + commit('SET_ROLES', res.roles) + commit('SET_PERMISSIONS', res.permissions) + } else { + commit('SET_ROLES', ['ROLE_DEFAULT']) + } + commit('SET_ID', user.userId) + 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/staffing-ui/src/utils/auth.js b/staffing-ui/src/utils/auth.js new file mode 100644 index 0000000..08a43d6 --- /dev/null +++ b/staffing-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/staffing-ui/src/utils/dict/Dict.js b/staffing-ui/src/utils/dict/Dict.js new file mode 100644 index 0000000..ecbda7a --- /dev/null +++ b/staffing-ui/src/utils/dict/Dict.js @@ -0,0 +1,82 @@ +import Vue from 'vue' +import { mergeRecursive } from "@/utils/staffing"; +import DictMeta from './DictMeta' +import DictData from './DictData' + +const DEFAULT_DICT_OPTIONS = { + types: [], +} + +/** + * @classdesc 字典 + * @property {Object} label 标签对象,内部属性名为字典类型名称 + * @property {Object} dict 字段数组,内部属性名为字典类型名称 + * @property {Array.} _dictMetas 字典元数据数组 + */ +export default class Dict { + constructor() { + this.owner = null + this.label = {} + this.type = {} + } + + init(options) { + if (options instanceof Array) { + options = { types: options } + } + const opts = mergeRecursive(DEFAULT_DICT_OPTIONS, options) + if (opts.types === undefined) { + throw new Error('need dict types') + } + const ps = [] + this._dictMetas = opts.types.map(t => DictMeta.parse(t)) + this._dictMetas.forEach(dictMeta => { + const type = dictMeta.type + Vue.set(this.label, type, {}) + Vue.set(this.type, type, []) + if (dictMeta.lazy) { + return + } + ps.push(loadDict(this, dictMeta)) + }) + return Promise.all(ps) + } + + /** + * 重新加载字典 + * @param {String} type 字典类型 + */ + reloadDict(type) { + const dictMeta = this._dictMetas.find(e => e.type === type) + if (dictMeta === undefined) { + return Promise.reject(`the dict meta of ${type} was not found`) + } + return loadDict(this, dictMeta) + } +} + +/** + * 加载字典 + * @param {Dict} dict 字典 + * @param {DictMeta} dictMeta 字典元数据 + * @returns {Promise} + */ +function loadDict(dict, dictMeta) { + return dictMeta.request(dictMeta) + .then(response => { + const type = dictMeta.type + let dicts = dictMeta.responseConverter(response, dictMeta) + if (!(dicts instanceof Array)) { + console.error('the return of responseConverter must be Array.') + dicts = [] + } else if (dicts.filter(d => d instanceof DictData).length !== dicts.length) { + console.error('the type of elements in dicts must be DictData') + dicts = [] + } + dict.type[type].splice(0, Number.MAX_SAFE_INTEGER, ...dicts) + dicts.forEach(d => { + Vue.set(dict.label[type], d.value, d.label) + }) + return dicts + }) +} diff --git a/staffing-ui/src/utils/dict/DictConverter.js b/staffing-ui/src/utils/dict/DictConverter.js new file mode 100644 index 0000000..0cf5df8 --- /dev/null +++ b/staffing-ui/src/utils/dict/DictConverter.js @@ -0,0 +1,17 @@ +import DictOptions from './DictOptions' +import DictData from './DictData' + +export default function(dict, dictMeta) { + const label = determineDictField(dict, dictMeta.labelField, ...DictOptions.DEFAULT_LABEL_FIELDS) + const value = determineDictField(dict, dictMeta.valueField, ...DictOptions.DEFAULT_VALUE_FIELDS) + return new DictData(dict[label], dict[value], dict) +} + +/** + * 确定字典字段 + * @param {DictData} dict + * @param {...String} fields + */ +function determineDictField(dict, ...fields) { + return fields.find(f => Object.prototype.hasOwnProperty.call(dict, f)) +} diff --git a/staffing-ui/src/utils/dict/DictData.js b/staffing-ui/src/utils/dict/DictData.js new file mode 100644 index 0000000..afc763e --- /dev/null +++ b/staffing-ui/src/utils/dict/DictData.js @@ -0,0 +1,13 @@ +/** + * @classdesc 字典数据 + * @property {String} label 标签 + * @property {*} value 标签 + * @property {Object} raw 原始数据 + */ +export default class DictData { + constructor(label, value, raw) { + this.label = label + this.value = value + this.raw = raw + } +} diff --git a/staffing-ui/src/utils/dict/DictMeta.js b/staffing-ui/src/utils/dict/DictMeta.js new file mode 100644 index 0000000..d743819 --- /dev/null +++ b/staffing-ui/src/utils/dict/DictMeta.js @@ -0,0 +1,38 @@ +import { mergeRecursive } from "@/utils/staffing"; +import DictOptions from './DictOptions' + +/** + * @classdesc 字典元数据 + * @property {String} type 类型 + * @property {Function} request 请求 + * @property {String} label 标签字段 + * @property {String} value 值字段 + */ +export default class DictMeta { + constructor(options) { + this.type = options.type + this.request = options.request + this.responseConverter = options.responseConverter + this.labelField = options.labelField + this.valueField = options.valueField + this.lazy = options.lazy === true + } +} + + +/** + * 解析字典元数据 + * @param {Object} options + * @returns {DictMeta} + */ +DictMeta.parse= function(options) { + let opts = null + if (typeof options === 'string') { + opts = DictOptions.metas[options] || {} + opts.type = options + } else if (typeof options === 'object') { + opts = options + } + opts = mergeRecursive(DictOptions.metas['*'], opts) + return new DictMeta(opts) +} diff --git a/staffing-ui/src/utils/dict/DictOptions.js b/staffing-ui/src/utils/dict/DictOptions.js new file mode 100644 index 0000000..12ebdc5 --- /dev/null +++ b/staffing-ui/src/utils/dict/DictOptions.js @@ -0,0 +1,51 @@ +import { mergeRecursive } from "@/utils/staffing"; +import dictConverter from './DictConverter' + +export const options = { + metas: { + '*': { + /** + * 字典请求,方法签名为function(dictMeta: DictMeta): Promise + */ + request: (dictMeta) => { + console.log(`load dict ${dictMeta.type}`) + return Promise.resolve([]) + }, + /** + * 字典响应数据转换器,方法签名为function(response: Object, dictMeta: DictMeta): DictData + */ + responseConverter, + labelField: 'label', + valueField: 'value', + }, + }, + /** + * 默认标签字段 + */ + DEFAULT_LABEL_FIELDS: ['label', 'name', 'title'], + /** + * 默认值字段 + */ + DEFAULT_VALUE_FIELDS: ['value', 'id', 'uid', 'key'], +} + +/** + * 映射字典 + * @param {Object} response 字典数据 + * @param {DictMeta} dictMeta 字典元数据 + * @returns {DictData} + */ +function responseConverter(response, dictMeta) { + const dicts = response.content instanceof Array ? response.content : response + if (dicts === undefined) { + console.warn(`no dict data of "${dictMeta.type}" found in the response`) + return [] + } + return dicts.map(d => dictConverter(d, dictMeta)) +} + +export function mergeOptions(src) { + mergeRecursive(options, src) +} + +export default options diff --git a/staffing-ui/src/utils/dict/index.js b/staffing-ui/src/utils/dict/index.js new file mode 100644 index 0000000..215eb9e --- /dev/null +++ b/staffing-ui/src/utils/dict/index.js @@ -0,0 +1,33 @@ +import Dict from './Dict' +import { mergeOptions } from './DictOptions' + +export default function(Vue, options) { + mergeOptions(options) + Vue.mixin({ + data() { + if (this.$options === undefined || this.$options.dicts === undefined || this.$options.dicts === null) { + return {} + } + const dict = new Dict() + dict.owner = this + return { + dict + } + }, + created() { + if (!(this.dict instanceof Dict)) { + return + } + options.onCreated && options.onCreated(this.dict) + this.dict.init(this.$options.dicts).then(() => { + options.onReady && options.onReady(this.dict) + this.$nextTick(() => { + this.$emit('dictReady', this.dict) + if (this.$options.methods && this.$options.methods.onDictReady instanceof Function) { + this.$options.methods.onDictReady.call(this, this.dict) + } + }) + }) + }, + }) +} diff --git a/staffing-ui/src/utils/errorCode.js b/staffing-ui/src/utils/errorCode.js new file mode 100644 index 0000000..d2111ee --- /dev/null +++ b/staffing-ui/src/utils/errorCode.js @@ -0,0 +1,6 @@ +export default { + '401': '认证失败,无法访问系统资源', + '403': '当前操作没有权限', + '404': '访问资源不存在', + 'default': '系统未知错误,请反馈给管理员' +} diff --git a/staffing-ui/src/utils/generator/config.js b/staffing-ui/src/utils/generator/config.js new file mode 100644 index 0000000..7abf227 --- /dev/null +++ b/staffing-ui/src/utils/generator/config.js @@ -0,0 +1,438 @@ +export const formConf = { + formRef: 'elForm', + formModel: 'formData', + size: 'medium', + labelPosition: 'right', + labelWidth: 100, + formRules: 'rules', + gutter: 15, + disabled: false, + span: 24, + formBtns: true +} + +export const inputComponents = [ + { + label: '单行文本', + tag: 'el-input', + tagIcon: 'input', + placeholder: '请输入', + defaultValue: undefined, + span: 24, + labelWidth: null, + style: { width: '100%' }, + clearable: true, + prepend: '', + append: '', + 'prefix-icon': '', + 'suffix-icon': '', + maxlength: null, + 'show-word-limit': false, + readonly: false, + disabled: false, + required: true, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/input' + }, + { + label: '多行文本', + tag: 'el-input', + tagIcon: 'textarea', + type: 'textarea', + placeholder: '请输入', + defaultValue: undefined, + span: 24, + labelWidth: null, + autosize: { + minRows: 4, + maxRows: 4 + }, + style: { width: '100%' }, + maxlength: null, + 'show-word-limit': false, + readonly: false, + disabled: false, + required: true, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/input' + }, + { + label: '密码', + tag: 'el-input', + tagIcon: 'password', + placeholder: '请输入', + defaultValue: undefined, + span: 24, + 'show-password': true, + labelWidth: null, + style: { width: '100%' }, + clearable: true, + prepend: '', + append: '', + 'prefix-icon': '', + 'suffix-icon': '', + maxlength: null, + 'show-word-limit': false, + readonly: false, + disabled: false, + required: true, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/input' + }, + { + label: '计数器', + tag: 'el-input-number', + tagIcon: 'number', + placeholder: '', + defaultValue: undefined, + span: 24, + labelWidth: null, + min: undefined, + max: undefined, + step: undefined, + 'step-strictly': false, + precision: undefined, + 'controls-position': '', + disabled: false, + required: true, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/input-number' + } +] + +export const selectComponents = [ + { + label: '下拉选择', + tag: 'el-select', + tagIcon: 'select', + placeholder: '请选择', + defaultValue: undefined, + span: 24, + labelWidth: null, + style: { width: '100%' }, + clearable: true, + disabled: false, + required: true, + filterable: false, + multiple: false, + options: [{ + label: '选项一', + value: 1 + }, { + label: '选项二', + value: 2 + }], + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/select' + }, + { + label: '级联选择', + tag: 'el-cascader', + tagIcon: 'cascader', + placeholder: '请选择', + defaultValue: [], + span: 24, + labelWidth: null, + style: { width: '100%' }, + props: { + props: { + multiple: false + } + }, + 'show-all-levels': true, + disabled: false, + clearable: true, + filterable: false, + required: true, + options: [{ + id: 1, + value: 1, + label: '选项1', + children: [{ + id: 2, + value: 2, + label: '选项1-1' + }] + }], + dataType: 'dynamic', + labelKey: 'label', + valueKey: 'value', + childrenKey: 'children', + separator: '/', + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/cascader' + }, + { + label: '单选框组', + tag: 'el-radio-group', + tagIcon: 'radio', + defaultValue: undefined, + span: 24, + labelWidth: null, + style: {}, + optionType: 'default', + border: false, + size: 'medium', + disabled: false, + required: true, + options: [{ + label: '选项一', + value: 1 + }, { + label: '选项二', + value: 2 + }], + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/radio' + }, + { + label: '多选框组', + tag: 'el-checkbox-group', + tagIcon: 'checkbox', + defaultValue: [], + span: 24, + labelWidth: null, + style: {}, + optionType: 'default', + border: false, + size: 'medium', + disabled: false, + required: true, + options: [{ + label: '选项一', + value: 1 + }, { + label: '选项二', + value: 2 + }], + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/checkbox' + }, + { + label: '开关', + tag: 'el-switch', + tagIcon: 'switch', + defaultValue: false, + span: 24, + labelWidth: null, + style: {}, + disabled: false, + required: true, + 'active-text': '', + 'inactive-text': '', + 'active-color': null, + 'inactive-color': null, + 'active-value': true, + 'inactive-value': false, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/switch' + }, + { + label: '滑块', + tag: 'el-slider', + tagIcon: 'slider', + defaultValue: null, + span: 24, + labelWidth: null, + disabled: false, + required: true, + min: 0, + max: 100, + step: 1, + 'show-stops': false, + range: false, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/slider' + }, + { + label: '时间选择', + tag: 'el-time-picker', + tagIcon: 'time', + placeholder: '请选择', + defaultValue: null, + span: 24, + labelWidth: null, + style: { width: '100%' }, + disabled: false, + clearable: true, + required: true, + 'picker-options': { + selectableRange: '00:00:00-23:59:59' + }, + format: 'HH:mm:ss', + 'value-format': 'HH:mm:ss', + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/time-picker' + }, + { + label: '时间范围', + tag: 'el-time-picker', + tagIcon: 'time-range', + defaultValue: null, + span: 24, + labelWidth: null, + style: { width: '100%' }, + disabled: false, + clearable: true, + required: true, + 'is-range': true, + 'range-separator': '至', + 'start-placeholder': '开始时间', + 'end-placeholder': '结束时间', + format: 'HH:mm:ss', + 'value-format': 'HH:mm:ss', + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/time-picker' + }, + { + label: '日期选择', + tag: 'el-date-picker', + tagIcon: 'date', + placeholder: '请选择', + defaultValue: null, + type: 'date', + span: 24, + labelWidth: null, + style: { width: '100%' }, + disabled: false, + clearable: true, + required: true, + format: 'yyyy-MM-dd', + 'value-format': 'yyyy-MM-dd', + readonly: false, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/date-picker' + }, + { + label: '日期范围', + tag: 'el-date-picker', + tagIcon: 'date-range', + defaultValue: null, + span: 24, + labelWidth: null, + style: { width: '100%' }, + type: 'daterange', + 'range-separator': '至', + 'start-placeholder': '开始日期', + 'end-placeholder': '结束日期', + disabled: false, + clearable: true, + required: true, + format: 'yyyy-MM-dd', + 'value-format': 'yyyy-MM-dd', + readonly: false, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/date-picker' + }, + { + label: '评分', + tag: 'el-rate', + tagIcon: 'rate', + defaultValue: 0, + span: 24, + labelWidth: null, + style: {}, + max: 5, + 'allow-half': false, + 'show-text': false, + 'show-score': false, + disabled: false, + required: true, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/rate' + }, + { + label: '颜色选择', + tag: 'el-color-picker', + tagIcon: 'color', + defaultValue: null, + labelWidth: null, + 'show-alpha': false, + 'color-format': '', + disabled: false, + required: true, + size: 'medium', + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/color-picker' + }, + { + label: '上传', + tag: 'el-upload', + tagIcon: 'upload', + action: 'https://jsonplaceholder.typicode.com/posts/', + defaultValue: null, + labelWidth: null, + disabled: false, + required: true, + accept: '', + name: 'file', + 'auto-upload': true, + showTip: false, + buttonText: '点击上传', + fileSize: 2, + sizeUnit: 'MB', + 'list-type': 'text', + multiple: false, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/upload' + } +] + +export const layoutComponents = [ + { + layout: 'rowFormItem', + tagIcon: 'row', + type: 'default', + justify: 'start', + align: 'top', + label: '行容器', + layoutTree: true, + children: [], + document: 'https://element.eleme.cn/#/zh-CN/component/layout' + }, + { + layout: 'colFormItem', + label: '按钮', + changeTag: true, + labelWidth: null, + tag: 'el-button', + tagIcon: 'button', + span: 24, + default: '主要按钮', + type: 'primary', + icon: 'el-icon-search', + size: 'medium', + disabled: false, + document: 'https://element.eleme.cn/#/zh-CN/component/button' + } +] + +// 组件rule的触发方式,无触发方式的组件不生成rule +export const trigger = { + 'el-input': 'blur', + 'el-input-number': 'blur', + 'el-select': 'change', + 'el-radio-group': 'change', + 'el-checkbox-group': 'change', + 'el-cascader': 'change', + 'el-time-picker': 'change', + 'el-date-picker': 'change', + 'el-rate': 'change' +} diff --git a/staffing-ui/src/utils/generator/css.js b/staffing-ui/src/utils/generator/css.js new file mode 100644 index 0000000..c1c62e6 --- /dev/null +++ b/staffing-ui/src/utils/generator/css.js @@ -0,0 +1,18 @@ +const styles = { + 'el-rate': '.el-rate{display: inline-block; vertical-align: text-top;}', + 'el-upload': '.el-upload__tip{line-height: 1.2;}' +} + +function addCss(cssList, el) { + const css = styles[el.tag] + css && cssList.indexOf(css) === -1 && cssList.push(css) + if (el.children) { + el.children.forEach(el2 => addCss(cssList, el2)) + } +} + +export function makeUpCss(conf) { + const cssList = [] + conf.fields.forEach(el => addCss(cssList, el)) + return cssList.join('\n') +} diff --git a/staffing-ui/src/utils/generator/drawingDefault.js b/staffing-ui/src/utils/generator/drawingDefault.js new file mode 100644 index 0000000..09f133c --- /dev/null +++ b/staffing-ui/src/utils/generator/drawingDefault.js @@ -0,0 +1,29 @@ +export default [ + { + layout: 'colFormItem', + tagIcon: 'input', + label: '手机号', + vModel: 'mobile', + formId: 6, + tag: 'el-input', + placeholder: '请输入手机号', + defaultValue: '', + span: 24, + style: { width: '100%' }, + clearable: true, + prepend: '', + append: '', + 'prefix-icon': 'el-icon-mobile', + 'suffix-icon': '', + maxlength: 11, + 'show-word-limit': true, + readonly: false, + disabled: false, + required: true, + changeTag: true, + regList: [{ + pattern: '/^1(3|4|5|7|8|9)\\d{9}$/', + message: '手机号格式错误' + }] + } +] diff --git a/staffing-ui/src/utils/generator/html.js b/staffing-ui/src/utils/generator/html.js new file mode 100644 index 0000000..9bcc536 --- /dev/null +++ b/staffing-ui/src/utils/generator/html.js @@ -0,0 +1,359 @@ +/* eslint-disable max-len */ +import { trigger } from './config' + +let confGlobal +let someSpanIsNot24 + +export function dialogWrapper(str) { + return ` + ${str} +

    + ` +} + +export function vueTemplate(str) { + return `` +} + +export function vueScript(str) { + return `` +} + +export function cssStyle(cssStr) { + return `` +} + +function buildFormTemplate(conf, child, type) { + let labelPosition = '' + if (conf.labelPosition !== 'right') { + labelPosition = `label-position="${conf.labelPosition}"` + } + const disabled = conf.disabled ? `:disabled="${conf.disabled}"` : '' + let str = ` + ${child} + ${buildFromBtns(conf, type)} + ` + if (someSpanIsNot24) { + str = ` + ${str} + ` + } + return str +} + +function buildFromBtns(conf, type) { + let str = '' + if (conf.formBtns && type === 'file') { + str = ` + 提交 + 重置 + ` + if (someSpanIsNot24) { + str = ` + ${str} + ` + } + } + return str +} + +// span不为24的用el-col包裹 +function colWrapper(element, str) { + if (someSpanIsNot24 || element.span !== 24) { + return ` + ${str} + ` + } + return str +} + +const layouts = { + colFormItem(element) { + let labelWidth = '' + if (element.labelWidth && element.labelWidth !== confGlobal.labelWidth) { + labelWidth = `label-width="${element.labelWidth}px"` + } + const required = !trigger[element.tag] && element.required ? 'required' : '' + const tagDom = tags[element.tag] ? tags[element.tag](element) : null + let str = ` + ${tagDom} + ` + str = colWrapper(element, str) + return str + }, + rowFormItem(element) { + const type = element.type === 'default' ? '' : `type="${element.type}"` + const justify = element.type === 'default' ? '' : `justify="${element.justify}"` + const align = element.type === 'default' ? '' : `align="${element.align}"` + const gutter = element.gutter ? `gutter="${element.gutter}"` : '' + const children = element.children.map(el => layouts[el.layout](el)) + let str = ` + ${children.join('\n')} + ` + str = colWrapper(element, str) + return str + } +} + +const tags = { + 'el-button': el => { + const { + tag, disabled + } = attrBuilder(el) + const type = el.type ? `type="${el.type}"` : '' + const icon = el.icon ? `icon="${el.icon}"` : '' + const size = el.size ? `size="${el.size}"` : '' + let child = buildElButtonChild(el) + + if (child) child = `\n${child}\n` // 换行 + return `<${el.tag} ${type} ${icon} ${size} ${disabled}>${child}` + }, + 'el-input': el => { + const { + disabled, vModel, clearable, placeholder, width + } = attrBuilder(el) + const maxlength = el.maxlength ? `:maxlength="${el.maxlength}"` : '' + const showWordLimit = el['show-word-limit'] ? 'show-word-limit' : '' + const readonly = el.readonly ? 'readonly' : '' + const prefixIcon = el['prefix-icon'] ? `prefix-icon='${el['prefix-icon']}'` : '' + const suffixIcon = el['suffix-icon'] ? `suffix-icon='${el['suffix-icon']}'` : '' + const showPassword = el['show-password'] ? 'show-password' : '' + const type = el.type ? `type="${el.type}"` : '' + const autosize = el.autosize && el.autosize.minRows + ? `:autosize="{minRows: ${el.autosize.minRows}, maxRows: ${el.autosize.maxRows}}"` + : '' + let child = buildElInputChild(el) + + if (child) child = `\n${child}\n` // 换行 + return `<${el.tag} ${vModel} ${type} ${placeholder} ${maxlength} ${showWordLimit} ${readonly} ${disabled} ${clearable} ${prefixIcon} ${suffixIcon} ${showPassword} ${autosize} ${width}>${child}` + }, + 'el-input-number': el => { + const { disabled, vModel, placeholder } = attrBuilder(el) + const controlsPosition = el['controls-position'] ? `controls-position=${el['controls-position']}` : '' + const min = el.min ? `:min='${el.min}'` : '' + const max = el.max ? `:max='${el.max}'` : '' + const step = el.step ? `:step='${el.step}'` : '' + const stepStrictly = el['step-strictly'] ? 'step-strictly' : '' + const precision = el.precision ? `:precision='${el.precision}'` : '' + + return `<${el.tag} ${vModel} ${placeholder} ${step} ${stepStrictly} ${precision} ${controlsPosition} ${min} ${max} ${disabled}>` + }, + 'el-select': el => { + const { + disabled, vModel, clearable, placeholder, width + } = attrBuilder(el) + const filterable = el.filterable ? 'filterable' : '' + const multiple = el.multiple ? 'multiple' : '' + let child = buildElSelectChild(el) + + if (child) child = `\n${child}\n` // 换行 + return `<${el.tag} ${vModel} ${placeholder} ${disabled} ${multiple} ${filterable} ${clearable} ${width}>${child}` + }, + 'el-radio-group': el => { + const { disabled, vModel } = attrBuilder(el) + const size = `size="${el.size}"` + let child = buildElRadioGroupChild(el) + + if (child) child = `\n${child}\n` // 换行 + return `<${el.tag} ${vModel} ${size} ${disabled}>${child}` + }, + 'el-checkbox-group': el => { + const { disabled, vModel } = attrBuilder(el) + const size = `size="${el.size}"` + const min = el.min ? `:min="${el.min}"` : '' + const max = el.max ? `:max="${el.max}"` : '' + let child = buildElCheckboxGroupChild(el) + + if (child) child = `\n${child}\n` // 换行 + return `<${el.tag} ${vModel} ${min} ${max} ${size} ${disabled}>${child}` + }, + 'el-switch': el => { + const { disabled, vModel } = attrBuilder(el) + const activeText = el['active-text'] ? `active-text="${el['active-text']}"` : '' + const inactiveText = el['inactive-text'] ? `inactive-text="${el['inactive-text']}"` : '' + const activeColor = el['active-color'] ? `active-color="${el['active-color']}"` : '' + const inactiveColor = el['inactive-color'] ? `inactive-color="${el['inactive-color']}"` : '' + const activeValue = el['active-value'] !== true ? `:active-value='${JSON.stringify(el['active-value'])}'` : '' + const inactiveValue = el['inactive-value'] !== false ? `:inactive-value='${JSON.stringify(el['inactive-value'])}'` : '' + + return `<${el.tag} ${vModel} ${activeText} ${inactiveText} ${activeColor} ${inactiveColor} ${activeValue} ${inactiveValue} ${disabled}>` + }, + 'el-cascader': el => { + const { + disabled, vModel, clearable, placeholder, width + } = attrBuilder(el) + const options = el.options ? `:options="${el.vModel}Options"` : '' + const props = el.props ? `:props="${el.vModel}Props"` : '' + const showAllLevels = el['show-all-levels'] ? '' : ':show-all-levels="false"' + const filterable = el.filterable ? 'filterable' : '' + const separator = el.separator === '/' ? '' : `separator="${el.separator}"` + + return `<${el.tag} ${vModel} ${options} ${props} ${width} ${showAllLevels} ${placeholder} ${separator} ${filterable} ${clearable} ${disabled}>` + }, + 'el-slider': el => { + const { disabled, vModel } = attrBuilder(el) + const min = el.min ? `:min='${el.min}'` : '' + const max = el.max ? `:max='${el.max}'` : '' + const step = el.step ? `:step='${el.step}'` : '' + const range = el.range ? 'range' : '' + const showStops = el['show-stops'] ? `:show-stops="${el['show-stops']}"` : '' + + return `<${el.tag} ${min} ${max} ${step} ${vModel} ${range} ${showStops} ${disabled}>` + }, + 'el-time-picker': el => { + const { + disabled, vModel, clearable, placeholder, width + } = attrBuilder(el) + const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : '' + const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : '' + const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : '' + const isRange = el['is-range'] ? 'is-range' : '' + const format = el.format ? `format="${el.format}"` : '' + const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : '' + const pickerOptions = el['picker-options'] ? `:picker-options='${JSON.stringify(el['picker-options'])}'` : '' + + return `<${el.tag} ${vModel} ${isRange} ${format} ${valueFormat} ${pickerOptions} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${disabled}>` + }, + 'el-date-picker': el => { + const { + disabled, vModel, clearable, placeholder, width + } = attrBuilder(el) + const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : '' + const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : '' + const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : '' + const format = el.format ? `format="${el.format}"` : '' + const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : '' + const type = el.type === 'date' ? '' : `type="${el.type}"` + const readonly = el.readonly ? 'readonly' : '' + + return `<${el.tag} ${type} ${vModel} ${format} ${valueFormat} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${readonly} ${disabled}>` + }, + 'el-rate': el => { + const { disabled, vModel } = attrBuilder(el) + const max = el.max ? `:max='${el.max}'` : '' + const allowHalf = el['allow-half'] ? 'allow-half' : '' + const showText = el['show-text'] ? 'show-text' : '' + const showScore = el['show-score'] ? 'show-score' : '' + + return `<${el.tag} ${vModel} ${allowHalf} ${showText} ${showScore} ${disabled}>` + }, + 'el-color-picker': el => { + const { disabled, vModel } = attrBuilder(el) + const size = `size="${el.size}"` + const showAlpha = el['show-alpha'] ? 'show-alpha' : '' + const colorFormat = el['color-format'] ? `color-format="${el['color-format']}"` : '' + + return `<${el.tag} ${vModel} ${size} ${showAlpha} ${colorFormat} ${disabled}>` + }, + 'el-upload': el => { + const disabled = el.disabled ? ':disabled=\'true\'' : '' + const action = el.action ? `:action="${el.vModel}Action"` : '' + const multiple = el.multiple ? 'multiple' : '' + const listType = el['list-type'] !== 'text' ? `list-type="${el['list-type']}"` : '' + const accept = el.accept ? `accept="${el.accept}"` : '' + const name = el.name !== 'file' ? `name="${el.name}"` : '' + const autoUpload = el['auto-upload'] === false ? ':auto-upload="false"' : '' + const beforeUpload = `:before-upload="${el.vModel}BeforeUpload"` + const fileList = `:file-list="${el.vModel}fileList"` + const ref = `ref="${el.vModel}"` + let child = buildElUploadChild(el) + + if (child) child = `\n${child}\n` // 换行 + return `<${el.tag} ${ref} ${fileList} ${action} ${autoUpload} ${multiple} ${beforeUpload} ${listType} ${accept} ${name} ${disabled}>${child}` + } +} + +function attrBuilder(el) { + return { + vModel: `v-model="${confGlobal.formModel}.${el.vModel}"`, + clearable: el.clearable ? 'clearable' : '', + placeholder: el.placeholder ? `placeholder="${el.placeholder}"` : '', + width: el.style && el.style.width ? ':style="{width: \'100%\'}"' : '', + disabled: el.disabled ? ':disabled=\'true\'' : '' + } +} + +// el-buttin 子级 +function buildElButtonChild(conf) { + const children = [] + if (conf.default) { + children.push(conf.default) + } + return children.join('\n') +} + +// el-input innerHTML +function buildElInputChild(conf) { + const children = [] + if (conf.prepend) { + children.push(``) + } + if (conf.append) { + children.push(``) + } + return children.join('\n') +} + +function buildElSelectChild(conf) { + const children = [] + if (conf.options && conf.options.length) { + children.push(``) + } + return children.join('\n') +} + +function buildElRadioGroupChild(conf) { + const children = [] + if (conf.options && conf.options.length) { + const tag = conf.optionType === 'button' ? 'el-radio-button' : 'el-radio' + const border = conf.border ? 'border' : '' + children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}`) + } + return children.join('\n') +} + +function buildElCheckboxGroupChild(conf) { + const children = [] + if (conf.options && conf.options.length) { + const tag = conf.optionType === 'button' ? 'el-checkbox-button' : 'el-checkbox' + const border = conf.border ? 'border' : '' + children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}`) + } + return children.join('\n') +} + +function buildElUploadChild(conf) { + const list = [] + if (conf['list-type'] === 'picture-card') list.push('') + else list.push(`${conf.buttonText}`) + if (conf.showTip) list.push(`
    只能上传不超过 ${conf.fileSize}${conf.sizeUnit} 的${conf.accept}文件
    `) + return list.join('\n') +} + +export function makeUpHtml(conf, type) { + const htmlList = [] + confGlobal = conf + someSpanIsNot24 = conf.fields.some(item => item.span !== 24) + conf.fields.forEach(el => { + htmlList.push(layouts[el.layout](el)) + }) + const htmlStr = htmlList.join('\n') + + let temp = buildFormTemplate(conf, htmlStr, type) + if (type === 'dialog') { + temp = dialogWrapper(temp) + } + confGlobal = null + return temp +} diff --git a/staffing-ui/src/utils/generator/icon.json b/staffing-ui/src/utils/generator/icon.json new file mode 100644 index 0000000..2d9999a --- /dev/null +++ b/staffing-ui/src/utils/generator/icon.json @@ -0,0 +1 @@ +["platform-eleme","eleme","delete-solid","delete","s-tools","setting","user-solid","user","phone","phone-outline","more","more-outline","star-on","star-off","s-goods","goods","warning","warning-outline","question","info","remove","circle-plus","success","error","zoom-in","zoom-out","remove-outline","circle-plus-outline","circle-check","circle-close","s-help","help","minus","plus","check","close","picture","picture-outline","picture-outline-round","upload","upload2","download","camera-solid","camera","video-camera-solid","video-camera","message-solid","bell","s-cooperation","s-order","s-platform","s-fold","s-unfold","s-operation","s-promotion","s-home","s-release","s-ticket","s-management","s-open","s-shop","s-marketing","s-flag","s-comment","s-finance","s-claim","s-custom","s-opportunity","s-data","s-check","s-grid","menu","share","d-caret","caret-left","caret-right","caret-bottom","caret-top","bottom-left","bottom-right","back","right","bottom","top","top-left","top-right","arrow-left","arrow-right","arrow-down","arrow-up","d-arrow-left","d-arrow-right","video-pause","video-play","refresh","refresh-right","refresh-left","finished","sort","sort-up","sort-down","rank","loading","view","c-scale-to-original","date","edit","edit-outline","folder","folder-opened","folder-add","folder-remove","folder-delete","folder-checked","tickets","document-remove","document-delete","document-copy","document-checked","document","document-add","printer","paperclip","takeaway-box","search","monitor","attract","mobile","scissors","umbrella","headset","brush","mouse","coordinate","magic-stick","reading","data-line","data-board","pie-chart","data-analysis","collection-tag","film","suitcase","suitcase-1","receiving","collection","files","notebook-1","notebook-2","toilet-paper","office-building","school","table-lamp","house","no-smoking","smoking","shopping-cart-full","shopping-cart-1","shopping-cart-2","shopping-bag-1","shopping-bag-2","sold-out","sell","present","box","bank-card","money","coin","wallet","discount","price-tag","news","guide","male","female","thumb","cpu","link","connection","open","turn-off","set-up","chat-round","chat-line-round","chat-square","chat-dot-round","chat-dot-square","chat-line-square","message","postcard","position","turn-off-microphone","microphone","close-notification","bangzhu","time","odometer","crop","aim","switch-button","full-screen","copy-document","mic","stopwatch","medal-1","medal","trophy","trophy-1","first-aid-kit","discover","place","location","location-outline","location-information","add-location","delete-location","map-location","alarm-clock","timer","watch-1","watch","lock","unlock","key","service","mobile-phone","bicycle","truck","ship","basketball","football","soccer","baseball","wind-power","light-rain","lightning","heavy-rain","sunrise","sunrise-1","sunset","sunny","cloudy","partly-cloudy","cloudy-and-sunny","moon","moon-night","dish","dish-1","food","chicken","fork-spoon","knife-fork","burger","tableware","sugar","dessert","ice-cream","hot-water","water-cup","coffee-cup","cold-drink","goblet","goblet-full","goblet-square","goblet-square-full","refrigerator","grape","watermelon","cherry","apple","pear","orange","coffee","ice-tea","ice-drink","milk-tea","potato-strips","lollipop","ice-cream-square","ice-cream-round"] \ No newline at end of file diff --git a/staffing-ui/src/utils/generator/js.js b/staffing-ui/src/utils/generator/js.js new file mode 100644 index 0000000..ee8668d --- /dev/null +++ b/staffing-ui/src/utils/generator/js.js @@ -0,0 +1,235 @@ +import { exportDefault, titleCase } from '@/utils/index' +import { trigger } from './config' + +const units = { + KB: '1024', + MB: '1024 / 1024', + GB: '1024 / 1024 / 1024' +} +let confGlobal +const inheritAttrs = { + file: '', + dialog: 'inheritAttrs: false,' +} + + +export function makeUpJs(conf, type) { + confGlobal = conf = JSON.parse(JSON.stringify(conf)) + const dataList = [] + const ruleList = [] + const optionsList = [] + const propsList = [] + const methodList = mixinMethod(type) + const uploadVarList = [] + + conf.fields.forEach(el => { + buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) + }) + + const script = buildexport( + conf, + type, + dataList.join('\n'), + ruleList.join('\n'), + optionsList.join('\n'), + uploadVarList.join('\n'), + propsList.join('\n'), + methodList.join('\n') + ) + confGlobal = null + return script +} + +function buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) { + buildData(el, dataList) + buildRules(el, ruleList) + + if (el.options && el.options.length) { + buildOptions(el, optionsList) + if (el.dataType === 'dynamic') { + const model = `${el.vModel}Options` + const options = titleCase(model) + buildOptionMethod(`get${options}`, model, methodList) + } + } + + if (el.props && el.props.props) { + buildProps(el, propsList) + } + + if (el.action && el.tag === 'el-upload') { + uploadVarList.push( + `${el.vModel}Action: '${el.action}', + ${el.vModel}fileList: [],` + ) + methodList.push(buildBeforeUpload(el)) + if (!el['auto-upload']) { + methodList.push(buildSubmitUpload(el)) + } + } + + if (el.children) { + el.children.forEach(el2 => { + buildAttributes(el2, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) + }) + } +} + +function mixinMethod(type) { + const list = []; const + minxins = { + file: confGlobal.formBtns ? { + submitForm: `submitForm() { + this.$refs['${confGlobal.formRef}'].validate(valid => { + if(!valid) return + // TODO 提交表单 + }) + },`, + resetForm: `resetForm() { + this.$refs['${confGlobal.formRef}'].resetFields() + },` + } : null, + dialog: { + onOpen: 'onOpen() {},', + onClose: `onClose() { + this.$refs['${confGlobal.formRef}'].resetFields() + },`, + close: `close() { + this.$emit('update:visible', false) + },`, + handleConfirm: `handleConfirm() { + this.$refs['${confGlobal.formRef}'].validate(valid => { + if(!valid) return + this.close() + }) + },` + } + } + + const methods = minxins[type] + if (methods) { + Object.keys(methods).forEach(key => { + list.push(methods[key]) + }) + } + + return list +} + +function buildData(conf, dataList) { + if (conf.vModel === undefined) return + let defaultValue + if (typeof (conf.defaultValue) === 'string' && !conf.multiple) { + defaultValue = `'${conf.defaultValue}'` + } else { + defaultValue = `${JSON.stringify(conf.defaultValue)}` + } + dataList.push(`${conf.vModel}: ${defaultValue},`) +} + +function buildRules(conf, ruleList) { + if (conf.vModel === undefined) return + const rules = [] + if (trigger[conf.tag]) { + if (conf.required) { + const type = Array.isArray(conf.defaultValue) ? 'type: \'array\',' : '' + let message = Array.isArray(conf.defaultValue) ? `请至少选择一个${conf.vModel}` : conf.placeholder + if (message === undefined) message = `${conf.label}不能为空` + rules.push(`{ required: true, ${type} message: '${message}', trigger: '${trigger[conf.tag]}' }`) + } + if (conf.regList && Array.isArray(conf.regList)) { + conf.regList.forEach(item => { + if (item.pattern) { + rules.push(`{ pattern: ${eval(item.pattern)}, message: '${item.message}', trigger: '${trigger[conf.tag]}' }`) + } + }) + } + ruleList.push(`${conf.vModel}: [${rules.join(',')}],`) + } +} + +function buildOptions(conf, optionsList) { + if (conf.vModel === undefined) return + if (conf.dataType === 'dynamic') { conf.options = [] } + const str = `${conf.vModel}Options: ${JSON.stringify(conf.options)},` + optionsList.push(str) +} + +function buildProps(conf, propsList) { + if (conf.dataType === 'dynamic') { + conf.valueKey !== 'value' && (conf.props.props.value = conf.valueKey) + conf.labelKey !== 'label' && (conf.props.props.label = conf.labelKey) + conf.childrenKey !== 'children' && (conf.props.props.children = conf.childrenKey) + } + const str = `${conf.vModel}Props: ${JSON.stringify(conf.props.props)},` + propsList.push(str) +} + +function buildBeforeUpload(conf) { + const unitNum = units[conf.sizeUnit]; let rightSizeCode = ''; let acceptCode = ''; const + returnList = [] + if (conf.fileSize) { + rightSizeCode = `let isRightSize = file.size / ${unitNum} < ${conf.fileSize} + if(!isRightSize){ + this.$message.error('文件大小超过 ${conf.fileSize}${conf.sizeUnit}') + }` + returnList.push('isRightSize') + } + if (conf.accept) { + acceptCode = `let isAccept = new RegExp('${conf.accept}').test(file.type) + if(!isAccept){ + this.$message.error('应该选择${conf.accept}类型的文件') + }` + returnList.push('isAccept') + } + const str = `${conf.vModel}BeforeUpload(file) { + ${rightSizeCode} + ${acceptCode} + return ${returnList.join('&&')} + },` + return returnList.length ? str : '' +} + +function buildSubmitUpload(conf) { + const str = `submitUpload() { + this.$refs['${conf.vModel}'].submit() + },` + return str +} + +function buildOptionMethod(methodName, model, methodList) { + const str = `${methodName}() { + // TODO 发起请求获取数据 + this.${model} + },` + methodList.push(str) +} + +function buildexport(conf, type, data, rules, selectOptions, uploadVar, props, methods) { + const str = `${exportDefault}{ + ${inheritAttrs[type]} + components: {}, + props: [], + data () { + return { + ${conf.formModel}: { + ${data} + }, + ${conf.formRules}: { + ${rules} + }, + ${uploadVar} + ${selectOptions} + ${props} + } + }, + computed: {}, + watch: {}, + created () {}, + mounted () {}, + methods: { + ${methods} + } +}` + return str +} diff --git a/staffing-ui/src/utils/generator/render.js b/staffing-ui/src/utils/generator/render.js new file mode 100644 index 0000000..e8640f0 --- /dev/null +++ b/staffing-ui/src/utils/generator/render.js @@ -0,0 +1,126 @@ +import { makeMap } from '@/utils/index' + +// 参考https://github.com/vuejs/vue/blob/v2.6.10/src/platforms/web/server/util.js +const isAttr = makeMap( + 'accept,accept-charset,accesskey,action,align,alt,async,autocomplete,' + + 'autofocus,autoplay,autosave,bgcolor,border,buffered,challenge,charset,' + + 'checked,cite,class,code,codebase,color,cols,colspan,content,http-equiv,' + + 'name,contenteditable,contextmenu,controls,coords,data,datetime,default,' + + 'defer,dir,dirname,disabled,download,draggable,dropzone,enctype,method,for,' + + 'form,formaction,headers,height,hidden,high,href,hreflang,http-equiv,' + + 'icon,id,ismap,itemprop,keytype,kind,label,lang,language,list,loop,low,' + + 'manifest,max,maxlength,media,method,GET,POST,min,multiple,email,file,' + + 'muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,' + + 'preload,radiogroup,readonly,rel,required,reversed,rows,rowspan,sandbox,' + + 'scope,scoped,seamless,selected,shape,size,type,text,password,sizes,span,' + + 'spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,' + + 'target,title,type,usemap,value,width,wrap' +) + +function vModel(self, dataObject, defaultValue) { + dataObject.props.value = defaultValue + + dataObject.on.input = val => { + self.$emit('input', val) + } +} + +const componentChild = { + 'el-button': { + default(h, conf, key) { + return conf[key] + }, + }, + 'el-input': { + prepend(h, conf, key) { + return + }, + append(h, conf, key) { + return + } + }, + 'el-select': { + options(h, conf, key) { + const list = [] + conf.options.forEach(item => { + list.push() + }) + return list + } + }, + 'el-radio-group': { + options(h, conf, key) { + const list = [] + conf.options.forEach(item => { + if (conf.optionType === 'button') list.push({item.label}) + else list.push({item.label}) + }) + return list + } + }, + 'el-checkbox-group': { + options(h, conf, key) { + const list = [] + conf.options.forEach(item => { + if (conf.optionType === 'button') { + list.push({item.label}) + } else { + list.push({item.label}) + } + }) + return list + } + }, + 'el-upload': { + 'list-type': (h, conf, key) => { + const list = [] + if (conf['list-type'] === 'picture-card') { + list.push() + } else { + list.push({conf.buttonText}) + } + if (conf.showTip) { + list.push(
    只能上传不超过 {conf.fileSize}{conf.sizeUnit} 的{conf.accept}文件
    ) + } + return list + } + } +} + +export default { + render(h) { + const dataObject = { + attrs: {}, + props: {}, + on: {}, + style: {} + } + const confClone = JSON.parse(JSON.stringify(this.conf)) + const children = [] + + const childObjs = componentChild[confClone.tag] + if (childObjs) { + Object.keys(childObjs).forEach(key => { + const childFunc = childObjs[key] + if (confClone[key]) { + children.push(childFunc(h, confClone, key)) + } + }) + } + + Object.keys(confClone).forEach(key => { + const val = confClone[key] + if (key === 'vModel') { + vModel(this, dataObject, confClone.defaultValue) + } else if (dataObject[key]) { + dataObject[key] = val + } else if (!isAttr(key)) { + dataObject.props[key] = val + } else { + dataObject.attrs[key] = val + } + }) + return h(this.conf.tag, dataObject, children) + }, + props: ['conf'] +} diff --git a/staffing-ui/src/utils/index.js b/staffing-ui/src/utils/index.js new file mode 100644 index 0000000..cee4a69 --- /dev/null +++ b/staffing-ui/src/utils/index.js @@ -0,0 +1,390 @@ +import { parseTime } from './staffing' + +/** + * 表格时间格式化 + */ +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 = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') + if (!search) { + return {} + } + const obj = {} + const searchArr = search.split('&') + searchArr.forEach(v => { + const index = v.indexOf('=') + if (index !== -1) { + const name = v.substring(0, index) + const val = v.substring(index + 1, v.length) + obj[name] = val + } + }) + return obj +} + +/** + * @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 + // 如果设定为immediate===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, ' ') + } +} + +export function makeMap(str, expectsLowerCase) { + const map = Object.create(null) + const list = str.split(',') + for (let i = 0; i < list.length; i++) { + map[list[i]] = true + } + return expectsLowerCase + ? val => map[val.toLowerCase()] + : val => map[val] +} + +export const exportDefault = 'export default ' + +export const beautifierConf = { + html: { + indent_size: '2', + indent_char: ' ', + max_preserve_newlines: '-1', + preserve_newlines: false, + keep_array_indentation: false, + break_chained_methods: false, + indent_scripts: 'separate', + brace_style: 'end-expand', + space_before_conditional: true, + unescape_strings: false, + jslint_happy: false, + end_with_newline: true, + wrap_line_length: '110', + indent_inner_html: true, + comma_first: false, + e4x: true, + indent_empty_lines: true + }, + js: { + indent_size: '2', + indent_char: ' ', + max_preserve_newlines: '-1', + preserve_newlines: false, + keep_array_indentation: false, + break_chained_methods: false, + indent_scripts: 'normal', + brace_style: 'end-expand', + space_before_conditional: true, + unescape_strings: false, + jslint_happy: true, + end_with_newline: true, + wrap_line_length: '110', + indent_inner_html: true, + comma_first: false, + e4x: true, + indent_empty_lines: true + } +} + +// 首字母大小 +export function titleCase(str) { + return str.replace(/( |^)[a-z]/g, L => L.toUpperCase()) +} + +// 下划转驼峰 +export function camelCase(str) { + return str.replace(/_[a-z]/g, str1 => str1.substr(-1).toUpperCase()) +} + +export function isNumberStr(str) { + return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str) +} + diff --git a/staffing-ui/src/utils/jsencrypt.js b/staffing-ui/src/utils/jsencrypt.js new file mode 100644 index 0000000..78d9523 --- /dev/null +++ b/staffing-ui/src/utils/jsencrypt.js @@ -0,0 +1,30 @@ +import JSEncrypt from 'jsencrypt/bin/jsencrypt.min' + +// 密钥对生成 http://web.chacuo.net/netrsakeypair + +const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' + + 'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==' + +const privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' + + '7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' + + 'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' + + 'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' + + 'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' + + 'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' + + 'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' + + 'UP8iWi1Qw0Y=' + +// 加密 +export function encrypt(txt) { + const encryptor = new JSEncrypt() + encryptor.setPublicKey(publicKey) // 设置公钥 + return encryptor.encrypt(txt) // 对数据进行加密 +} + +// 解密 +export function decrypt(txt) { + const encryptor = new JSEncrypt() + encryptor.setPrivateKey(privateKey) // 设置私钥 + return encryptor.decrypt(txt) // 对数据进行解密 +} + diff --git a/staffing-ui/src/utils/permission.js b/staffing-ui/src/utils/permission.js new file mode 100644 index 0000000..189a716 --- /dev/null +++ b/staffing-ui/src/utils/permission.js @@ -0,0 +1,47 @@ +import store from '@/store' + +/** + * 字符权限校验 + * @param {Array} value 校验值 + * @returns {Boolean} + */ +export function checkPermi(value) { + if (value && value instanceof Array && value.length > 0) { + const permissions = store.getters && store.getters.permissions + const permissionDatas = value + const all_permission = "*:*:*"; + + const hasPermission = permissions.some(permission => { + return all_permission === permission || permissionDatas.includes(permission) + }) + + return hasPermission; + + } else { + console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`) + return false + } +} + +/** + * 角色权限校验 + * @param {Array} value 校验值 + * @returns {Boolean} + */ +export function checkRole(value) { + if (value && value instanceof Array && value.length > 0) { + const roles = store.getters && store.getters.roles + const permissionRoles = value + const super_admin = "admin"; + + const hasRole = roles.some(role => { + return super_admin === role || permissionRoles.includes(role) + }) + + return hasRole; + + } else { + console.error(`need roles! Like checkRole="['admin','editor']"`) + return false + } +} \ No newline at end of file diff --git a/staffing-ui/src/utils/request.js b/staffing-ui/src/utils/request.js new file mode 100644 index 0000000..2709a76 --- /dev/null +++ b/staffing-ui/src/utils/request.js @@ -0,0 +1,152 @@ +import axios from 'axios' +import { Notification, MessageBox, Message, Loading } from 'element-ui' +import store from '@/store' +import { getToken } from '@/utils/auth' +import errorCode from '@/utils/errorCode' +import { tansParams, blobValidate } from "@/utils/staffing"; +import cache from '@/plugins/cache' +import { saveAs } from 'file-saver' + +let downloadLoadingInstance; +// 是否显示重新登录 +export let isRelogin = { show: false }; + +axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' +// 创建axios实例 +const service = axios.create({ + // axios中请求配置有baseURL选项,表示请求URL公共部分 + baseURL: process.env.VUE_APP_BASE_API, + // 超时 + timeout: 10000 +}) + +// request拦截器 +service.interceptors.request.use(config => { + // 是否需要设置 token + const isToken = (config.headers || {}).isToken === false + // 是否需要防止数据重复提交 + const isRepeatSubmit = (config.headers || {}).repeatSubmit === false + if (getToken() && !isToken) { + config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 + } + // get请求映射params参数 + if (config.method === 'get' && config.params) { + let url = config.url + '?' + tansParams(config.params); + url = url.slice(0, -1); + config.params = {}; + config.url = url; + } + if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) { + const requestObj = { + url: config.url, + data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, + time: new Date().getTime() + } + const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小 + const limitSize = 5 * 1024 * 1024; // 限制存放数据5M + if (requestSize >= limitSize) { + console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制,无法进行防重复提交验证。') + return config; + } + const sessionObj = cache.session.getJSON('sessionObj') + if (sessionObj === undefined || sessionObj === null || sessionObj === '') { + cache.session.setJSON('sessionObj', requestObj) + } else { + const s_url = sessionObj.url; // 请求地址 + const s_data = sessionObj.data; // 请求数据 + const s_time = sessionObj.time; // 请求时间 + const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交 + if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) { + const message = '数据正在处理,请勿重复提交'; + console.warn(`[${s_url}]: ` + message) + return Promise.reject(new Error(message)) + } else { + cache.session.setJSON('sessionObj', requestObj) + } + } + } + return config +}, error => { + console.log(error) + Promise.reject(error) +}) + +// 响应拦截器 +service.interceptors.response.use(res => { + // 未设置状态码则默认成功状态 + const code = res.data.code || 200; + // 获取错误信息 + const msg = errorCode[code] || res.data.msg || errorCode['default'] + // 二进制数据则直接返回 + if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') { + return res.data + } + if (code === 401) { + if (!isRelogin.show) { + isRelogin.show = true; + MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => { + isRelogin.show = false; + store.dispatch('LogOut').then(() => { + location.href = '/login'; + }) + }).catch(() => { + isRelogin.show = false; + }); + } + return Promise.reject('无效的会话,或者会话已过期,请重新登录。') + } else if (code === 500) { + Message({ message: msg, type: 'error' }) + return Promise.reject(new Error(msg)) + } else if (code === 601) { + Message({ message: msg, type: 'warning' }) + return Promise.reject('error') + } else if (code !== 200) { + Notification.error({ title: msg }) + return Promise.reject('error') + } else { + return res.data + } + }, + error => { + console.log('err' + error) + let { message } = error; + if (message == "Network Error") { + message = "后端接口连接异常"; + } else if (message.includes("timeout")) { + message = "系统接口请求超时"; + } else if (message.includes("Request failed with status code")) { + message = "系统接口" + message.substr(message.length - 3) + "异常"; + } + Message({ message: message, type: 'error', duration: 5 * 1000 }) + return Promise.reject(error) + } +) + +// 通用下载方法 +export function download(url, params, filename, config) { + downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", }) + return service.post(url, params, { + transformRequest: [(params) => { return tansParams(params) }], + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + responseType: 'blob', + ...config + }).then(async (data) => { + const isBlob = blobValidate(data); + if (isBlob) { + const blob = new Blob([data]) + saveAs(blob, filename) + } else { + const resText = await data.text(); + const rspObj = JSON.parse(resText); + const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] + Message.error(errMsg); + } + downloadLoadingInstance.close(); + }).catch((r) => { + console.error(r) + Message.error('下载文件出现错误,请联系管理员!') + downloadLoadingInstance.close(); + }) +} + +export default service diff --git a/staffing-ui/src/utils/scroll-to.js b/staffing-ui/src/utils/scroll-to.js new file mode 100644 index 0000000..c5d8e04 --- /dev/null +++ b/staffing-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/staffing-ui/src/utils/staffing.js b/staffing-ui/src/utils/staffing.js new file mode 100644 index 0000000..6f1bf3c --- /dev/null +++ b/staffing-ui/src/utils/staffing.js @@ -0,0 +1,233 @@ + + +/** + * 通用js方法封装处理 + * Copyright (c) 2019 staffing + */ + +// 日期格式化 +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) + } else if (typeof time === 'string') { + time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), ''); + } + 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, propName) { + let search = params; + search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {}; + dateRange = Array.isArray(dateRange) ? dateRange : []; + if (typeof (propName) === 'undefined') { + search.params['beginTime'] = dateRange[0]; + search.params['endTime'] = dateRange[1]; + } else { + search.params['begin' + propName] = dateRange[0]; + search.params['end' + propName] = dateRange[1]; + } + return search; +} + +// 回显数据字典 +export function selectDictLabel(datas, value) { + if (value === undefined) { + return ""; + } + var actions = []; + Object.keys(datas).some((key) => { + if (datas[key].value == ('' + value)) { + actions.push(datas[key].label); + return true; + } + }) + if (actions.length === 0) { + actions.push(value); + } + return actions.join(''); +} + +// 回显数据字典(字符串、数组) +export function selectDictLabels(datas, value, separator) { + if (value === undefined || value.length ===0) { + return ""; + } + if (Array.isArray(value)) { + value = value.join(","); + } + var actions = []; + var currentSeparator = undefined === separator ? "," : separator; + var temp = value.split(currentSeparator); + Object.keys(value.split(currentSeparator)).some((val) => { + var match = false; + Object.keys(datas).some((key) => { + if (datas[key].value == ('' + temp[val])) { + actions.push(datas[key].label + currentSeparator); + match = true; + } + }) + if (!match) { + actions.push(temp[val] + currentSeparator); + } + }) + return actions.join('').substring(0, actions.join('').length - 1); +} + +// 字符串格式化(%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 parseStrEmpty(str) { + if (!str || str == "undefined" || str == "null") { + return ""; + } + return str; +} + +// 数据合并 +export function mergeRecursive(source, target) { + for (var p in target) { + try { + if (target[p].constructor == Object) { + source[p] = mergeRecursive(source[p], target[p]); + } else { + source[p] = target[p]; + } + } catch (e) { + source[p] = target[p]; + } + } + return source; +}; + +/** + * 构造树型结构数据 + * @param {*} data 数据源 + * @param {*} id id字段 默认 'id' + * @param {*} parentId 父节点字段 默认 'parentId' + * @param {*} children 孩子节点字段 默认 'children' + */ +export function handleTree(data, id, parentId, children) { + let config = { + id: id || 'id', + parentId: parentId || 'parentId', + childrenList: children || 'children' + }; + + var childrenListMap = {}; + var nodeIds = {}; + var tree = []; + + for (let d of data) { + let parentId = d[config.parentId]; + if (childrenListMap[parentId] == null) { + childrenListMap[parentId] = []; + } + nodeIds[d[config.id]] = d; + childrenListMap[parentId].push(d); + } + + for (let d of data) { + let parentId = d[config.parentId]; + if (nodeIds[parentId] == null) { + tree.push(d); + } + } + + for (let t of tree) { + adaptToChildrenList(t); + } + + function adaptToChildrenList(o) { + if (childrenListMap[o[config.id]] !== null) { + o[config.childrenList] = childrenListMap[o[config.id]]; + } + if (o[config.childrenList]) { + for (let c of o[config.childrenList]) { + adaptToChildrenList(c); + } + } + } + return tree; +} + +/** +* 参数处理 +* @param {*} params 参数 +*/ +export function tansParams(params) { + let result = '' + for (const propName of Object.keys(params)) { + const value = params[propName]; + var part = encodeURIComponent(propName) + "="; + if (value !== null && value !== "" && typeof (value) !== "undefined") { + if (typeof value === 'object') { + for (const key of Object.keys(value)) { + if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') { + let params = propName + '[' + key + ']'; + var subPart = encodeURIComponent(params) + "="; + result += subPart + encodeURIComponent(value[key]) + "&"; + } + } + } else { + result += part + encodeURIComponent(value) + "&"; + } + } + } + return result +} + +// 验证是否为blob格式 +export function blobValidate(data) { + return data.type !== 'application/json' +} diff --git a/staffing-ui/src/utils/validate.js b/staffing-ui/src/utils/validate.js new file mode 100644 index 0000000..57a568e --- /dev/null +++ b/staffing-ui/src/utils/validate.js @@ -0,0 +1,80 @@ +/** + * @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) { + return typeof str === 'string' || str instanceof String; +} + +/** + * @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/staffing-ui/src/views/dashboard/BarChart.vue b/staffing-ui/src/views/dashboard/BarChart.vue new file mode 100644 index 0000000..88e7ef6 --- /dev/null +++ b/staffing-ui/src/views/dashboard/BarChart.vue @@ -0,0 +1,102 @@ + + + diff --git a/staffing-ui/src/views/dashboard/LineChart.vue b/staffing-ui/src/views/dashboard/LineChart.vue new file mode 100644 index 0000000..702ff73 --- /dev/null +++ b/staffing-ui/src/views/dashboard/LineChart.vue @@ -0,0 +1,135 @@ + + + diff --git a/staffing-ui/src/views/dashboard/PanelGroup.vue b/staffing-ui/src/views/dashboard/PanelGroup.vue new file mode 100644 index 0000000..1a1081f --- /dev/null +++ b/staffing-ui/src/views/dashboard/PanelGroup.vue @@ -0,0 +1,181 @@ + + + + + diff --git a/staffing-ui/src/views/dashboard/PieChart.vue b/staffing-ui/src/views/dashboard/PieChart.vue new file mode 100644 index 0000000..63f0d84 --- /dev/null +++ b/staffing-ui/src/views/dashboard/PieChart.vue @@ -0,0 +1,79 @@ + + + diff --git a/staffing-ui/src/views/dashboard/RaddarChart.vue b/staffing-ui/src/views/dashboard/RaddarChart.vue new file mode 100644 index 0000000..312e018 --- /dev/null +++ b/staffing-ui/src/views/dashboard/RaddarChart.vue @@ -0,0 +1,116 @@ + + + diff --git a/staffing-ui/src/views/dashboard/mixins/resize.js b/staffing-ui/src/views/dashboard/mixins/resize.js new file mode 100644 index 0000000..b1e76e9 --- /dev/null +++ b/staffing-ui/src/views/dashboard/mixins/resize.js @@ -0,0 +1,56 @@ +import { debounce } from '@/utils' + +export default { + data() { + return { + $_sidebarElm: null, + $_resizeHandler: null + } + }, + mounted() { + this.initListener() + }, + activated() { + if (!this.$_resizeHandler) { + // avoid duplication init + this.initListener() + } + + // when keep-alive chart activated, auto resize + this.resize() + }, + beforeDestroy() { + this.destroyListener() + }, + deactivated() { + this.destroyListener() + }, + methods: { + // use $_ for mixins properties + // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential + $_sidebarResizeHandler(e) { + if (e.propertyName === 'width') { + this.$_resizeHandler() + } + }, + initListener() { + this.$_resizeHandler = debounce(() => { + this.resize() + }, 100) + window.addEventListener('resize', this.$_resizeHandler) + + this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0] + this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler) + }, + destroyListener() { + window.removeEventListener('resize', this.$_resizeHandler) + this.$_resizeHandler = null + + this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler) + }, + resize() { + const { chart } = this + chart && chart.resize() + } + } +} diff --git a/staffing-ui/src/views/employee/employee/index.vue b/staffing-ui/src/views/employee/employee/index.vue new file mode 100644 index 0000000..1d3512e --- /dev/null +++ b/staffing-ui/src/views/employee/employee/index.vue @@ -0,0 +1,408 @@ + + + + + diff --git a/staffing-ui/src/views/error/401.vue b/staffing-ui/src/views/error/401.vue new file mode 100644 index 0000000..448b6ec --- /dev/null +++ b/staffing-ui/src/views/error/401.vue @@ -0,0 +1,88 @@ + + + + + diff --git a/staffing-ui/src/views/error/404.vue b/staffing-ui/src/views/error/404.vue new file mode 100644 index 0000000..96f075c --- /dev/null +++ b/staffing-ui/src/views/error/404.vue @@ -0,0 +1,233 @@ + + + + + diff --git a/staffing-ui/src/views/fund/fund/index.vue b/staffing-ui/src/views/fund/fund/index.vue new file mode 100644 index 0000000..c208740 --- /dev/null +++ b/staffing-ui/src/views/fund/fund/index.vue @@ -0,0 +1,495 @@ + + + diff --git a/staffing-ui/src/views/index.vue b/staffing-ui/src/views/index.vue new file mode 100644 index 0000000..d5503c9 --- /dev/null +++ b/staffing-ui/src/views/index.vue @@ -0,0 +1,87 @@ + + + + + + diff --git a/staffing-ui/src/views/index_v1.vue b/staffing-ui/src/views/index_v1.vue new file mode 100644 index 0000000..d2d2ec6 --- /dev/null +++ b/staffing-ui/src/views/index_v1.vue @@ -0,0 +1,98 @@ + + + + + diff --git a/staffing-ui/src/views/login.vue b/staffing-ui/src/views/login.vue new file mode 100644 index 0000000..c85635f --- /dev/null +++ b/staffing-ui/src/views/login.vue @@ -0,0 +1,240 @@ + + + + + diff --git a/staffing-ui/src/views/monitor/cache/index.vue b/staffing-ui/src/views/monitor/cache/index.vue new file mode 100644 index 0000000..8d2f378 --- /dev/null +++ b/staffing-ui/src/views/monitor/cache/index.vue @@ -0,0 +1,148 @@ + + + diff --git a/staffing-ui/src/views/monitor/cache/list.vue b/staffing-ui/src/views/monitor/cache/list.vue new file mode 100644 index 0000000..29a7c74 --- /dev/null +++ b/staffing-ui/src/views/monitor/cache/list.vue @@ -0,0 +1,241 @@ + + + diff --git a/staffing-ui/src/views/monitor/druid/index.vue b/staffing-ui/src/views/monitor/druid/index.vue new file mode 100644 index 0000000..c6ad585 --- /dev/null +++ b/staffing-ui/src/views/monitor/druid/index.vue @@ -0,0 +1,15 @@ + + diff --git a/staffing-ui/src/views/monitor/job/index.vue b/staffing-ui/src/views/monitor/job/index.vue new file mode 100644 index 0000000..83d0456 --- /dev/null +++ b/staffing-ui/src/views/monitor/job/index.vue @@ -0,0 +1,513 @@ + + + diff --git a/staffing-ui/src/views/monitor/job/log.vue b/staffing-ui/src/views/monitor/job/log.vue new file mode 100644 index 0000000..60bee1d --- /dev/null +++ b/staffing-ui/src/views/monitor/job/log.vue @@ -0,0 +1,295 @@ + + + diff --git a/staffing-ui/src/views/monitor/logininfor/index.vue b/staffing-ui/src/views/monitor/logininfor/index.vue new file mode 100644 index 0000000..d6af834 --- /dev/null +++ b/staffing-ui/src/views/monitor/logininfor/index.vue @@ -0,0 +1,246 @@ + + + + diff --git a/staffing-ui/src/views/monitor/online/index.vue b/staffing-ui/src/views/monitor/online/index.vue new file mode 100644 index 0000000..ad613c9 --- /dev/null +++ b/staffing-ui/src/views/monitor/online/index.vue @@ -0,0 +1,122 @@ + + + + diff --git a/staffing-ui/src/views/monitor/operlog/index.vue b/staffing-ui/src/views/monitor/operlog/index.vue new file mode 100644 index 0000000..4a1828f --- /dev/null +++ b/staffing-ui/src/views/monitor/operlog/index.vue @@ -0,0 +1,323 @@ + + + + diff --git a/staffing-ui/src/views/monitor/server/index.vue b/staffing-ui/src/views/monitor/server/index.vue new file mode 100644 index 0000000..15ffc9a --- /dev/null +++ b/staffing-ui/src/views/monitor/server/index.vue @@ -0,0 +1,207 @@ + + + diff --git a/staffing-ui/src/views/redirect.vue b/staffing-ui/src/views/redirect.vue new file mode 100644 index 0000000..db4c1d6 --- /dev/null +++ b/staffing-ui/src/views/redirect.vue @@ -0,0 +1,12 @@ + diff --git a/staffing-ui/src/views/register.vue b/staffing-ui/src/views/register.vue new file mode 100644 index 0000000..6cf57cf --- /dev/null +++ b/staffing-ui/src/views/register.vue @@ -0,0 +1,210 @@ + + + + + diff --git a/staffing-ui/src/views/system/config/index.vue b/staffing-ui/src/views/system/config/index.vue new file mode 100644 index 0000000..3ab81fc --- /dev/null +++ b/staffing-ui/src/views/system/config/index.vue @@ -0,0 +1,343 @@ + + + diff --git a/staffing-ui/src/views/system/dept/index.vue b/staffing-ui/src/views/system/dept/index.vue new file mode 100644 index 0000000..e502b4e --- /dev/null +++ b/staffing-ui/src/views/system/dept/index.vue @@ -0,0 +1,340 @@ + + + diff --git a/staffing-ui/src/views/system/dict/data.vue b/staffing-ui/src/views/system/dict/data.vue new file mode 100644 index 0000000..3befe4a --- /dev/null +++ b/staffing-ui/src/views/system/dict/data.vue @@ -0,0 +1,402 @@ + + + \ No newline at end of file diff --git a/staffing-ui/src/views/system/dict/index.vue b/staffing-ui/src/views/system/dict/index.vue new file mode 100644 index 0000000..6ca5457 --- /dev/null +++ b/staffing-ui/src/views/system/dict/index.vue @@ -0,0 +1,347 @@ + + + \ No newline at end of file diff --git a/staffing-ui/src/views/system/menu/index.vue b/staffing-ui/src/views/system/menu/index.vue new file mode 100644 index 0000000..c703fa0 --- /dev/null +++ b/staffing-ui/src/views/system/menu/index.vue @@ -0,0 +1,452 @@ + + + diff --git a/staffing-ui/src/views/system/notice/index.vue b/staffing-ui/src/views/system/notice/index.vue new file mode 100644 index 0000000..7982b54 --- /dev/null +++ b/staffing-ui/src/views/system/notice/index.vue @@ -0,0 +1,312 @@ + + + diff --git a/staffing-ui/src/views/system/post/index.vue b/staffing-ui/src/views/system/post/index.vue new file mode 100644 index 0000000..444bf63 --- /dev/null +++ b/staffing-ui/src/views/system/post/index.vue @@ -0,0 +1,309 @@ + + + diff --git a/staffing-ui/src/views/system/role/authUser.vue b/staffing-ui/src/views/system/role/authUser.vue new file mode 100644 index 0000000..147aa33 --- /dev/null +++ b/staffing-ui/src/views/system/role/authUser.vue @@ -0,0 +1,199 @@ + + + \ No newline at end of file diff --git a/staffing-ui/src/views/system/role/index.vue b/staffing-ui/src/views/system/role/index.vue new file mode 100644 index 0000000..fb3b5ef --- /dev/null +++ b/staffing-ui/src/views/system/role/index.vue @@ -0,0 +1,605 @@ + + + \ No newline at end of file diff --git a/staffing-ui/src/views/system/role/selectUser.vue b/staffing-ui/src/views/system/role/selectUser.vue new file mode 100644 index 0000000..10a5365 --- /dev/null +++ b/staffing-ui/src/views/system/role/selectUser.vue @@ -0,0 +1,136 @@ + + + diff --git a/staffing-ui/src/views/system/user/authRole.vue b/staffing-ui/src/views/system/user/authRole.vue new file mode 100644 index 0000000..943710e --- /dev/null +++ b/staffing-ui/src/views/system/user/authRole.vue @@ -0,0 +1,117 @@ + + + \ No newline at end of file diff --git a/staffing-ui/src/views/system/user/index.vue b/staffing-ui/src/views/system/user/index.vue new file mode 100644 index 0000000..6b2a0aa --- /dev/null +++ b/staffing-ui/src/views/system/user/index.vue @@ -0,0 +1,676 @@ + + + \ No newline at end of file diff --git a/staffing-ui/src/views/system/user/profile/index.vue b/staffing-ui/src/views/system/user/profile/index.vue new file mode 100644 index 0000000..529c564 --- /dev/null +++ b/staffing-ui/src/views/system/user/profile/index.vue @@ -0,0 +1,91 @@ + + + diff --git a/staffing-ui/src/views/system/user/profile/resetPwd.vue b/staffing-ui/src/views/system/user/profile/resetPwd.vue new file mode 100644 index 0000000..f329e6e --- /dev/null +++ b/staffing-ui/src/views/system/user/profile/resetPwd.vue @@ -0,0 +1,69 @@ + + + diff --git a/staffing-ui/src/views/system/user/profile/userAvatar.vue b/staffing-ui/src/views/system/user/profile/userAvatar.vue new file mode 100644 index 0000000..cbf3ca1 --- /dev/null +++ b/staffing-ui/src/views/system/user/profile/userAvatar.vue @@ -0,0 +1,184 @@ + + + + diff --git a/staffing-ui/src/views/system/user/profile/userInfo.vue b/staffing-ui/src/views/system/user/profile/userInfo.vue new file mode 100644 index 0000000..c970dc9 --- /dev/null +++ b/staffing-ui/src/views/system/user/profile/userInfo.vue @@ -0,0 +1,88 @@ + + + diff --git a/staffing-ui/src/views/task/task/index.vue b/staffing-ui/src/views/task/task/index.vue new file mode 100644 index 0000000..5f5c763 --- /dev/null +++ b/staffing-ui/src/views/task/task/index.vue @@ -0,0 +1,832 @@ + + + + + + diff --git a/staffing-ui/src/views/taskSign/sign/index.vue b/staffing-ui/src/views/taskSign/sign/index.vue new file mode 100644 index 0000000..e72c00d --- /dev/null +++ b/staffing-ui/src/views/taskSign/sign/index.vue @@ -0,0 +1,311 @@ + + + diff --git a/staffing-ui/src/views/tool/build/CodeTypeDialog.vue b/staffing-ui/src/views/tool/build/CodeTypeDialog.vue new file mode 100644 index 0000000..b5c2e2e --- /dev/null +++ b/staffing-ui/src/views/tool/build/CodeTypeDialog.vue @@ -0,0 +1,106 @@ + + diff --git a/staffing-ui/src/views/tool/build/DraggableItem.vue b/staffing-ui/src/views/tool/build/DraggableItem.vue new file mode 100644 index 0000000..e881778 --- /dev/null +++ b/staffing-ui/src/views/tool/build/DraggableItem.vue @@ -0,0 +1,100 @@ + diff --git a/staffing-ui/src/views/tool/build/IconsDialog.vue b/staffing-ui/src/views/tool/build/IconsDialog.vue new file mode 100644 index 0000000..958be50 --- /dev/null +++ b/staffing-ui/src/views/tool/build/IconsDialog.vue @@ -0,0 +1,123 @@ + + + diff --git a/staffing-ui/src/views/tool/build/RightPanel.vue b/staffing-ui/src/views/tool/build/RightPanel.vue new file mode 100644 index 0000000..c2760eb --- /dev/null +++ b/staffing-ui/src/views/tool/build/RightPanel.vue @@ -0,0 +1,946 @@ + + + + + diff --git a/staffing-ui/src/views/tool/build/TreeNodeDialog.vue b/staffing-ui/src/views/tool/build/TreeNodeDialog.vue new file mode 100644 index 0000000..fa7f0b2 --- /dev/null +++ b/staffing-ui/src/views/tool/build/TreeNodeDialog.vue @@ -0,0 +1,149 @@ + + diff --git a/staffing-ui/src/views/tool/build/index.vue b/staffing-ui/src/views/tool/build/index.vue new file mode 100644 index 0000000..2bd298b --- /dev/null +++ b/staffing-ui/src/views/tool/build/index.vue @@ -0,0 +1,768 @@ + + + + + diff --git a/staffing-ui/src/views/tool/gen/basicInfoForm.vue b/staffing-ui/src/views/tool/gen/basicInfoForm.vue new file mode 100644 index 0000000..7029529 --- /dev/null +++ b/staffing-ui/src/views/tool/gen/basicInfoForm.vue @@ -0,0 +1,60 @@ + + + diff --git a/staffing-ui/src/views/tool/gen/createTable.vue b/staffing-ui/src/views/tool/gen/createTable.vue new file mode 100644 index 0000000..f914b5d --- /dev/null +++ b/staffing-ui/src/views/tool/gen/createTable.vue @@ -0,0 +1,45 @@ + + + diff --git a/staffing-ui/src/views/tool/gen/editTable.vue b/staffing-ui/src/views/tool/gen/editTable.vue new file mode 100644 index 0000000..951497a --- /dev/null +++ b/staffing-ui/src/views/tool/gen/editTable.vue @@ -0,0 +1,234 @@ + + + diff --git a/staffing-ui/src/views/tool/gen/genInfoForm.vue b/staffing-ui/src/views/tool/gen/genInfoForm.vue new file mode 100644 index 0000000..b216d93 --- /dev/null +++ b/staffing-ui/src/views/tool/gen/genInfoForm.vue @@ -0,0 +1,312 @@ + + + diff --git a/staffing-ui/src/views/tool/gen/importTable.vue b/staffing-ui/src/views/tool/gen/importTable.vue new file mode 100644 index 0000000..3ea9532 --- /dev/null +++ b/staffing-ui/src/views/tool/gen/importTable.vue @@ -0,0 +1,120 @@ + + + diff --git a/staffing-ui/src/views/tool/gen/index.vue b/staffing-ui/src/views/tool/gen/index.vue new file mode 100644 index 0000000..8116e41 --- /dev/null +++ b/staffing-ui/src/views/tool/gen/index.vue @@ -0,0 +1,354 @@ + + + diff --git a/staffing-ui/src/views/tool/swagger/index.vue b/staffing-ui/src/views/tool/swagger/index.vue new file mode 100644 index 0000000..b8becc6 --- /dev/null +++ b/staffing-ui/src/views/tool/swagger/index.vue @@ -0,0 +1,15 @@ + + diff --git a/staffing-ui/vue.config.js b/staffing-ui/vue.config.js new file mode 100644 index 0000000..c74d366 --- /dev/null +++ b/staffing-ui/vue.config.js @@ -0,0 +1,130 @@ +'use strict' +const path = require('path') + +function resolve(dir) { + return path.join(__dirname, dir) +} + +const CompressionPlugin = require('compression-webpack-plugin') + +const name = process.env.VUE_APP_TITLE || 'xx管理系统' // 网页标题 + +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 = { + // 部署生产环境和开发环境下的URL。 + // 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上 + // 例如 https://www.staffing.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.staffing.vip/admin/,则设置 baseUrl 为 /admin/。 + publicPath: process.env.NODE_ENV === "production" ? "/" : "/", + // 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist) + outputDir: 'dist', + // 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下) + assetsDir: 'static', + // 是否开启eslint保存检测,有效值: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, + open: true, + 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 + }, + css: { + loaderOptions: { + sass: { + sassOptions: { outputStyle: "expanded" } + } + } + }, + configureWebpack: { + name: name, + resolve: { + alias: { + '@': resolve('src') + } + }, + plugins: [ + // http://doc.staffing.vip/staffing-vue/other/faq.html#使用gzip解压缩静态文件 + new CompressionPlugin({ + cache: false, // 不启用文件缓存 + test: /\.(js|css|html|jpe?g|png|gif|svg)?$/i, // 压缩文件格式 + filename: '[path][base].gz[query]', // 压缩后的文件名 + algorithm: 'gzip', // 使用gzip压缩 + minRatio: 0.8, // 压缩比例,小于 80% 的文件不会被压缩 + deleteOriginalAssets: false // 压缩后删除原文件 + }) + ], + }, + 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() + + 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 + test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm + priority: 20 // the weight needs to be larger than libs and app or it will be packaged into libs or app + }, + 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/wx-pay/pom.xml b/wx-pay/pom.xml new file mode 100644 index 0000000..1581c76 --- /dev/null +++ b/wx-pay/pom.xml @@ -0,0 +1,101 @@ + + + + staffing + com.staffing + 3.8.8 + + 4.0.0 + + wx-pay + + + com.google.code.gson + gson + 2.9.1 + + + + com.squareup.okhttp3 + okhttp + 4.10.0 + + + + org.slf4j + slf4j-api + 1.7.36 + + + + com.staffing + staffing-common + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/AbstractRSAConfig.java b/wx-pay/src/main/java/com/wechat/pay/java/core/AbstractRSAConfig.java new file mode 100644 index 0000000..76d8ec0 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/AbstractRSAConfig.java @@ -0,0 +1,97 @@ +package com.wechat.pay.java.core; + +import com.wechat.pay.java.core.auth.Credential; +import com.wechat.pay.java.core.auth.Validator; +import com.wechat.pay.java.core.auth.WechatPay2Credential; +import com.wechat.pay.java.core.auth.WechatPay2Validator; +import com.wechat.pay.java.core.certificate.CertificateProvider; +import com.wechat.pay.java.core.cipher.*; +import com.wechat.pay.java.core.util.PemUtil; + +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.cert.X509Certificate; + +/** RSAConfig抽象类 */ +public abstract class AbstractRSAConfig implements Config { + + /** 使用微信支付平台证书验签 */ + protected AbstractRSAConfig( + String merchantId, + PrivateKey privateKey, + String merchantSerialNumber, + CertificateProvider certificateProvider) { + this.merchantId = merchantId; + this.privateKey = privateKey; + this.merchantSerialNumber = merchantSerialNumber; + this.certificateProvider = certificateProvider; + this.publicKey = null; + this.publicKeyId = null; + } + + /** 使用微信支付公钥验签 */ + protected AbstractRSAConfig( + String merchantId, + PrivateKey privateKey, + String merchantSerialNumber, + PublicKey publicKey, + String publicKeyId) { + this.merchantId = merchantId; + this.privateKey = privateKey; + this.merchantSerialNumber = merchantSerialNumber; + this.certificateProvider = null; + this.publicKey = publicKey; + this.publicKeyId = publicKeyId; + } + + /** 商户号 */ + private final String merchantId; + + /** 商户私钥 */ + private final PrivateKey privateKey; + + /** 商户证书序列号 */ + private final String merchantSerialNumber; + + /** 微信支付平台证书Provider */ + private final CertificateProvider certificateProvider; + + /** 微信支付平台公钥 */ + private final PublicKey publicKey; + + /** 微信支付平台公钥Id */ + private final String publicKeyId; + + @Override + public PrivacyEncryptor createEncryptor() { + if (publicKey != null) { + return new RSAPrivacyEncryptor(publicKey, publicKeyId); + } + X509Certificate certificate = certificateProvider.getAvailableCertificate(); + return new RSAPrivacyEncryptor( + certificate.getPublicKey(), PemUtil.getSerialNumber(certificate)); + } + + @Override + public PrivacyDecryptor createDecryptor() { + return new RSAPrivacyDecryptor(privateKey); + } + + @Override + public Credential createCredential() { + return new WechatPay2Credential(merchantId, createSigner()); + } + + @Override + public Validator createValidator() { + if (publicKey != null) { + return new WechatPay2Validator(new RSAVerifier(publicKey, publicKeyId)); + } + return new WechatPay2Validator(new RSAVerifier(certificateProvider)); + } + + @Override + public Signer createSigner() { + return new RSASigner(merchantSerialNumber, privateKey); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/AbstractRSAConfigBuilder.java b/wx-pay/src/main/java/com/wechat/pay/java/core/AbstractRSAConfigBuilder.java new file mode 100644 index 0000000..2b9678e --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/AbstractRSAConfigBuilder.java @@ -0,0 +1,40 @@ +package com.wechat.pay.java.core; + +import com.wechat.pay.java.core.util.PemUtil; + +import java.security.PrivateKey; + +/** RSAConfigBuilder抽象类 */ +public abstract class AbstractRSAConfigBuilder> { + + protected String merchantId; + protected PrivateKey privateKey; + protected String merchantSerialNumber; + + protected abstract T self(); + + public T merchantId(String merchantId) { + this.merchantId = merchantId; + return self(); + } + + public T privateKey(String privateKey) { + this.privateKey = PemUtil.loadPrivateKeyFromString(privateKey); + return self(); + } + + public T privateKey(PrivateKey privateKey) { + this.privateKey = privateKey; + return self(); + } + + public T privateKeyFromPath(String keyPath) { + this.privateKey = PemUtil.loadPrivateKeyFromPath(keyPath); + return self(); + } + + public T merchantSerialNumber(String merchantSerialNumber) { + this.merchantSerialNumber = merchantSerialNumber; + return self(); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/Config.java b/wx-pay/src/main/java/com/wechat/pay/java/core/Config.java new file mode 100644 index 0000000..21c612f --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/Config.java @@ -0,0 +1,46 @@ +package com.wechat.pay.java.core; + +import com.wechat.pay.java.core.auth.Credential; +import com.wechat.pay.java.core.auth.Validator; +import com.wechat.pay.java.core.cipher.PrivacyDecryptor; +import com.wechat.pay.java.core.cipher.PrivacyEncryptor; +import com.wechat.pay.java.core.cipher.Signer; + +/** 调用微信支付服务的所需配置 */ +public interface Config { + + /** + * 创建敏感信息加密器 + * + * @return 敏感信息加密器 + */ + PrivacyEncryptor createEncryptor(); + + /** + * 创建敏感信息解密器 + * + * @return 敏感信息解密器 + */ + PrivacyDecryptor createDecryptor(); + + /** + * 创建认证凭据生成器 + * + * @return 认证凭据生成器 + */ + Credential createCredential(); + + /** + * 创建请求验证器 + * + * @return 请求验证器 + */ + Validator createValidator(); + + /** + * 创建签名器 + * + * @return 签名器 + */ + Signer createSigner(); +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/RSAAutoCertificateConfig.java b/wx-pay/src/main/java/com/wechat/pay/java/core/RSAAutoCertificateConfig.java new file mode 100644 index 0000000..18a8224 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/RSAAutoCertificateConfig.java @@ -0,0 +1,123 @@ +package com.wechat.pay.java.core; + +import com.wechat.pay.java.core.certificate.CertificateProvider; +import com.wechat.pay.java.core.certificate.RSAAutoCertificateProvider; +import com.wechat.pay.java.core.cipher.*; +import com.wechat.pay.java.core.http.AbstractHttpClientBuilder; +import com.wechat.pay.java.core.http.HttpClient; +import com.wechat.pay.java.core.notification.NotificationConfig; + +import java.nio.charset.StandardCharsets; + +import static com.wechat.pay.java.core.notification.Constant.AES_CIPHER_ALGORITHM; +import static com.wechat.pay.java.core.notification.Constant.RSA_SIGN_TYPE; +import static java.util.Objects.requireNonNull; + +/** + * 具有自动下载并更新平台证书能力的RSA配置类。 每次构造,都会立即使用传入的商户参数下载微信支付平台证书。 如果下载成功,SDK 会将商户参数注册或更新至 + * AutoCertificateService。若下载失败,将会抛出异常。 为了提高性能,建议将配置类作为全局变量,减少不必要的证书下载,避免资源浪费 + */ +public final class RSAAutoCertificateConfig extends AbstractRSAConfig + implements NotificationConfig { + + private final CertificateProvider certificateProvider; + private final AeadCipher aeadCipher; + + private RSAAutoCertificateConfig(Builder builder) { + super( + builder.merchantId, + builder.privateKey, + builder.merchantSerialNumber, + builder.certificateProvider); + this.certificateProvider = builder.certificateProvider; + this.aeadCipher = new AeadAesCipher(builder.apiV3Key); + } + + /** + * 获取签名类型 + * + * @return 签名类型 + */ + @Override + public String getSignType() { + return RSA_SIGN_TYPE; + } + + /** + * 获取认证加解密器类型 + * + * @return 认证加解密器类型 + */ + @Override + public String getCipherType() { + return AES_CIPHER_ALGORITHM; + } + + /** + * 创建验签器 + * + * @return 验签器 + */ + @Override + public Verifier createVerifier() { + return new RSAVerifier(certificateProvider); + } + + /** + * 创建认证加解密器 + * + * @return 认证加解密器 + */ + @Override + public AeadCipher createAeadCipher() { + return aeadCipher; + } + + public static class Builder extends AbstractRSAConfigBuilder { + protected HttpClient httpClient; + protected byte[] apiV3Key; + protected CertificateProvider certificateProvider; + protected AbstractHttpClientBuilder httpClientBuilder; + + public Builder apiV3Key(String apiV3Key) { + this.apiV3Key = apiV3Key.getBytes(StandardCharsets.UTF_8); + return self(); + } + + public Builder httpClient(HttpClient httpClient) { + this.httpClient = httpClient; + return this; + } + + public Builder httpClientBuilder(AbstractHttpClientBuilder builder) { + httpClientBuilder = builder; + return this; + } + + @Override + protected Builder self() { + return this; + } + + public RSAAutoCertificateConfig build() { + RSAAutoCertificateProvider.Builder providerBuilder = + new RSAAutoCertificateProvider.Builder() + .merchantId(requireNonNull(merchantId)) + .apiV3Key(requireNonNull(apiV3Key)) + .privateKey(requireNonNull(privateKey)) + .merchantSerialNumber(requireNonNull(merchantSerialNumber)); + + if (httpClient != null) { + providerBuilder.httpClient(httpClient); + } + + if (httpClientBuilder != null) { + providerBuilder.httpClientBuilder(httpClientBuilder); + } + + certificateProvider = providerBuilder.build(); + + return new RSAAutoCertificateConfig(this); + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/RSAConfig.java b/wx-pay/src/main/java/com/wechat/pay/java/core/RSAConfig.java new file mode 100644 index 0000000..b54e93d --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/RSAConfig.java @@ -0,0 +1,64 @@ +package com.wechat.pay.java.core; + +import com.wechat.pay.java.core.certificate.CertificateProvider; +import com.wechat.pay.java.core.certificate.InMemoryCertificateProvider; +import com.wechat.pay.java.core.util.PemUtil; + +import java.security.PrivateKey; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; + +import static java.util.Objects.requireNonNull; + +/** 调用微信支付服务需要的RSA相关配置 */ +public final class RSAConfig extends AbstractRSAConfig { + + private RSAConfig( + String merchantId, + PrivateKey privateKey, + String merchantSerialNumber, + CertificateProvider certificateProvider) { + super(merchantId, privateKey, merchantSerialNumber, certificateProvider); + } + + public static class Builder extends AbstractRSAConfigBuilder { + + private List wechatPayCertificates; + + @Override + protected Builder self() { + return this; + } + + public Builder wechatPayCertificates(String... wechatPayCertificates) { + this.wechatPayCertificates = new ArrayList<>(); + for (String certificate : wechatPayCertificates) { + X509Certificate x509Certificate = PemUtil.loadX509FromString(certificate); + if (x509Certificate != null) { + this.wechatPayCertificates.add(x509Certificate); + } + } + return this; + } + + public Builder wechatPayCertificatesFromPath(String... certPaths) { + this.wechatPayCertificates = new ArrayList<>(); + for (String certPath : certPaths) { + X509Certificate x509Certificate = PemUtil.loadX509FromPath(certPath); + if (x509Certificate != null) { + this.wechatPayCertificates.add(x509Certificate); + } + } + return this; + } + + public RSAConfig build() { + return new RSAConfig( + requireNonNull(merchantId), + requireNonNull(privateKey), + requireNonNull(merchantSerialNumber), + new InMemoryCertificateProvider(requireNonNull(wechatPayCertificates))); + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/RSAPublicKeyConfig.java b/wx-pay/src/main/java/com/wechat/pay/java/core/RSAPublicKeyConfig.java new file mode 100644 index 0000000..0895c2f --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/RSAPublicKeyConfig.java @@ -0,0 +1,121 @@ +package com.wechat.pay.java.core; + +import com.wechat.pay.java.core.cipher.AeadAesCipher; +import com.wechat.pay.java.core.cipher.AeadCipher; +import com.wechat.pay.java.core.cipher.RSAVerifier; +import com.wechat.pay.java.core.cipher.Verifier; +import com.wechat.pay.java.core.notification.NotificationConfig; +import com.wechat.pay.java.core.util.PemUtil; + +import java.nio.charset.StandardCharsets; +import java.security.PublicKey; + +import static com.wechat.pay.java.core.notification.Constant.AES_CIPHER_ALGORITHM; +import static com.wechat.pay.java.core.notification.Constant.RSA_SIGN_TYPE; +import static java.util.Objects.requireNonNull; + +/** 使用微信支付平台公钥的RSA配置类。 每次构造都要求传入平台公钥以及平台公钥id,如果使用平台证书建议用RSAAutoCertificateConfig类 */ +public final class RSAPublicKeyConfig extends AbstractRSAConfig implements NotificationConfig { + + private final PublicKey publicKey; + private final AeadCipher aeadCipher; + private final String publicKeyId; + + private RSAPublicKeyConfig(Builder builder) { + super( + builder.merchantId, + builder.privateKey, + builder.merchantSerialNumber, + builder.publicKey, + builder.publicKeyId); + this.publicKey = builder.publicKey; + this.publicKeyId = builder.publicKeyId; + this.aeadCipher = new AeadAesCipher(builder.apiV3Key); + } + + /** + * 获取签名类型 + * + * @return 签名类型 + */ + @Override + public String getSignType() { + return RSA_SIGN_TYPE; + } + + /** + * 获取认证加解密器类型 + * + * @return 认证加解密器类型 + */ + @Override + public String getCipherType() { + return AES_CIPHER_ALGORITHM; + } + + /** + * 创建验签器 + * + * @return 验签器 + */ + @Override + public Verifier createVerifier() { + return new RSAVerifier(publicKey, publicKeyId); + } + + /** + * 创建认证加解密器 + * + * @return 认证加解密器 + */ + @Override + public AeadCipher createAeadCipher() { + return aeadCipher; + } + + public static class Builder extends AbstractRSAConfigBuilder { + protected byte[] apiV3Key; + protected PublicKey publicKey; + protected String publicKeyId; + + public Builder apiV3Key(String apiV3Key) { + this.apiV3Key = apiV3Key.getBytes(StandardCharsets.UTF_8); + return self(); + } + + public Builder publicKey(String publicKey) { + this.publicKey = PemUtil.loadPublicKeyFromString(publicKey); + return self(); + } + + public Builder publicKey(PublicKey publicKey) { + this.publicKey = publicKey; + return self(); + } + + public Builder publicKeyFromPath(String publicKeyPath) { + this.publicKey = PemUtil.loadPublicKeyFromPath(publicKeyPath); + return self(); + } + + public Builder publicKeyId(String publicKeyId) { + this.publicKeyId = publicKeyId; + return self(); + } + + @Override + protected Builder self() { + return this; + } + + public RSAPublicKeyConfig build() { + requireNonNull(merchantId); + requireNonNull(publicKey); + requireNonNull(publicKeyId); + requireNonNull(privateKey); + requireNonNull(merchantSerialNumber); + + return new RSAPublicKeyConfig(this); + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/auth/Credential.java b/wx-pay/src/main/java/com/wechat/pay/java/core/auth/Credential.java new file mode 100644 index 0000000..46322ab --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/auth/Credential.java @@ -0,0 +1,31 @@ +package com.wechat.pay.java.core.auth; + +import java.net.URI; + +/** 认证凭据生成器 */ +public interface Credential { + + /** + * 获取认证类型 + * + * @return 认证类型 + */ + String getSchema(); + + /** + * 获取商户号 + * + * @return 商户号 + */ + String getMerchantId(); + + /** + * 获取认证信息 + * + * @param uri 请求uri + * @param httpMethod HTTP方法,GET、POST等 + * @param signBody 用于签名的请求体 + * @return 认证信息 + */ + String getAuthorization(URI uri, String httpMethod, String signBody); +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/auth/Validator.java b/wx-pay/src/main/java/com/wechat/pay/java/core/auth/Validator.java new file mode 100644 index 0000000..60d9cc3 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/auth/Validator.java @@ -0,0 +1,17 @@ +package com.wechat.pay.java.core.auth; + +import com.wechat.pay.java.core.http.HttpHeaders; + +/** 验证器 */ +public interface Validator { + + /** + * 验证返回是否合法 + * + * @param responseHeaders HTTP返回头 + * @param body HTTP返回体 + * @param 返回对象类型 + * @return 返回是否合法 + */ + boolean validate(HttpHeaders responseHeaders, String body); +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/auth/WechatPay2Credential.java b/wx-pay/src/main/java/com/wechat/pay/java/core/auth/WechatPay2Credential.java new file mode 100644 index 0000000..f56bc54 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/auth/WechatPay2Credential.java @@ -0,0 +1,89 @@ +package com.wechat.pay.java.core.auth; + +import com.wechat.pay.java.core.cipher.SignatureResult; +import com.wechat.pay.java.core.cipher.Signer; +import com.wechat.pay.java.core.util.NonceUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.URI; +import java.time.Instant; + +import static java.util.Objects.requireNonNull; + +/** 微信支付认证凭据生成器 */ +public final class WechatPay2Credential implements Credential { + + private static final Logger logger = LoggerFactory.getLogger(WechatPay2Credential.class); + + private static final int NONCE_LENGTH = 32; + public static final String SCHEMA_PREFIX = "WECHATPAY2-"; + private final String merchantId; + private final Signer signer; + + public WechatPay2Credential(String merchantId, Signer signer) { + this.merchantId = requireNonNull(merchantId); + this.signer = requireNonNull(signer); + } + + @Override + public String getMerchantId() { + return merchantId; + } + + @Override + public String getSchema() { + return SCHEMA_PREFIX + signer.getAlgorithm(); + } + + @Override + public String getAuthorization(URI uri, String httpMethod, String signBody) { + requireNonNull(uri); + requireNonNull(httpMethod); + return getSchema() + " " + getToken(uri, httpMethod, signBody); + } + + private String getToken(URI uri, String httpMethod, String signBody) { + String nonceStr = NonceUtil.createNonce(NONCE_LENGTH); + long timestamp = Instant.now().getEpochSecond(); + String message = buildMessage(nonceStr, timestamp, uri, httpMethod, signBody); + logger.debug("authorization message[{}]", message); + SignatureResult signature = signer.sign(message); + String token = + "mchid=\"" + + getMerchantId() + + "\"," + + "nonce_str=\"" + + nonceStr + + "\"," + + "timestamp=\"" + + timestamp + + "\"," + + "serial_no=\"" + + signature.getCertificateSerialNumber() + + "\"," + + "signature=\"" + + signature.getSign() + + "\""; + logger.debug("The generated request signature information is[{}]", token); + return token; + } + + private String buildMessage( + String nonce, long timestamp, URI uri, String httpMethod, String signBody) { + String canonicalUrl = uri.getRawPath(); + if (uri.getQuery() != null) { + canonicalUrl += "?" + uri.getRawQuery(); + } + return httpMethod + + "\n" + + canonicalUrl + + "\n" + + timestamp + + "\n" + + nonce + + "\n" + + (signBody == null ? "" : signBody) + + "\n"; + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/auth/WechatPay2Validator.java b/wx-pay/src/main/java/com/wechat/pay/java/core/auth/WechatPay2Validator.java new file mode 100644 index 0000000..e7c19ee --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/auth/WechatPay2Validator.java @@ -0,0 +1,60 @@ +package com.wechat.pay.java.core.auth; + +import com.wechat.pay.java.core.cipher.Verifier; +import com.wechat.pay.java.core.http.HttpHeaders; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.DateTimeException; +import java.time.Duration; +import java.time.Instant; + +import static com.wechat.pay.java.core.http.Constant.*; +import static java.util.Objects.requireNonNull; + +/** 微信支付返回验证器 */ +public final class WechatPay2Validator implements Validator { + + private static final Logger logger = LoggerFactory.getLogger(WechatPay2Validator.class); + private static final int RESPONSE_EXPIRED_MINUTES = 5; + private final Verifier verifier; + + public WechatPay2Validator(Verifier verifier) { + this.verifier = requireNonNull(verifier); + } + + @Override + public boolean validate(HttpHeaders responseHeaders, String responseBody) { + String timestamp = responseHeaders.getHeader(WECHAT_PAY_TIMESTAMP); + try { + Instant responseTime = Instant.ofEpochSecond(Long.parseLong(timestamp)); + // 拒绝过期请求 + if (Duration.between(responseTime, Instant.now()).abs().toMinutes() + >= RESPONSE_EXPIRED_MINUTES) { + throw new IllegalArgumentException( + String.format( + "Validate http response,timestamp[%s] of httpResponse is expires, " + + "request-id[%s]", + timestamp, responseHeaders.getHeader(REQUEST_ID))); + } + } catch (DateTimeException | NumberFormatException e) { + throw new IllegalArgumentException( + String.format( + "Validate http response,timestamp[%s] of httpResponse is invalid, request-id[%s]", + timestamp, responseHeaders.getHeader(REQUEST_ID))); + } + String message = + timestamp + + "\n" + + responseHeaders.getHeader(WECHAT_PAY_NONCE) + + "\n" + + (responseBody == null ? "" : responseBody) + + "\n"; + logger.debug("Message for verifying signatures is[{}]", message); + String serialNumber = responseHeaders.getHeader(WECHAT_PAY_SERIAL); + logger.debug("SerialNumber for verifying signatures is[{}]", serialNumber); + String signature = responseHeaders.getHeader(WECHAT_PAY_SIGNATURE); + logger.debug("Signature for verifying signatures is[{}]", signature); + return verifier.verify(serialNumber, message, signature); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/AutoCertificateService.java b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/AutoCertificateService.java new file mode 100644 index 0000000..71fa4d2 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/AutoCertificateService.java @@ -0,0 +1,159 @@ +package com.wechat.pay.java.core.certificate; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.security.cert.X509Certificate; +import java.time.Duration; +import java.util.Map; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; + +/** 定时更新证书的服务,它是一个由静态函数构成的工具类 */ +public class AutoCertificateService { + private static final Logger log = LoggerFactory.getLogger(AutoCertificateService.class); + protected static final int UPDATE_INTERVAL_MINUTE = 60; + private static final Duration defaultUpdateInterval = Duration.ofMinutes(UPDATE_INTERVAL_MINUTE); + private static final ConcurrentHashMap> certificateMap = + new ConcurrentHashMap<>(); + private static final ConcurrentHashMap downloadWorkerMap = + new ConcurrentHashMap<>(); + private static final ScheduledThreadPoolExecutor serviceExecutor = + new ScheduledThreadPoolExecutor( + 1, + new ThreadFactory() { + + private final AtomicInteger threadCount = new AtomicInteger(0); + + @Override + public Thread newThread(Runnable r) { + Thread t = + new Thread(r, "auto-certificate-service-daemon-" + threadCount.incrementAndGet()); + // 用户线程执行完成后不会阻止 JVM 退出 + t.setDaemon(true); + return t; + } + }); + + static { + // 取消时立即从工作队列中删除 + serviceExecutor.setRemoveOnCancelPolicy(true); + } + + private static ScheduledFuture future; + + private static int updateCount; + + private AutoCertificateService() { + throw new IllegalStateException("this class cannot be instantiated"); + } + + /** + * 注册证书下载任务 如果是第一次注册,会先下载证书。如果能成功下载,再保存下载器,供定时更新证书使用。如果下载失败,会抛出异常。 + * 如果已经注册过,当前传入的下载器将覆盖之前的下载器。如果当前下载器不能下载证书,定时更新证书会失败。 + * + * @param merchantId 商户号 + * @param type 调用方自定义的证书类型,例如 RSA/ShangMi + * @param downloader 证书下载器 + */ + public static void register(String merchantId, String type, CertificateDownloader downloader) { + String key = calculateDownloadWorkerMapKey(merchantId, type); + Runnable worker = + () -> { + Map result = downloader.download(); + certificateMap.put(key, result); + }; + + // 下载证书,以验证配置是正确的 + // 如果错误将抛出异常,fast-fail + worker.run(); + // 更新配置 + downloadWorkerMap.put(key, worker); + + start(defaultUpdateInterval); + } + + /** + * 注销证书下载任务 + * + * @param merchantId 商户号 + * @param type 调用方自定义的证书类型,应等于 `register()` 时的值 + */ + public static void unregister(String merchantId, String type) { + String key = calculateDownloadWorkerMapKey(merchantId, type); + downloadWorkerMap.remove(key); + } + + /** 清理所有已注册的下载器和已下载的证书,并取消定时更新证书的动作。 */ + public static void shutdown() { + downloadWorkerMap.clear(); + certificateMap.clear(); + synchronized (AutoCertificateService.class) { + if (future != null) { + future.cancel(false); + future = null; + } + } + } + + /** + * 启动更新证书的周期性动作 + * + * @param updateInterval 更新证书的周期 + */ + public static void start(Duration updateInterval) { + synchronized (AutoCertificateService.class) { + if (future == null) { + future = + serviceExecutor.scheduleAtFixedRate( + AutoCertificateService::update, + updateInterval.toMillis() / TimeUnit.SECONDS.toMillis(1), + updateInterval.toMillis() / TimeUnit.SECONDS.toMillis(1), + TimeUnit.SECONDS); + } + } + } + + private static void update() { + log.info("Begin update Certificates. total updates: {}", updateCount); + downloadWorkerMap.forEach( + (k, v) -> { + try { + v.run(); + log.info("update wechatpay certificate {} done", k); + } catch (Exception e) { + log.error("Download and update wechatpay certificate {} failed", k); + } + }); + updateCount++; + } + + private static String calculateDownloadWorkerMapKey(String merchantId, String type) { + return merchantId + "-" + type; + } + + private static X509Certificate getAvailableCertificate( + Map certificateMap) { + // 假设拿到的都是可用的,选取一个能用最久的 + X509Certificate longest = null; + for (X509Certificate item : certificateMap.values()) { + if (longest == null || item.getNotAfter().after(longest.getNotAfter())) { + longest = item; + } + } + return longest; + } + + // 根据证书序列号获取证书 + public static X509Certificate getCertificate( + String merchantId, String type, String serialNumber) { + String key = calculateDownloadWorkerMapKey(merchantId, type); + return certificateMap.get(key).get(serialNumber); + } + + // 获取最新可用的微信支付平台证书 + public static X509Certificate getAvailableCertificate(String merchantId, String type) { + String key = calculateDownloadWorkerMapKey(merchantId, type); + return getAvailableCertificate(certificateMap.get(key)); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/CertificateDownloader.java b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/CertificateDownloader.java new file mode 100644 index 0000000..29eab11 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/CertificateDownloader.java @@ -0,0 +1,113 @@ +package com.wechat.pay.java.core.certificate; + +import com.wechat.pay.java.core.certificate.model.Data; +import com.wechat.pay.java.core.certificate.model.DownloadCertificateResponse; +import com.wechat.pay.java.core.certificate.model.EncryptCertificate; +import com.wechat.pay.java.core.cipher.AeadCipher; +import com.wechat.pay.java.core.exception.ServiceException; +import com.wechat.pay.java.core.http.*; + +import java.nio.charset.StandardCharsets; +import java.security.cert.X509Certificate; +import java.util.Base64; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static java.util.Objects.requireNonNull; + +public final class CertificateDownloader { + private final CertificateHandler certificateHandler; + private final AeadCipher aeadCipher; + private final HttpClient httpClient; + private final String downloadUrl; + + public CertificateDownloader(Builder builder) { + this.downloadUrl = builder.downloadUrl; + this.httpClient = builder.httpClient; + this.aeadCipher = builder.aeadCipher; + this.certificateHandler = builder.certificateHandler; + } + + public static class Builder { + private String downloadUrl; + private HttpClient httpClient; + private AeadCipher aeadCipher; + private CertificateHandler certificateHandler; + + public Builder downloadUrl(String downloadUrl) { + this.downloadUrl = downloadUrl; + return this; + } + + public Builder httpClient(HttpClient httpClient) { + this.httpClient = httpClient; + return this; + } + + public Builder aeadCipher(AeadCipher cipher) { + this.aeadCipher = cipher; + return this; + } + + public Builder certificateHandler(CertificateHandler handler) { + this.certificateHandler = handler; + return this; + } + + public CertificateDownloader build() { + requireNonNull(downloadUrl); + requireNonNull(httpClient); + requireNonNull(aeadCipher); + requireNonNull(certificateHandler); + return new CertificateDownloader(this); + } + } + + /** 下载证书 */ + public Map download() { + HttpRequest httpRequest = + new HttpRequest.Builder() + .httpMethod(HttpMethod.GET) + .url(downloadUrl) + .addHeader(Constant.ACCEPT, " */*") + .addHeader(Constant.CONTENT_TYPE, MediaType.APPLICATION_JSON.getValue()) + .build(); + try { + HttpResponse httpResponse = + httpClient.execute(httpRequest, DownloadCertificateResponse.class); + return decryptCertificate(httpResponse); + } catch (ServiceException e) { + // 如果证书不存在,可能是切换为平台公钥,该处不报错 + if (e.getErrorCode().equals("NOT_FOUND")) { + return new HashMap<>(); + } + throw e; + } + } + + /** + * 从应答报文中解密证书 + * + * @param httpResponse httpResponse + * @return 应答报文解密后,生成X.509证书对象的Map + */ + private Map decryptCertificate( + HttpResponse httpResponse) { + List dataList = httpResponse.getServiceResponse().getData(); + Map downloadCertMap = new HashMap<>(); + for (Data data : dataList) { + EncryptCertificate encryptCertificate = data.getEncryptCertificate(); + X509Certificate certificate; + String decryptCertificate = + aeadCipher.decrypt( + encryptCertificate.getAssociatedData().getBytes(StandardCharsets.UTF_8), + encryptCertificate.getNonce().getBytes(StandardCharsets.UTF_8), + Base64.getDecoder().decode(encryptCertificate.getCiphertext())); + + certificate = certificateHandler.generateCertificate(decryptCertificate); + downloadCertMap.put(data.getSerialNo(), certificate); + } + return downloadCertMap; + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/CertificateHandler.java b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/CertificateHandler.java new file mode 100644 index 0000000..cf12bd1 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/CertificateHandler.java @@ -0,0 +1,23 @@ +package com.wechat.pay.java.core.certificate; + +import java.security.cert.X509Certificate; + +/** 证书处理器 */ +public interface CertificateHandler { + + /** + * 将证书从String转为X509Certificate + * + * @param certificate 证书字符串 + * @return X509Certificate + */ + X509Certificate generateCertificate(String certificate); + + /** + * * 验证证书链(不推荐验证,如果证书过期不及时更换会导致验证失败,从而影响业务) + * + * @param certificate 微信支付平台证书 + * @throws com.wechat.pay.java.core.exception.ValidationException 证书验证失败 + */ + void validateCertPath(X509Certificate certificate); +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/CertificateProvider.java b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/CertificateProvider.java new file mode 100644 index 0000000..7b21d61 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/CertificateProvider.java @@ -0,0 +1,22 @@ +package com.wechat.pay.java.core.certificate; + +import java.security.cert.X509Certificate; + +/** 微信支付平台证书提供器 */ +public interface CertificateProvider { + + /** + * 根据证书序列号获取证书 + * + * @param serialNumber 微信支付平台证书序列号 + * @return X.509证书实例 + */ + X509Certificate getCertificate(String serialNumber); + + /** + * 获取最新可用的微信支付平台证书 + * + * @return X.509证书实例 + */ + X509Certificate getAvailableCertificate(); +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/InMemoryCertificateProvider.java b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/InMemoryCertificateProvider.java new file mode 100644 index 0000000..4f033bd --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/InMemoryCertificateProvider.java @@ -0,0 +1,53 @@ +package com.wechat.pay.java.core.certificate; + +import com.wechat.pay.java.core.cipher.Constant; + +import java.math.BigInteger; +import java.security.cert.X509Certificate; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +/** 证书提供器的简单实现,证书存储在内存ConcurrentHashMap中 */ +public final class InMemoryCertificateProvider implements CertificateProvider { + + private final ConcurrentHashMap certificates = + new ConcurrentHashMap<>(); + private final X509Certificate availableCertificate; + + public InMemoryCertificateProvider(List certificates) { + if (certificates.isEmpty()) { + throw new IllegalArgumentException("The parameter list of constructor is empty."); + } + // 假设拿到的都是可用的,选取一个能用最久的 + X509Certificate longest = null; + for (X509Certificate item : certificates) { + this.certificates.put(item.getSerialNumber(), item); + if (longest == null || item.getNotAfter().after(longest.getNotAfter())) { + longest = item; + } + } + availableCertificate = longest; + } + + /** + * 根据证书序列号获取证书 + * + * @param serialNumber 微信支付平台证书序列号 + * @return X.509证书实例 + */ + @Override + public X509Certificate getCertificate(String serialNumber) { + BigInteger key = new BigInteger(serialNumber, Constant.HEX); + return certificates.get(key); + } + + /** + * 获取最新可用的微信支付平台证书 + * + * @return X.509证书实例 + */ + @Override + public X509Certificate getAvailableCertificate() { + return availableCertificate; + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/RSAAutoCertificateProvider.java b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/RSAAutoCertificateProvider.java new file mode 100644 index 0000000..561ee38 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/RSAAutoCertificateProvider.java @@ -0,0 +1,138 @@ +package com.wechat.pay.java.core.certificate; + +import com.wechat.pay.java.core.auth.Credential; +import com.wechat.pay.java.core.auth.Validator; +import com.wechat.pay.java.core.auth.WechatPay2Credential; +import com.wechat.pay.java.core.cipher.AeadAesCipher; +import com.wechat.pay.java.core.cipher.AeadCipher; +import com.wechat.pay.java.core.cipher.RSASigner; +import com.wechat.pay.java.core.http.AbstractHttpClientBuilder; +import com.wechat.pay.java.core.http.DefaultHttpClientBuilder; +import com.wechat.pay.java.core.http.HttpClient; +import com.wechat.pay.java.core.http.HttpHeaders; + +import java.security.PrivateKey; +import java.security.cert.X509Certificate; + +import static java.util.Objects.requireNonNull; + +/** RSA自动更新平台证书提供器 */ +public class RSAAutoCertificateProvider implements CertificateProvider { + + private static final CertificateHandler rsaCertificateHandler = new RSACertificateHandler(); + private static final String ALGORITHM_TYPE = "RSA"; + private static final String REQUEST_URL = + "https://api.mch.weixin.qq.com/v3/certificates?algorithm_type=" + ALGORITHM_TYPE; + + private final String merchantId; + + private RSAAutoCertificateProvider( + String merchantId, AeadCipher aeadCipher, HttpClient httpClient) { + this.merchantId = merchantId; + + CertificateDownloader downloader = + new CertificateDownloader.Builder() + .certificateHandler(rsaCertificateHandler) + .downloadUrl(REQUEST_URL) + .aeadCipher(aeadCipher) + .httpClient(httpClient) + .build(); + + AutoCertificateService.register(merchantId, ALGORITHM_TYPE, downloader); + } + + /** + * 根据证书序列号获取证书 + * + * @param serialNumber 微信支付平台证书序列号 + * @return X.509证书实例 + */ + @Override + public X509Certificate getCertificate(String serialNumber) { + return AutoCertificateService.getCertificate(merchantId, ALGORITHM_TYPE, serialNumber); + } + + /** + * 获取最新可用的微信支付平台证书 + * + * @return X.509证书实例 + */ + @Override + public X509Certificate getAvailableCertificate() { + return AutoCertificateService.getAvailableCertificate(merchantId, ALGORITHM_TYPE); + } + + public static class Builder { + private String merchantId; + private byte[] apiV3Key; + + private Credential credential; + private PrivateKey privateKey; + private String merchantSerialNumber; + private HttpClient httpClient; + private AbstractHttpClientBuilder httpClientBuilder; + + public Builder merchantId(String merchantId) { + this.merchantId = merchantId; + return this; + } + + public Builder apiV3Key(byte[] apiV3Key) { + this.apiV3Key = apiV3Key; + return this; + } + + public Builder httpClient(HttpClient httpClient) { + this.httpClient = httpClient; + return this; + } + + public Builder credential(Credential credential) { + this.credential = credential; + return this; + } + + public Builder privateKey(PrivateKey privateKey) { + this.privateKey = privateKey; + return this; + } + + public Builder merchantSerialNumber(String merchantSerialNumber) { + this.merchantSerialNumber = merchantSerialNumber; + return this; + } + + public Builder httpClientBuilder(AbstractHttpClientBuilder builder) { + // httpClientBuilder 不是不可变的,所以为了避免过程中修改入参或者值发生变化,这里制作了一个副本 + this.httpClientBuilder = builder.newInstance(); + return this; + } + + private final Validator emptyValidator = + new Validator() { + @Override + public boolean validate(HttpHeaders responseHeaders, String body) { + return true; + } + }; + + public RSAAutoCertificateProvider build() { + if (httpClient == null) { + if (httpClientBuilder == null) { + httpClientBuilder = new DefaultHttpClientBuilder(); + } + + if (credential == null && privateKey != null) { + credential = + new WechatPay2Credential( + requireNonNull(merchantId), + new RSASigner(requireNonNull(merchantSerialNumber), privateKey)); + } + + httpClient = httpClientBuilder.credential(credential).validator(emptyValidator).build(); + } + return new RSAAutoCertificateProvider( + merchantId, new AeadAesCipher(requireNonNull(apiV3Key)), httpClient); + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/RSACertificateHandler.java b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/RSACertificateHandler.java new file mode 100644 index 0000000..f1f506b --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/RSACertificateHandler.java @@ -0,0 +1,18 @@ +package com.wechat.pay.java.core.certificate; + +import com.wechat.pay.java.core.util.PemUtil; + +import java.security.cert.X509Certificate; + +final class RSACertificateHandler implements CertificateHandler { + + @Override + public X509Certificate generateCertificate(String certificate) { + return PemUtil.loadX509FromString(certificate); + } + + @Override + public void validateCertPath(X509Certificate certificate) { + // 为防止证书过期导致验签失败,从而影响业务,后续不再验证证书信任链 + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/model/Data.java b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/model/Data.java new file mode 100644 index 0000000..2ab4e0f --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/model/Data.java @@ -0,0 +1,49 @@ +package com.wechat.pay.java.core.certificate.model; + +import com.wechat.pay.java.core.util.GsonUtil; + +/** 获取平台证书列表返回数据 */ +public class Data { + + private String serialNo; + private String effectiveTime; + private String expireTime; + private EncryptCertificate encryptCertificate; + + public String getSerialNo() { + return serialNo; + } + + public void setSerialNo(String serialNo) { + this.serialNo = serialNo; + } + + public EncryptCertificate getEncryptCertificate() { + return encryptCertificate; + } + + public void setEncryptCertificate(EncryptCertificate encryptCertificate) { + this.encryptCertificate = encryptCertificate; + } + + public String getEffectiveTime() { + return effectiveTime; + } + + public void setEffectiveTime(String effectiveTime) { + this.effectiveTime = effectiveTime; + } + + public String getExpireTime() { + return expireTime; + } + + public void setExpireTime(String expireTime) { + this.expireTime = expireTime; + } + + @Override + public String toString() { + return GsonUtil.getGson().toJson(this); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/model/DownloadCertificateResponse.java b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/model/DownloadCertificateResponse.java new file mode 100644 index 0000000..2d59c1a --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/model/DownloadCertificateResponse.java @@ -0,0 +1,25 @@ +package com.wechat.pay.java.core.certificate.model; + +import com.google.gson.annotations.SerializedName; +import com.wechat.pay.java.core.util.GsonUtil; + +import java.util.List; + +public class DownloadCertificateResponse { + + @SerializedName("data") + List dataList; + + public List getData() { + return dataList; + } + + public void setData(List dataList) { + this.dataList = dataList; + } + + @Override + public String toString() { + return GsonUtil.getGson().toJson(this); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/model/EncryptCertificate.java b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/model/EncryptCertificate.java new file mode 100644 index 0000000..472d66a --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/certificate/model/EncryptCertificate.java @@ -0,0 +1,48 @@ +package com.wechat.pay.java.core.certificate.model; + +import com.wechat.pay.java.core.util.GsonUtil; + +public class EncryptCertificate { + + private String algorithm; + private String nonce; + private String associatedData; + private String ciphertext; + + public String getAlgorithm() { + return algorithm; + } + + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; + } + + public void setNonce(String nonce) { + this.nonce = nonce; + } + + public String getAssociatedData() { + return associatedData; + } + + public void setAssociatedData(String associatedData) { + this.associatedData = associatedData; + } + + public String getCiphertext() { + return ciphertext; + } + + public void setCiphertext(String ciphertext) { + this.ciphertext = ciphertext; + } + + @Override + public String toString() { + return GsonUtil.getGson().toJson(this); + } + + public String getNonce() { + return nonce; + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractAeadCipher.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractAeadCipher.java new file mode 100644 index 0000000..1b2a7f8 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractAeadCipher.java @@ -0,0 +1,89 @@ +package com.wechat.pay.java.core.cipher; + +import com.wechat.pay.java.core.exception.DecryptionException; + +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.Base64; + +/** 带有关联数据的认证加密器 */ +public abstract class AbstractAeadCipher implements AeadCipher { + + private final String algorithm; + private final String transformation; + private final int tagLengthBit; + private final byte[] key; + + protected AbstractAeadCipher( + String algorithm, String transformation, int tagLengthBit, byte[] key) { + this.algorithm = algorithm; + this.transformation = transformation; + this.tagLengthBit = tagLengthBit; + this.key = key; + } + + /** + * 加密并转换为字符串 + * + * @param associatedData AAD,额外的认证加密数据,可以为空 + * @param nonce IV,随机字符串初始化向量 + * @param plaintext 明文 + * @return Base64编码的密文 + */ + public String encrypt(byte[] associatedData, byte[] nonce, byte[] plaintext) { + try { + javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(transformation); + cipher.init( + javax.crypto.Cipher.ENCRYPT_MODE, + new SecretKeySpec(key, algorithm), + new GCMParameterSpec(tagLengthBit, nonce)); + if (associatedData != null) { + cipher.updateAAD(associatedData); + } + return Base64.getEncoder().encodeToString(cipher.doFinal(plaintext)); + } catch (InvalidKeyException + | InvalidAlgorithmParameterException + | BadPaddingException + | IllegalBlockSizeException + | NoSuchAlgorithmException + | NoSuchPaddingException e) { + throw new IllegalArgumentException(e); + } + } + + /** + * 解密并转换为字符串 + * + * @param associatedData AAD,额外的认证加密数据,可以为空 + * @param nonce IV,随机字符串初始化向量 + * @param ciphertext 密文 + * @return UTF-8编码的明文 + */ + public String decrypt(byte[] associatedData, byte[] nonce, byte[] ciphertext) { + try { + javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(transformation); + cipher.init( + javax.crypto.Cipher.DECRYPT_MODE, + new SecretKeySpec(key, algorithm), + new GCMParameterSpec(tagLengthBit, nonce)); + if (associatedData != null) { + cipher.updateAAD(associatedData); + } + return new String(cipher.doFinal(ciphertext), StandardCharsets.UTF_8); + } catch (InvalidKeyException + | InvalidAlgorithmParameterException + | NoSuchAlgorithmException + | NoSuchPaddingException e) { + throw new IllegalArgumentException(e); + } catch (BadPaddingException | IllegalBlockSizeException e) { + throw new DecryptionException("Decryption failed", e); + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractPrivacyDecryptor.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractPrivacyDecryptor.java new file mode 100644 index 0000000..ae4d667 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractPrivacyDecryptor.java @@ -0,0 +1,50 @@ +package com.wechat.pay.java.core.cipher; + +import com.wechat.pay.java.core.exception.DecryptionException; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.util.Base64; + +import static java.util.Objects.requireNonNull; + +public abstract class AbstractPrivacyDecryptor implements PrivacyDecryptor { + private final PrivateKey privateKey; + private final Cipher cipher; + + /** + * 构造敏感信息解密的抽象类 + * + * @param transformation 加密使用的模式 + * @param privateKey 加密使用的私钥 + */ + protected AbstractPrivacyDecryptor(String transformation, PrivateKey privateKey) { + this.privateKey = requireNonNull(privateKey); + try { + cipher = Cipher.getInstance(transformation); + } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { + throw new IllegalArgumentException( + "The current Java environment does not support " + transformation, e); + } + } + + @Override + public String decrypt(String ciphertext) { + requireNonNull(ciphertext); + try { + cipher.init(Cipher.DECRYPT_MODE, privateKey); + return new String( + cipher.doFinal(Base64.getDecoder().decode(ciphertext)), StandardCharsets.UTF_8); + } catch (InvalidKeyException e) { + throw new IllegalArgumentException("The given private key is invalid for decryption", e); + } catch (BadPaddingException | IllegalBlockSizeException e) { + throw new DecryptionException("Decryption failed", e); + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractPrivacyEncryptor.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractPrivacyEncryptor.java new file mode 100644 index 0000000..191f6bb --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractPrivacyEncryptor.java @@ -0,0 +1,50 @@ +package com.wechat.pay.java.core.cipher; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.util.Base64; + +import static java.util.Objects.requireNonNull; + +public abstract class AbstractPrivacyEncryptor implements PrivacyEncryptor { + private final PublicKey publicKey; + private final Cipher cipher; + private final String wechatPaySerial; + + protected AbstractPrivacyEncryptor( + String transformation, PublicKey publicKey, String wechatPaySerial) { + this.publicKey = requireNonNull(publicKey); + this.wechatPaySerial = requireNonNull(wechatPaySerial).toUpperCase(); + try { + cipher = Cipher.getInstance(transformation); + } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { + throw new IllegalArgumentException( + "The current Java environment does not support " + transformation, e); + } + } + + @Override + public String encrypt(String plaintext) { + requireNonNull(plaintext); + try { + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + return Base64.getEncoder() + .encodeToString(cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8))); + } catch (InvalidKeyException e) { + throw new IllegalArgumentException("RSA encryption using an illegal publicKey", e); + } catch (BadPaddingException | IllegalBlockSizeException e) { + throw new IllegalArgumentException("Plaintext is too long", e); + } + } + + @Override + public String getWechatpaySerial() { + return wechatPaySerial; + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractSigner.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractSigner.java new file mode 100644 index 0000000..b8ebaac --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractSigner.java @@ -0,0 +1,60 @@ +package com.wechat.pay.java.core.cipher; + +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.util.Base64; + +import static java.util.Objects.requireNonNull; + +public abstract class AbstractSigner implements Signer { + + private final String certificateSerialNumber; + private final String algorithm; + private final String algorithmName; + private final PrivateKey privateKey; + + /** + * AbstractSigner 构造函数 + * + * @param algorithm 微信支付的签名算法,例如SHA256-RSA2048 + * @param algorithmName 获取Signature对象时指定的算法,例如SHA256withRSA + * @param certificateSerialNumber 商户API证书序列号 + * @param privateKey 商户API私钥 + */ + protected AbstractSigner( + String algorithm, + String algorithmName, + String certificateSerialNumber, + PrivateKey privateKey) { + this.algorithm = requireNonNull(algorithm); + this.algorithmName = requireNonNull(algorithmName); + this.certificateSerialNumber = requireNonNull(certificateSerialNumber); + this.privateKey = requireNonNull(privateKey); + } + + @Override + public SignatureResult sign(String message) { + requireNonNull(message); + + byte[] sign; + try { + Signature signature = Signature.getInstance(algorithmName); + signature.initSign(privateKey); + signature.update(message.getBytes(StandardCharsets.UTF_8)); + sign = signature.sign(); + } catch (NoSuchAlgorithmException e) { + throw new UnsupportedOperationException( + "The current Java environment does not support " + algorithmName, e); + } catch (InvalidKeyException e) { + throw new IllegalArgumentException(algorithm + " signature uses an illegal privateKey.", e); + } catch (SignatureException e) { + throw new RuntimeException("An error occurred during the sign process.", e); + } + return new SignatureResult(Base64.getEncoder().encodeToString(sign), certificateSerialNumber); + } + + @Override + public String getAlgorithm() { + return algorithm; + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractVerifier.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractVerifier.java new file mode 100644 index 0000000..7c660e1 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AbstractVerifier.java @@ -0,0 +1,126 @@ +package com.wechat.pay.java.core.cipher; + +import com.wechat.pay.java.core.certificate.CertificateProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.security.cert.X509Certificate; +import java.util.Base64; + +import static java.util.Objects.requireNonNull; + +public abstract class AbstractVerifier implements Verifier { + + protected static final Logger logger = LoggerFactory.getLogger(AbstractVerifier.class); + protected final CertificateProvider certificateProvider; + protected final PublicKey publicKey; + protected final String publicKeyId; + protected final String algorithmName; + + /** + * AbstractVerifier 构造函数 + * + * @param algorithmName 获取Signature对象时指定的算法,例如SHA256withRSA + * @param certificateProvider 验签使用的微信支付平台证书管理器,非空 + */ + protected AbstractVerifier(String algorithmName, CertificateProvider certificateProvider) { + this.certificateProvider = requireNonNull(certificateProvider); + this.algorithmName = requireNonNull(algorithmName); + this.publicKey = null; + this.publicKeyId = null; + } + + /** + * AbstractVerifier 构造函数 + * + * @param algorithmName 获取Signature对象时指定的算法,例如SHA256withRSA + * @param publicKey 验签使用的微信支付平台公钥,非空 + * @param publicKeyId 验签使用的微信支付平台公钥id + */ + protected AbstractVerifier(String algorithmName, PublicKey publicKey, String publicKeyId) { + this.publicKey = requireNonNull(publicKey); + this.publicKeyId = publicKeyId; + this.algorithmName = requireNonNull(algorithmName); + this.certificateProvider = null; + } + + /** + * AbstractVerifier 构造函数,仅在平台证书和平台公钥灰度切换阶段使用 + * + * @param algorithmName 获取Signature对象时指定的算法,例如SHA256withRSA + * @param publicKey 验签使用的微信支付平台公钥,非空 + * @param publicKeyId 验签使用的微信支付平台公钥id + * @param certificateProvider 验签使用的微信支付平台证书管理器,非空 + */ + protected AbstractVerifier( + String algorithmName, + PublicKey publicKey, + String publicKeyId, + CertificateProvider certificateProvider) { + this.publicKey = requireNonNull(publicKey); + this.publicKeyId = publicKeyId; + this.algorithmName = requireNonNull(algorithmName); + this.certificateProvider = requireNonNull(certificateProvider); + } + + protected boolean verify(X509Certificate certificate, String message, String signature) { + try { + Signature sign = Signature.getInstance(algorithmName); + sign.initVerify(certificate); + sign.update(message.getBytes(StandardCharsets.UTF_8)); + return sign.verify(Base64.getDecoder().decode(signature)); + } catch (SignatureException e) { + return false; + } catch (InvalidKeyException e) { + throw new IllegalArgumentException("verify uses an illegal certificate.", e); + } catch (NoSuchAlgorithmException e) { + throw new UnsupportedOperationException( + "The current Java environment does not support " + algorithmName, e); + } + } + + private boolean verify(String message, String signature) { + try { + Signature sign = Signature.getInstance(algorithmName); + sign.initVerify(publicKey); + sign.update(message.getBytes(StandardCharsets.UTF_8)); + return sign.verify(Base64.getDecoder().decode(signature)); + } catch (SignatureException e) { + return false; + } catch (InvalidKeyException e) { + throw new IllegalArgumentException("verify uses an illegal publickey.", e); + } catch (NoSuchAlgorithmException e) { + throw new UnsupportedOperationException( + "The current Java environment does not support " + algorithmName, e); + } + } + + @Override + public boolean verify(String serialNumber, String message, String signature) { + // 如果公钥不为空,使用公钥验签 + if (publicKey != null) { + if (serialNumber.equals(publicKeyId)) { + return verify(message, signature); + } + // 如果证书为空,则说明是传入的publicKeyId错误,如果不为空,则继续使用证书验签 + if (certificateProvider == null) { + logger.error( + "publicKeyId[{}] and serialNumber[{}] are not equal", publicKeyId, serialNumber); + return false; + } + } + // 使用证书验签 + requireNonNull(certificateProvider); + X509Certificate certificate = certificateProvider.getCertificate(serialNumber); + if (certificate == null) { + logger.error( + "Verify the signature and get the WechatPay certificate or publicKey corresponding to " + + "serialNumber[{}] is empty.", + serialNumber); + return false; + } + return verify(certificate, message, signature); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AeadAesCipher.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AeadAesCipher.java new file mode 100644 index 0000000..250a336 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AeadAesCipher.java @@ -0,0 +1,14 @@ +package com.wechat.pay.java.core.cipher; + +/** 带有关联数据的AES认证加解密器 */ +public final class AeadAesCipher extends AbstractAeadCipher { + + private static final String TRANSFORMATION = "AES/GCM/NoPadding"; + + private static final int TAG_LENGTH_BIT = 128; + private static final String ALGORITHM = "AES"; + + public AeadAesCipher(byte[] key) { + super(ALGORITHM, TRANSFORMATION, TAG_LENGTH_BIT, key); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AeadCipher.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AeadCipher.java new file mode 100644 index 0000000..0df71d2 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/AeadCipher.java @@ -0,0 +1,24 @@ +package com.wechat.pay.java.core.cipher; + +/** 认证加密器 */ +public interface AeadCipher { + /** + * 加密并转换为字符串 + * + * @param associatedData AAD,额外的认证加密数据,可以为空 + * @param nonce IV,随机字符串初始化向量 + * @param plaintext 明文 + * @return Base64编码的密文 + */ + String encrypt(byte[] associatedData, byte[] nonce, byte[] plaintext); + + /** + * 解密并转换为字符串 + * + * @param associatedData AAD,额外的认证加密数据,可以为空 + * @param nonce IV,随机字符串初始化向量 + * @param ciphertext 密文 + * @return UTF-8编码的明文 + */ + String decrypt(byte[] associatedData, byte[] nonce, byte[] ciphertext); +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/Constant.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/Constant.java new file mode 100644 index 0000000..1632d2e --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/Constant.java @@ -0,0 +1,11 @@ +package com.wechat.pay.java.core.cipher; + +/** 用于签名和加密的常量 */ +public final class Constant { + + public static final String SHA256WITHRSA = "SHA256withRSA"; + + public static final int HEX = 16; + + private Constant() {} +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/Encryption.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/Encryption.java new file mode 100644 index 0000000..d5762a5 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/Encryption.java @@ -0,0 +1,10 @@ +package com.wechat.pay.java.core.cipher; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Encryption {} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/PrivacyDecryptor.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/PrivacyDecryptor.java new file mode 100644 index 0000000..ad574b7 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/PrivacyDecryptor.java @@ -0,0 +1,13 @@ +package com.wechat.pay.java.core.cipher; + +/** 敏感信息解密器 */ +public interface PrivacyDecryptor { + + /** + * 解密并转换为字符串 + * + * @param ciphertext 密文 + * @return UTF-8编码的明文 + */ + String decrypt(String ciphertext); +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/PrivacyEncryptor.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/PrivacyEncryptor.java new file mode 100644 index 0000000..f6e485f --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/PrivacyEncryptor.java @@ -0,0 +1,19 @@ +package com.wechat.pay.java.core.cipher; + +/** 敏感信息加密器 */ +public interface PrivacyEncryptor { + /** + * 加密并转换为字符串 + * + * @param plaintext 明文 + * @return Base64编码的密文 + */ + String encrypt(String plaintext); + + /** + * 获取加密使用公钥所属证书的证书序列号,可设置到请求的 HTTP 头部 Wechatpay-Serial + * + * @return 证书序列号 + */ + String getWechatpaySerial(); +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAPkcs1v15Decryptor.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAPkcs1v15Decryptor.java new file mode 100644 index 0000000..e98cea7 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAPkcs1v15Decryptor.java @@ -0,0 +1,11 @@ +package com.wechat.pay.java.core.cipher; + +import java.security.PrivateKey; + +/** RSA-Pkcs1v15敏感信息解密器 */ +public final class RSAPkcs1v15Decryptor extends AbstractPrivacyDecryptor { + + public RSAPkcs1v15Decryptor(PrivateKey privateKey) { + super("RSA/ECB/PKCS1Padding", privateKey); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAPkcs1v15Encryptor.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAPkcs1v15Encryptor.java new file mode 100644 index 0000000..e3472d5 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAPkcs1v15Encryptor.java @@ -0,0 +1,11 @@ +package com.wechat.pay.java.core.cipher; + +import java.security.PublicKey; + +/** RSA-Pkcs1v15 敏感信息加密器 */ +public final class RSAPkcs1v15Encryptor extends AbstractPrivacyEncryptor { + + public RSAPkcs1v15Encryptor(PublicKey publicKey, String wechatpaySerialNumber) { + super("RSA/ECB/PKCS1Padding", publicKey, wechatpaySerialNumber); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAPrivacyDecryptor.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAPrivacyDecryptor.java new file mode 100644 index 0000000..5498b41 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAPrivacyDecryptor.java @@ -0,0 +1,16 @@ +package com.wechat.pay.java.core.cipher; + +import java.security.PrivateKey; + +/** RSA敏感信息解密器 */ +public final class RSAPrivacyDecryptor extends AbstractPrivacyDecryptor { + + /** + * RSAPrivacyDecryptor 构造函数 + * + * @param privateKey 应答的敏感信息解密时使用的商户私钥 + */ + public RSAPrivacyDecryptor(PrivateKey privateKey) { + super("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", privateKey); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAPrivacyEncryptor.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAPrivacyEncryptor.java new file mode 100644 index 0000000..50908ea --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAPrivacyEncryptor.java @@ -0,0 +1,17 @@ +package com.wechat.pay.java.core.cipher; + +import java.security.PublicKey; + +/** RSA敏感信息加密器 */ +public final class RSAPrivacyEncryptor extends AbstractPrivacyEncryptor { + + /** + * RSAPrivacyEncryptor 构造函数 + * + * @param publicKey 请求的敏感信息加密时使用的微信支付公钥 + * @param wechatpaySerialNumber 微信支付平台证书的证书序列号 + */ + public RSAPrivacyEncryptor(PublicKey publicKey, String wechatpaySerialNumber) { + super("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", publicKey, wechatpaySerialNumber); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSASigner.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSASigner.java new file mode 100644 index 0000000..2f0251a --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSASigner.java @@ -0,0 +1,11 @@ +package com.wechat.pay.java.core.cipher; + +import java.security.PrivateKey; + +/** RSA签名器 */ +public final class RSASigner extends AbstractSigner { + + public RSASigner(String certificateSerialNumber, PrivateKey privateKey) { + super("SHA256-RSA2048", Constant.SHA256WITHRSA, certificateSerialNumber, privateKey); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAVerifier.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAVerifier.java new file mode 100644 index 0000000..787e1f0 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/RSAVerifier.java @@ -0,0 +1,23 @@ +package com.wechat.pay.java.core.cipher; + +import com.wechat.pay.java.core.certificate.CertificateProvider; + +import java.security.PublicKey; + +import static com.wechat.pay.java.core.cipher.Constant.SHA256WITHRSA; + +/** RSA验签器 */ +public final class RSAVerifier extends AbstractVerifier { + + public RSAVerifier(CertificateProvider provider) { + super(SHA256WITHRSA, provider); + } + + public RSAVerifier(PublicKey publicKey, String publicKeyId) { + super(SHA256WITHRSA, publicKey, publicKeyId); + } + + public RSAVerifier(PublicKey publicKey, String publicKeyId, CertificateProvider provider) { + super(SHA256WITHRSA, publicKey, publicKeyId, provider); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/SignatureResult.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/SignatureResult.java new file mode 100644 index 0000000..ea6dc15 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/SignatureResult.java @@ -0,0 +1,41 @@ +package com.wechat.pay.java.core.cipher; + +import com.wechat.pay.java.core.util.GsonUtil; + +import static java.util.Objects.requireNonNull; + +/** 签名结果 */ +public class SignatureResult { + + private final String signature; + + private final String certificateSerialNumber; + + public SignatureResult(String signature, String certificateSerialNumber) { + this.signature = requireNonNull(signature); + this.certificateSerialNumber = requireNonNull(certificateSerialNumber); + } + + /** + * 获取签名 + * + * @return 签名 + */ + public String getSign() { + return signature; + } + + /** + * 获取签名对应的商户证书序列号 + * + * @return 商户证书序列号 + */ + public String getCertificateSerialNumber() { + return certificateSerialNumber; + } + + @Override + public String toString() { + return GsonUtil.getGson().toJson(this); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/Signer.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/Signer.java new file mode 100644 index 0000000..88cee3c --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/Signer.java @@ -0,0 +1,20 @@ +package com.wechat.pay.java.core.cipher; + +/** 签名器 */ +public interface Signer { + + /** + * 生成签名结果 + * + * @param message 签名信息 + * @return 签名结果 + */ + SignatureResult sign(String message); + + /** + * 获取签名算法 + * + * @return 签名算法 + */ + String getAlgorithm(); +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/Verifier.java b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/Verifier.java new file mode 100644 index 0000000..e7b1b8a --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/cipher/Verifier.java @@ -0,0 +1,15 @@ +package com.wechat.pay.java.core.cipher; + +/** 验签器 */ +public interface Verifier { + + /** + * 验证签名 + * + * @param serialNumber 用于验证签名的证书序列号或者公钥id + * @param message 签名信息 + * @param signature 待验证的签名 + * @return 是否验证通过 + */ + boolean verify(String serialNumber, String message, String signature); +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/exception/DecryptionException.java b/wx-pay/src/main/java/com/wechat/pay/java/core/exception/DecryptionException.java new file mode 100644 index 0000000..2eb27d8 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/exception/DecryptionException.java @@ -0,0 +1,9 @@ +package com.wechat.pay.java.core.exception; + +public class DecryptionException extends WechatPayException { + private static final long serialVersionUID = 1L; + + public DecryptionException(String message, Throwable throwable) { + super(message, throwable); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/exception/HttpException.java b/wx-pay/src/main/java/com/wechat/pay/java/core/exception/HttpException.java new file mode 100644 index 0000000..969b525 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/exception/HttpException.java @@ -0,0 +1,49 @@ +package com.wechat.pay.java.core.exception; + +import com.wechat.pay.java.core.http.HttpRequest; + +/** 发送HTTP请求失败时抛出。例如构建请求参数失败、发送请求失败、I/O错误等。包含请求信息。 */ +public class HttpException extends WechatPayException { + + private static final long serialVersionUID = 8583990125724273072L; + private HttpRequest httpRequest; + + /** + * 构造请求参数失败时调用 + * + * @param message 错误信息 + * @param cause 引起失败的原始异常 + */ + public HttpException(String message, Throwable cause) { + super(message, cause); + } + + /** + * 发送请求失败时调用 + * + * @param httpRequest http请求 + * @param cause 引起失败的原始异常 + */ + public HttpException(HttpRequest httpRequest, Throwable cause) { + super(String.format("Send Http Request failed,httpRequest[%s]", httpRequest), cause); + this.httpRequest = httpRequest; + } + + /** + * 获取序列化版本UID + * + * @return UID + */ + public static long getSerialVersionUID() { + return serialVersionUID; + } + + /** + * 获取HTTP请求 + * + * @return HTTP请求 + */ + public HttpRequest getHttpRequest() { + return httpRequest; + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/exception/MalformedMessageException.java b/wx-pay/src/main/java/com/wechat/pay/java/core/exception/MalformedMessageException.java new file mode 100644 index 0000000..202f62e --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/exception/MalformedMessageException.java @@ -0,0 +1,15 @@ +package com.wechat.pay.java.core.exception; + +/** 解析微信支付应答或回调报文异常时抛出,例如回调通知参数不正确、应答类型错误。 */ +public class MalformedMessageException extends WechatPayException { + + private static final long serialVersionUID = -1049702516796430238L; + + public MalformedMessageException(String message) { + super(message); + } + + public MalformedMessageException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/exception/ServiceException.java b/wx-pay/src/main/java/com/wechat/pay/java/core/exception/ServiceException.java new file mode 100644 index 0000000..4e3d434 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/exception/ServiceException.java @@ -0,0 +1,86 @@ +package com.wechat.pay.java.core.exception; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.wechat.pay.java.core.http.HttpRequest; +import com.wechat.pay.java.core.util.GsonUtil; + +/** 发送HTTP请求成功,返回异常时抛出。例如返回状态码小于200或大于等于300、返回体参数不完整。 */ +public class ServiceException extends WechatPayException { + + private static final long serialVersionUID = -7174975090366956652L; + + private final HttpRequest httpRequest; + private final int httpStatusCode; + private final String responseBody; + private String errorCode; + private String errorMessage; + + /** + * 返回状态码小于200或大于300调用 + * + * @param httpRequest http请求 + * @param httpStatusCode http状态码 + * @param responseBody http返回体 + */ + public ServiceException(HttpRequest httpRequest, int httpStatusCode, String responseBody) { + super( + String.format( + "Wrong HttpStatusCode[%d]%nhttpResponseBody[%.1024s]\tHttpRequest[%s]", + httpStatusCode, responseBody, httpRequest)); + this.httpRequest = httpRequest; + this.httpStatusCode = httpStatusCode; + this.responseBody = responseBody; + if (responseBody != null && !responseBody.isEmpty()) { + JsonObject jsonObject = GsonUtil.getGson().fromJson(responseBody, JsonObject.class); + JsonElement code = jsonObject.get("code"); + JsonElement message = jsonObject.get("message"); + this.errorCode = code == null ? null : code.getAsString(); + this.errorMessage = message == null ? null : message.getAsString(); + } + } + + /** + * 获取序列化版本UID + * + * @return UID + */ + public static long getSerialVersionUID() { + return serialVersionUID; + } + + /** + * 获取HTTP请求 + * + * @return HTTP请求 + */ + public HttpRequest getHttpRequest() { + return httpRequest; + } + + /** + * 获取HTTP返回体 + * + * @return HTTP返回体 + */ + public String getResponseBody() { + return responseBody; + } + + /** + * 获取HTTP状态码 + * + * @return HTTP状态码 + */ + public int getHttpStatusCode() { + return httpStatusCode; + } + + public String getErrorCode() { + return errorCode; + } + + public String getErrorMessage() { + return errorMessage; + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/exception/ValidationException.java b/wx-pay/src/main/java/com/wechat/pay/java/core/exception/ValidationException.java new file mode 100644 index 0000000..a343fad --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/exception/ValidationException.java @@ -0,0 +1,15 @@ +package com.wechat.pay.java.core.exception; + +/** 验证签名失败时抛出 */ +public class ValidationException extends WechatPayException { + + private static final long serialVersionUID = -5439484392712167452L; + + public ValidationException(String message) { + super(message); + } + + public ValidationException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/exception/WechatPayException.java b/wx-pay/src/main/java/com/wechat/pay/java/core/exception/WechatPayException.java new file mode 100644 index 0000000..7ae55e7 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/exception/WechatPayException.java @@ -0,0 +1,15 @@ +package com.wechat.pay.java.core.exception; + +/** 微信支付异常基类 */ +public abstract class WechatPayException extends RuntimeException { + + private static final long serialVersionUID = -5896431877288268263L; + + public WechatPayException(String message) { + super(message); + } + + public WechatPayException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/AbstractHttpClient.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/AbstractHttpClient.java new file mode 100644 index 0000000..3a3937e --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/AbstractHttpClient.java @@ -0,0 +1,139 @@ +package com.wechat.pay.java.core.http; + +import com.wechat.pay.java.core.auth.Credential; +import com.wechat.pay.java.core.auth.Validator; +import com.wechat.pay.java.core.exception.MalformedMessageException; +import com.wechat.pay.java.core.exception.ServiceException; +import com.wechat.pay.java.core.exception.ValidationException; +import com.wechat.pay.java.core.http.HttpRequest.Builder; + +import java.io.InputStream; + +import static com.wechat.pay.java.core.http.Constant.*; +import static java.net.HttpURLConnection.HTTP_MULT_CHOICE; +import static java.net.HttpURLConnection.HTTP_OK; +import static java.util.Objects.requireNonNull; + +/** 请求客户端抽象基类 */ +public abstract class AbstractHttpClient implements HttpClient { + + protected final Credential credential; + protected final Validator validator; + + public AbstractHttpClient(Credential credential, Validator validator) { + this.credential = requireNonNull(credential); + this.validator = requireNonNull(validator); + } + + @Override + public HttpResponse execute(HttpRequest httpRequest, Class responseClass) { + HttpRequest innerRequest = + new Builder() + .url(httpRequest.getUrl()) + .httpMethod(httpRequest.getHttpMethod()) + .headers(httpRequest.getHeaders()) + .addHeader(AUTHORIZATION, getAuthorization(httpRequest)) + .addHeader(USER_AGENT, getUserAgent()) + .body(httpRequest.getBody()) + .build(); + OriginalResponse originalResponse = innerExecute(innerRequest); + validateResponse(originalResponse); + return assembleHttpResponse(originalResponse, responseClass); + } + + @Override + public InputStream download(String url) { + HttpRequest originRequest = + new HttpRequest.Builder().httpMethod(HttpMethod.GET).url(url).build(); + HttpRequest httpRequest = + new HttpRequest.Builder() + .url(url) + .httpMethod(HttpMethod.GET) + .addHeader(AUTHORIZATION, getAuthorization(originRequest)) + .addHeader(ACCEPT, "*/*") + .addHeader(USER_AGENT, getUserAgent()) + .build(); + return innerDownload(httpRequest); + } + + protected abstract InputStream innerDownload(HttpRequest httpRequest); + + protected abstract OriginalResponse innerExecute(HttpRequest httpRequest); + + private void validateResponse(OriginalResponse originalResponse) { + + if (isInvalidHttpCode(originalResponse.getStatusCode())) { + throw new ServiceException( + originalResponse.getRequest(), + originalResponse.getStatusCode(), + originalResponse.getBody()); + } + + if (originalResponse.getBody() != null + && !originalResponse.getBody().isEmpty() + && !MediaType.APPLICATION_JSON.equalsWith(originalResponse.getContentType())) { + throw new MalformedMessageException( + String.format( + "Unsupported content-type[%s]%nhttpRequest[%s]", + originalResponse.getContentType(), originalResponse.getRequest())); + } + + if (!validator.validate(originalResponse.getHeaders(), originalResponse.getBody())) { + String requestId = originalResponse.getHeaders().getHeader(REQUEST_ID); + throw new ValidationException( + String.format( + "Validate response failed,the WechatPay signature is incorrect.%n" + + "Request-ID[%s]\tresponseHeader[%s]\tresponseBody[%.1024s]", + requestId, originalResponse.getHeaders(), originalResponse.getBody())); + } + } + + protected boolean isInvalidHttpCode(int httpCode) { + return httpCode < HTTP_OK || httpCode >= HTTP_MULT_CHOICE; + } + + private HttpResponse assembleHttpResponse( + OriginalResponse originalResponse, Class responseClass) { + return new HttpResponse.Builder() + .originalResponse(originalResponse) + .serviceResponseType(responseClass) + .build(); + } + + private String getSignBody(RequestBody requestBody) { + if (requestBody == null) { + return ""; + } + if (requestBody instanceof JsonRequestBody) { + return ((JsonRequestBody) requestBody).getBody(); + } + if (requestBody instanceof FileRequestBody) { + return ((FileRequestBody) requestBody).getMeta(); + } + throw new UnsupportedOperationException( + String.format("Unsupported RequestBody Type[%s]", requestBody.getClass().getName())); + } + + private String getUserAgent() { + return String.format( + USER_AGENT_FORMAT, + getClass().getPackage().getImplementationVersion(), + OS, + VERSION == null ? "Unknown" : VERSION, + credential.getClass().getSimpleName(), + validator.getClass().getSimpleName(), + getHttpClientInfo()); + } + + /** + * 获取http客户端信息,用于User-Agent。 格式:客户端名称/版本 示例:okhttp3/4.9.3 + * + * @return 客户端信息 + */ + protected abstract String getHttpClientInfo(); + + private String getAuthorization(HttpRequest request) { + return credential.getAuthorization( + request.getUri(), request.getHttpMethod().name(), getSignBody(request.getBody())); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/AbstractHttpClientBuilder.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/AbstractHttpClientBuilder.java new file mode 100644 index 0000000..1f1b616 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/AbstractHttpClientBuilder.java @@ -0,0 +1,37 @@ +package com.wechat.pay.java.core.http; + +import com.wechat.pay.java.core.auth.Credential; +import com.wechat.pay.java.core.auth.Validator; + +public interface AbstractHttpClientBuilder> { + + /** + * 复制工厂,复制一个当前对象 + * + * @return 对象的副本 + */ + T newInstance(); + + /** + * 设置验证器 + * + * @param validator 验证器 + * @return the AbstractHttpClientBuilder + */ + T validator(Validator validator); + + /** + * 设置凭据生成器 + * + * @param credential 凭据生成器 + * @return the AbstractHttpClientBuilder + */ + T credential(Credential credential); + + /** + * 构建 AbstractHttpClient + * + * @return AbstractHttpClient + */ + AbstractHttpClient build(); +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/Constant.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/Constant.java new file mode 100644 index 0000000..9117c1c --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/Constant.java @@ -0,0 +1,36 @@ +package com.wechat.pay.java.core.http; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** HTTP常量 */ +public final class Constant { + + /** + * User-Agent头部值格式:WechatPay-Java/版本 操作系统/版本 Java/版本 Credential/Credential信息 Validator/Validator信息 + * HttpClient信息 示例: WechatPay-Java/0.0.1 (Linux/3.10.0-957.el7.x86_64) Java/1.8.0_222 + * Crendetial/WechatPay2Crendetial Validator/WechatPay2Validator okhttp3/4.9.3 + */ + public static final String USER_AGENT_FORMAT = + "WechatPay-Java/%s (%s) Java/%s Credential/%s Validator/%s %s"; + + public static final String OS = + System.getProperty("os.name") + "/" + System.getProperty("os.version"); + public static final String VERSION = System.getProperty("java.version"); + public static final String AUTHORIZATION = "Authorization"; + public static final String REQUEST_ID = "Request-ID"; + public static final String WECHAT_PAY_SERIAL = "Wechatpay-Serial"; + public static final String WECHAT_PAY_SIGNATURE = "Wechatpay-Signature"; + public static final String WECHAT_PAY_TIMESTAMP = "Wechatpay-Timestamp"; + public static final String WECHAT_PAY_NONCE = "Wechatpay-Nonce"; + public static final String USER_AGENT = "User-Agent"; + public static final String ACCEPT = "Accept"; + public static final String CONTENT_TYPE = "Content-Type"; + + public static final List PRIMARY_API_DOMAIN = + Collections.unmodifiableList(Arrays.asList("api.mch.weixin.qq.com", "api.wechatpay.cn")); + public static final String SECONDARY_API_DOMAIN = "api2.wechatpay.cn"; + + private Constant() {} +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/DefaultHttpClientBuilder.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/DefaultHttpClientBuilder.java new file mode 100644 index 0000000..88917a2 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/DefaultHttpClientBuilder.java @@ -0,0 +1,189 @@ +package com.wechat.pay.java.core.http; + +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.auth.Credential; +import com.wechat.pay.java.core.auth.Validator; +import com.wechat.pay.java.core.http.okhttp.OkHttpClientAdapter; +import com.wechat.pay.java.core.http.okhttp.OkHttpMultiDomainInterceptor; +import okhttp3.ConnectionPool; +import okhttp3.OkHttpClient; + +import java.net.Proxy; +import java.util.concurrent.TimeUnit; + +import static java.util.Objects.requireNonNull; + +/** 默认HttpClient构造器 */ +public class DefaultHttpClientBuilder + implements AbstractHttpClientBuilder { + + private Credential credential; + private Validator validator; + + // 最大空闲连接 maxIdleConnections 为5个,跟 OkHttp 默认值保持一致 + private static final int MAX_IDLE_CONNECTIONS = 5; + // 连接的 Keep-Alive 空闲时长为7秒, 微信支付服务器目前是8秒 + // 防止空闲客户端被服务器断掉,而造成不必要的重试 + private static final int KEEP_ALIVE_SECONDS = 7; + private static final okhttp3.OkHttpClient defaultOkHttpClient = + new OkHttpClient.Builder() + .connectionPool( + new ConnectionPool(MAX_IDLE_CONNECTIONS, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS)) + .build(); + private okhttp3.OkHttpClient customizeOkHttpClient; + private int readTimeoutMs = -1; + private int writeTimeoutMs = -1; + private int connectTimeoutMs = -1; + private Proxy proxy; + private boolean retryMultiDomain = false; + private Boolean retryOnConnectionFailure = null; + private static final OkHttpMultiDomainInterceptor multiDomainInterceptor = + new OkHttpMultiDomainInterceptor(); + + /** + * 复制工厂,复制一个当前对象 + * + * @return 对象的副本 + */ + @Override + public DefaultHttpClientBuilder newInstance() { + DefaultHttpClientBuilder result = new DefaultHttpClientBuilder(); + result.credential = this.credential; + result.validator = this.validator; + result.customizeOkHttpClient = this.customizeOkHttpClient; + result.readTimeoutMs = this.readTimeoutMs; + result.writeTimeoutMs = this.writeTimeoutMs; + result.connectTimeoutMs = this.connectTimeoutMs; + result.proxy = this.proxy; + return result; + } + + /** + * 设置读超时 + * + * @param readTimeoutMs 读超时,单位毫秒 + * @return defaultHttpClientBuilder + */ + public DefaultHttpClientBuilder readTimeoutMs(int readTimeoutMs) { + this.readTimeoutMs = readTimeoutMs; + return this; + } + + /** + * 设置写超时 + * + * @param writeTimeoutMs 写超时,单位毫秒 + * @return defaultHttpClientBuilder + */ + public DefaultHttpClientBuilder writeTimeoutMs(int writeTimeoutMs) { + this.writeTimeoutMs = writeTimeoutMs; + return this; + } + + /** + * 设置连接超时 + * + * @param connectTimeoutMs 连接超时,单位毫秒 + * @return defaultHttpClientBuilder + */ + public DefaultHttpClientBuilder connectTimeoutMs(int connectTimeoutMs) { + this.connectTimeoutMs = connectTimeoutMs; + return this; + } + + /** + * 设置凭据生成器 + * + * @param credential 凭据生成器 + * @return defaultHttpClientBuilder + */ + @Override + public DefaultHttpClientBuilder credential(Credential credential) { + this.credential = credential; + return this; + } + + /** + * 设置验证器 + * + * @param validator 验证器 + * @return defaultHttpClientBuilder + */ + @Override + public DefaultHttpClientBuilder validator(Validator validator) { + this.validator = validator; + return this; + } + + /** + * 设置 okHttpClient 若设置该参数,会覆盖client中的原有配置 + * + * @param okHttpClient 用户自定义的okHttpClient + * @return defaultHttpClientBuilder + */ + public DefaultHttpClientBuilder okHttpClient(okhttp3.OkHttpClient okHttpClient) { + this.customizeOkHttpClient = okHttpClient; + return this; + } + + public DefaultHttpClientBuilder config(Config config) { + requireNonNull(config); + this.credential = config.createCredential(); + this.validator = config.createValidator(); + return this; + } + + public DefaultHttpClientBuilder proxy(Proxy proxy) { + requireNonNull(proxy); + this.proxy = proxy; + return this; + } + + /** + * 启用双域名容灾 + * + * @return defaultHttpClientBuilder + */ + public DefaultHttpClientBuilder enableRetryMultiDomain() { + this.retryMultiDomain = true; + return this; + } + + /** OkHttp 在网络问题时不重试 */ + public DefaultHttpClientBuilder disableRetryOnConnectionFailure() { + this.retryOnConnectionFailure = false; + return this; + } + + /** + * 构建默认HttpClient + * + * @return httpClient + */ + @Override + public AbstractHttpClient build() { + requireNonNull(credential); + requireNonNull(validator); + okhttp3.OkHttpClient.Builder okHttpClientBuilder = + (customizeOkHttpClient == null ? defaultOkHttpClient : customizeOkHttpClient).newBuilder(); + if (connectTimeoutMs >= 0) { + okHttpClientBuilder.connectTimeout(connectTimeoutMs, TimeUnit.MILLISECONDS); + } + if (readTimeoutMs >= 0) { + okHttpClientBuilder.readTimeout(readTimeoutMs, TimeUnit.MILLISECONDS); + } + if (writeTimeoutMs >= 0) { + okHttpClientBuilder.writeTimeout(writeTimeoutMs, TimeUnit.MILLISECONDS); + } + if (proxy != null) { + okHttpClientBuilder.proxy(proxy); + } + if (retryMultiDomain) { + okHttpClientBuilder.addInterceptor(multiDomainInterceptor); + } + if (retryOnConnectionFailure != null && !retryOnConnectionFailure) { + okHttpClientBuilder.retryOnConnectionFailure(false); + } + return new OkHttpClientAdapter(credential, validator, okHttpClientBuilder.build()); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/FileRequestBody.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/FileRequestBody.java new file mode 100644 index 0000000..2ded48e --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/FileRequestBody.java @@ -0,0 +1,90 @@ +package com.wechat.pay.java.core.http; + +import com.wechat.pay.java.core.util.GsonUtil; + +import java.net.URLConnection; + +import static java.util.Objects.requireNonNull; + +/** 文件类型请求体 */ +public final class FileRequestBody implements RequestBody { + + private final String meta; + private final String fileName; + private final byte[] file; + + private FileRequestBody(String meta, String fileName, byte[] file) { + this.meta = meta; + this.fileName = fileName; + this.file = file; + } + + /** + * 获取媒体文件元信息 + * + * @return 媒体文件元信息 + */ + public String getMeta() { + return meta; + } + + /** + * 获取文件名 + * + * @return 文件名 + */ + public String getFileName() { + return fileName; + } + + /** + * 获取文件 + * + * @return 文件 + */ + public byte[] getFile() { + return file; + } + + @Override + public String getContentType() { + String contentTypeFromName = URLConnection.guessContentTypeFromName(fileName); + if (contentTypeFromName == null) { + // 表明是某种二进制数据 + return MediaType.APPLICATION_OCTET_STREAM.getValue(); + } + return contentTypeFromName; + } + + @Override + public String toString() { + return GsonUtil.getGson().toJson(this); + } + + public static class Builder { + + private String meta; + private String fileName; + private byte[] file; + + public Builder meta(String meta) { + this.meta = meta; + return this; + } + + public Builder fileName(String fileName) { + this.fileName = fileName; + return this; + } + + public Builder file(byte[] file) { + this.file = file; + return this; + } + + public FileRequestBody build() { + return new FileRequestBody( + requireNonNull(meta), requireNonNull(fileName), requireNonNull(file)); + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/HostName.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/HostName.java new file mode 100644 index 0000000..d9a1af5 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/HostName.java @@ -0,0 +1,23 @@ +package com.wechat.pay.java.core.http; + +import static java.util.Objects.requireNonNull; + +/** 微信支付域名 */ +public enum HostName { + API("api.mch.weixin.qq.com"), + APIHK("apihk.mch.weixin.qq.com"); + private final String value; + + HostName(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public boolean equalsWith(String string) { + requireNonNull(string); + return string.startsWith(value); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpClient.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpClient.java new file mode 100644 index 0000000..2c9af9e --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpClient.java @@ -0,0 +1,150 @@ +package com.wechat.pay.java.core.http; + +import com.wechat.pay.java.core.exception.HttpException; +import com.wechat.pay.java.core.exception.MalformedMessageException; +import com.wechat.pay.java.core.exception.ServiceException; +import com.wechat.pay.java.core.exception.ValidationException; + +import java.io.InputStream; + +/** HTTP请求客户端,自动生成签名和验证签名 */ +public interface HttpClient { + + /** + * 发送HTTP请求 + * + * @param request HTTP请求 + * @param responseClass 业务返回类的Class对象,如果不确定业务返回类型,或该请求没有返回体,可以传入Object.class + * @param 由Class对象建模的类的类型 + * @return HTTP返回 + * @throws HttpException 发送HTTP请求失败。例如构建请求参数失败、发送请求失败、I/O错误等。包含请求信息。 + * @throws ValidationException 发送HTTP请求成功,验证微信支付返回签名失败。 + * @throws ServiceException 发送HTTP请求成功,服务返回异常。例如返回状态码小于200或大于等于300。 + * @throws MalformedMessageException 服务返回成功,content-type不为application/json、解析返回体失败。 + */ + HttpResponse execute(HttpRequest request, Class responseClass); + + /** + * 发送GET请求 + * + * @param headers 请求头 + * @param url 请求URL + * @param responseClass 业务返回类的Class对象,如果不确定业务返回类型,或该请求没有返回体,可以传入Object.class + * @param 由Class对象建模的类的类型 + * @return HTTP返回 + * @throws HttpException 发送HTTP请求失败。例如构建请求参数失败、发送请求失败、I/O错误等。包含请求信息。 + * @throws ValidationException 发送HTTP请求成功,验证微信支付返回签名失败。 + * @throws ServiceException 发送HTTP请求成功,服务返回异常。例如返回状态码小于200或大于等于300。 + * @throws MalformedMessageException 服务返回成功,content-type不为application/json、解析返回体失败。 + */ + default HttpResponse get(HttpHeaders headers, String url, Class responseClass) { + HttpRequest httpRequest = + new HttpRequest.Builder().url(url).httpMethod(HttpMethod.GET).headers(headers).build(); + return execute(httpRequest, responseClass); + } + + /** + * 发送POST请求 + * + * @param headers 请求头 + * @param url 请求URL + * @param body 请求体 + * @param responseClass 业务返回类的Class对象,如果不确定业务返回类型,或该请求没有返回体,可以传入Object.class + * @param 由Class对象建模的类的类型 + * @return HTTP返回 + * @throws HttpException 发送HTTP请求失败。例如构建请求参数失败、发送请求失败、I/O错误等。包含请求信息。 + * @throws ValidationException 发送HTTP请求成功,验证微信支付返回签名失败。 + * @throws ServiceException 发送HTTP请求成功,服务返回异常。例如返回状态码小于200或大于等于300。 + * @throws MalformedMessageException 服务返回成功,content-type不为application/json、解析返回体失败。 + */ + default HttpResponse post( + HttpHeaders headers, String url, RequestBody body, Class responseClass) { + HttpRequest httpRequest = + new HttpRequest.Builder() + .url(url) + .httpMethod(HttpMethod.POST) + .headers(headers) + .body(body) + .build(); + return execute(httpRequest, responseClass); + } + + /** + * 发送PATCH请求 + * + * @param headers 请求头 + * @param url 请求URL + * @param body 请求体 + * @param responseClass 业务返回类的Class对象,如果不确定业务返回类型,或该请求没有返回体,可以传入Object.class + * @param 由Class对象建模的类的类型 + * @return HTTP返回 + * @throws HttpException 发送HTTP请求失败。例如构建请求参数失败、发送请求失败、I/O错误等。包含请求信息。 + * @throws ValidationException 发送HTTP请求成功,验证微信支付返回签名失败。 + * @throws ServiceException 发送HTTP请求成功,服务返回异常。例如返回状态码小于200或大于等于300。 + * @throws MalformedMessageException 服务返回成功,content-type不为application/json、解析返回体失败。 + */ + default HttpResponse patch( + HttpHeaders headers, String url, RequestBody body, Class responseClass) { + HttpRequest httpRequest = + new HttpRequest.Builder() + .url(url) + .httpMethod(HttpMethod.PATCH) + .headers(headers) + .body(body) + .build(); + return execute(httpRequest, responseClass); + } + + /** + * 发送PUT请求 + * + * @param headers 请求头 + * @param url 请求URL + * @param body 请求体 + * @param responseClass 业务返回类的Class对象,如果不确定业务返回类型,或该请求没有返回体,可以传入Object.class + * @param 由Class对象建模的类的类型 + * @return HTTP返回 + * @throws HttpException 发送HTTP请求失败。例如构建请求参数失败、发送请求失败、I/O错误等。包含请求信息。 + * @throws ValidationException 发送HTTP请求成功,验证微信支付返回签名失败。 + * @throws ServiceException 发送HTTP请求成功,服务返回异常。例如返回状态码小于200或大于等于300。 + * @throws MalformedMessageException 服务返回成功,content-type不为application/json、解析返回体失败。 + */ + default HttpResponse put( + HttpHeaders headers, String url, RequestBody body, Class responseClass) { + HttpRequest httpRequest = + new HttpRequest.Builder() + .url(url) + .httpMethod(HttpMethod.PUT) + .headers(headers) + .body(body) + .build(); + return execute(httpRequest, responseClass); + } + + /** + * 发送DELETE请求 + * + * @param headers 请求头 + * @param url 请求URL + * @param responseClass 业务返回类的Class对象,如果不确定业务返回类型,或该请求没有返回体,可以传入Object.class + * @param 由Class对象建模的类的类型 + * @return HTTP返回 + * @throws HttpException 发送HTTP请求失败。例如构建请求参数失败、发送请求失败、I/O错误等。包含请求信息。 + * @throws ValidationException 发送HTTP请求成功,验证微信支付返回签名失败。 + * @throws ServiceException 发送HTTP请求成功,服务返回异常。例如返回状态码小于200或大于等于300。 + * @throws MalformedMessageException 服务返回成功,content-type不为application/json、解析返回体失败。 + */ + default HttpResponse delete(HttpHeaders headers, String url, Class responseClass) { + HttpRequest httpRequest = + new HttpRequest.Builder().url(url).httpMethod(HttpMethod.DELETE).headers(headers).build(); + return execute(httpRequest, responseClass); + } + + /** + * 下载文件,文件流使用完后需要关闭 + * + * @param url 请求URL + * @return 文件流 + */ + InputStream download(String url); +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpHeaders.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpHeaders.java new file mode 100644 index 0000000..00f5b3a --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpHeaders.java @@ -0,0 +1,61 @@ +package com.wechat.pay.java.core.http; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import static java.util.Objects.requireNonNull; + +/** HTTP请求头 */ +public class HttpHeaders { + + private final Map headers = new HashMap<>(); + + public HttpHeaders() {} + + public HttpHeaders(Map headers) { + this.headers.putAll(headers); + } + + /** + * 增加请求头参数 + * + * @param name 参数名称 + * @param value 参数值 + */ + public void addHeader(String name, String value) { + headers.put(requireNonNull(name), requireNonNull(value)); + } + + /** + * 获取请求头参数 + * + * @param name 参数名称 + * @return 参数值 + */ + public String getHeader(String name) { + return headers.get(name); + } + + /** + * 获取请求头 + * + * @return 请求头 + */ + public Map getHeaders() { + return new HashMap<>(headers); + } + + @Override + public String toString() { + if (headers.isEmpty()) { + return ""; + } + StringBuilder sb = new StringBuilder(); + for (Entry entry : headers.entrySet()) { + sb.append(entry.getKey()).append("=").append(entry.getValue()).append(","); + } + sb.delete(sb.length() - 1, sb.length()).append("\n"); + return sb.toString(); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpMethod.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpMethod.java new file mode 100644 index 0000000..4ac5496 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpMethod.java @@ -0,0 +1,14 @@ +package com.wechat.pay.java.core.http; + +/** HTTP方法 */ +public enum HttpMethod { + GET, + + PUT, + + POST, + + PATCH, + + DELETE +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpRequest.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpRequest.java new file mode 100644 index 0000000..cb7bd64 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpRequest.java @@ -0,0 +1,179 @@ +package com.wechat.pay.java.core.http; + +import com.wechat.pay.java.core.exception.HttpException; +import com.wechat.pay.java.core.util.GsonUtil; + +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; + +import static java.util.Objects.requireNonNull; + +/** HTTP请求 */ +public final class HttpRequest { + + private final HttpMethod httpMethod; + private final URL url; + private final URI uri; + private final HttpHeaders headers; + private final RequestBody body; + + private HttpRequest( + HttpMethod httpMethod, URL url, URI uri, HttpHeaders headers, RequestBody body) { + this.httpMethod = httpMethod; + this.url = url; + this.uri = uri; + this.headers = headers; + this.body = body; + } + + /** + * 获取HttpMethod + * + * @return httpMethod + */ + public HttpMethod getHttpMethod() { + return httpMethod; + } + + /** + * 获取请求URL + * + * @return 请求URL + */ + public URL getUrl() { + return url; + } + + /** + * 获取请求URI + * + * @return 请求uri + */ + public URI getUri() { + return uri; + } + + /** + * 获取请求头 + * + * @return 请求头 + */ + public HttpHeaders getHeaders() { + return headers; + } + + /** + * 获取请求体 + * + * @return 请求体 + */ + public RequestBody getBody() { + return body; + } + + @Override + public String toString() { + return GsonUtil.getGson().toJson(this); + } + + public static class Builder { + + HttpMethod httpMethod; + private URL url; + private HttpHeaders headers = new HttpHeaders(); + private RequestBody body; + + /** + * 设置httpMethod + * + * @param httpMethod httpMethod + * @return Builder + */ + public Builder httpMethod(HttpMethod httpMethod) { + this.httpMethod = httpMethod; + return this; + } + + /** + * 设置url + * + * @param url url + * @return Builder + */ + public Builder url(URL url) { + this.url = url; + return this; + } + + /** + * 设置url + * + * @param urlString urlString + * @return Builder + */ + public Builder url(String urlString) { + try { + this.url = new URL(urlString); + return this; + } catch (MalformedURLException e) { + throw new IllegalArgumentException( + "The urlString passed in when building httpRequest is invalid:" + urlString); + } + } + + /** + * 重置headers + * + * @param headers headers + * @return Builder + */ + public Builder headers(HttpHeaders headers) { + this.headers = headers; + return this; + } + + /** + * 添加header + * + * @param name name + * @param value value + * @return Builder + */ + public Builder addHeader(String name, String value) { + headers.addHeader(name, value); + return this; + } + + /** + * 设置body + * + * @param body body + * @return Builder + */ + public Builder body(RequestBody body) { + this.body = body; + return this; + } + + /** + * 构建HttpRequest + * + * @return HttpRequest + * @throws HttpException url转uri失败 + */ + public HttpRequest build() { + try { + return new HttpRequest( + requireNonNull(httpMethod), + requireNonNull(url), + url.toURI(), + headers == null ? new HttpHeaders() : headers, + body); + } catch (URISyntaxException e) { + throw new HttpException(String.format("Parse url[%s] to uri failed.", url), e); + } + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpResponse.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpResponse.java new file mode 100644 index 0000000..a84e778 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/HttpResponse.java @@ -0,0 +1,111 @@ +package com.wechat.pay.java.core.http; + +import com.google.gson.JsonSyntaxException; +import com.wechat.pay.java.core.exception.MalformedMessageException; +import com.wechat.pay.java.core.util.GsonUtil; + +import java.util.Objects; + +/** + * HTTP返回 + * + * @param 业务返回体类型 + */ +public final class HttpResponse { + + private final HttpRequest request; + private final HttpHeaders headers; + private final ResponseBody body; + private final T serviceResponse; + + private HttpResponse( + HttpRequest request, HttpHeaders headers, ResponseBody body, T serviceResponse) { + this.request = request; + this.headers = headers; + this.body = body; + this.serviceResponse = serviceResponse; + } + + /** + * 获取返回头 + * + * @return 返回头 + */ + public HttpHeaders getHeaders() { + return headers; + } + + /** + * 获取返回对应的请求 + * + * @return 请求 + */ + public HttpRequest getRequest() { + return request; + } + + /** + * 获取返回体 + * + * @return 返回体 + */ + public ResponseBody getBody() { + return body; + } + + /** + * 获取业务返回 + * + * @return 业务返回 + */ + public T getServiceResponse() { + return serviceResponse; + } + + @Override + public String toString() { + return GsonUtil.getGson().toJson(this); + } + + public static class Builder { + + private OriginalResponse originalResponse; + private Class serviceResponseType; + + public Builder originalResponse(OriginalResponse originalResponse) { + this.originalResponse = originalResponse; + return this; + } + + public Builder serviceResponseType(Class serviceResponseType) { + this.serviceResponseType = serviceResponseType; + return this; + } + + /** + * 构造 HttpResponse + * + * @return httpResponse + */ + public HttpResponse build() { + Objects.requireNonNull(originalResponse); + if (originalResponse.getBody() == null + || originalResponse.getBody().isEmpty() + || serviceResponseType == null) { + return new HttpResponse<>( + originalResponse.getRequest(), originalResponse.getHeaders(), null, null); + } + ResponseBody body = new JsonResponseBody.Builder().body(originalResponse.getBody()).build(); + T serviceResponse; + try { + serviceResponse = + GsonUtil.getGson().fromJson(originalResponse.getBody(), serviceResponseType); + } catch (JsonSyntaxException e) { + throw new MalformedMessageException( + String.format("Invalid json response body[%s]", originalResponse.getBody()), e); + } + return new HttpResponse<>( + originalResponse.getRequest(), originalResponse.getHeaders(), body, serviceResponse); + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/JsonRequestBody.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/JsonRequestBody.java new file mode 100644 index 0000000..a4fb53a --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/JsonRequestBody.java @@ -0,0 +1,48 @@ +package com.wechat.pay.java.core.http; + +import com.wechat.pay.java.core.util.GsonUtil; + +import static java.util.Objects.requireNonNull; + +/** HTTP JSON类型请求体 */ +public final class JsonRequestBody implements RequestBody { + + private final String body; + + private JsonRequestBody(String body) { + this.body = body; + } + + /** + * 获取请求体 + * + * @return 请求体 + */ + public String getBody() { + return body; + } + + @Override + public String getContentType() { + return MediaType.APPLICATION_JSON.getValue(); + } + + @Override + public String toString() { + return GsonUtil.getGson().toJson(this); + } + + public static class Builder { + + private String body; + + public Builder body(String body) { + this.body = body; + return this; + } + + public JsonRequestBody build() { + return new JsonRequestBody(requireNonNull(body)); + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/JsonResponseBody.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/JsonResponseBody.java new file mode 100644 index 0000000..964ba5f --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/JsonResponseBody.java @@ -0,0 +1,46 @@ +package com.wechat.pay.java.core.http; + +import com.wechat.pay.java.core.util.GsonUtil; + +/** JSON类型返回体 */ +public final class JsonResponseBody implements ResponseBody { + + private final String body; + + private JsonResponseBody(String body) { + this.body = body; + } + + /** + * 获取返回体 + * + * @return 返回体 + */ + public String getBody() { + return body; + } + + @Override + public String getContentType() { + return MediaType.APPLICATION_JSON.getValue(); + } + + @Override + public String toString() { + return GsonUtil.getGson().toJson(this); + } + + public static class Builder { + + private String body; + + public Builder body(String body) { + this.body = body; + return this; + } + + public JsonResponseBody build() { + return new JsonResponseBody(body); + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/MediaType.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/MediaType.java new file mode 100644 index 0000000..756e8a3 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/MediaType.java @@ -0,0 +1,26 @@ +package com.wechat.pay.java.core.http; + +import static java.util.Objects.requireNonNull; + +/** HTTP媒体类型 */ +public enum MediaType { + APPLICATION_JSON("application/json"), + MULTIPART_FORM_DATA("multipart/form-data"), + APPLICATION_X_GZIP("application/x-gzip"), + APPLICATION_OCTET_STREAM("application/octet-stream"); + + private final String value; + + MediaType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public boolean equalsWith(String string) { + requireNonNull(string); + return string.startsWith(value); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/OriginalResponse.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/OriginalResponse.java new file mode 100644 index 0000000..9384434 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/OriginalResponse.java @@ -0,0 +1,133 @@ +package com.wechat.pay.java.core.http; + +import java.util.Map; +import java.util.Objects; + +public class OriginalResponse { + + private final HttpHeaders headers; + private final HttpRequest request; + private final String contentType; + private final int statusCode; + private final String body; + + private OriginalResponse( + HttpRequest request, int statusCode, HttpHeaders headers, String contentType, String body) { + this.request = request; + this.contentType = contentType; + this.headers = headers; + this.statusCode = statusCode; + this.body = body; + } + + /** + * 获取返回头 + * + * @return 返回头 + */ + public HttpHeaders getHeaders() { + return headers; + } + + /** + * 获取返回对应的请求 + * + * @return 请求 + */ + public HttpRequest getRequest() { + return request; + } + + /** + * 获取返回体 + * + * @return 返回体 + */ + public String getBody() { + return body; + } + + public String getContentType() { + return contentType; + } + + public int getStatusCode() { + return statusCode; + } + + /** OriginalResponse Builder */ + public static class Builder { + + private HttpRequest request; + private int statusCode; + private HttpHeaders headers; + private String contentType; + + private String jsonBody; + + /** + * 设置返回contentType + * + * @param contentType contentType + * @return OriginalResponse Builder + */ + public Builder contentType(String contentType) { + this.contentType = contentType; + return this; + } + + /** + * 设置返回headers + * + * @param headers contentType + * @return OriginalResponse Builder + */ + public Builder headers(Map headers) { + this.headers = new HttpHeaders(headers); + return this; + } + + /** + * 设置request + * + * @param request request + * @return OriginalResponse Builder + */ + public Builder request(HttpRequest request) { + this.request = request; + return this; + } + + /** + * 设置返回statusCode + * + * @param statusCode statusCode + * @return OriginalResponse Builder + */ + public Builder statusCode(int statusCode) { + this.statusCode = statusCode; + return this; + } + + /** + * 设置返回body + * + * @param jsonBody jsonBody + * @return OriginalResponse Builder + */ + public Builder body(String jsonBody) { + this.jsonBody = jsonBody; + return this; + } + + /** + * 构建 OriginalResponse + * + * @return OriginalResponse + */ + public OriginalResponse build() { + Objects.requireNonNull(request); + return new OriginalResponse(request, statusCode, headers, contentType, jsonBody); + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/QueryParameter.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/QueryParameter.java new file mode 100644 index 0000000..1434fcc --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/QueryParameter.java @@ -0,0 +1,28 @@ +package com.wechat.pay.java.core.http; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +public class QueryParameter { + + private final Map params = new HashMap<>(); + + public void add(String key, Object value) { + params.put(key, value); + } + + public String getQueryStr() { + boolean isFirstQueryParam = true; + StringBuilder queryStrBuilder = new StringBuilder(); + for (Entry entry : params.entrySet()) { + if (isFirstQueryParam) { + queryStrBuilder.append("?").append(entry.getKey()).append("=").append(entry.getValue()); + isFirstQueryParam = false; + continue; + } + queryStrBuilder.append("&").append(entry.getKey()).append("=").append(entry.getValue()); + } + return queryStrBuilder.toString(); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/RequestBody.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/RequestBody.java new file mode 100644 index 0000000..c61b2d2 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/RequestBody.java @@ -0,0 +1,12 @@ +package com.wechat.pay.java.core.http; + +/** HTTP请求体 */ +public interface RequestBody { + + /** + * 获取请求体的数据类型 + * + * @return 请求体的数据类型 + */ + String getContentType(); +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/ResponseBody.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/ResponseBody.java new file mode 100644 index 0000000..e7070c1 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/ResponseBody.java @@ -0,0 +1,12 @@ +package com.wechat.pay.java.core.http; + +/** HTTP返回体 */ +public interface ResponseBody { + + /** + * 获取返回体的数据类型 + * + * @return 返回体的数据类型 + */ + String getContentType(); +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/UrlEncoder.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/UrlEncoder.java new file mode 100644 index 0000000..653208d --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/UrlEncoder.java @@ -0,0 +1,22 @@ +package com.wechat.pay.java.core.http; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +public class UrlEncoder { + + /** + * 对参数进行url编码 + * + * @param string 待编码的字符串 + * @return 编码后的字符串 + */ + public static String urlEncode(String string) { + try { + return URLEncoder.encode(string, StandardCharsets.UTF_8.name()); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/okhttp/OkHttpClientAdapter.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/okhttp/OkHttpClientAdapter.java new file mode 100644 index 0000000..6f1ddbb --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/okhttp/OkHttpClientAdapter.java @@ -0,0 +1,164 @@ +package com.wechat.pay.java.core.http.okhttp; + +import com.wechat.pay.java.core.auth.Credential; +import com.wechat.pay.java.core.auth.Validator; +import com.wechat.pay.java.core.exception.HttpException; +import com.wechat.pay.java.core.exception.MalformedMessageException; +import com.wechat.pay.java.core.exception.ServiceException; +import com.wechat.pay.java.core.http.*; +import okhttp3.MultipartBody; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import static java.util.Objects.requireNonNull; + +/** OkHttp请求客户端 */ +public final class OkHttpClientAdapter extends AbstractHttpClient { + + private static final Logger logger = LoggerFactory.getLogger(OkHttpClientAdapter.class); + private static final String META_NAME = "meta"; + private static final String FILE_NAME = "file"; + + private final okhttp3.OkHttpClient okHttpClient; + + public OkHttpClientAdapter( + Credential credential, Validator validator, okhttp3.OkHttpClient client) { + super(credential, validator); + this.okHttpClient = requireNonNull(client); + } + + @Override + protected String getHttpClientInfo() { + return "okhttp3/" + okHttpClient.getClass().getPackage().getImplementationVersion(); + } + + @Override + public OriginalResponse innerExecute(HttpRequest wechatPayRequest) { + Request okHttpRequest = buildOkHttpRequest(wechatPayRequest); + try (Response okHttpResponse = okHttpClient.newCall(okHttpRequest).execute()) { + return assembleOriginalResponse(wechatPayRequest, okHttpResponse); + } catch (IOException e) { + throw new HttpException(wechatPayRequest, e); + } + } + + private Request buildOkHttpRequest(HttpRequest wechatPayRequest) { + Request.Builder okHttpRequestBuilder = new Request.Builder().url(wechatPayRequest.getUrl()); + Map headers = wechatPayRequest.getHeaders().getHeaders(); + headers.forEach(okHttpRequestBuilder::addHeader); + String method = wechatPayRequest.getHttpMethod().name(); + RequestBody okHttpRequestBody = + method.equals("GET") ? null : buildOkHttpRequestBody(wechatPayRequest.getBody()); + okHttpRequestBuilder.method(method, okHttpRequestBody); + return okHttpRequestBuilder.build(); + } + + private RequestBody buildOkHttpRequestBody( + com.wechat.pay.java.core.http.RequestBody wechatPayRequestBody) { + if (wechatPayRequestBody == null) { + // create an empty request body + return RequestBody.create("", null); + } + if (wechatPayRequestBody instanceof JsonRequestBody) { + return createOkHttpRequestBody(wechatPayRequestBody); + } + if (wechatPayRequestBody instanceof FileRequestBody) { + return createOkHttpMultipartRequestBody(wechatPayRequestBody); + } + logger.error( + "When an http request is sent and the okhttp request body is constructed, the requestBody parameter" + + " type cannot be found,requestBody class name[{}]", + wechatPayRequestBody.getClass().getName()); + return null; + } + + @SuppressWarnings("deprecation") + private okhttp3.RequestBody createRequestBody(String content, okhttp3.MediaType mediaType) { + // use an OkHttp3.x compatible method + // see https://github.com/wechatpay-apiv3/wechatpay-java/issues/70 + return okhttp3.RequestBody.create(mediaType, content); + } + + @SuppressWarnings("deprecation") + private okhttp3.RequestBody createRequestBody(byte[] content, okhttp3.MediaType mediaType) { + return okhttp3.RequestBody.create(mediaType, content); + } + + private RequestBody createOkHttpRequestBody( + com.wechat.pay.java.core.http.RequestBody wechatPayRequestBody) { + return createRequestBody( + ((JsonRequestBody) wechatPayRequestBody).getBody(), + okhttp3.MediaType.parse(wechatPayRequestBody.getContentType())); + } + + private RequestBody createOkHttpMultipartRequestBody( + com.wechat.pay.java.core.http.RequestBody wechatPayRequestBody) { + FileRequestBody fileRequestBody = (FileRequestBody) wechatPayRequestBody; + okhttp3.RequestBody okHttpFileBody = + createRequestBody( + fileRequestBody.getFile(), okhttp3.MediaType.parse(fileRequestBody.getContentType())); + return new okhttp3.MultipartBody.Builder() + .setType(MultipartBody.FORM) + .addFormDataPart(META_NAME, fileRequestBody.getMeta()) + .addFormDataPart(FILE_NAME, fileRequestBody.getFileName(), okHttpFileBody) + .build(); + } + + private Map assembleResponseHeader(Response okHttpResponse) { + Map responseHeaders = new ConcurrentHashMap<>(); + // use an OkHttp3.x compatible method + int headerSize = okHttpResponse.headers().size(); + for (int i = 0; i < headerSize; ++i) { + responseHeaders.put(okHttpResponse.headers().name(i), okHttpResponse.headers().value(i)); + } + return responseHeaders; + } + + private OriginalResponse assembleOriginalResponse( + HttpRequest wechatPayRequest, Response okHttpResponse) { + Map responseHeaders = assembleResponseHeader(okHttpResponse); + try { + return new OriginalResponse.Builder() + .request(wechatPayRequest) + .headers(responseHeaders) + .statusCode(okHttpResponse.code()) + .contentType( + okHttpResponse.body() == null || okHttpResponse.body().contentType() == null + ? null + : okHttpResponse.body().contentType().toString()) + .body(okHttpResponse.body().string()) + .build(); + } catch (IOException e) { + throw new MalformedMessageException( + String.format( + "Assemble OriginalResponse,get responseBody failed.%nHttpRequest[%s]", + wechatPayRequest)); + } + } + + @Override + protected InputStream innerDownload(HttpRequest httpRequest) { + Request okHttpRequest = buildOkHttpRequest(httpRequest); + try { + Response okHttpResponse = okHttpClient.newCall(okHttpRequest).execute(); + if (isInvalidHttpCode(okHttpResponse.code())) { + throw new ServiceException(httpRequest, okHttpResponse.code(), ""); + } + InputStream responseBodyStream = null; + if (okHttpResponse.body() != null) { + responseBodyStream = okHttpResponse.body().byteStream(); + } + return responseBodyStream; + } catch (IOException e) { + throw new HttpException(httpRequest, e); + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/http/okhttp/OkHttpMultiDomainInterceptor.java b/wx-pay/src/main/java/com/wechat/pay/java/core/http/okhttp/OkHttpMultiDomainInterceptor.java new file mode 100644 index 0000000..6abeb8d --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/http/okhttp/OkHttpMultiDomainInterceptor.java @@ -0,0 +1,60 @@ +package com.wechat.pay.java.core.http.okhttp; + +import com.wechat.pay.java.core.http.Constant; +import okhttp3.HttpUrl; +import okhttp3.Interceptor; +import okhttp3.Request; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +/** + * A dual-domain retry interceptor. This is an application interceptor that retries a request using + * "api2.wechatpay.cn" in case of network failure. It leverages disaster recovery in different city + * access data centers, while also avoiding failures due to DNS blocking. + */ +public class OkHttpMultiDomainInterceptor implements Interceptor { + private static final Logger logger = LoggerFactory.getLogger(OkHttpMultiDomainInterceptor.class); + + @NotNull + @Override + public okhttp3.Response intercept(Chain chain) throws IOException { + Request request = chain.request(); + + if (shouldRetry(request)) { + try { + /* + * Implementations of this interface throw IOException to signal connectivity failures. + * This includes both natural exceptions such as unreachable servers, + * as well as synthetic exceptions when responses are of an unexpected type or cannot be decoded + */ + return chain.proceed(request); + } catch (IOException e) { + logger.warn("Retrying request due to connectivity failure: {}", e.getMessage(), e); + + Request retryRequest = modifyRequestForRetry(request); + return chain.proceed(retryRequest); + } + } + + return chain.proceed(request); + } + + private boolean shouldRetry(Request request) { + return Constant.PRIMARY_API_DOMAIN.contains(request.url().host()); + } + + private Request modifyRequestForRetry(Request originalRequest) { + HttpUrl.Builder urlBuilder = originalRequest.url().newBuilder(); + urlBuilder.host(Constant.SECONDARY_API_DOMAIN); + + Request.Builder reqBuilder = originalRequest.newBuilder(); + reqBuilder.url(urlBuilder.build()); + reqBuilder.header( + Constant.USER_AGENT, originalRequest.header(Constant.USER_AGENT) + " (Retried-V1)"); + + return reqBuilder.build(); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/notification/AbstractNotificationConfig.java b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/AbstractNotificationConfig.java new file mode 100644 index 0000000..c5500be --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/AbstractNotificationConfig.java @@ -0,0 +1,86 @@ +package com.wechat.pay.java.core.notification; + +import com.wechat.pay.java.core.certificate.CertificateProvider; +import com.wechat.pay.java.core.cipher.AeadCipher; +import com.wechat.pay.java.core.cipher.RSAVerifier; +import com.wechat.pay.java.core.cipher.Verifier; + +import java.security.PublicKey; + +public abstract class AbstractNotificationConfig implements NotificationConfig { + + public final String signType; + private final String cipherAlgorithm; + private final CertificateProvider certificateProvider; + private final AeadCipher aeadCipher; + private final PublicKey publicKey; + private final String publicKeyId; + + protected AbstractNotificationConfig( + String signType, + String cipherAlgorithm, + CertificateProvider certificateProvider, + AeadCipher aeadCipher) { + this.signType = signType; + this.cipherAlgorithm = cipherAlgorithm; + this.certificateProvider = certificateProvider; + this.aeadCipher = aeadCipher; + this.publicKey = null; + this.publicKeyId = null; + } + + protected AbstractNotificationConfig( + String signType, + String cipherAlgorithm, + PublicKey publicKey, + String publicKeyId, + AeadCipher aeadCipher) { + this.signType = signType; + this.cipherAlgorithm = cipherAlgorithm; + this.publicKey = publicKey; + this.publicKeyId = publicKeyId; + this.aeadCipher = aeadCipher; + this.certificateProvider = null; + } + + protected AbstractNotificationConfig( + String signType, + String cipherAlgorithm, + CertificateProvider certificateProvider, + PublicKey publicKey, + String publicKeyId, + AeadCipher aeadCipher) { + this.signType = signType; + this.cipherAlgorithm = cipherAlgorithm; + this.publicKey = publicKey; + this.publicKeyId = publicKeyId; + this.aeadCipher = aeadCipher; + this.certificateProvider = certificateProvider; + } + + @Override + public String getSignType() { + return signType; + } + + @Override + public String getCipherType() { + return cipherAlgorithm; + } + + @Override + public Verifier createVerifier() { + if (publicKey != null && certificateProvider != null) { + return new RSAVerifier(publicKey, publicKeyId, certificateProvider); + } + if (publicKey != null) { + return new RSAVerifier(publicKey, publicKeyId); + } + return new RSAVerifier(certificateProvider); + } + + @Override + public AeadCipher createAeadCipher() { + return aeadCipher; + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/notification/AutoCertificateNotificationConfig.java b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/AutoCertificateNotificationConfig.java new file mode 100644 index 0000000..1dae719 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/AutoCertificateNotificationConfig.java @@ -0,0 +1,63 @@ +package com.wechat.pay.java.core.notification; + +import com.wechat.pay.java.core.AbstractRSAConfigBuilder; +import com.wechat.pay.java.core.certificate.CertificateProvider; +import com.wechat.pay.java.core.certificate.RSAAutoCertificateProvider; +import com.wechat.pay.java.core.cipher.AeadAesCipher; +import com.wechat.pay.java.core.cipher.AeadCipher; +import com.wechat.pay.java.core.http.HttpClient; + +import java.nio.charset.StandardCharsets; + +import static com.wechat.pay.java.core.notification.Constant.AES_CIPHER_ALGORITHM; +import static com.wechat.pay.java.core.notification.Constant.RSA_SIGN_TYPE; +import static java.util.Objects.requireNonNull; + +/** + * 通知回调配置类 + * + * @deprecated 请使用 RSAAutoCertificateConfig。 从版本 v0.2.4 起, 该类是多余的,而且功能不完整。 + * 开发者应尽快迁移。我们将在未来某个时间移除这段废弃的代码。 + */ +@Deprecated +public final class AutoCertificateNotificationConfig extends AbstractNotificationConfig { + + private AutoCertificateNotificationConfig( + CertificateProvider certificateProvider, AeadCipher aeadAesCipher) { + super(RSA_SIGN_TYPE, AES_CIPHER_ALGORITHM, certificateProvider, aeadAesCipher); + } + + public static class Builder extends AbstractRSAConfigBuilder { + protected HttpClient httpClient; + protected byte[] apiV3Key; + + public Builder apiV3Key(String apiV3Key) { + this.apiV3Key = apiV3Key.getBytes(StandardCharsets.UTF_8); + return this; + } + + public Builder httpClient(HttpClient httpClient) { + this.httpClient = httpClient; + return this; + } + + @Override + protected Builder self() { + return this; + } + + public AutoCertificateNotificationConfig build() { + RSAAutoCertificateProvider.Builder builder = + new RSAAutoCertificateProvider.Builder() + .apiV3Key(requireNonNull(apiV3Key)) + .privateKey(requireNonNull(privateKey)) + .merchantId(requireNonNull(merchantId)) + .merchantSerialNumber(requireNonNull(merchantSerialNumber)); + if (httpClient != null) { + builder.httpClient(httpClient); + } + return new AutoCertificateNotificationConfig( + builder.build(), new AeadAesCipher(requireNonNull(apiV3Key))); + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/notification/Constant.java b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/Constant.java new file mode 100644 index 0000000..ce00750 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/Constant.java @@ -0,0 +1,9 @@ +package com.wechat.pay.java.core.notification; + +/** Notification 常量 */ +public final class Constant { + public static final String RSA_SIGN_TYPE = "WECHATPAY2-SHA256-RSA2048"; + public static final String AES_CIPHER_ALGORITHM = "AEAD_AES_256_GCM"; + + private Constant() {} +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/notification/Notification.java b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/Notification.java new file mode 100644 index 0000000..369e9ae --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/Notification.java @@ -0,0 +1,89 @@ +package com.wechat.pay.java.core.notification; + +import com.google.gson.annotations.SerializedName; +import com.wechat.pay.java.core.util.GsonUtil; + +/** 微信支付回调通知 */ +public class Notification { + + @SerializedName("id") + private String id; + + @SerializedName("create_time") + private String createTime; + + @SerializedName("event_type") + private String eventType; + + @SerializedName("resource_type") + private String resourceType; + + @SerializedName("summary") + private String summary; + + @SerializedName("resource") + private Resource resource; + + private String plaintext; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getEventType() { + return eventType; + } + + public void setEventType(String eventType) { + this.eventType = eventType; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public String getSummary() { + return summary; + } + + public void setSummary(String summary) { + this.summary = summary; + } + + public Resource getResource() { + return resource; + } + + public void setResource(Resource resource) { + this.resource = resource; + } + + public String getPlaintext() { + return plaintext; + } + + public void setPlaintext(String plaintext) { + this.plaintext = plaintext; + } + + @Override + public String toString() { + return GsonUtil.getGson().toJson(this); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/notification/NotificationConfig.java b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/NotificationConfig.java new file mode 100644 index 0000000..78535e5 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/NotificationConfig.java @@ -0,0 +1,36 @@ +package com.wechat.pay.java.core.notification; + +import com.wechat.pay.java.core.cipher.AeadCipher; +import com.wechat.pay.java.core.cipher.Verifier; + +/** 用于解析通知的配置 */ +public interface NotificationConfig { + + /** + * 获取签名类型 + * + * @return 签名类型 + */ + String getSignType(); + + /** + * 获取认证加解密器类型 + * + * @return 认证加解密器类型 + */ + String getCipherType(); + + /** + * 创建验签器 + * + * @return 验签器 + */ + Verifier createVerifier(); + + /** + * 创建认证加解密器 + * + * @return 认证加解密器 + */ + AeadCipher createAeadCipher(); +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/notification/NotificationParser.java b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/NotificationParser.java new file mode 100644 index 0000000..b305415 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/NotificationParser.java @@ -0,0 +1,160 @@ +package com.wechat.pay.java.core.notification; + +import com.google.gson.Gson; +import com.wechat.pay.java.core.cipher.AeadCipher; +import com.wechat.pay.java.core.cipher.Verifier; +import com.wechat.pay.java.core.exception.MalformedMessageException; +import com.wechat.pay.java.core.exception.ValidationException; +import com.wechat.pay.java.core.util.GsonUtil; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; + +import static java.util.Objects.requireNonNull; + +/** 通知解析器 */ +public class NotificationParser { + + private final Gson gson = GsonUtil.getGson(); + private final Map verifiers = new HashMap<>(); + private final Map ciphers = new HashMap<>(); + + public NotificationParser(NotificationConfig... configs) { + if (configs.length == 0) { + throw new IllegalArgumentException("NotificationConfig is empty."); + } + for (NotificationConfig config : configs) { + this.verifiers.put(config.getSignType(), config.createVerifier()); + this.ciphers.put(config.getCipherType(), config.createAeadCipher()); + } + } + + public NotificationParser(Map verifiers, Map ciphers) { + this.verifiers.putAll(verifiers); + this.ciphers.putAll(ciphers); + } + + /** + * 解析微信支付回调通知 + * + * @param requestParam 解析通知所需要的请求参数 + * @param decryptObjectClass 解密数据的Class对象 + * @param 由Class对象建模的类的类型 + * @return 解密后的回调报文 + * @throws MalformedMessageException 回调通知参数不正确、解析通知数据失败 + * @throws ValidationException 签名验证失败 + */ + public T parse(RequestParam requestParam, Class decryptObjectClass) { + validateRequest(requestParam); + return getDecryptObject(requestParam, requireNonNull(decryptObjectClass)); + } + + private void validateRequest(RequestParam requestParam) { + if (requestParam == null) { + throw new ValidationException( + "Verify WechatPay notification parameters, requestParam is null."); + } + if (requestParam.getSignType() == null) { + throw new ValidationException( + String.format( + "Verify WechatPay notification parameters, signType is empty" + ".RequestParam[%s]", + requestParam)); + } + if (requestParam.getSerialNumber() == null) { + throw new ValidationException( + String.format( + "Verify WechatPay notification parameters, serialNumber is empty" + + ".RequestParam[%s]", + requestParam)); + } + if (requestParam.getMessage() == null) { + throw new ValidationException( + String.format( + "Verify WechatPay notification parameters, message is empty" + ".RequestParam[%s]", + requestParam)); + } + if (requestParam.getSignature() == null) { + throw new ValidationException( + String.format( + "Verify WechatPay notification parameters, signature is empty" + ".RequestParam[%s]", + requestParam)); + } + Verifier verifier = verifiers.get(requestParam.getSignType()); + if (verifier == null) { + throw new ValidationException( + String.format( + "Processing WechatPay notification, there is no verifier corresponding to signType[%s]", + requestParam.getSignType())); + } + if (!verifier.verify( + requestParam.getSerialNumber(), requestParam.getMessage(), requestParam.getSignature())) { + throw new ValidationException( + String.format( + "Processing WechatPay notification,signature verification failed," + + "signType[%s]\tserial[%s]\tmessage[%s]\tsign[%s]", + requestParam.getSignType(), + requestParam.getSerialNumber(), + requestParam.getMessage(), + requestParam.getSignature())); + } + } + + private T getDecryptObject(RequestParam requestParam, Class decryptObjectClass) { + Notification notification = gson.fromJson(requestParam.getBody(), Notification.class); + validateNotification(notification); + String algorithm = notification.getResource().getAlgorithm(); + String associatedData = notification.getResource().getAssociatedData(); + String nonce = notification.getResource().createNonce(); + String ciphertext = notification.getResource().getCiphertext(); + String plaintext = decryptData(algorithm, associatedData, nonce, ciphertext); + return gson.fromJson(plaintext, decryptObjectClass); + } + + private void validateNotification(Notification notification) { + if (notification == null) { + throw new MalformedMessageException( + "The notification obtained by parsing the WechatPay notification is null."); + } + Resource resource = notification.getResource(); + if (resource == null) { + throw new MalformedMessageException( + String.format( + "The resource obtained by parsing the WechatPay notification is null" + + ".Notification[%s]", + notification)); + } + if (resource.getAlgorithm() == null) { + throw new MalformedMessageException( + String.format( + "The algorithm obtained by parsing the WechatPay notification is empty.Notification[%s]", + notification)); + } + if (resource.getCiphertext() == null) { + throw new MalformedMessageException( + String.format( + "The ciphertext obtained by parsing the WechatPay notification is empty.Notification[%s]", + notification)); + } + if (resource.createNonce() == null) { + throw new MalformedMessageException( + String.format( + "The nonce obtained by parsing the WechatPay notification is empty.Notification[%s]", + notification)); + } + } + + private String decryptData( + String algorithm, String associatedData, String nonce, String ciphertext) { + AeadCipher aeadCipher = ciphers.get(algorithm); + if (aeadCipher == null) { + throw new MalformedMessageException( + "Parse WechatPay notification,There is no AeadCipher corresponding to the algorithm."); + } + return aeadCipher.decrypt( + associatedData.getBytes(StandardCharsets.UTF_8), + nonce.getBytes(StandardCharsets.UTF_8), + Base64.getDecoder().decode(ciphertext)); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/notification/RSACombinedNotificationConfig.java b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/RSACombinedNotificationConfig.java new file mode 100644 index 0000000..0838aa5 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/RSACombinedNotificationConfig.java @@ -0,0 +1,95 @@ +package com.wechat.pay.java.core.notification; + +import com.wechat.pay.java.core.AbstractRSAConfigBuilder; +import com.wechat.pay.java.core.certificate.CertificateProvider; +import com.wechat.pay.java.core.certificate.RSAAutoCertificateProvider; +import com.wechat.pay.java.core.cipher.AeadAesCipher; +import com.wechat.pay.java.core.cipher.AeadCipher; +import com.wechat.pay.java.core.http.HttpClient; +import com.wechat.pay.java.core.util.PemUtil; + +import java.nio.charset.StandardCharsets; +import java.security.PublicKey; + +import static com.wechat.pay.java.core.notification.Constant.AES_CIPHER_ALGORITHM; +import static com.wechat.pay.java.core.notification.Constant.RSA_SIGN_TYPE; +import static java.util.Objects.requireNonNull; + +/** 通知回调配置类 该类仅在商户由平台证书切换为平台公钥的灰度阶段使用,灰度完成后请切换为RSAPublicKeyNotificationConfig */ +public final class RSACombinedNotificationConfig extends AbstractNotificationConfig { + + private RSACombinedNotificationConfig( + CertificateProvider certificateProvider, + PublicKey publicKey, + String publicKeyId, + AeadCipher aeadAesCipher) { + super( + RSA_SIGN_TYPE, + AES_CIPHER_ALGORITHM, + certificateProvider, + publicKey, + publicKeyId, + aeadAesCipher); + } + + public static class Builder extends AbstractRSAConfigBuilder { + protected HttpClient httpClient; + protected byte[] apiV3Key; + + private PublicKey publicKey; + private String publicKeyId; + + public Builder apiV3Key(String apiV3Key) { + this.apiV3Key = apiV3Key.getBytes(StandardCharsets.UTF_8); + return this; + } + + public Builder httpClient(HttpClient httpClient) { + this.httpClient = httpClient; + return this; + } + + public Builder publicKey(String publicKey) { + this.publicKey = PemUtil.loadPublicKeyFromString(publicKey); + return this; + } + + public Builder publicKey(PublicKey publicKey) { + this.publicKey = publicKey; + return this; + } + + public Builder publicKeyFromPath(String publicKeyPath) { + this.publicKey = PemUtil.loadPublicKeyFromPath(publicKeyPath); + return this; + } + + public Builder publicKeyId(String publicKeyId) { + this.publicKeyId = publicKeyId; + return this; + } + + @Override + protected Builder self() { + return this; + } + + public RSACombinedNotificationConfig build() { + + RSAAutoCertificateProvider.Builder builder = + new RSAAutoCertificateProvider.Builder() + .apiV3Key(requireNonNull(apiV3Key)) + .privateKey(requireNonNull(privateKey)) + .merchantId(requireNonNull(merchantId)) + .merchantSerialNumber(requireNonNull(merchantSerialNumber)); + if (httpClient != null) { + builder.httpClient(httpClient); + } + return new RSACombinedNotificationConfig( + builder.build(), + requireNonNull(publicKey), + requireNonNull(publicKeyId), + new AeadAesCipher(requireNonNull(apiV3Key))); + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/notification/RSANotificationConfig.java b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/RSANotificationConfig.java new file mode 100644 index 0000000..786a6ef --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/RSANotificationConfig.java @@ -0,0 +1,71 @@ +package com.wechat.pay.java.core.notification; + +import com.wechat.pay.java.core.certificate.CertificateProvider; +import com.wechat.pay.java.core.certificate.InMemoryCertificateProvider; +import com.wechat.pay.java.core.cipher.AeadAesCipher; +import com.wechat.pay.java.core.cipher.AeadCipher; +import com.wechat.pay.java.core.util.PemUtil; + +import java.nio.charset.StandardCharsets; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static com.wechat.pay.java.core.notification.Constant.AES_CIPHER_ALGORITHM; +import static com.wechat.pay.java.core.notification.Constant.RSA_SIGN_TYPE; +import static java.util.Objects.requireNonNull; + +/** + * 通知回调配置类 + * + * @deprecated 请使用 RSAAutoCertificateConfig,开发者应尽快迁移,我们将在未来某个时间移除这段废弃的代码。 + */ +public final class RSANotificationConfig extends AbstractNotificationConfig { + + private RSANotificationConfig(CertificateProvider certificateProvider, AeadCipher aeadCipher) { + super(RSA_SIGN_TYPE, AES_CIPHER_ALGORITHM, certificateProvider, aeadCipher); + } + + public static class Builder { + + private List certificates; + private byte[] apiV3Key; + + public Builder certificates(X509Certificate... certificates) { + this.certificates = Arrays.asList(certificates); + return this; + } + + public Builder certificates(String... certificates) { + List certificateList = new ArrayList<>(); + for (String certificateString : certificates) { + X509Certificate x509Certificate = PemUtil.loadX509FromString(certificateString); + certificateList.add(x509Certificate); + } + this.certificates = certificateList; + return this; + } + + public Builder certificatesFromPath(String... certificatePaths) { + List certificateList = new ArrayList<>(); + for (String certificatePath : certificatePaths) { + X509Certificate x509Certificate = PemUtil.loadX509FromPath(certificatePath); + certificateList.add(x509Certificate); + } + this.certificates = certificateList; + return this; + } + + public Builder apiV3Key(String apiV3Key) { + this.apiV3Key = apiV3Key.getBytes(StandardCharsets.UTF_8); + return this; + } + + public RSANotificationConfig build() { + CertificateProvider certificateProvider = new InMemoryCertificateProvider(certificates); + return new RSANotificationConfig( + certificateProvider, new AeadAesCipher(requireNonNull(apiV3Key))); + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/notification/RSAPublicKeyNotificationConfig.java b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/RSAPublicKeyNotificationConfig.java new file mode 100644 index 0000000..5957f32 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/RSAPublicKeyNotificationConfig.java @@ -0,0 +1,61 @@ +package com.wechat.pay.java.core.notification; + +import com.wechat.pay.java.core.cipher.AeadAesCipher; +import com.wechat.pay.java.core.cipher.AeadCipher; +import com.wechat.pay.java.core.util.PemUtil; + +import java.nio.charset.StandardCharsets; +import java.security.PublicKey; + +import static com.wechat.pay.java.core.notification.Constant.AES_CIPHER_ALGORITHM; +import static com.wechat.pay.java.core.notification.Constant.RSA_SIGN_TYPE; +import static java.util.Objects.requireNonNull; + +/** 签名类型为RSA的通知配置参数 */ +public final class RSAPublicKeyNotificationConfig extends AbstractNotificationConfig { + + private RSAPublicKeyNotificationConfig( + PublicKey publicKey, String publicKeyId, AeadCipher aeadCipher) { + super(RSA_SIGN_TYPE, AES_CIPHER_ALGORITHM, publicKey, publicKeyId, aeadCipher); + } + + public static class Builder { + private byte[] apiV3Key; + + private PublicKey publicKey; + private String publicKeyId; + + public Builder publicKey(String publicKey) { + this.publicKey = PemUtil.loadPublicKeyFromString(publicKey); + return this; + } + + public Builder publicKey(PublicKey publicKey) { + this.publicKey = publicKey; + return this; + } + + public Builder publicKeyFromPath(String publicKeyPath) { + this.publicKey = PemUtil.loadPublicKeyFromPath(publicKeyPath); + return this; + } + + public Builder apiV3Key(String apiV3Key) { + this.apiV3Key = apiV3Key.getBytes(StandardCharsets.UTF_8); + return this; + } + + public Builder publicKeyId(String publicKeyId) { + this.publicKeyId = publicKeyId; + return this; + } + + public RSAPublicKeyNotificationConfig build() { + requireNonNull(publicKey); + requireNonNull(publicKeyId); + requireNonNull(apiV3Key); + return new RSAPublicKeyNotificationConfig( + publicKey, requireNonNull(publicKeyId), new AeadAesCipher(requireNonNull(apiV3Key))); + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/notification/RequestParam.java b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/RequestParam.java new file mode 100644 index 0000000..089bbc1 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/RequestParam.java @@ -0,0 +1,99 @@ +package com.wechat.pay.java.core.notification; + +import com.wechat.pay.java.core.util.GsonUtil; + +import static com.wechat.pay.java.core.notification.Constant.RSA_SIGN_TYPE; + +/** 微信支付通知请求参数 */ +public class RequestParam { + + private final String serialNumber; + private final String signature; + private final String message; + private final String body; + private final String signType; + + private RequestParam( + String serialNumber, String signature, String message, String body, String signType) { + this.serialNumber = serialNumber; + this.signature = signature; + this.message = message; + this.body = body; + // 回调报文头新增Wechatpay-Signature-Type,默认为WECHATPAY2-SHA256-RSA2048 + if (signType == null || signType.isEmpty()) { + this.signType = RSA_SIGN_TYPE; + } else { + this.signType = signType; + } + } + + public String getSerialNumber() { + return serialNumber; + } + + public String getMessage() { + return message; + } + + public String getSignature() { + return signature; + } + + public String getBody() { + return body; + } + + public String getSignType() { + return signType; + } + + @Override + public String toString() { + return GsonUtil.getGson().toJson(this); + } + + public static class Builder { + + String signType; + private String serialNumber; + private String timestamp; + private String nonce; + private String signature; + private String body; + + public Builder serialNumber(String serialNumber) { + this.serialNumber = serialNumber; + return this; + } + + public Builder timestamp(String timestamp) { + this.timestamp = timestamp; + return this; + } + + public Builder nonce(String nonce) { + this.nonce = nonce; + return this; + } + + public Builder signature(String signature) { + this.signature = signature; + return this; + } + + public Builder signType(String signType) { + this.signType = signType; + return this; + } + + public Builder body(String body) { + this.body = body; + return this; + } + + public RequestParam build() { + String message = timestamp + "\n" + nonce + "\n" + body + "\n"; + return new RequestParam(serialNumber, signature, message, body, signType); + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/notification/Resource.java b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/Resource.java new file mode 100644 index 0000000..9fdb0ec --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/notification/Resource.java @@ -0,0 +1,62 @@ +package com.wechat.pay.java.core.notification; + +import com.wechat.pay.java.core.util.GsonUtil; + +/** 通知数据 */ +public class Resource { + + private String algorithm; + private String ciphertext; + private String associatedData; + private String nonce; + private String originalType; + + public String getAlgorithm() { + return algorithm; + } + + public String getCiphertext() { + return ciphertext; + } + + public String getAssociatedData() { + return associatedData; + } + + public String createNonce() { + return nonce; + } + + public String getOriginalType() { + return originalType; + } + + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; + } + + public void setCiphertext(String ciphertext) { + this.ciphertext = ciphertext; + } + + public void setAssociatedData(String associatedData) { + this.associatedData = associatedData; + } + + public void setNonce(String nonce) { + this.nonce = nonce; + } + + public void setOriginalType(String originalType) { + this.originalType = originalType; + } + + @Override + public String toString() { + return GsonUtil.getGson().toJson(this); + } + + public String getNonce() { + return nonce; + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/util/GsonUtil.java b/wx-pay/src/main/java/com/wechat/pay/java/core/util/GsonUtil.java new file mode 100644 index 0000000..6e0cad5 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/util/GsonUtil.java @@ -0,0 +1,65 @@ +package com.wechat.pay.java.core.util; + +import com.google.gson.*; +import com.google.gson.annotations.Expose; + +/** Gson工具类 */ +public class GsonUtil { + + private GsonUtil() {} + + private static final Gson gson; + + static { + gson = + new GsonBuilder() + .disableHtmlEscaping() + .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) + .addSerializationExclusionStrategy( + new ExclusionStrategy() { + @Override + public boolean shouldSkipField(FieldAttributes fieldAttributes) { + final Expose expose = fieldAttributes.getAnnotation(Expose.class); + return expose != null && !expose.serialize(); + } + + @Override + public boolean shouldSkipClass(Class aClass) { + return false; + } + }) + .addDeserializationExclusionStrategy( + new ExclusionStrategy() { + @Override + public boolean shouldSkipField(FieldAttributes fieldAttributes) { + final Expose expose = fieldAttributes.getAnnotation(Expose.class); + return expose != null && !expose.deserialize(); + } + + @Override + public boolean shouldSkipClass(Class aClass) { + return false; + } + }) + .create(); + } + + /** + * 获取自定义设置的Gson对象 + * + * @return Gson对象 + */ + public static Gson getGson() { + return gson; + } + + /** + * 转换对象为JSON格式字符串 + * + * @param object 待转换对象 + * @return JSON格式字符串 + */ + public static String toJson(Object object) { + return gson.toJson(object); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/util/IOUtil.java b/wx-pay/src/main/java/com/wechat/pay/java/core/util/IOUtil.java new file mode 100644 index 0000000..7f18826 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/util/IOUtil.java @@ -0,0 +1,59 @@ +package com.wechat.pay.java.core.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; + +/** I/O工具 */ +public class IOUtil { + + private static final int DEFAULT_BUFFER_SIZE = 8192; + + private IOUtil() {} + + /** + * 转换输入流为字节数组 + * + * @param inputStream 输入流 + * @return 字节数组 + * @throws IOException 读取字节失败、关闭流失败等 + */ + public static byte[] toByteArray(InputStream inputStream) throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + int nRead; + byte[] data = new byte[DEFAULT_BUFFER_SIZE]; + while ((nRead = inputStream.read(data, 0, data.length)) != -1) { + buffer.write(data, 0, nRead); + } + + return buffer.toByteArray(); + } + + /** + * 转换输入流为字符串 + * + * @param inputStream 输入流 + * @return UTF-8编码的字符串 + * @throws IOException 读取字节失败、关闭流失败等 + */ + public static String toString(InputStream inputStream) throws IOException { + return new String(toByteArray(inputStream), StandardCharsets.UTF_8); + } + + /** + * 从文件路径中读取字符串 + * + * @param path 文件路径 + * @return UTF-8编码的字符串 + * @throws IOException 读取字节失败、关闭流失败等 + */ + public static String loadStringFromPath(String path) throws IOException { + try (InputStream inputStream = Files.newInputStream(Paths.get(path))) { + return toString(inputStream); + } + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/util/NonceUtil.java b/wx-pay/src/main/java/com/wechat/pay/java/core/util/NonceUtil.java new file mode 100644 index 0000000..b366a1c --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/util/NonceUtil.java @@ -0,0 +1,27 @@ +package com.wechat.pay.java.core.util; + +import java.security.SecureRandom; + +/** 随机串生成工具 */ +public class NonceUtil { + + private NonceUtil() {} + + private static final char[] SYMBOLS = + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); + private static final SecureRandom random = new SecureRandom(); + + /** + * 使用SecureRandom生成随机串 + * + * @param length 随机串长度 + * @return nonce 随机串 + */ + public static String createNonce(int length) { + char[] buf = new char[length]; + for (int i = 0; i < length; ++i) { + buf[i] = SYMBOLS[random.nextInt(SYMBOLS.length)]; + } + return new String(buf); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/util/PemUtil.java b/wx-pay/src/main/java/com/wechat/pay/java/core/util/PemUtil.java new file mode 100644 index 0000000..ee418f4 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/util/PemUtil.java @@ -0,0 +1,236 @@ +package com.wechat.pay.java.core.util; + +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +import static com.wechat.pay.java.core.cipher.Constant.HEX; + +/** PEM工具 */ +public class PemUtil { + + private PemUtil() {} + + /** + * 从字符串中加载RSA私钥。 + * + * @param keyString 私钥字符串 + * @return RSA私钥 + */ + public static PrivateKey loadPrivateKeyFromString(String keyString) { + try { + keyString = + keyString + .replace("-----BEGIN PRIVATE KEY-----", "") + .replace("-----END PRIVATE KEY-----", "") + .replaceAll("\\s+", ""); + return KeyFactory.getInstance("RSA") + .generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(keyString))); + } catch (NoSuchAlgorithmException e) { + throw new UnsupportedOperationException(e); + } catch (InvalidKeySpecException e) { + throw new IllegalArgumentException(e); + } + } + + /** + * 从字符串中加载指定算法的私钥 + * + * @param keyString 私钥字符串 + * @param algorithm 私钥算法 + * @param provider the provider + * @return 私钥 + */ + public static PrivateKey loadPrivateKeyFromString( + String keyString, String algorithm, String provider) { + try { + keyString = + keyString + .replace("-----BEGIN PRIVATE KEY-----", "") + .replace("-----END PRIVATE KEY-----", "") + .replaceAll("\\s+", ""); + return KeyFactory.getInstance(algorithm, provider) + .generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(keyString))); + } catch (NoSuchAlgorithmException e) { + throw new UnsupportedOperationException(e); + } catch (InvalidKeySpecException | NoSuchProviderException e) { + throw new IllegalArgumentException(e); + } + } + + /** + * 从字符串中加载RSA公钥。 + * + * @param keyString 公钥字符串 + * @return RSA公钥 + */ + public static PublicKey loadPublicKeyFromString(String keyString) { + try { + keyString = + keyString + .replace("-----BEGIN PUBLIC KEY-----", "") + .replace("-----END PUBLIC KEY-----", "") + .replaceAll("\\s+", ""); + return KeyFactory.getInstance("RSA") + .generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(keyString))); + } catch (NoSuchAlgorithmException e) { + throw new UnsupportedOperationException(e); + } catch (InvalidKeySpecException e) { + throw new IllegalArgumentException(e); + } + } + + /** + * 从文件路径加载RSA私钥 + * + * @param keyPath 私钥路径 + * @return RSA私钥 + */ + public static PrivateKey loadPrivateKeyFromPath(String keyPath) { + return loadPrivateKeyFromString(readKeyStringFromPath(keyPath)); + } + + /** + * 从文件路径加载指定算法的私钥 + * + * @param keyPath 私钥路径 + * @param algorithm 私钥算法 + * @param provider the provider + * @return 私钥 + */ + public static PrivateKey loadPrivateKeyFromPath( + String keyPath, String algorithm, String provider) { + return loadPrivateKeyFromString(readKeyStringFromPath(keyPath), algorithm, provider); + } + + /** + * 从文件路径加载RSA公钥 + * + * @param keyPath 公钥路径 + * @return RSA公钥 + */ + public static PublicKey loadPublicKeyFromPath(String keyPath) { + return loadPublicKeyFromString(readKeyStringFromPath(keyPath)); + } + + private static String readKeyStringFromPath(String keyPath) { +// try (FileInputStream inputStream = new FileInputStream(keyPath)) { +// return IOUtil.toString(inputStream); +// } catch (IOException e) { +// throw new UncheckedIOException(e); +// } + + try { + InputStream a = new ClassPathResource(keyPath).getInputStream(); + return IOUtil.toString(a); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + + } + + /** + * 从输入流加载X.509证书 + * + * @param inputStream 私钥输入流 + * @return X.509证书 + */ + public static X509Certificate loadX509FromStream(InputStream inputStream) { + try { + return (X509Certificate) + CertificateFactory.getInstance("X.509").generateCertificate(inputStream); + } catch (CertificateException e) { + throw new IllegalArgumentException(e); + } + } + + /** + * 从输入流加载X.509证书 + * + * @param inputStream 私钥输入流 + * @param provider the provider + * @return X.509证书 + */ + public static X509Certificate loadX509FromStream(InputStream inputStream, String provider) { + try { + return (X509Certificate) + CertificateFactory.getInstance("X.509", provider).generateCertificate(inputStream); + } catch (CertificateException | NoSuchProviderException e) { + throw new IllegalArgumentException(e); + } + } + + /** + * 从文件路径加载X.509证书 + * + * @param certificatePath 证书文件路径 + * @return X.509证书 + */ + public static X509Certificate loadX509FromPath(String certificatePath) { + try (FileInputStream inputStream = new FileInputStream(certificatePath)) { + return loadX509FromStream(inputStream); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + /** + * 从文件路径加载X.509证书 + * + * @param certificatePath 证书文件路径 + * @param provider the provider + * @return X.509证书 + */ + public static X509Certificate loadX509FromPath(String certificatePath, String provider) { + try (FileInputStream inputStream = new FileInputStream(certificatePath)) { + return loadX509FromStream(inputStream, provider); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + /** + * 从字符串加载X.509证书 + * + * @param certificateString 证书字符串 + * @return X.509证书 + */ + public static X509Certificate loadX509FromString(String certificateString) { + try (ByteArrayInputStream inputStream = + new ByteArrayInputStream(certificateString.getBytes(StandardCharsets.UTF_8))) { + return loadX509FromStream(inputStream); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + /** + * 从字符串加载X.509证书 + * + * @param certificateString 证书字符串 + * @param provider the provider + * @return X.509证书 + */ + public static X509Certificate loadX509FromString(String certificateString, String provider) { + try (ByteArrayInputStream inputStream = + new ByteArrayInputStream(certificateString.getBytes(StandardCharsets.UTF_8))) { + return loadX509FromStream(inputStream, provider); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public static String getSerialNumber(X509Certificate certificate) { + return certificate.getSerialNumber().toString(HEX).toUpperCase(); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/util/ShaUtil.java b/wx-pay/src/main/java/com/wechat/pay/java/core/util/ShaUtil.java new file mode 100644 index 0000000..08b6ea2 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/util/ShaUtil.java @@ -0,0 +1,107 @@ +package com.wechat.pay.java.core.util; + +import java.io.IOException; +import java.io.InputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import static java.util.Objects.requireNonNull; + +/** SHA工具 */ +public class ShaUtil { + + private ShaUtil() {} + + public static final int BUFFER_SIZE = 1024; + public static final String SHA1 = "SHA-1"; + public static final String SHA256 = "SHA-256"; + + /** + * 生成SHA1的HEX编码消息摘要字符串 + * + * @param inputStream 消息输入流 + * @return HEX编码消息摘要字符串 + * @throws IOException 读取输入流失字节、关闭流失败等 + */ + public static String getSha1HexString(InputStream inputStream) throws IOException { + return getShaHexString(inputStream, SHA1); + } + + /** + * 生成SHA1的HEX编码消息摘要字符串 + * + * @param source 消息输入 + * @return HEX编码消息摘要字符串 + */ + public static String getSha1HexString(byte[] source) { + return getShaHexString(source, SHA1); + } + + /** + * 生成SHA256的HEX编码消息摘要字符串 + * + * @param inputStream 消息输入流 + * @return HEX编码消息摘要字符串 + * @throws IOException 读取输入流失字节、关闭流失败等 + */ + public static String getSha256HexString(InputStream inputStream) throws IOException { + return getShaHexString(inputStream, SHA256); + } + + /** + * 生成SHA256的HEX编码消息摘要字符串 + * + * @param source 消息输入 + * @return HEX编码消息摘要字符串 + */ + public static String getSha256HexString(byte[] source) { + return getShaHexString(source, SHA256); + } + + private static String getShaHexString(InputStream inputStream, String algorithm) + throws IOException { + byte[] data = new byte[BUFFER_SIZE]; + int nRead; + try { + MessageDigest digest = MessageDigest.getInstance(algorithm); + while ((nRead = inputStream.read(data, 0, data.length)) != -1) { + digest.update(data, 0, nRead); + } + return toHexString(digest.digest()); + } catch (NoSuchAlgorithmException e) { + throw new SecurityException(e); + } + } + + /** + * 生成SHA算法的HEX编码消息摘要字符串 + * + * @param source 消息字节数组 + * @param algorithm 具体的SHA算法,例如SHA-1、SHA-256 + * @return HEX编码消息摘要字符串 + */ + private static String getShaHexString(byte[] source, String algorithm) { + requireNonNull(source); + try { + MessageDigest digest = MessageDigest.getInstance(algorithm); + digest.update(source); + return toHexString(digest.digest()); + } catch (NoSuchAlgorithmException e) { + throw new SecurityException(e); + } + } + + /** + * 转换字节数组为HEX编码字符串 + * + * @param bytes 字节数组 + * @return HEX编码字符串 + */ + public static String toHexString(byte[] bytes) { + StringBuilder sb = new StringBuilder(bytes.length * 2); + for (byte b : bytes) { + sb.append(String.format("%02x", b)); + } + return sb.toString(); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/core/util/StringUtil.java b/wx-pay/src/main/java/com/wechat/pay/java/core/util/StringUtil.java new file mode 100644 index 0000000..f9b2487 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/core/util/StringUtil.java @@ -0,0 +1,19 @@ +package com.wechat.pay.java.core.util; + +/** 字符串工具类 */ +public class StringUtil { + private StringUtil() {} + + /** + * 将给定对象转换为字符串,每行缩进 4 个空格(除了首行) + * + * @param o 对象 + * @return 格式化字符串 + */ + public static String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/TransferBatchServiceBase.java b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/TransferBatchServiceBase.java new file mode 100644 index 0000000..bb3eb32 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/TransferBatchServiceBase.java @@ -0,0 +1,303 @@ +// Copyright 2021 Tencent Inc. All rights reserved. +// +// 商家转账对外API +// +// * 场景及业务流程: 商户可通过该产品实现同时向多个用户微信零钱进行转账的操作,可用于发放奖金补贴、佣金货款结算、员工报销等场景。 +// [https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0](https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0) * 接入步骤: * 商户在微信支付商户平台开通“批量转账到零钱”产品权限,并勾选“使用API方式发起转账”。 * 调用批量转账接口,对多个用户微信零钱发起转账。 * 调用查询批次接口,可获取到转账批次详情及当前状态。 * 调用查询明细接口,可获取到单条转账明细详情及当前状态。 +// +// API version: 1.0.5 + +// Code generated by WechatPay APIv3 Generator based on [OpenAPI +// Generator](https://openapi-generator.tech); DO NOT EDIT. + +package com.wechat.pay.java.service.transferbatch; + +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.cipher.PrivacyDecryptor; +import com.wechat.pay.java.core.cipher.PrivacyEncryptor; +import com.wechat.pay.java.core.exception.HttpException; +import com.wechat.pay.java.core.exception.MalformedMessageException; +import com.wechat.pay.java.core.exception.ServiceException; +import com.wechat.pay.java.core.exception.ValidationException; +import com.wechat.pay.java.core.http.*; +import com.wechat.pay.java.service.transferbatch.model.*; + +import static com.wechat.pay.java.core.http.UrlEncoder.urlEncode; +import static com.wechat.pay.java.core.util.GsonUtil.toJson; +import static java.util.Objects.requireNonNull; + +/** TransferBatchService服务 */ +public class TransferBatchServiceBase { + + private final HttpClient httpClient; + private final HostName hostName; + private final PrivacyEncryptor encryptor; + private final PrivacyDecryptor decryptor; + + private TransferBatchServiceBase( + HttpClient httpClient, + HostName hostName, + PrivacyEncryptor encryptor, + PrivacyDecryptor decryptor) { + this.httpClient = requireNonNull(httpClient); + this.hostName = hostName; + this.encryptor = requireNonNull(encryptor); + this.decryptor = requireNonNull(decryptor); + } + + /** TransferBatchService构造器 */ + public static class Builder { + + private HttpClient httpClient; + private HostName hostName; + private PrivacyEncryptor encryptor; + private PrivacyDecryptor decryptor; + + public Builder config(Config config) { + this.httpClient = new DefaultHttpClientBuilder().config(config).build(); + this.encryptor = config.createEncryptor(); + this.decryptor = config.createDecryptor(); + return this; + } + + public Builder hostName(HostName hostName) { + this.hostName = hostName; + return this; + } + + public Builder httpClient(HttpClient httpClient) { + this.httpClient = httpClient; + return this; + } + + public Builder encryptor(PrivacyEncryptor encryptor) { + this.encryptor = encryptor; + return this; + } + + public Builder decryptor(PrivacyDecryptor decryptor) { + this.decryptor = decryptor; + return this; + } + + public TransferBatchServiceBase build() { + return new TransferBatchServiceBase(httpClient, hostName, encryptor, decryptor); + } + } + + /** + * 通过微信批次单号查询批次单 + * + * @param request 请求参数 + * @return TransferBatchEntity + * @throws HttpException 发送HTTP请求失败。例如构建请求参数失败、发送请求失败、I/O错误等。包含请求信息。 + * @throws ValidationException 发送HTTP请求成功,验证微信支付返回签名失败。 + * @throws ServiceException 发送HTTP请求成功,服务返回异常。例如返回状态码小于200或大于等于300。 + * @throws MalformedMessageException 服务返回成功,content-type不为application/json、解析返回体失败。 + */ + public TransferBatchEntity getTransferBatchByNo(GetTransferBatchByNoRequest request) { + String requestPath = "https://api.mch.weixin.qq.com/v3/transfer/batches/batch-id/{batch_id}"; + + GetTransferBatchByNoRequest realRequest = request; + // 添加 path param + requestPath = requestPath.replace("{" + "batch_id" + "}", urlEncode(realRequest.getBatchId())); + + // 添加 query param + QueryParameter queryParameter = new QueryParameter(); + if (realRequest.getNeedQueryDetail() != null) { + queryParameter.add( + "need_query_detail", urlEncode(realRequest.getNeedQueryDetail().toString())); + } + if (realRequest.getOffset() != null) { + queryParameter.add("offset", urlEncode(realRequest.getOffset().toString())); + } + if (realRequest.getLimit() != null) { + queryParameter.add("limit", urlEncode(realRequest.getLimit().toString())); + } + if (realRequest.getDetailStatus() != null) { + queryParameter.add("detail_status", urlEncode(realRequest.getDetailStatus())); + } + requestPath += queryParameter.getQueryStr(); + if (this.hostName != null) { + requestPath = requestPath.replaceFirst(HostName.API.getValue(), hostName.getValue()); + } + HttpHeaders headers = new HttpHeaders(); + headers.addHeader(Constant.ACCEPT, MediaType.APPLICATION_JSON.getValue()); + headers.addHeader(Constant.CONTENT_TYPE, MediaType.APPLICATION_JSON.getValue()); + HttpRequest httpRequest = + new HttpRequest.Builder() + .httpMethod(HttpMethod.GET) + .url(requestPath) + .headers(headers) + .build(); + HttpResponse httpResponse = + httpClient.execute(httpRequest, TransferBatchEntity.class); + return httpResponse.getServiceResponse(); + } + + /** + * 通过商家批次单号查询批次单 + * + * @param request 请求参数 + * @return TransferBatchEntity + * @throws HttpException 发送HTTP请求失败。例如构建请求参数失败、发送请求失败、I/O错误等。包含请求信息。 + * @throws ValidationException 发送HTTP请求成功,验证微信支付返回签名失败。 + * @throws ServiceException 发送HTTP请求成功,服务返回异常。例如返回状态码小于200或大于等于300。 + * @throws MalformedMessageException 服务返回成功,content-type不为application/json、解析返回体失败。 + */ + public TransferBatchEntity getTransferBatchByOutNo(GetTransferBatchByOutNoRequest request) { + String requestPath = + "https://api.mch.weixin.qq.com/v3/transfer/batches/out-batch-no/{out_batch_no}"; + + GetTransferBatchByOutNoRequest realRequest = request; + // 添加 path param + requestPath = + requestPath.replace("{" + "out_batch_no" + "}", urlEncode(realRequest.getOutBatchNo())); + + // 添加 query param + QueryParameter queryParameter = new QueryParameter(); + if (realRequest.getNeedQueryDetail() != null) { + queryParameter.add( + "need_query_detail", urlEncode(realRequest.getNeedQueryDetail().toString())); + } + if (realRequest.getOffset() != null) { + queryParameter.add("offset", urlEncode(realRequest.getOffset().toString())); + } + if (realRequest.getLimit() != null) { + queryParameter.add("limit", urlEncode(realRequest.getLimit().toString())); + } + if (realRequest.getDetailStatus() != null) { + queryParameter.add("detail_status", urlEncode(realRequest.getDetailStatus())); + } + requestPath += queryParameter.getQueryStr(); + if (this.hostName != null) { + requestPath = requestPath.replaceFirst(HostName.API.getValue(), hostName.getValue()); + } + HttpHeaders headers = new HttpHeaders(); + headers.addHeader(Constant.ACCEPT, MediaType.APPLICATION_JSON.getValue()); + headers.addHeader(Constant.CONTENT_TYPE, MediaType.APPLICATION_JSON.getValue()); + HttpRequest httpRequest = + new HttpRequest.Builder() + .httpMethod(HttpMethod.GET) + .url(requestPath) + .headers(headers) + .build(); + HttpResponse httpResponse = + httpClient.execute(httpRequest, TransferBatchEntity.class); + return httpResponse.getServiceResponse(); + } + + /** + * 发起商家转账 + * + * @param request 请求参数 + * @return InitiateBatchTransferResponse + * @throws HttpException 发送HTTP请求失败。例如构建请求参数失败、发送请求失败、I/O错误等。包含请求信息。 + * @throws ValidationException 发送HTTP请求成功,验证微信支付返回签名失败。 + * @throws ServiceException 发送HTTP请求成功,服务返回异常。例如返回状态码小于200或大于等于300。 + * @throws MalformedMessageException 服务返回成功,content-type不为application/json、解析返回体失败。 + */ + public InitiateBatchTransferResponse initiateBatchTransfer(InitiateBatchTransferRequest request) { + String requestPath = "https://api.mch.weixin.qq.com/v3/transfer/batches"; + // 加密敏感信息 + InitiateBatchTransferRequest realRequest = request.cloneWithCipher(encryptor::encrypt); + if (this.hostName != null) { + requestPath = requestPath.replaceFirst(HostName.API.getValue(), hostName.getValue()); + } + HttpHeaders headers = new HttpHeaders(); + headers.addHeader(Constant.ACCEPT, MediaType.APPLICATION_JSON.getValue()); + headers.addHeader(Constant.CONTENT_TYPE, MediaType.APPLICATION_JSON.getValue()); + headers.addHeader(Constant.WECHAT_PAY_SERIAL, encryptor.getWechatpaySerial()); + HttpRequest httpRequest = + new HttpRequest.Builder() + .httpMethod(HttpMethod.POST) + .url(requestPath) + .headers(headers) + .body(createRequestBody(realRequest)) + .build(); + HttpResponse httpResponse = + httpClient.execute(httpRequest, InitiateBatchTransferResponse.class); + return httpResponse.getServiceResponse(); + } + + /** + * 通过微信明细单号查询明细单 + * + * @param request 请求参数 + * @return TransferDetailEntity + * @throws HttpException 发送HTTP请求失败。例如构建请求参数失败、发送请求失败、I/O错误等。包含请求信息。 + * @throws ValidationException 发送HTTP请求成功,验证微信支付返回签名失败。 + * @throws ServiceException 发送HTTP请求成功,服务返回异常。例如返回状态码小于200或大于等于300。 + * @throws MalformedMessageException 服务返回成功,content-type不为application/json、解析返回体失败。 + */ + public TransferDetailEntity getTransferDetailByNo(GetTransferDetailByNoRequest request) { + String requestPath = + "https://api.mch.weixin.qq.com/v3/transfer/batches/batch-id/{batch_id}/details/detail-id/{detail_id}"; + + GetTransferDetailByNoRequest realRequest = request; + // 添加 path param + requestPath = requestPath.replace("{" + "batch_id" + "}", urlEncode(realRequest.getBatchId())); + + requestPath = + requestPath.replace("{" + "detail_id" + "}", urlEncode(realRequest.getDetailId())); + + if (this.hostName != null) { + requestPath = requestPath.replaceFirst(HostName.API.getValue(), hostName.getValue()); + } + HttpHeaders headers = new HttpHeaders(); + headers.addHeader(Constant.ACCEPT, MediaType.APPLICATION_JSON.getValue()); + headers.addHeader(Constant.CONTENT_TYPE, MediaType.APPLICATION_JSON.getValue()); + HttpRequest httpRequest = + new HttpRequest.Builder() + .httpMethod(HttpMethod.GET) + .url(requestPath) + .headers(headers) + .build(); + HttpResponse httpResponse = + httpClient.execute(httpRequest, TransferDetailEntity.class); + return httpResponse.getServiceResponse().cloneWithCipher(decryptor::decrypt); + } + + /** + * 通过商家明细单号查询明细单 + * + * @param request 请求参数 + * @return TransferDetailEntity + * @throws HttpException 发送HTTP请求失败。例如构建请求参数失败、发送请求失败、I/O错误等。包含请求信息。 + * @throws ValidationException 发送HTTP请求成功,验证微信支付返回签名失败。 + * @throws ServiceException 发送HTTP请求成功,服务返回异常。例如返回状态码小于200或大于等于300。 + * @throws MalformedMessageException 服务返回成功,content-type不为application/json、解析返回体失败。 + */ + public TransferDetailEntity getTransferDetailByOutNo(GetTransferDetailByOutNoRequest request) { + String requestPath = + "https://api.mch.weixin.qq.com/v3/transfer/batches/out-batch-no/{out_batch_no}/details/out-detail-no/{out_detail_no}"; + + GetTransferDetailByOutNoRequest realRequest = request; + // 添加 path param + requestPath = + requestPath.replace("{" + "out_detail_no" + "}", urlEncode(realRequest.getOutDetailNo())); + + requestPath = + requestPath.replace("{" + "out_batch_no" + "}", urlEncode(realRequest.getOutBatchNo())); + + if (this.hostName != null) { + requestPath = requestPath.replaceFirst(HostName.API.getValue(), hostName.getValue()); + } + HttpHeaders headers = new HttpHeaders(); + headers.addHeader(Constant.ACCEPT, MediaType.APPLICATION_JSON.getValue()); + headers.addHeader(Constant.CONTENT_TYPE, MediaType.APPLICATION_JSON.getValue()); + HttpRequest httpRequest = + new HttpRequest.Builder() + .httpMethod(HttpMethod.GET) + .url(requestPath) + .headers(headers) + .build(); + HttpResponse httpResponse = + httpClient.execute(httpRequest, TransferDetailEntity.class); + return httpResponse.getServiceResponse().cloneWithCipher(decryptor::decrypt); + } + + private RequestBody createRequestBody(Object request) { + return new JsonRequestBody.Builder().body(toJson(request)).build(); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/CloseReasonType.java b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/CloseReasonType.java new file mode 100644 index 0000000..4e21fa3 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/CloseReasonType.java @@ -0,0 +1,24 @@ +// Copyright 2021 Tencent Inc. All rights reserved. +// +// 商家转账对外API +// +// * 场景及业务流程: 商户可通过该产品实现同时向多个用户微信零钱进行转账的操作,可用于发放奖金补贴、佣金货款结算、员工报销等场景。 +// [https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0](https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0) * 接入步骤: * 商户在微信支付商户平台开通“批量转账到零钱”产品权限,并勾选“使用API方式发起转账”。 * 调用批量转账接口,对多个用户微信零钱发起转账。 * 调用查询批次接口,可获取到转账批次详情及当前状态。 * 调用查询明细接口,可获取到单条转账明细详情及当前状态。 +// +// API version: 1.0.5 + +// Code generated by WechatPay APIv3 Generator based on [OpenAPI +// Generator](https://openapi-generator.tech); DO NOT EDIT. + +package com.wechat.pay.java.service.transferbatch.model; + +import com.google.gson.annotations.SerializedName; + +/** CloseReasonType */ +public enum CloseReasonType { + @SerializedName("OVERDUE_CLOSE") + OVERDUE_CLOSE, + + @SerializedName("TRANSFER_SCENE_INVALID") + TRANSFER_SCENE_INVALID +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/FailReasonType.java b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/FailReasonType.java new file mode 100644 index 0000000..fde4745 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/FailReasonType.java @@ -0,0 +1,96 @@ +// Copyright 2021 Tencent Inc. All rights reserved. +// +// 商家转账对外API +// +// * 场景及业务流程: 商户可通过该产品实现同时向多个用户微信零钱进行转账的操作,可用于发放奖金补贴、佣金货款结算、员工报销等场景。 +// [https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0](https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0) * 接入步骤: * 商户在微信支付商户平台开通“批量转账到零钱”产品权限,并勾选“使用API方式发起转账”。 * 调用批量转账接口,对多个用户微信零钱发起转账。 * 调用查询批次接口,可获取到转账批次详情及当前状态。 * 调用查询明细接口,可获取到单条转账明细详情及当前状态。 +// +// API version: 1.0.5 + +// Code generated by WechatPay APIv3 Generator based on [OpenAPI +// Generator](https://openapi-generator.tech); DO NOT EDIT. + +package com.wechat.pay.java.service.transferbatch.model; + +import com.google.gson.annotations.SerializedName; + +/** FailReasonType */ +public enum FailReasonType { + @SerializedName("ACCOUNT_FROZEN") + ACCOUNT_FROZEN, + + @SerializedName("REAL_NAME_CHECK_FAIL") + REAL_NAME_CHECK_FAIL, + + @SerializedName("NAME_NOT_CORRECT") + NAME_NOT_CORRECT, + + @SerializedName("OPENID_INVALID") + OPENID_INVALID, + + @SerializedName("TRANSFER_QUOTA_EXCEED") + TRANSFER_QUOTA_EXCEED, + + @SerializedName("DAY_RECEIVED_QUOTA_EXCEED") + DAY_RECEIVED_QUOTA_EXCEED, + + @SerializedName("MONTH_RECEIVED_QUOTA_EXCEED") + MONTH_RECEIVED_QUOTA_EXCEED, + + @SerializedName("DAY_RECEIVED_COUNT_EXCEED") + DAY_RECEIVED_COUNT_EXCEED, + + @SerializedName("PRODUCT_AUTH_CHECK_FAIL") + PRODUCT_AUTH_CHECK_FAIL, + + @SerializedName("OVERDUE_CLOSE") + OVERDUE_CLOSE, + + @SerializedName("ID_CARD_NOT_CORRECT") + ID_CARD_NOT_CORRECT, + + @SerializedName("ACCOUNT_NOT_EXIST") + ACCOUNT_NOT_EXIST, + + @SerializedName("TRANSFER_RISK") + TRANSFER_RISK, + + @SerializedName("OTHER_FAIL_REASON_TYPE") + OTHER_FAIL_REASON_TYPE, + + @SerializedName("REALNAME_ACCOUNT_RECEIVED_QUOTA_EXCEED") + REALNAME_ACCOUNT_RECEIVED_QUOTA_EXCEED, + + @SerializedName("RECEIVE_ACCOUNT_NOT_PERMMIT") + RECEIVE_ACCOUNT_NOT_PERMMIT, + + @SerializedName("PAYEE_ACCOUNT_ABNORMAL") + PAYEE_ACCOUNT_ABNORMAL, + + @SerializedName("PAYER_ACCOUNT_ABNORMAL") + PAYER_ACCOUNT_ABNORMAL, + + @SerializedName("TRANSFER_SCENE_UNAVAILABLE") + TRANSFER_SCENE_UNAVAILABLE, + + @SerializedName("TRANSFER_SCENE_INVALID") + TRANSFER_SCENE_INVALID, + + @SerializedName("TRANSFER_REMARK_SET_FAIL") + TRANSFER_REMARK_SET_FAIL, + + @SerializedName("RECEIVE_ACCOUNT_NOT_CONFIGURE") + RECEIVE_ACCOUNT_NOT_CONFIGURE, + + @SerializedName("BLOCK_B2C_USERLIMITAMOUNT_BSRULE_MONTH") + BLOCK_B2C_USERLIMITAMOUNT_BSRULE_MONTH, + + @SerializedName("BLOCK_B2C_USERLIMITAMOUNT_MONTH") + BLOCK_B2C_USERLIMITAMOUNT_MONTH, + + @SerializedName("MERCHANT_REJECT") + MERCHANT_REJECT, + + @SerializedName("MERCHANT_NOT_CONFIRM") + MERCHANT_NOT_CONFIRM +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/GetTransferBatchByNoRequest.java b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/GetTransferBatchByNoRequest.java new file mode 100644 index 0000000..d0ceb26 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/GetTransferBatchByNoRequest.java @@ -0,0 +1,104 @@ +// Copyright 2021 Tencent Inc. All rights reserved. +// +// 商家转账对外API +// +// * 场景及业务流程: 商户可通过该产品实现同时向多个用户微信零钱进行转账的操作,可用于发放奖金补贴、佣金货款结算、员工报销等场景。 +// [https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0](https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0) * 接入步骤: * 商户在微信支付商户平台开通“批量转账到零钱”产品权限,并勾选“使用API方式发起转账”。 * 调用批量转账接口,对多个用户微信零钱发起转账。 * 调用查询批次接口,可获取到转账批次详情及当前状态。 * 调用查询明细接口,可获取到单条转账明细详情及当前状态。 +// +// API version: 1.0.5 + +// Code generated by WechatPay APIv3 Generator based on [OpenAPI +// Generator](https://openapi-generator.tech); DO NOT EDIT. + +package com.wechat.pay.java.service.transferbatch.model; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +import static com.wechat.pay.java.core.util.StringUtil.toIndentedString; + +/** GetTransferBatchByNoRequest */ +public class GetTransferBatchByNoRequest { + /** 微信批次单号 说明:微信批次单号,微信商家转账系统返回的唯一标识 */ + @SerializedName("batch_id") + @Expose(serialize = false) + private String batchId; + + /** + * 是否查询转账明细单 说明:true-是;false-否,默认否。商户可选择是否查询指定状态的转账明细单,当转账批次单状态为“FINISHED”(已完成)时,才会返回满足条件的转账明细单 + */ + @SerializedName("need_query_detail") + @Expose(serialize = false) + private Boolean needQueryDetail; + + /** 请求资源起始位置 说明:该次请求资源的起始位置。返回的明细是按照设置的明细条数进行分页展示的,一次查询可能无法返回所有明细,我们使用该参数标识查询开始位置,默认值为0 */ + @SerializedName("offset") + @Expose(serialize = false) + private Integer offset; + + /** 最大资源条数 说明:该次请求可返回的最大明细条数,最小20条,最大100条,不传则默认20条。不足20条按实际条数返回 */ + @SerializedName("limit") + @Expose(serialize = false) + private Integer limit; + + /** + * 明细状态 说明:WAIT_PAY: 待确认。待商户确认, 符合免密条件时, 系统会自动扭转为转账中 ALL:全部。需要同时查询转账成功、失败和待确认的明细单 SUCCESS:转账成功 + * FAIL:转账失败。需要确认失败原因后,再决定是否重新发起对该笔明细单的转账(并非整个转账批次单) + */ + @SerializedName("detail_status") + @Expose(serialize = false) + private String detailStatus; + + public String getBatchId() { + return batchId; + } + + public void setBatchId(String batchId) { + this.batchId = batchId; + } + + public Boolean getNeedQueryDetail() { + return needQueryDetail; + } + + public void setNeedQueryDetail(Boolean needQueryDetail) { + this.needQueryDetail = needQueryDetail; + } + + public Integer getOffset() { + return offset; + } + + public void setOffset(Integer offset) { + this.offset = offset; + } + + public Integer getLimit() { + return limit; + } + + public void setLimit(Integer limit) { + this.limit = limit; + } + + public String getDetailStatus() { + return detailStatus; + } + + public void setDetailStatus(String detailStatus) { + this.detailStatus = detailStatus; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class GetTransferBatchByNoRequest {\n"); + sb.append(" batchId: ").append(toIndentedString(batchId)).append("\n"); + sb.append(" needQueryDetail: ").append(toIndentedString(needQueryDetail)).append("\n"); + sb.append(" offset: ").append(toIndentedString(offset)).append("\n"); + sb.append(" limit: ").append(toIndentedString(limit)).append("\n"); + sb.append(" detailStatus: ").append(toIndentedString(detailStatus)).append("\n"); + sb.append("}"); + return sb.toString(); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/GetTransferBatchByOutNoRequest.java b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/GetTransferBatchByOutNoRequest.java new file mode 100644 index 0000000..37667cc --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/GetTransferBatchByOutNoRequest.java @@ -0,0 +1,104 @@ +// Copyright 2021 Tencent Inc. All rights reserved. +// +// 商家转账对外API +// +// * 场景及业务流程: 商户可通过该产品实现同时向多个用户微信零钱进行转账的操作,可用于发放奖金补贴、佣金货款结算、员工报销等场景。 +// [https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0](https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0) * 接入步骤: * 商户在微信支付商户平台开通“批量转账到零钱”产品权限,并勾选“使用API方式发起转账”。 * 调用批量转账接口,对多个用户微信零钱发起转账。 * 调用查询批次接口,可获取到转账批次详情及当前状态。 * 调用查询明细接口,可获取到单条转账明细详情及当前状态。 +// +// API version: 1.0.5 + +// Code generated by WechatPay APIv3 Generator based on [OpenAPI +// Generator](https://openapi-generator.tech); DO NOT EDIT. + +package com.wechat.pay.java.service.transferbatch.model; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +import static com.wechat.pay.java.core.util.StringUtil.toIndentedString; + +/** GetTransferBatchByOutNoRequest */ +public class GetTransferBatchByOutNoRequest { + /** 商家批次单号 说明:商户系统内部的商家批次单号,在商户系统内部唯一 */ + @SerializedName("out_batch_no") + @Expose(serialize = false) + private String outBatchNo; + + /** + * 是否查询转账明细单 说明:true-是;false-否,默认否。商户可选择是否查询指定状态的转账明细单,当转账批次单状态为“FINISHED”(已完成)时,才会返回满足条件的转账明细单 + */ + @SerializedName("need_query_detail") + @Expose(serialize = false) + private Boolean needQueryDetail; + + /** 请求资源起始位置 说明:该次请求资源(转账明细单)的起始位置,从0开始,默认值为0 */ + @SerializedName("offset") + @Expose(serialize = false) + private Integer offset; + + /** 最大资源条数 说明:该次请求可返回的最大资源(转账明细单)条数,最小20条,最大100条,不传则默认20条。不足20条按实际条数返回 */ + @SerializedName("limit") + @Expose(serialize = false) + private Integer limit; + + /** + * 明细状态 说明:WAIT_PAY: 待确认。待商户确认, 符合免密条件时, 系统会自动扭转为转账中 ALL:全部。需要同时查询转账成功、失败和待确认的明细单 SUCCESS:转账成功 + * FAIL:转账失败。需要确认失败原因后,再决定是否重新发起对该笔明细单的转账(并非整个转账批次单) + */ + @SerializedName("detail_status") + @Expose(serialize = false) + private String detailStatus; + + public String getOutBatchNo() { + return outBatchNo; + } + + public void setOutBatchNo(String outBatchNo) { + this.outBatchNo = outBatchNo; + } + + public Boolean getNeedQueryDetail() { + return needQueryDetail; + } + + public void setNeedQueryDetail(Boolean needQueryDetail) { + this.needQueryDetail = needQueryDetail; + } + + public Integer getOffset() { + return offset; + } + + public void setOffset(Integer offset) { + this.offset = offset; + } + + public Integer getLimit() { + return limit; + } + + public void setLimit(Integer limit) { + this.limit = limit; + } + + public String getDetailStatus() { + return detailStatus; + } + + public void setDetailStatus(String detailStatus) { + this.detailStatus = detailStatus; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class GetTransferBatchByOutNoRequest {\n"); + sb.append(" outBatchNo: ").append(toIndentedString(outBatchNo)).append("\n"); + sb.append(" needQueryDetail: ").append(toIndentedString(needQueryDetail)).append("\n"); + sb.append(" offset: ").append(toIndentedString(offset)).append("\n"); + sb.append(" limit: ").append(toIndentedString(limit)).append("\n"); + sb.append(" detailStatus: ").append(toIndentedString(detailStatus)).append("\n"); + sb.append("}"); + return sb.toString(); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/GetTransferDetailByNoRequest.java b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/GetTransferDetailByNoRequest.java new file mode 100644 index 0000000..195e0d6 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/GetTransferDetailByNoRequest.java @@ -0,0 +1,57 @@ +// Copyright 2021 Tencent Inc. All rights reserved. +// +// 商家转账对外API +// +// * 场景及业务流程: 商户可通过该产品实现同时向多个用户微信零钱进行转账的操作,可用于发放奖金补贴、佣金货款结算、员工报销等场景。 +// [https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0](https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0) * 接入步骤: * 商户在微信支付商户平台开通“批量转账到零钱”产品权限,并勾选“使用API方式发起转账”。 * 调用批量转账接口,对多个用户微信零钱发起转账。 * 调用查询批次接口,可获取到转账批次详情及当前状态。 * 调用查询明细接口,可获取到单条转账明细详情及当前状态。 +// +// API version: 1.0.5 + +// Code generated by WechatPay APIv3 Generator based on [OpenAPI +// Generator](https://openapi-generator.tech); DO NOT EDIT. + +package com.wechat.pay.java.service.transferbatch.model; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +import static com.wechat.pay.java.core.util.StringUtil.toIndentedString; + +/** GetTransferDetailByNoRequest */ +public class GetTransferDetailByNoRequest { + /** 微信批次单号 说明:微信批次单号,微信商家转账系统返回的唯一标识 */ + @SerializedName("batch_id") + @Expose(serialize = false) + private String batchId; + + /** 微信明细单号 说明:微信支付系统内部区分转账批次单下不同转账明细单的唯一标识 */ + @SerializedName("detail_id") + @Expose(serialize = false) + private String detailId; + + public String getBatchId() { + return batchId; + } + + public void setBatchId(String batchId) { + this.batchId = batchId; + } + + public String getDetailId() { + return detailId; + } + + public void setDetailId(String detailId) { + this.detailId = detailId; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class GetTransferDetailByNoRequest {\n"); + sb.append(" batchId: ").append(toIndentedString(batchId)).append("\n"); + sb.append(" detailId: ").append(toIndentedString(detailId)).append("\n"); + sb.append("}"); + return sb.toString(); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/GetTransferDetailByOutNoRequest.java b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/GetTransferDetailByOutNoRequest.java new file mode 100644 index 0000000..063bdfb --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/GetTransferDetailByOutNoRequest.java @@ -0,0 +1,57 @@ +// Copyright 2021 Tencent Inc. All rights reserved. +// +// 商家转账对外API +// +// * 场景及业务流程: 商户可通过该产品实现同时向多个用户微信零钱进行转账的操作,可用于发放奖金补贴、佣金货款结算、员工报销等场景。 +// [https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0](https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0) * 接入步骤: * 商户在微信支付商户平台开通“批量转账到零钱”产品权限,并勾选“使用API方式发起转账”。 * 调用批量转账接口,对多个用户微信零钱发起转账。 * 调用查询批次接口,可获取到转账批次详情及当前状态。 * 调用查询明细接口,可获取到单条转账明细详情及当前状态。 +// +// API version: 1.0.5 + +// Code generated by WechatPay APIv3 Generator based on [OpenAPI +// Generator](https://openapi-generator.tech); DO NOT EDIT. + +package com.wechat.pay.java.service.transferbatch.model; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +import static com.wechat.pay.java.core.util.StringUtil.toIndentedString; + +/** GetTransferDetailByOutNoRequest */ +public class GetTransferDetailByOutNoRequest { + /** 商家明细单号 说明:商户系统内部区分转账批次单下不同转账明细单的唯一标识 */ + @SerializedName("out_detail_no") + @Expose(serialize = false) + private String outDetailNo; + + /** 商家批次单号 说明:商户系统内部的商家批次单号,在商户系统内部唯一 */ + @SerializedName("out_batch_no") + @Expose(serialize = false) + private String outBatchNo; + + public String getOutDetailNo() { + return outDetailNo; + } + + public void setOutDetailNo(String outDetailNo) { + this.outDetailNo = outDetailNo; + } + + public String getOutBatchNo() { + return outBatchNo; + } + + public void setOutBatchNo(String outBatchNo) { + this.outBatchNo = outBatchNo; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class GetTransferDetailByOutNoRequest {\n"); + sb.append(" outDetailNo: ").append(toIndentedString(outDetailNo)).append("\n"); + sb.append(" outBatchNo: ").append(toIndentedString(outBatchNo)).append("\n"); + sb.append("}"); + return sb.toString(); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/InitiateBatchTransferRequest.java b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/InitiateBatchTransferRequest.java new file mode 100644 index 0000000..dd5b5c8 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/InitiateBatchTransferRequest.java @@ -0,0 +1,173 @@ +// Copyright 2021 Tencent Inc. All rights reserved. +// +// 商家转账对外API +// +// * 场景及业务流程: 商户可通过该产品实现同时向多个用户微信零钱进行转账的操作,可用于发放奖金补贴、佣金货款结算、员工报销等场景。 +// [https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0](https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0) * 接入步骤: * 商户在微信支付商户平台开通“批量转账到零钱”产品权限,并勾选“使用API方式发起转账”。 * 调用批量转账接口,对多个用户微信零钱发起转账。 * 调用查询批次接口,可获取到转账批次详情及当前状态。 * 调用查询明细接口,可获取到单条转账明细详情及当前状态。 +// +// API version: 1.0.5 + +// Code generated by WechatPay APIv3 Generator based on [OpenAPI +// Generator](https://openapi-generator.tech); DO NOT EDIT. + +package com.wechat.pay.java.service.transferbatch.model; + +import com.google.gson.annotations.SerializedName; +import com.wechat.pay.java.core.cipher.Encryption; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.UnaryOperator; + +import static com.wechat.pay.java.core.util.StringUtil.toIndentedString; + +/** InitiateBatchTransferRequest */ +public class InitiateBatchTransferRequest { + /** 商户appid 说明:申请商户号的appid或商户号绑定的appid(企业号corpid即为此appid) */ + @SerializedName("appid") + private String appid; + + /** 商家批次单号 说明:商户系统内部的商家批次单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一 */ + @SerializedName("out_batch_no") + private String outBatchNo; + + /** 批次名称 说明:该笔批量转账的名称 */ + @SerializedName("batch_name") + private String batchName; + + /** 批次备注 说明:转账说明,UTF8编码,最多允许32个字符 */ + @SerializedName("batch_remark") + private String batchRemark; + + /** 转账总金额 说明:转账金额单位为“分”。转账总金额必须与批次内所有明细转账金额之和保持一致,否则无法发起转账操作 */ + @SerializedName("total_amount") + private Long totalAmount; + + /** 转账总笔数 说明:一个转账批次单最多发起一千笔转账。转账总笔数必须与批次内所有明细之和保持一致,否则无法发起转账操作 */ + @SerializedName("total_num") + private Integer totalNum; + + /** 转账明细列表 说明:发起批量转账的明细列表,最多一千笔 */ + @Encryption + @SerializedName("transfer_detail_list") + private List transferDetailList = new ArrayList(); + + /** 转账场景ID 说明:该批次转账使用的转账场景,如不填写则使用商家的默认场景,如无默认场景可为空,可前往“商家转账到零钱-前往功能”中申请。 如:1001-现金营销 */ + @SerializedName("transfer_scene_id") + private String transferSceneId; + + /** 通知地址 说明:异步接收微信支付结果通知的回调地址,通知url必须为公网可访问的url,必须为https,不能携带参数。 */ + @SerializedName("notify_url") + private String notifyUrl; + + public String getAppid() { + return appid; + } + + public void setAppid(String appid) { + this.appid = appid; + } + + public String getOutBatchNo() { + return outBatchNo; + } + + public void setOutBatchNo(String outBatchNo) { + this.outBatchNo = outBatchNo; + } + + public String getBatchName() { + return batchName; + } + + public void setBatchName(String batchName) { + this.batchName = batchName; + } + + public String getBatchRemark() { + return batchRemark; + } + + public void setBatchRemark(String batchRemark) { + this.batchRemark = batchRemark; + } + + public Long getTotalAmount() { + return totalAmount; + } + + public void setTotalAmount(Long totalAmount) { + this.totalAmount = totalAmount; + } + + public Integer getTotalNum() { + return totalNum; + } + + public void setTotalNum(Integer totalNum) { + this.totalNum = totalNum; + } + + public List getTransferDetailList() { + return transferDetailList; + } + + public void setTransferDetailList(List transferDetailList) { + this.transferDetailList = transferDetailList; + } + + public String getTransferSceneId() { + return transferSceneId; + } + + public void setTransferSceneId(String transferSceneId) { + this.transferSceneId = transferSceneId; + } + + public String getNotifyUrl() { + return notifyUrl; + } + + public void setNotifyUrl(String notifyUrl) { + this.notifyUrl = notifyUrl; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class InitiateBatchTransferRequest {\n"); + sb.append(" appid: ").append(toIndentedString(appid)).append("\n"); + sb.append(" outBatchNo: ").append(toIndentedString(outBatchNo)).append("\n"); + sb.append(" batchName: ").append(toIndentedString(batchName)).append("\n"); + sb.append(" batchRemark: ").append(toIndentedString(batchRemark)).append("\n"); + sb.append(" totalAmount: ").append(toIndentedString(totalAmount)).append("\n"); + sb.append(" totalNum: ").append(toIndentedString(totalNum)).append("\n"); + sb.append(" transferDetailList: ").append(toIndentedString(transferDetailList)).append("\n"); + sb.append(" transferSceneId: ").append(toIndentedString(transferSceneId)).append("\n"); + sb.append(" notifyUrl: ").append(toIndentedString(notifyUrl)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + public InitiateBatchTransferRequest cloneWithCipher(UnaryOperator s) { + InitiateBatchTransferRequest copy = new InitiateBatchTransferRequest(); + copy.appid = appid; + copy.outBatchNo = outBatchNo; + copy.batchName = batchName; + copy.batchRemark = batchRemark; + copy.totalAmount = totalAmount; + copy.totalNum = totalNum; + if (transferDetailList != null && transferDetailList.size() != 0) { + // arr + copy.transferDetailList = new ArrayList<>(); + for (TransferDetailInput val : transferDetailList) { + if (val != null) { + copy.transferDetailList.add(val.cloneWithCipher(s)); + } + } + } + copy.transferSceneId = transferSceneId; + copy.notifyUrl = notifyUrl; + return copy; + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/InitiateBatchTransferResponse.java b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/InitiateBatchTransferResponse.java new file mode 100644 index 0000000..2df549c --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/InitiateBatchTransferResponse.java @@ -0,0 +1,84 @@ +// Copyright 2021 Tencent Inc. All rights reserved. +// +// 商家转账对外API +// +// * 场景及业务流程: 商户可通过该产品实现同时向多个用户微信零钱进行转账的操作,可用于发放奖金补贴、佣金货款结算、员工报销等场景。 +// [https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0](https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0) * 接入步骤: * 商户在微信支付商户平台开通“批量转账到零钱”产品权限,并勾选“使用API方式发起转账”。 * 调用批量转账接口,对多个用户微信零钱发起转账。 * 调用查询批次接口,可获取到转账批次详情及当前状态。 * 调用查询明细接口,可获取到单条转账明细详情及当前状态。 +// +// API version: 1.0.5 + +// Code generated by WechatPay APIv3 Generator based on [OpenAPI +// Generator](https://openapi-generator.tech); DO NOT EDIT. + +package com.wechat.pay.java.service.transferbatch.model; + +import com.google.gson.annotations.SerializedName; + +import static com.wechat.pay.java.core.util.StringUtil.toIndentedString; + +/** InitiateBatchTransferResponse */ +public class InitiateBatchTransferResponse { + /** 商家批次单号 说明:商户系统内部的商家批次单号,在商户系统内部唯一 */ + @SerializedName("out_batch_no") + private String outBatchNo; + + /** 微信批次单号 说明:微信批次单号,微信商家转账系统返回的唯一标识 */ + @SerializedName("batch_id") + private String batchId; + + /** 批次创建时间 说明:批次受理成功时返回,按照使用rfc3339所定义的格式,格式为YYYY-MM-DDThh:mm:ss+TIMEZONE */ + @SerializedName("create_time") + private String createTime; + + /** + * 批次状态 + * 说明:ACCEPTED:已受理。批次已受理成功,若发起批量转账的30分钟后,转账批次单仍处于该状态,可能原因是商户账户余额不足等。商户可查询账户资金流水,若该笔转账批次单的扣款已经发生,则表示批次已经进入转账中,请再次查单确认 + * PROCESSING:转账中。已开始处理批次内的转账明细单 FINISHED:已完成。批次内的所有转账明细单都已处理完成 CLOSED:已关闭。可查询具体的批次关闭原因确认 + */ + @SerializedName("batch_status") + private String batchStatus; + + public String getOutBatchNo() { + return outBatchNo; + } + + public void setOutBatchNo(String outBatchNo) { + this.outBatchNo = outBatchNo; + } + + public String getBatchId() { + return batchId; + } + + public void setBatchId(String batchId) { + this.batchId = batchId; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getBatchStatus() { + return batchStatus; + } + + public void setBatchStatus(String batchStatus) { + this.batchStatus = batchStatus; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class InitiateBatchTransferResponse {\n"); + sb.append(" outBatchNo: ").append(toIndentedString(outBatchNo)).append("\n"); + sb.append(" batchId: ").append(toIndentedString(batchId)).append("\n"); + sb.append(" createTime: ").append(toIndentedString(createTime)).append("\n"); + sb.append(" batchStatus: ").append(toIndentedString(batchStatus)).append("\n"); + sb.append("}"); + return sb.toString(); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferBatchEntity.java b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferBatchEntity.java new file mode 100644 index 0000000..9db0aff --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferBatchEntity.java @@ -0,0 +1,56 @@ +// Copyright 2021 Tencent Inc. All rights reserved. +// +// 商家转账对外API +// +// * 场景及业务流程: 商户可通过该产品实现同时向多个用户微信零钱进行转账的操作,可用于发放奖金补贴、佣金货款结算、员工报销等场景。 +// [https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0](https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0) * 接入步骤: * 商户在微信支付商户平台开通“批量转账到零钱”产品权限,并勾选“使用API方式发起转账”。 * 调用批量转账接口,对多个用户微信零钱发起转账。 * 调用查询批次接口,可获取到转账批次详情及当前状态。 * 调用查询明细接口,可获取到单条转账明细详情及当前状态。 +// +// API version: 1.0.5 + +// Code generated by WechatPay APIv3 Generator based on [OpenAPI +// Generator](https://openapi-generator.tech); DO NOT EDIT. + +package com.wechat.pay.java.service.transferbatch.model; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +import static com.wechat.pay.java.core.util.StringUtil.toIndentedString; + +/** TransferBatchEntity */ +public class TransferBatchEntity { + /** 转账批次单 说明:转账批次单基本信息 */ + @SerializedName("transfer_batch") + private TransferBatchGet transferBatch; + + /** 转账明细单列表 说明:当批次状态为“FINISHED”(已完成),且成功查询到转账明细单时返回。包括微信明细单号、明细状态信息 */ + @SerializedName("transfer_detail_list") + private List transferDetailList; + + public TransferBatchGet getTransferBatch() { + return transferBatch; + } + + public void setTransferBatch(TransferBatchGet transferBatch) { + this.transferBatch = transferBatch; + } + + public List getTransferDetailList() { + return transferDetailList; + } + + public void setTransferDetailList(List transferDetailList) { + this.transferDetailList = transferDetailList; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class TransferBatchEntity {\n"); + sb.append(" transferBatch: ").append(toIndentedString(transferBatch)).append("\n"); + sb.append(" transferDetailList: ").append(toIndentedString(transferDetailList)).append("\n"); + sb.append("}"); + return sb.toString(); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferBatchGet.java b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferBatchGet.java new file mode 100644 index 0000000..653dc71 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferBatchGet.java @@ -0,0 +1,266 @@ +// Copyright 2021 Tencent Inc. All rights reserved. +// +// 商家转账对外API +// +// * 场景及业务流程: 商户可通过该产品实现同时向多个用户微信零钱进行转账的操作,可用于发放奖金补贴、佣金货款结算、员工报销等场景。 +// [https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0](https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0) * 接入步骤: * 商户在微信支付商户平台开通“批量转账到零钱”产品权限,并勾选“使用API方式发起转账”。 * 调用批量转账接口,对多个用户微信零钱发起转账。 * 调用查询批次接口,可获取到转账批次详情及当前状态。 * 调用查询明细接口,可获取到单条转账明细详情及当前状态。 +// +// API version: 1.0.5 + +// Code generated by WechatPay APIv3 Generator based on [OpenAPI +// Generator](https://openapi-generator.tech); DO NOT EDIT. + +package com.wechat.pay.java.service.transferbatch.model; + +import com.google.gson.annotations.SerializedName; + +import static com.wechat.pay.java.core.util.StringUtil.toIndentedString; + +/** TransferBatchGet */ +public class TransferBatchGet { + /** 商户号 说明:微信支付分配的商户号 */ + @SerializedName("mchid") + private String mchid; + + /** 商家批次单号 说明:商户系统内部的商家批次单号,在商户系统内部唯一 */ + @SerializedName("out_batch_no") + private String outBatchNo; + + /** 微信批次单号 说明:微信批次单号,微信商家转账系统返回的唯一标识 */ + @SerializedName("batch_id") + private String batchId; + + /** 商户appid 说明:申请商户号的appid或商户号绑定的appid(企业号corpid即为此appid) */ + @SerializedName("appid") + private String appid; + + /** + * 批次状态 说明:WAIT_PAY: 待付款确认。需要付款出资商户在商家助手小程序或服务商助手小程序进行付款确认 + * ACCEPTED:已受理。批次已受理成功,若发起批量转账的30分钟后,转账批次单仍处于该状态,可能原因是商户账户余额不足等。商户可查询账户资金流水,若该笔转账批次单的扣款已经发生,则表示批次已经进入转账中,请再次查单确认 + * PROCESSING:转账中。已开始处理批次内的转账明细单 FINISHED:已完成。批次内的所有转账明细单都已处理完成 CLOSED:已关闭。可查询具体的批次关闭原因确认 + */ + @SerializedName("batch_status") + private String batchStatus; + + /** 批次类型 说明:API:API方式发起 WEB:页面方式发起 */ + @SerializedName("batch_type") + private String batchType; + + /** 批次名称 说明:该笔批量转账的名称 */ + @SerializedName("batch_name") + private String batchName; + + /** 批次备注 说明:转账说明,UTF8编码,最多允许32个字符 */ + @SerializedName("batch_remark") + private String batchRemark; + + /** 批次关闭原因 说明:如果批次单状态为“CLOSED”(已关闭),则有关闭原因 */ + @SerializedName("close_reason") + private CloseReasonType closeReason; + + /** 转账总金额 说明:转账金额单位为“分” */ + @SerializedName("total_amount") + private Long totalAmount; + + /** 转账总笔数 说明:一个转账批次单最多发起三千笔转账 */ + @SerializedName("total_num") + private Integer totalNum; + + /** 批次创建时间 说明:批次受理成功时返回,按照使用rfc3339所定义的格式,格式为YYYY-MM-DDThh:mm:ss+TIMEZONE */ + @SerializedName("create_time") + private String createTime; + + /** 批次更新时间 说明:批次最近一次状态变更的时间,按照使用rfc3339所定义的格式,格式为YYYY-MM-DDThh:mm:ss+TIMEZONE */ + @SerializedName("update_time") + private String updateTime; + + /** 转账成功金额 说明:转账成功的金额,单位为“分”。当批次状态为“PROCESSING”(转账中)时,转账成功金额随时可能变化 */ + @SerializedName("success_amount") + private Long successAmount; + + /** 转账成功笔数 说明:转账成功的笔数。当批次状态为“PROCESSING”(转账中)时,转账成功笔数随时可能变化 */ + @SerializedName("success_num") + private Integer successNum; + + /** 转账失败金额 说明:转账失败的金额,单位为“分” */ + @SerializedName("fail_amount") + private Long failAmount; + + /** 转账失败笔数 说明:转账失败的笔数 */ + @SerializedName("fail_num") + private Integer failNum; + + /** 转账场景ID 说明:指定的转账场景ID */ + @SerializedName("transfer_scene_id") + private String transferSceneId; + + public String getMchid() { + return mchid; + } + + public void setMchid(String mchid) { + this.mchid = mchid; + } + + public String getOutBatchNo() { + return outBatchNo; + } + + public void setOutBatchNo(String outBatchNo) { + this.outBatchNo = outBatchNo; + } + + public String getBatchId() { + return batchId; + } + + public void setBatchId(String batchId) { + this.batchId = batchId; + } + + public String getAppid() { + return appid; + } + + public void setAppid(String appid) { + this.appid = appid; + } + + public String getBatchStatus() { + return batchStatus; + } + + public void setBatchStatus(String batchStatus) { + this.batchStatus = batchStatus; + } + + public String getBatchType() { + return batchType; + } + + public void setBatchType(String batchType) { + this.batchType = batchType; + } + + public String getBatchName() { + return batchName; + } + + public void setBatchName(String batchName) { + this.batchName = batchName; + } + + public String getBatchRemark() { + return batchRemark; + } + + public void setBatchRemark(String batchRemark) { + this.batchRemark = batchRemark; + } + + public CloseReasonType getCloseReason() { + return closeReason; + } + + public void setCloseReason(CloseReasonType closeReason) { + this.closeReason = closeReason; + } + + public Long getTotalAmount() { + return totalAmount; + } + + public void setTotalAmount(Long totalAmount) { + this.totalAmount = totalAmount; + } + + public Integer getTotalNum() { + return totalNum; + } + + public void setTotalNum(Integer totalNum) { + this.totalNum = totalNum; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + + public Long getSuccessAmount() { + return successAmount; + } + + public void setSuccessAmount(Long successAmount) { + this.successAmount = successAmount; + } + + public Integer getSuccessNum() { + return successNum; + } + + public void setSuccessNum(Integer successNum) { + this.successNum = successNum; + } + + public Long getFailAmount() { + return failAmount; + } + + public void setFailAmount(Long failAmount) { + this.failAmount = failAmount; + } + + public Integer getFailNum() { + return failNum; + } + + public void setFailNum(Integer failNum) { + this.failNum = failNum; + } + + public String getTransferSceneId() { + return transferSceneId; + } + + public void setTransferSceneId(String transferSceneId) { + this.transferSceneId = transferSceneId; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class TransferBatchGet {\n"); + sb.append(" mchid: ").append(toIndentedString(mchid)).append("\n"); + sb.append(" outBatchNo: ").append(toIndentedString(outBatchNo)).append("\n"); + sb.append(" batchId: ").append(toIndentedString(batchId)).append("\n"); + sb.append(" appid: ").append(toIndentedString(appid)).append("\n"); + sb.append(" batchStatus: ").append(toIndentedString(batchStatus)).append("\n"); + sb.append(" batchType: ").append(toIndentedString(batchType)).append("\n"); + sb.append(" batchName: ").append(toIndentedString(batchName)).append("\n"); + sb.append(" batchRemark: ").append(toIndentedString(batchRemark)).append("\n"); + sb.append(" closeReason: ").append(toIndentedString(closeReason)).append("\n"); + sb.append(" totalAmount: ").append(toIndentedString(totalAmount)).append("\n"); + sb.append(" totalNum: ").append(toIndentedString(totalNum)).append("\n"); + sb.append(" createTime: ").append(toIndentedString(createTime)).append("\n"); + sb.append(" updateTime: ").append(toIndentedString(updateTime)).append("\n"); + sb.append(" successAmount: ").append(toIndentedString(successAmount)).append("\n"); + sb.append(" successNum: ").append(toIndentedString(successNum)).append("\n"); + sb.append(" failAmount: ").append(toIndentedString(failAmount)).append("\n"); + sb.append(" failNum: ").append(toIndentedString(failNum)).append("\n"); + sb.append(" transferSceneId: ").append(toIndentedString(transferSceneId)).append("\n"); + sb.append("}"); + return sb.toString(); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferDetailCompact.java b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferDetailCompact.java new file mode 100644 index 0000000..d3444d0 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferDetailCompact.java @@ -0,0 +1,70 @@ +// Copyright 2021 Tencent Inc. All rights reserved. +// +// 商家转账对外API +// +// * 场景及业务流程: 商户可通过该产品实现同时向多个用户微信零钱进行转账的操作,可用于发放奖金补贴、佣金货款结算、员工报销等场景。 +// [https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0](https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0) * 接入步骤: * 商户在微信支付商户平台开通“批量转账到零钱”产品权限,并勾选“使用API方式发起转账”。 * 调用批量转账接口,对多个用户微信零钱发起转账。 * 调用查询批次接口,可获取到转账批次详情及当前状态。 * 调用查询明细接口,可获取到单条转账明细详情及当前状态。 +// +// API version: 1.0.5 + +// Code generated by WechatPay APIv3 Generator based on [OpenAPI +// Generator](https://openapi-generator.tech); DO NOT EDIT. + +package com.wechat.pay.java.service.transferbatch.model; + +import com.google.gson.annotations.SerializedName; + +import static com.wechat.pay.java.core.util.StringUtil.toIndentedString; + +/** TransferDetailCompact */ +public class TransferDetailCompact { + /** 微信明细单号 说明:微信支付系统内部区分转账批次单下不同转账明细单的唯一标识 */ + @SerializedName("detail_id") + private String detailId; + + /** 商家明细单号 说明:商户系统内部区分转账批次单下不同转账明细单的唯一标识 */ + @SerializedName("out_detail_no") + private String outDetailNo; + + /** + * 明细状态 说明:INIT: 初始态。 系统转账校验中 WAIT_PAY: 待确认。待商户确认, 符合免密条件时, 系统会自动扭转为转账中 + * PROCESSING:转账中。正在处理中,转账结果尚未明确 SUCCESS:转账成功 FAIL:转账失败。需要确认失败原因后,再决定是否重新发起对该笔明细单的转账(并非整个转账批次单) + */ + @SerializedName("detail_status") + private String detailStatus; + + public String getDetailId() { + return detailId; + } + + public void setDetailId(String detailId) { + this.detailId = detailId; + } + + public String getOutDetailNo() { + return outDetailNo; + } + + public void setOutDetailNo(String outDetailNo) { + this.outDetailNo = outDetailNo; + } + + public String getDetailStatus() { + return detailStatus; + } + + public void setDetailStatus(String detailStatus) { + this.detailStatus = detailStatus; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class TransferDetailCompact {\n"); + sb.append(" detailId: ").append(toIndentedString(detailId)).append("\n"); + sb.append(" outDetailNo: ").append(toIndentedString(outDetailNo)).append("\n"); + sb.append(" detailStatus: ").append(toIndentedString(detailStatus)).append("\n"); + sb.append("}"); + return sb.toString(); + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferDetailEntity.java b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferDetailEntity.java new file mode 100644 index 0000000..f2b8af2 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferDetailEntity.java @@ -0,0 +1,238 @@ +// Copyright 2021 Tencent Inc. All rights reserved. +// +// 商家转账对外API +// +// * 场景及业务流程: 商户可通过该产品实现同时向多个用户微信零钱进行转账的操作,可用于发放奖金补贴、佣金货款结算、员工报销等场景。 +// [https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0](https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0) * 接入步骤: * 商户在微信支付商户平台开通“批量转账到零钱”产品权限,并勾选“使用API方式发起转账”。 * 调用批量转账接口,对多个用户微信零钱发起转账。 * 调用查询批次接口,可获取到转账批次详情及当前状态。 * 调用查询明细接口,可获取到单条转账明细详情及当前状态。 +// +// API version: 1.0.5 + +// Code generated by WechatPay APIv3 Generator based on [OpenAPI +// Generator](https://openapi-generator.tech); DO NOT EDIT. + +package com.wechat.pay.java.service.transferbatch.model; + +import com.google.gson.annotations.SerializedName; +import com.wechat.pay.java.core.cipher.Encryption; + +import java.util.function.UnaryOperator; + +import static com.wechat.pay.java.core.util.StringUtil.toIndentedString; + +/** TransferDetailEntity */ +public class TransferDetailEntity { + /** 商户号 说明:微信支付分配的商户号 */ + @SerializedName("mchid") + private String mchid; + + /** 商家批次单号 说明:商户系统内部的商家批次单号,在商户系统内部唯一 */ + @SerializedName("out_batch_no") + private String outBatchNo; + + /** 微信批次单号 说明:微信批次单号,微信商家转账系统返回的唯一标识 */ + @SerializedName("batch_id") + private String batchId; + + /** 商户appid 说明:申请商户号的appid或商户号绑定的appid(企业号corpid即为此appid) */ + @SerializedName("appid") + private String appid; + + /** 商家明细单号 说明:商户系统内部区分转账批次单下不同转账明细单的唯一标识 */ + @SerializedName("out_detail_no") + private String outDetailNo; + + /** 微信明细单号 说明:微信支付系统内部区分转账批次单下不同转账明细单的唯一标识 */ + @SerializedName("detail_id") + private String detailId; + + /** + * 明细状态 说明:INIT: 初始态。 系统转账校验中 WAIT_PAY: 待确认。待商户确认, 符合免密条件时, 系统会自动扭转为转账中 + * PROCESSING:转账中。正在处理中,转账结果尚未明确 SUCCESS:转账成功 FAIL:转账失败。需要确认失败原因后,再决定是否重新发起对该笔明细单的转账(并非整个转账批次单) + */ + @SerializedName("detail_status") + private String detailStatus; + + /** 转账金额 说明:转账金额单位为“分” */ + @SerializedName("transfer_amount") + private Long transferAmount; + + /** 转账备注 说明:单条转账备注(微信用户会收到该备注),UTF8编码,最多允许32个字符 */ + @SerializedName("transfer_remark") + private String transferRemark; + + /** 明细失败原因 说明:如果转账失败则有失败原因 */ + @SerializedName("fail_reason") + private FailReasonType failReason; + + /** 收款用户openid 说明:商户appid下,某用户的openid */ + @SerializedName("openid") + private String openid; + + /** 收款用户姓名 说明:收款方姓名。采用标准RSA算法,公钥由微信侧提供 商户转账时传入了收款用户姓名、查询时会返回收款用户姓名 */ + @Encryption + @SerializedName("user_name") + private String userName; + + /** 转账发起时间 说明:转账发起的时间,按照使用rfc3339所定义的格式,格式为YYYY-MM-DDThh:mm:ss+TIMEZONE */ + @SerializedName("initiate_time") + private String initiateTime; + + /** 明细更新时间 说明:明细最后一次状态变更的时间,按照使用rfc3339所定义的格式,格式为YYYY-MM-DDThh:mm:ss+TIMEZONE */ + @SerializedName("update_time") + private String updateTime; + + public String getMchid() { + return mchid; + } + + public void setMchid(String mchid) { + this.mchid = mchid; + } + + public String getOutBatchNo() { + return outBatchNo; + } + + public void setOutBatchNo(String outBatchNo) { + this.outBatchNo = outBatchNo; + } + + public String getBatchId() { + return batchId; + } + + public void setBatchId(String batchId) { + this.batchId = batchId; + } + + public String getAppid() { + return appid; + } + + public void setAppid(String appid) { + this.appid = appid; + } + + public String getOutDetailNo() { + return outDetailNo; + } + + public void setOutDetailNo(String outDetailNo) { + this.outDetailNo = outDetailNo; + } + + public String getDetailId() { + return detailId; + } + + public void setDetailId(String detailId) { + this.detailId = detailId; + } + + public String getDetailStatus() { + return detailStatus; + } + + public void setDetailStatus(String detailStatus) { + this.detailStatus = detailStatus; + } + + public Long getTransferAmount() { + return transferAmount; + } + + public void setTransferAmount(Long transferAmount) { + this.transferAmount = transferAmount; + } + + public String getTransferRemark() { + return transferRemark; + } + + public void setTransferRemark(String transferRemark) { + this.transferRemark = transferRemark; + } + + public FailReasonType getFailReason() { + return failReason; + } + + public void setFailReason(FailReasonType failReason) { + this.failReason = failReason; + } + + public String getOpenid() { + return openid; + } + + public void setOpenid(String openid) { + this.openid = openid; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getInitiateTime() { + return initiateTime; + } + + public void setInitiateTime(String initiateTime) { + this.initiateTime = initiateTime; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class TransferDetailEntity {\n"); + sb.append(" mchid: ").append(toIndentedString(mchid)).append("\n"); + sb.append(" outBatchNo: ").append(toIndentedString(outBatchNo)).append("\n"); + sb.append(" batchId: ").append(toIndentedString(batchId)).append("\n"); + sb.append(" appid: ").append(toIndentedString(appid)).append("\n"); + sb.append(" outDetailNo: ").append(toIndentedString(outDetailNo)).append("\n"); + sb.append(" detailId: ").append(toIndentedString(detailId)).append("\n"); + sb.append(" detailStatus: ").append(toIndentedString(detailStatus)).append("\n"); + sb.append(" transferAmount: ").append(toIndentedString(transferAmount)).append("\n"); + sb.append(" transferRemark: ").append(toIndentedString(transferRemark)).append("\n"); + sb.append(" failReason: ").append(toIndentedString(failReason)).append("\n"); + sb.append(" openid: ").append(toIndentedString(openid)).append("\n"); + sb.append(" userName: ").append(toIndentedString(userName)).append("\n"); + sb.append(" initiateTime: ").append(toIndentedString(initiateTime)).append("\n"); + sb.append(" updateTime: ").append(toIndentedString(updateTime)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + public TransferDetailEntity cloneWithCipher(UnaryOperator s) { + TransferDetailEntity copy = new TransferDetailEntity(); + copy.mchid = mchid; + copy.outBatchNo = outBatchNo; + copy.batchId = batchId; + copy.appid = appid; + copy.outDetailNo = outDetailNo; + copy.detailId = detailId; + copy.detailStatus = detailStatus; + copy.transferAmount = transferAmount; + copy.transferRemark = transferRemark; + copy.failReason = failReason; + copy.openid = openid; + if (userName != null && !userName.isEmpty()) { + copy.userName = s.apply(userName); + } + copy.initiateTime = initiateTime; + copy.updateTime = updateTime; + return copy; + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferDetailInput.java b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferDetailInput.java new file mode 100644 index 0000000..dc656c9 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/model/TransferDetailInput.java @@ -0,0 +1,113 @@ +// Copyright 2021 Tencent Inc. All rights reserved. +// +// 商家转账对外API +// +// * 场景及业务流程: 商户可通过该产品实现同时向多个用户微信零钱进行转账的操作,可用于发放奖金补贴、佣金货款结算、员工报销等场景。 +// [https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0](https://pay.weixin.qq.com/index.php/public/product/detail?pid=108&productType=0) * 接入步骤: * 商户在微信支付商户平台开通“批量转账到零钱”产品权限,并勾选“使用API方式发起转账”。 * 调用批量转账接口,对多个用户微信零钱发起转账。 * 调用查询批次接口,可获取到转账批次详情及当前状态。 * 调用查询明细接口,可获取到单条转账明细详情及当前状态。 +// +// API version: 1.0.5 + +// Code generated by WechatPay APIv3 Generator based on [OpenAPI +// Generator](https://openapi-generator.tech); DO NOT EDIT. + +package com.wechat.pay.java.service.transferbatch.model; + +import com.google.gson.annotations.SerializedName; +import com.wechat.pay.java.core.cipher.Encryption; + +import java.util.function.UnaryOperator; + +import static com.wechat.pay.java.core.util.StringUtil.toIndentedString; + +/** TransferDetailInput */ +public class TransferDetailInput { + /** 商家明细单号 说明:商户系统内部区分转账批次单下不同转账明细单的唯一标识,要求此参数只能由数字、大小写字母组成 */ + @SerializedName("out_detail_no") + private String outDetailNo; + + /** 转账金额 说明:转账金额单位为“分” */ + @SerializedName("transfer_amount") + private Long transferAmount; + + /** 转账备注 说明:单条转账备注(微信用户会收到该备注),UTF8编码,最多允许32个字符 */ + @SerializedName("transfer_remark") + private String transferRemark; + + /** 收款用户openid 说明:商户appid下,某用户的openid */ + @SerializedName("openid") + private String openid; + + /** + * 收款用户姓名 说明:收款方真实姓名。支持标准RSA算法和国密算法,公钥由微信侧提供 明细转账金额<0.3元时,不允许填写收款用户姓名 明细转账金额 >= + * 2,000元时,该笔明细必须填写收款用户姓名 同一批次转账明细中的姓名字段传入规则需保持一致,也即全部填写、或全部不填写 + * 若商户传入收款用户姓名,微信支付会校验用户openID与姓名是否一致,并提供电子回单 + */ + @Encryption + @SerializedName("user_name") + private String userName; + + public String getOutDetailNo() { + return outDetailNo; + } + + public void setOutDetailNo(String outDetailNo) { + this.outDetailNo = outDetailNo; + } + + public Long getTransferAmount() { + return transferAmount; + } + + public void setTransferAmount(Long transferAmount) { + this.transferAmount = transferAmount; + } + + public String getTransferRemark() { + return transferRemark; + } + + public void setTransferRemark(String transferRemark) { + this.transferRemark = transferRemark; + } + + public String getOpenid() { + return openid; + } + + public void setOpenid(String openid) { + this.openid = openid; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class TransferDetailInput {\n"); + sb.append(" outDetailNo: ").append(toIndentedString(outDetailNo)).append("\n"); + sb.append(" transferAmount: ").append(toIndentedString(transferAmount)).append("\n"); + sb.append(" transferRemark: ").append(toIndentedString(transferRemark)).append("\n"); + sb.append(" openid: ").append(toIndentedString(openid)).append("\n"); + sb.append(" userName: ").append(toIndentedString(userName)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + public TransferDetailInput cloneWithCipher(UnaryOperator s) { + TransferDetailInput copy = new TransferDetailInput(); + copy.outDetailNo = outDetailNo; + copy.transferAmount = transferAmount; + copy.transferRemark = transferRemark; + copy.openid = openid; + if (userName != null && !userName.isEmpty()) { + copy.userName = s.apply(userName); + } + return copy; + } +} diff --git a/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/package-info.java b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/package-info.java new file mode 100644 index 0000000..1c50f84 --- /dev/null +++ b/wx-pay/src/main/java/com/wechat/pay/java/service/transferbatch/package-info.java @@ -0,0 +1,2 @@ +/** 商家转账对外API */ +package com.wechat.pay.java.service.transferbatch; diff --git a/wx-pay/src/main/resources/apiclient_key.pem b/wx-pay/src/main/resources/apiclient_key.pem new file mode 100644 index 0000000..eef0b43 --- /dev/null +++ b/wx-pay/src/main/resources/apiclient_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDKl801cqUtGl0q +qE2V/wgHNfc1fIV1eKIvGCYGbw6fhsW2qI0Uj0y0FlVR8Psntj/prHdf4N8u4i5L +mTBmPyuQqEz+o6TmK1R5NGFR8SsJKjwaRVhj+0qDrdCGgTqcKWaUkTAfvsPlhFkC +mawXhcPdKtzTR/tKuqKybXg1GjNQFQIglBP92j3iw4moPfbaxTPVBcsogcrT/AU+ +QP05Am/n6CQAwNRTI7PmRAUV+V9Yc1zK38jXoUsIJC0FMGrxNbZty4V2NuHT0sgE +12+Fk9JWUfXGWpRgbB1qrIzH2xKkn4xugWczGZAx5bPfMZaF0Qrm7o5lr5E9AALy +196QKnwtAgMBAAECggEAEwVHjfISkfZ8ssmUZzXHgi3N5Oao/QtzZqqEv2vj2pRj +sa+Hd1uw3uON5SCT4/mXbI/1sTnCmns/z3c1dRQPOgijGfExRS7iQnLphDD5UmX1 +uJ20G8b3Cv/hqQ8u+oRkjiRHeWOGruDLHpRg9OBpMDWa//ctH6oAJnJiq9Gm6ai0 +YXkthCzTdZ7YhCl1lHyM2NHJCQ1mnAQPNH8jKIAigXxmwXbQW9QF0rd3uOfsSJCA +K0o2MFAV7McCursqiE0JWmOQAeSYf6dSm0Caa8IWoBDGN7l88mwQQBStrN0pkAt/ +tK88Icrgb+4Go6gSpn6H6KedeWM5rWusq1JjqAuOPQKBgQD2k34+wWMt9e+10fkc +0q+0CcalPlWhOrkoFSkyPzOF3D37g7rJ5VEI4bH0fOPdE8wfpqq97TUIqu7zexRS +CVbFek741lGX80GDMmf+x0hR0+FekeynQMRpmagnZ2wgPe1H4kmOhUSEVugmN+mj +LF+L5VsAjqQXuuZMgrSWLXngPwKBgQDSVfnf1LpP8A9cDcWh0xKn+DzdpwCy1q9c +yKL6doevWw1gtAtVAFeniKgY/J6iKNP536qvB0ks/AUGNXJLGrsiEdy5qiWtjdzb +CU32HcJFNwibLZ5JKMQsoiwOcJVKI5VyA+Dwj0Brzmf/qpRzY2ErfumhhPggEhVM +d+ponKNIkwKBgDx0RQuV1n86QR9O78jFTxbRHsb81XnGMAdHyOXs4PD84qV70pwV +gRywWTUcObHGXNGVx17xfYM2hYdkscK7T27zYdFYmoCqv3EvNpgcu/pz/Fl3ZZJM +KtvJNJUUokn1ZOuu62HqArZ/qENWig3bn0FpZjpovoqi5Dv1/9iiJbN5AoGBAJqH +ygYVjzBtqYszHxDuNxWq/mTGbm/15G6hhYPIE5XUqnZysKSplLykXQPGjXGL13kM +R6VCEBP5sGNIXwkowXWdc/IAPKBOyoUuR9XbNUCO10bS9CjBx6cXGpEdS8FldUWH +7fou9OB/i869b0V7LQe8vT8KpxVA098TdueWtSv7AoGAbD0dukQwhvyIazUiiHbb +UDPi4FW1Z8nFMoz7R4k3+CMrcU4dh8eM3NondcIDHOtKye6oae1DQSR6bMxcjKpX +qXhk6eyS/UKRc9kd3vzg1k5Gi5xkCrJ0HiaXTtrdfAq3Wc5WNpc7Se08ri5Yjr18 +2+SqyzR/9YzqeE7GRPyQCxU= +-----END PRIVATE KEY-----