From 29930f98ff161ff91d5af37dad1001837772293c Mon Sep 17 00:00:00 2001 From: tzy Date: Sun, 4 May 2025 14:49:15 +0800 Subject: [PATCH 1/8] Changes --- .gitignore | 47 + LICENSE | 20 + bin/clean.bat | 12 + bin/package.bat | 12 + bin/run.bat | 14 + evo-admin/pom.xml | 229 +++ .../src/main/java/com/evo/EvoApplication.java | 22 + .../java/com/evo/EvoServletInitializer.java | 18 + .../controller/PunchTheClockController.java | 62 + .../controller/RzAbnormalController.java | 106 + .../RzAbnormalDetailController.java | 93 + .../controller/RzAttendanceController.java | 105 + .../RzAttendanceStatisticalController.java | 96 + .../RzSpecialAttendanceController.java | 104 + .../RzSpecialOverTimeController.java | 104 + .../com/evo/attendance/domain/RzAbnormal.java | 152 ++ .../attendance/domain/RzAbnormalDetail.java | 146 ++ .../evo/attendance/domain/RzAttendance.java | 242 +++ .../attendance/domain/RzAttendanceDetail.java | 140 ++ .../domain/RzAttendanceStatistical.java | 282 +++ .../domain/RzSpecialAttendance.java | 172 ++ .../attendance/domain/RzSpecialOverTime.java | 135 ++ .../domain/vo/RzAttendanceData.java | 19 + .../attendance/domain/vo/RzAttendanceVo.java | 30 + .../mapper/RzAbnormalDetailMapper.java | 52 + .../attendance/mapper/RzAbnormalMapper.java | 55 + .../mapper/RzAttendanceDetailMapper.java | 53 + .../attendance/mapper/RzAttendanceMapper.java | 83 + .../mapper/RzAttendanceStatisticalMapper.java | 62 + .../mapper/RzSpecialAttendanceMapper.java | 51 + .../mapper/RzSpecialOverTimeMapper.java | 51 + .../service/IRzAbnormalDetailService.java | 51 + .../service/IRzAbnormalService.java | 52 + .../service/IRzAttendanceService.java | 55 + .../IRzAttendanceStatisticalService.java | 50 + .../service/IRzSpecialAttendanceService.java | 54 + .../service/IRzSpecialOverTimeService.java | 53 + .../service/PunchTheClockService.java | 14 + .../impl/PunchTheClockServiceImpl.java | 559 +++++ .../impl/RzAbnormalDetailServiceImpl.java | 176 ++ .../service/impl/RzAbnormalServiceImpl.java | 105 + .../service/impl/RzAttendanceServiceImpl.java | 192 ++ .../RzAttendanceStatisticalServiceImpl.java | 136 ++ .../impl/RzSpecialAttendanceServiceImpl.java | 134 ++ .../impl/RzSpecialOverTimeServiceImpl.java | 104 + .../com/evo/common/annotation/Anonymous.java | 19 + .../com/evo/common/annotation/DataScope.java | 33 + .../com/evo/common/annotation/DataSource.java | 28 + .../java/com/evo/common/annotation/Excel.java | 192 ++ .../com/evo/common/annotation/Excels.java | 18 + .../java/com/evo/common/annotation/Log.java | 51 + .../evo/common/annotation/RateLimiter.java | 40 + .../evo/common/annotation/RepeatSubmit.java | 31 + .../com/evo/common/annotation/Sensitive.java | 24 + .../java/com/evo/common/config/EvoConfig.java | 111 + .../com/evo/common/config/SwaggerConfig.java | 124 ++ .../serializer/SensitiveJsonSerializer.java | 67 + .../evo/common/constant/CacheConstants.java | 44 + .../com/evo/common/constant/Constants.java | 120 ++ .../com/evo/common/constant/GenConstants.java | 117 ++ .../com/evo/common/constant/HttpStatus.java | 94 + .../common/constant/ScheduleConstants.java | 50 + .../evo/common/constant/UserConstants.java | 78 + .../core/controller/BaseController.java | 202 ++ .../evo/common/core/domain/AjaxResult.java | 216 ++ .../evo/common/core/domain/BaseEntity.java | 118 ++ .../java/com/evo/common/core/domain/R.java | 115 ++ .../evo/common/core/domain/TreeEntity.java | 79 + .../evo/common/core/domain/TreeSelect.java | 77 + .../common/core/domain/entity/SysDept.java | 171 ++ .../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 | 311 +++ .../common/core/domain/model/LoginBody.java | 69 + .../common/core/domain/model/LoginUser.java | 266 +++ .../core/domain/model/RegisterBody.java | 11 + .../com/evo/common/core/page/PageDomain.java | 101 + .../evo/common/core/page/TableDataInfo.java | 85 + .../evo/common/core/page/TableSupport.java | 56 + .../com/evo/common/core/redis/RedisCache.java | 268 +++ .../com/evo/common/core/text/CharsetKit.java | 86 + .../com/evo/common/core/text/Convert.java | 1010 +++++++++ .../evo/common/core/text/StrFormatter.java | 92 + .../com/evo/common/enums/BusinessStatus.java | 20 + .../com/evo/common/enums/BusinessType.java | 59 + .../com/evo/common/enums/DataSourceType.java | 19 + .../evo/common/enums/DesensitizedType.java | 59 + .../java/com/evo/common/enums/HttpMethod.java | 36 + .../java/com/evo/common/enums/LimitType.java | 20 + .../com/evo/common/enums/OperatorType.java | 24 + .../java/com/evo/common/enums/UserStatus.java | 30 + .../evo/common/exception/CustomException.java | 43 + .../common/exception/DemoModeException.java | 15 + .../evo/common/exception/GlobalException.java | 58 + .../common/exception/ServiceException.java | 74 + .../evo/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 + .../evo/common/filter/RepeatableFilter.java | 52 + .../filter/RepeatedlyRequestWrapper.java | 76 + .../java/com/evo/common/filter/XssFilter.java | 75 + .../filter/XssHttpServletRequestWrapper.java | 111 + .../main/java/com/evo/common/utils/Arith.java | 114 ++ .../java/com/evo/common/utils/DateUtils.java | 191 ++ .../evo/common/utils/DesensitizedUtil.java | 49 + .../java/com/evo/common/utils/DictUtils.java | 239 +++ .../com/evo/common/utils/ExceptionUtil.java | 39 + .../java/com/evo/common/utils/LogUtils.java | 18 + .../com/evo/common/utils/MessageUtils.java | 26 + .../java/com/evo/common/utils/PageUtils.java | 35 + .../com/evo/common/utils/SecurityUtils.java | 178 ++ .../com/evo/common/utils/ServletUtils.java | 218 ++ .../com/evo/common/utils/StringUtils.java | 684 +++++++ .../java/com/evo/common/utils/Threads.java | 99 + .../com/evo/common/utils/bean/BeanUtils.java | 110 + .../evo/common/utils/bean/BeanValidators.java | 24 + .../evo/common/utils/file/FileTypeUtils.java | 76 + .../common/utils/file/FileUploadUtils.java | 232 +++ .../com/evo/common/utils/file/FileUtils.java | 291 +++ .../com/evo/common/utils/file/ImageUtils.java | 98 + .../evo/common/utils/file/MimeTypeUtils.java | 59 + .../com/evo/common/utils/html/EscapeUtil.java | 167 ++ .../com/evo/common/utils/html/HTMLFilter.java | 570 ++++++ .../com/evo/common/utils/http/HttpHelper.java | 55 + .../com/evo/common/utils/http/HttpUtils.java | 274 +++ .../com/evo/common/utils/ip/AddressUtils.java | 56 + .../java/com/evo/common/utils/ip/IpUtils.java | 382 ++++ .../common/utils/poi/ExcelHandlerAdapter.java | 24 + .../com/evo/common/utils/poi/ExcelUtil.java | 1812 +++++++++++++++++ .../com/evo/common/utils/poi/ExcelUtilSs.java | 1040 ++++++++++ .../com/evo/common/utils/poi/ExcelUtils.java | 1009 +++++++++ .../common/utils/reflect/ReflectUtils.java | 410 ++++ .../com/evo/common/utils/sign/Base64.java | 291 +++ .../com/evo/common/utils/sign/Md5Utils.java | 67 + .../evo/common/utils/spring/SpringUtils.java | 158 ++ .../com/evo/common/utils/sql/SqlUtil.java | 70 + .../com/evo/common/utils/uuid/IdUtils.java | 49 + .../java/com/evo/common/utils/uuid/Seq.java | 86 + .../java/com/evo/common/utils/uuid/UUID.java | 484 +++++ .../src/main/java/com/evo/common/xss/Xss.java | 27 + .../java/com/evo/common/xss/XssValidator.java | 39 + .../com/evo/equipment/constant/Constants.java | 21 + .../controller/EqButtonController.java | 142 ++ .../controller/EqImagesController.java | 91 + .../controller/EqSnDetailController.java | 40 + .../controller/EqStatusTimeController.java | 86 + .../com/evo/equipment/domain/EqButton.java | 110 + .../com/evo/equipment/domain/EqImages.java | 120 ++ .../com/evo/equipment/domain/EqSnDetail.java | 142 ++ .../evo/equipment/domain/EqStatusTime.java | 83 + .../evo/equipment/domain/vo/CwBottonDto.java | 19 + .../evo/equipment/domain/vo/CwButtonData.java | 26 + .../evo/equipment/domain/vo/CwButtonVo.java | 56 + .../equipment/domain/vo/RzStatusTimeData.java | 68 + .../equipment/domain/vo/RzStatusTimeVo.java | 39 + .../evo/equipment/domain/vo/StaffData.java | 133 ++ .../com/evo/equipment/domain/vo/StaffDto.java | 50 + .../evo/equipment/mapper/EqButtonMapper.java | 54 + .../evo/equipment/mapper/EqImagesMapper.java | 54 + .../equipment/mapper/EqSnDetailMapper.java | 45 + .../equipment/mapper/EqStatusTimeMapper.java | 54 + .../equipment/service/IEqButtonService.java | 63 + .../equipment/service/IEqImagesService.java | 49 + .../equipment/service/IEqSnDetailService.java | 46 + .../service/IEqStatusTimeService.java | 55 + .../service/impl/EqButtonServiceImpl.java | 208 ++ .../service/impl/EqImagesServiceImpl.java | 329 +++ .../service/impl/EqSnDetailServiceImpl.java | 84 + .../service/impl/EqStatusTimeServiceImpl.java | 155 ++ .../controller/RzSalaryDetailController.java | 495 +++++ .../RzSalaryStatisticsController.java | 54 + .../evo/finance/domain/RzSalaryDetail.java | 662 ++++++ .../finance/domain/RzSalaryStatistics.java | 113 + .../com/evo/finance/domain/vo/SalaryVo.java | 293 +++ .../finance/mapper/RzSalaryDetailMapper.java | 70 + .../mapper/RzSalaryStatisticsMapper.java | 54 + .../service/IRzSalaryDetailService.java | 69 + .../service/IRzSalaryStatisticsService.java | 31 + .../impl/RzSalaryDetailServiceImpl.java | 543 +++++ .../impl/RzSalaryStatisticsServiceImpl.java | 89 + .../framework/aspectj/DataScopeAspect.java | 184 ++ .../framework/aspectj/DataSourceAspect.java | 72 + .../com/evo/framework/aspectj/LogAspect.java | 255 +++ .../framework/aspectj/RateLimiterAspect.java | 89 + .../framework/config/ApplicationConfig.java | 30 + .../com/evo/framework/config/DruidConfig.java | 126 ++ .../config/FastJson2JsonRedisSerializer.java | 52 + .../evo/framework/config/FilterConfig.java | 58 + .../com/evo/framework/config/I18nConfig.java | 43 + .../evo/framework/config/MyBatisConfig.java | 132 ++ .../com/evo/framework/config/RedisConfig.java | 69 + .../evo/framework/config/ResourcesConfig.java | 73 + .../evo/framework/config/SecurityConfig.java | 144 ++ .../evo/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 + .../evo/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 + .../web/exception/GlobalExceptionHandler.java | 145 ++ .../web/service/PermissionService.java | 159 ++ .../web/service/SysLoginService.java | 129 ++ .../web/service/SysPasswordService.java | 86 + .../web/service/SysPermissionService.java | 83 + .../web/service/SysRegisterService.java | 104 + .../framework/web/service/TokenService.java | 231 +++ .../web/service/UserDetailsServiceImpl.java | 66 + .../framework/websocket/SemaphoreUtils.java | 59 + .../framework/websocket/WebSocketConfig.java | 22 + .../framework/websocket/WebSocketServer.java | 166 ++ .../framework/websocket/WebSocketUsers.java | 135 ++ .../com/evo/generator/config/GenConfig.java | 73 + .../generator/controller/GenController.java | 258 +++ .../com/evo/generator/domain/GenTable.java | 385 ++++ .../evo/generator/domain/GenTableColumn.java | 373 ++++ .../mapper/GenTableColumnMapper.java | 60 + .../evo/generator/mapper/GenTableMapper.java | 91 + .../service/GenTableColumnServiceImpl.java | 68 + .../service/GenTableServiceImpl.java | 531 +++++ .../service/IGenTableColumnService.java | 44 + .../generator/service/IGenTableService.java | 130 ++ .../java/com/evo/generator/util/GenUtils.java | 257 +++ .../generator/util/VelocityInitializer.java | 34 + .../com/evo/generator/util/VelocityUtils.java | 408 ++++ .../controller/RzBusinessTripController.java | 98 + .../RzBusinessTripDetailController.java | 82 + .../controller/RzHolidayController.java | 85 + .../controller/RzInterviewerController.java | 98 + .../controller/RzLeaveController.java | 107 + .../controller/RzLeaveDetailController.java | 82 + .../controller/RzOverTimeController.java | 107 + .../RzOverTimeDetailController.java | 83 + .../controller/RzSubsidyController.java | 97 + .../controller/SpecialOverTimeController.java | 163 ++ .../personnelMatters/domain/EqOverStaff.java | 96 + .../domain/RzBusinessTrip.java | 138 ++ .../domain/RzBusinessTripDetail.java | 138 ++ .../personnelMatters/domain/RzHoliday.java | 94 + .../domain/RzInterviewer.java | 170 ++ .../evo/personnelMatters/domain/RzLeave.java | 250 +++ .../domain/RzLeaveDetail.java | 146 ++ .../personnelMatters/domain/RzOverTime.java | 131 ++ .../domain/RzOverTimeDetail.java | 129 ++ .../personnelMatters/domain/RzSubsidy.java | 97 + .../domain/SpecialOverTime.java | 59 + .../mapper/BsOverTimeMapper.java | 11 + .../mapper/EqOverStaffMapper.java | 48 + .../mapper/RzBusinessTripDetailMapper.java | 63 + .../mapper/RzBusinessTripMapper.java | 57 + .../mapper/RzHolidayMapper.java | 46 + .../mapper/RzInterviewerMapper.java | 47 + .../mapper/RzLeaveDetailMapper.java | 64 + .../mapper/RzLeaveMapper.java | 53 + .../mapper/RzOverTimeDetailMapper.java | 63 + .../mapper/RzOverTimeMapper.java | 56 + .../mapper/RzSubsidyMapper.java | 54 + .../service/IRzBusinessTripDetailService.java | 54 + .../service/IRzBusinessTripService.java | 55 + .../service/IRzHolidayService.java | 55 + .../service/IRzInterviewerService.java | 54 + .../service/IRzLeaveDetailService.java | 53 + .../service/IRzLeaveService.java | 61 + .../service/IRzOverTimeDetailService.java | 55 + .../service/IRzOverTimeService.java | 63 + .../service/IRzSubsidyService.java | 54 + .../service/SpecialOverTimeService.java | 48 + .../impl/RzBusinessTripDetailServiceImpl.java | 189 ++ .../impl/RzBusinessTripServiceImpl.java | 127 ++ .../service/impl/RzHolidayServiceImpl.java | 102 + .../impl/RzInterviewerServiceImpl.java | 92 + .../impl/RzLeaveDetailServiceImpl.java | 293 +++ .../service/impl/RzLeaveServiceImpl.java | 153 ++ .../impl/RzOverTimeDetailServiceImpl.java | 168 ++ .../service/impl/RzOverTimeServiceImpl.java | 155 ++ .../service/impl/RzSubsidyServiceImpl.java | 104 + .../impl/SpecialOverTimeServiceImpl.java | 99 + .../RzRestaurantDetailController.java | 89 + .../RzRestaurantImagesController.java | 61 + .../RzRestaurantStatisticsController.java | 244 +++ .../restaurant/domain/RzRestaurantDetail.java | 146 ++ .../restaurant/domain/RzRestaurantImages.java | 82 + .../domain/RzRestaurantStatistics.java | 330 +++ .../restaurant/domain/vo/RestaurantData.java | 19 + .../restaurant/domain/vo/RestaurantVo.java | 49 + .../mapper/RzRestaurantDetailMapper.java | 40 + .../mapper/RzRestaurantImagesMapper.java | 55 + .../mapper/RzRestaurantStatisticsMapper.java | 58 + .../service/IRzRestaurantDetailService.java | 39 + .../service/IRzRestaurantImagesService.java | 40 + .../IRzRestaurantStatisticsService.java | 49 + .../impl/RzRestaurantDetailServiceImpl.java | 167 ++ .../impl/RzRestaurantImagesServiceImpl.java | 199 ++ .../RzRestaurantStatisticsServiceImpl.java | 187 ++ .../com/evo/restaurant/utils/ExcelUtilCy.java | 1008 +++++++++ .../system/controller/CacheController.java | 121 ++ .../system/controller/CommonController.java | 163 ++ .../system/controller/SysDeptController.java | 144 ++ .../controller/SysDictDataController.java | 121 ++ .../controller/SysDictTypeController.java | 131 ++ .../system/controller/SysIndexController.java | 29 + .../system/controller/SysLoginController.java | 85 + .../controller/SysLogininforController.java | 82 + .../system/controller/SysMenuController.java | 142 ++ .../controller/SysOperlogController.java | 69 + .../controller/SysProfileController.java | 136 ++ .../system/controller/SysRoleController.java | 262 +++ .../system/controller/SysStaffController.java | 164 ++ .../controller/SysStaffDetailController.java | 69 + .../system/controller/SysUserController.java | 250 +++ .../controller/SysUserOnlineController.java | 83 + .../java/com/evo/system/domain/SysCache.java | 81 + .../com/evo/system/domain/SysLogininfor.java | 144 ++ .../com/evo/system/domain/SysOperLog.java | 269 +++ .../com/evo/system/domain/SysRoleDept.java | 46 + .../com/evo/system/domain/SysRoleMenu.java | 46 + .../java/com/evo/system/domain/SysStaff.java | 563 +++++ .../com/evo/system/domain/SysStaffDetail.java | 592 ++++++ .../com/evo/system/domain/SysUserOnline.java | 113 + .../com/evo/system/domain/SysUserRole.java | 46 + .../java/com/evo/system/domain/vo/MetaVo.java | 106 + .../com/evo/system/domain/vo/RouterVo.java | 148 ++ .../com/evo/system/domain/vo/SysStaffVo.java | 769 +++++++ .../com/evo/system/mapper/SysDeptMapper.java | 130 ++ .../evo/system/mapper/SysDictDataMapper.java | 95 + .../evo/system/mapper/SysDictTypeMapper.java | 83 + .../system/mapper/SysLogininforMapper.java | 42 + .../com/evo/system/mapper/SysMenuMapper.java | 125 ++ .../evo/system/mapper/SysOperLogMapper.java | 48 + .../evo/system/mapper/SysRoleDeptMapper.java | 44 + .../com/evo/system/mapper/SysRoleMapper.java | 107 + .../evo/system/mapper/SysRoleMenuMapper.java | 44 + .../system/mapper/SysStaffDetailMapper.java | 56 + .../com/evo/system/mapper/SysStaffMapper.java | 84 + .../com/evo/system/mapper/SysUserMapper.java | 127 ++ .../evo/system/mapper/SysUserRoleMapper.java | 62 + .../evo/system/service/ISysDeptService.java | 135 ++ .../system/service/ISysDictDataService.java | 60 + .../system/service/ISysDictTypeService.java | 98 + .../system/service/ISysLogininforService.java | 40 + .../evo/system/service/ISysMenuService.java | 144 ++ .../system/service/ISysOperLogService.java | 48 + .../evo/system/service/ISysRoleService.java | 173 ++ .../service/ISysStaffDetailService.java | 45 + .../evo/system/service/ISysStaffService.java | 95 + .../system/service/ISysUserOnlineService.java | 48 + .../evo/system/service/ISysUserService.java | 198 ++ .../service/impl/SysDeptServiceImpl.java | 363 ++++ .../service/impl/SysDictDataServiceImpl.java | 111 + .../service/impl/SysDictTypeServiceImpl.java | 223 ++ .../impl/SysLogininforServiceImpl.java | 65 + .../service/impl/SysMenuServiceImpl.java | 543 +++++ .../service/impl/SysOperLogServiceImpl.java | 76 + .../service/impl/SysRoleServiceImpl.java | 427 ++++ .../impl/SysStaffDetailServiceImpl.java | 140 ++ .../service/impl/SysStaffServiceImpl.java | 952 +++++++++ .../impl/SysUserOnlineServiceImpl.java | 96 + .../service/impl/SysUserServiceImpl.java | 484 +++++ .../java/com/evo/task/TaskController.java | 59 + .../src/main/java/com/evo/utils/DateUtil.java | 134 ++ .../META-INF/spring-devtools.properties | 1 + .../src/main/resources/application-druid.yml | 63 + evo-admin/src/main/resources/application.yml | 127 ++ evo-admin/src/main/resources/banner.txt | 24 + evo-admin/src/main/resources/generator.yml | 10 + .../main/resources/i18n/messages.properties | 38 + evo-admin/src/main/resources/logback.xml | 93 + .../attendance/RzAbnormalDetailMapper.xml | 97 + .../mapper/attendance/RzAbnormalMapper.xml | 102 + .../attendance/RzAttendanceDetailMapper.xml | 90 + .../mapper/attendance/RzAttendanceMapper.xml | 122 ++ .../RzAttendanceStatisticalMapper.xml | 139 ++ .../attendance/RzSpecialAttendanceMapper.xml | 103 + .../attendance/RzSpecialOverTimeMapper.xml | 89 + .../mapper/equipment/EqButtonMapper.xml | 83 + .../mapper/equipment/EqImagesMapper.xml | 89 + .../mapper/equipment/EqSnDetailMapper.xml | 78 + .../mapper/equipment/EqStatusTimeMapper.xml | 77 + .../mapper/finance/RzSalaryDetailMapper.xml | 252 +++ .../finance/RzSalaryStatisticsMapper.xml | 83 + .../mapper/generator/GenTableColumnMapper.xml | 127 ++ .../mapper/generator/GenTableMapper.xml | 210 ++ .../personnelMatters/BsOverTimeMapper.xml | 37 + .../personnelMatters/EqOverStaffMapper.xml | 82 + .../RzBusinessTripDetailMapper.xml | 107 + .../personnelMatters/RzBusinessTripMapper.xml | 102 + .../personnelMatters/RzHolidayMapper.xml | 78 + .../personnelMatters/RzInterviewerMapper.xml | 99 + .../personnelMatters/RzLeaveDetailMapper.xml | 103 + .../mapper/personnelMatters/RzLeaveMapper.xml | 129 ++ .../RzOverTimeDetailMapper.xml | 100 + .../personnelMatters/RzOverTimeMapper.xml | 97 + .../personnelMatters/RzSubsidyMapper.xml | 79 + .../restaurant/RzRestaurantDetailMapper.xml | 77 + .../restaurant/RzRestaurantImagesMapper.xml | 76 + .../RzRestaurantStatisticsMapper.xml | 156 ++ .../resources/mapper/system/SysDeptMapper.xml | 181 ++ .../mapper/system/SysDictDataMapper.xml | 124 ++ .../mapper/system/SysDictTypeMapper.xml | 106 + .../mapper/system/SysLogininforMapper.xml | 57 + .../resources/mapper/system/SysMenuMapper.xml | 206 ++ .../mapper/system/SysOperLogMapper.xml | 87 + .../mapper/system/SysRoleDeptMapper.xml | 34 + .../resources/mapper/system/SysRoleMapper.xml | 152 ++ .../mapper/system/SysRoleMenuMapper.xml | 34 + .../mapper/system/SysStaffDetailMapper.xml | 219 ++ .../mapper/system/SysStaffMapper.xml | 254 +++ .../resources/mapper/system/SysUserMapper.xml | 220 ++ .../mapper/system/SysUserRoleMapper.xml | 44 + .../main/resources/mybatis/mybatis-config.xml | 20 + .../main/resources/vm/java/controller.java.vm | 115 ++ .../src/main/resources/vm/java/domain.java.vm | 105 + .../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 | 76 + evo-admin/src/main/resources/vm/js/api.js.vm | 44 + evo-admin/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 ++ pom.xml | 189 ++ ry.bat | 67 + ry.sh | 86 + 450 files changed, 59347 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 evo-admin/pom.xml create mode 100644 evo-admin/src/main/java/com/evo/EvoApplication.java create mode 100644 evo-admin/src/main/java/com/evo/EvoServletInitializer.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/controller/PunchTheClockController.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/controller/RzAbnormalController.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/controller/RzAbnormalDetailController.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/controller/RzAttendanceController.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/controller/RzAttendanceStatisticalController.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/controller/RzSpecialAttendanceController.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/controller/RzSpecialOverTimeController.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/domain/RzAbnormal.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/domain/RzAbnormalDetail.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/domain/RzAttendance.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/domain/RzAttendanceDetail.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/domain/RzAttendanceStatistical.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/domain/RzSpecialAttendance.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/domain/RzSpecialOverTime.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/domain/vo/RzAttendanceData.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/domain/vo/RzAttendanceVo.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/mapper/RzAbnormalDetailMapper.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/mapper/RzAbnormalMapper.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceDetailMapper.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceMapper.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceStatisticalMapper.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/mapper/RzSpecialAttendanceMapper.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/mapper/RzSpecialOverTimeMapper.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/service/IRzAbnormalDetailService.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/service/IRzAbnormalService.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/service/IRzAttendanceService.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/service/IRzAttendanceStatisticalService.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/service/IRzSpecialAttendanceService.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/service/IRzSpecialOverTimeService.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/service/PunchTheClockService.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/service/impl/PunchTheClockServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/service/impl/RzAbnormalDetailServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/service/impl/RzAbnormalServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceStatisticalServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/service/impl/RzSpecialAttendanceServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/service/impl/RzSpecialOverTimeServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/common/annotation/Anonymous.java create mode 100644 evo-admin/src/main/java/com/evo/common/annotation/DataScope.java create mode 100644 evo-admin/src/main/java/com/evo/common/annotation/DataSource.java create mode 100644 evo-admin/src/main/java/com/evo/common/annotation/Excel.java create mode 100644 evo-admin/src/main/java/com/evo/common/annotation/Excels.java create mode 100644 evo-admin/src/main/java/com/evo/common/annotation/Log.java create mode 100644 evo-admin/src/main/java/com/evo/common/annotation/RateLimiter.java create mode 100644 evo-admin/src/main/java/com/evo/common/annotation/RepeatSubmit.java create mode 100644 evo-admin/src/main/java/com/evo/common/annotation/Sensitive.java create mode 100644 evo-admin/src/main/java/com/evo/common/config/EvoConfig.java create mode 100644 evo-admin/src/main/java/com/evo/common/config/SwaggerConfig.java create mode 100644 evo-admin/src/main/java/com/evo/common/config/serializer/SensitiveJsonSerializer.java create mode 100644 evo-admin/src/main/java/com/evo/common/constant/CacheConstants.java create mode 100644 evo-admin/src/main/java/com/evo/common/constant/Constants.java create mode 100644 evo-admin/src/main/java/com/evo/common/constant/GenConstants.java create mode 100644 evo-admin/src/main/java/com/evo/common/constant/HttpStatus.java create mode 100644 evo-admin/src/main/java/com/evo/common/constant/ScheduleConstants.java create mode 100644 evo-admin/src/main/java/com/evo/common/constant/UserConstants.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/controller/BaseController.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/domain/AjaxResult.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/domain/BaseEntity.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/domain/R.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/domain/TreeEntity.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/domain/TreeSelect.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/domain/entity/SysDept.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/domain/entity/SysDictData.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/domain/entity/SysDictType.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/domain/entity/SysMenu.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/domain/entity/SysRole.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/domain/entity/SysUser.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/domain/model/LoginBody.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/domain/model/LoginUser.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/domain/model/RegisterBody.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/page/PageDomain.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/page/TableDataInfo.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/page/TableSupport.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/redis/RedisCache.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/text/CharsetKit.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/text/Convert.java create mode 100644 evo-admin/src/main/java/com/evo/common/core/text/StrFormatter.java create mode 100644 evo-admin/src/main/java/com/evo/common/enums/BusinessStatus.java create mode 100644 evo-admin/src/main/java/com/evo/common/enums/BusinessType.java create mode 100644 evo-admin/src/main/java/com/evo/common/enums/DataSourceType.java create mode 100644 evo-admin/src/main/java/com/evo/common/enums/DesensitizedType.java create mode 100644 evo-admin/src/main/java/com/evo/common/enums/HttpMethod.java create mode 100644 evo-admin/src/main/java/com/evo/common/enums/LimitType.java create mode 100644 evo-admin/src/main/java/com/evo/common/enums/OperatorType.java create mode 100644 evo-admin/src/main/java/com/evo/common/enums/UserStatus.java create mode 100644 evo-admin/src/main/java/com/evo/common/exception/CustomException.java create mode 100644 evo-admin/src/main/java/com/evo/common/exception/DemoModeException.java create mode 100644 evo-admin/src/main/java/com/evo/common/exception/GlobalException.java create mode 100644 evo-admin/src/main/java/com/evo/common/exception/ServiceException.java create mode 100644 evo-admin/src/main/java/com/evo/common/exception/UtilException.java create mode 100644 evo-admin/src/main/java/com/evo/common/exception/base/BaseException.java create mode 100644 evo-admin/src/main/java/com/evo/common/exception/file/FileException.java create mode 100644 evo-admin/src/main/java/com/evo/common/exception/file/FileNameLengthLimitExceededException.java create mode 100644 evo-admin/src/main/java/com/evo/common/exception/file/FileSizeLimitExceededException.java create mode 100644 evo-admin/src/main/java/com/evo/common/exception/file/FileUploadException.java create mode 100644 evo-admin/src/main/java/com/evo/common/exception/file/InvalidExtensionException.java create mode 100644 evo-admin/src/main/java/com/evo/common/exception/job/TaskException.java create mode 100644 evo-admin/src/main/java/com/evo/common/exception/user/BlackListException.java create mode 100644 evo-admin/src/main/java/com/evo/common/exception/user/CaptchaException.java create mode 100644 evo-admin/src/main/java/com/evo/common/exception/user/CaptchaExpireException.java create mode 100644 evo-admin/src/main/java/com/evo/common/exception/user/UserException.java create mode 100644 evo-admin/src/main/java/com/evo/common/exception/user/UserNotExistsException.java create mode 100644 evo-admin/src/main/java/com/evo/common/exception/user/UserPasswordNotMatchException.java create mode 100644 evo-admin/src/main/java/com/evo/common/exception/user/UserPasswordRetryLimitExceedException.java create mode 100644 evo-admin/src/main/java/com/evo/common/filter/PropertyPreExcludeFilter.java create mode 100644 evo-admin/src/main/java/com/evo/common/filter/RepeatableFilter.java create mode 100644 evo-admin/src/main/java/com/evo/common/filter/RepeatedlyRequestWrapper.java create mode 100644 evo-admin/src/main/java/com/evo/common/filter/XssFilter.java create mode 100644 evo-admin/src/main/java/com/evo/common/filter/XssHttpServletRequestWrapper.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/Arith.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/DateUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/DesensitizedUtil.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/DictUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/ExceptionUtil.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/LogUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/MessageUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/PageUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/SecurityUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/ServletUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/StringUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/Threads.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/bean/BeanUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/bean/BeanValidators.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/file/FileTypeUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/file/FileUploadUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/file/FileUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/file/ImageUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/file/MimeTypeUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/html/EscapeUtil.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/html/HTMLFilter.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/http/HttpHelper.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/http/HttpUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/ip/AddressUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/ip/IpUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/poi/ExcelHandlerAdapter.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/poi/ExcelUtil.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/poi/ExcelUtilSs.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/poi/ExcelUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/reflect/ReflectUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/sign/Base64.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/sign/Md5Utils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/spring/SpringUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/sql/SqlUtil.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/uuid/IdUtils.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/uuid/Seq.java create mode 100644 evo-admin/src/main/java/com/evo/common/utils/uuid/UUID.java create mode 100644 evo-admin/src/main/java/com/evo/common/xss/Xss.java create mode 100644 evo-admin/src/main/java/com/evo/common/xss/XssValidator.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/constant/Constants.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/controller/EqButtonController.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/controller/EqImagesController.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/controller/EqSnDetailController.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/controller/EqStatusTimeController.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/domain/EqButton.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/domain/EqImages.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/domain/EqSnDetail.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/domain/EqStatusTime.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/domain/vo/CwBottonDto.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/domain/vo/CwButtonData.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/domain/vo/CwButtonVo.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/domain/vo/RzStatusTimeData.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/domain/vo/RzStatusTimeVo.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/domain/vo/StaffData.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/domain/vo/StaffDto.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/mapper/EqButtonMapper.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/mapper/EqImagesMapper.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/mapper/EqSnDetailMapper.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/mapper/EqStatusTimeMapper.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/service/IEqButtonService.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/service/IEqImagesService.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/service/IEqSnDetailService.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/service/IEqStatusTimeService.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/service/impl/EqButtonServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/service/impl/EqImagesServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/service/impl/EqSnDetailServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/equipment/service/impl/EqStatusTimeServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/finance/controller/RzSalaryDetailController.java create mode 100644 evo-admin/src/main/java/com/evo/finance/controller/RzSalaryStatisticsController.java create mode 100644 evo-admin/src/main/java/com/evo/finance/domain/RzSalaryDetail.java create mode 100644 evo-admin/src/main/java/com/evo/finance/domain/RzSalaryStatistics.java create mode 100644 evo-admin/src/main/java/com/evo/finance/domain/vo/SalaryVo.java create mode 100644 evo-admin/src/main/java/com/evo/finance/mapper/RzSalaryDetailMapper.java create mode 100644 evo-admin/src/main/java/com/evo/finance/mapper/RzSalaryStatisticsMapper.java create mode 100644 evo-admin/src/main/java/com/evo/finance/service/IRzSalaryDetailService.java create mode 100644 evo-admin/src/main/java/com/evo/finance/service/IRzSalaryStatisticsService.java create mode 100644 evo-admin/src/main/java/com/evo/finance/service/impl/RzSalaryDetailServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/finance/service/impl/RzSalaryStatisticsServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/framework/aspectj/DataScopeAspect.java create mode 100644 evo-admin/src/main/java/com/evo/framework/aspectj/DataSourceAspect.java create mode 100644 evo-admin/src/main/java/com/evo/framework/aspectj/LogAspect.java create mode 100644 evo-admin/src/main/java/com/evo/framework/aspectj/RateLimiterAspect.java create mode 100644 evo-admin/src/main/java/com/evo/framework/config/ApplicationConfig.java create mode 100644 evo-admin/src/main/java/com/evo/framework/config/DruidConfig.java create mode 100644 evo-admin/src/main/java/com/evo/framework/config/FastJson2JsonRedisSerializer.java create mode 100644 evo-admin/src/main/java/com/evo/framework/config/FilterConfig.java create mode 100644 evo-admin/src/main/java/com/evo/framework/config/I18nConfig.java create mode 100644 evo-admin/src/main/java/com/evo/framework/config/MyBatisConfig.java create mode 100644 evo-admin/src/main/java/com/evo/framework/config/RedisConfig.java create mode 100644 evo-admin/src/main/java/com/evo/framework/config/ResourcesConfig.java create mode 100644 evo-admin/src/main/java/com/evo/framework/config/SecurityConfig.java create mode 100644 evo-admin/src/main/java/com/evo/framework/config/ServerConfig.java create mode 100644 evo-admin/src/main/java/com/evo/framework/config/ThreadPoolConfig.java create mode 100644 evo-admin/src/main/java/com/evo/framework/config/properties/DruidProperties.java create mode 100644 evo-admin/src/main/java/com/evo/framework/config/properties/PermitAllUrlProperties.java create mode 100644 evo-admin/src/main/java/com/evo/framework/datasource/DynamicDataSource.java create mode 100644 evo-admin/src/main/java/com/evo/framework/datasource/DynamicDataSourceContextHolder.java create mode 100644 evo-admin/src/main/java/com/evo/framework/interceptor/RepeatSubmitInterceptor.java create mode 100644 evo-admin/src/main/java/com/evo/framework/interceptor/impl/SameUrlDataInterceptor.java create mode 100644 evo-admin/src/main/java/com/evo/framework/manager/AsyncManager.java create mode 100644 evo-admin/src/main/java/com/evo/framework/manager/ShutdownManager.java create mode 100644 evo-admin/src/main/java/com/evo/framework/manager/factory/AsyncFactory.java create mode 100644 evo-admin/src/main/java/com/evo/framework/security/context/AuthenticationContextHolder.java create mode 100644 evo-admin/src/main/java/com/evo/framework/security/context/PermissionContextHolder.java create mode 100644 evo-admin/src/main/java/com/evo/framework/security/filter/JwtAuthenticationTokenFilter.java create mode 100644 evo-admin/src/main/java/com/evo/framework/security/handle/AuthenticationEntryPointImpl.java create mode 100644 evo-admin/src/main/java/com/evo/framework/security/handle/LogoutSuccessHandlerImpl.java create mode 100644 evo-admin/src/main/java/com/evo/framework/web/exception/GlobalExceptionHandler.java create mode 100644 evo-admin/src/main/java/com/evo/framework/web/service/PermissionService.java create mode 100644 evo-admin/src/main/java/com/evo/framework/web/service/SysLoginService.java create mode 100644 evo-admin/src/main/java/com/evo/framework/web/service/SysPasswordService.java create mode 100644 evo-admin/src/main/java/com/evo/framework/web/service/SysPermissionService.java create mode 100644 evo-admin/src/main/java/com/evo/framework/web/service/SysRegisterService.java create mode 100644 evo-admin/src/main/java/com/evo/framework/web/service/TokenService.java create mode 100644 evo-admin/src/main/java/com/evo/framework/web/service/UserDetailsServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/framework/websocket/SemaphoreUtils.java create mode 100644 evo-admin/src/main/java/com/evo/framework/websocket/WebSocketConfig.java create mode 100644 evo-admin/src/main/java/com/evo/framework/websocket/WebSocketServer.java create mode 100644 evo-admin/src/main/java/com/evo/framework/websocket/WebSocketUsers.java create mode 100644 evo-admin/src/main/java/com/evo/generator/config/GenConfig.java create mode 100644 evo-admin/src/main/java/com/evo/generator/controller/GenController.java create mode 100644 evo-admin/src/main/java/com/evo/generator/domain/GenTable.java create mode 100644 evo-admin/src/main/java/com/evo/generator/domain/GenTableColumn.java create mode 100644 evo-admin/src/main/java/com/evo/generator/mapper/GenTableColumnMapper.java create mode 100644 evo-admin/src/main/java/com/evo/generator/mapper/GenTableMapper.java create mode 100644 evo-admin/src/main/java/com/evo/generator/service/GenTableColumnServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/generator/service/GenTableServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/generator/service/IGenTableColumnService.java create mode 100644 evo-admin/src/main/java/com/evo/generator/service/IGenTableService.java create mode 100644 evo-admin/src/main/java/com/evo/generator/util/GenUtils.java create mode 100644 evo-admin/src/main/java/com/evo/generator/util/VelocityInitializer.java create mode 100644 evo-admin/src/main/java/com/evo/generator/util/VelocityUtils.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/controller/RzBusinessTripController.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/controller/RzBusinessTripDetailController.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/controller/RzHolidayController.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/controller/RzInterviewerController.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/controller/RzLeaveController.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/controller/RzLeaveDetailController.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/controller/RzOverTimeController.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/controller/RzOverTimeDetailController.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/controller/RzSubsidyController.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/controller/SpecialOverTimeController.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/domain/EqOverStaff.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/domain/RzBusinessTrip.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/domain/RzBusinessTripDetail.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/domain/RzHoliday.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/domain/RzInterviewer.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/domain/RzLeave.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/domain/RzLeaveDetail.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/domain/RzOverTime.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/domain/RzOverTimeDetail.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/domain/RzSubsidy.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/domain/SpecialOverTime.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/mapper/BsOverTimeMapper.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/mapper/EqOverStaffMapper.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzBusinessTripDetailMapper.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzBusinessTripMapper.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzHolidayMapper.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzInterviewerMapper.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzLeaveDetailMapper.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzLeaveMapper.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzOverTimeDetailMapper.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzOverTimeMapper.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzSubsidyMapper.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/IRzBusinessTripDetailService.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/IRzBusinessTripService.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/IRzHolidayService.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/IRzInterviewerService.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/IRzLeaveDetailService.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/IRzLeaveService.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/IRzOverTimeDetailService.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/IRzOverTimeService.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/IRzSubsidyService.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/SpecialOverTimeService.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzBusinessTripDetailServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzBusinessTripServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzHolidayServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzInterviewerServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzLeaveDetailServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzLeaveServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzOverTimeDetailServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzOverTimeServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzSubsidyServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/personnelMatters/service/impl/SpecialOverTimeServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/restaurant/controller/RzRestaurantDetailController.java create mode 100644 evo-admin/src/main/java/com/evo/restaurant/controller/RzRestaurantImagesController.java create mode 100644 evo-admin/src/main/java/com/evo/restaurant/controller/RzRestaurantStatisticsController.java create mode 100644 evo-admin/src/main/java/com/evo/restaurant/domain/RzRestaurantDetail.java create mode 100644 evo-admin/src/main/java/com/evo/restaurant/domain/RzRestaurantImages.java create mode 100644 evo-admin/src/main/java/com/evo/restaurant/domain/RzRestaurantStatistics.java create mode 100644 evo-admin/src/main/java/com/evo/restaurant/domain/vo/RestaurantData.java create mode 100644 evo-admin/src/main/java/com/evo/restaurant/domain/vo/RestaurantVo.java create mode 100644 evo-admin/src/main/java/com/evo/restaurant/mapper/RzRestaurantDetailMapper.java create mode 100644 evo-admin/src/main/java/com/evo/restaurant/mapper/RzRestaurantImagesMapper.java create mode 100644 evo-admin/src/main/java/com/evo/restaurant/mapper/RzRestaurantStatisticsMapper.java create mode 100644 evo-admin/src/main/java/com/evo/restaurant/service/IRzRestaurantDetailService.java create mode 100644 evo-admin/src/main/java/com/evo/restaurant/service/IRzRestaurantImagesService.java create mode 100644 evo-admin/src/main/java/com/evo/restaurant/service/IRzRestaurantStatisticsService.java create mode 100644 evo-admin/src/main/java/com/evo/restaurant/service/impl/RzRestaurantDetailServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/restaurant/service/impl/RzRestaurantImagesServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/restaurant/service/impl/RzRestaurantStatisticsServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/restaurant/utils/ExcelUtilCy.java create mode 100644 evo-admin/src/main/java/com/evo/system/controller/CacheController.java create mode 100644 evo-admin/src/main/java/com/evo/system/controller/CommonController.java create mode 100644 evo-admin/src/main/java/com/evo/system/controller/SysDeptController.java create mode 100644 evo-admin/src/main/java/com/evo/system/controller/SysDictDataController.java create mode 100644 evo-admin/src/main/java/com/evo/system/controller/SysDictTypeController.java create mode 100644 evo-admin/src/main/java/com/evo/system/controller/SysIndexController.java create mode 100644 evo-admin/src/main/java/com/evo/system/controller/SysLoginController.java create mode 100644 evo-admin/src/main/java/com/evo/system/controller/SysLogininforController.java create mode 100644 evo-admin/src/main/java/com/evo/system/controller/SysMenuController.java create mode 100644 evo-admin/src/main/java/com/evo/system/controller/SysOperlogController.java create mode 100644 evo-admin/src/main/java/com/evo/system/controller/SysProfileController.java create mode 100644 evo-admin/src/main/java/com/evo/system/controller/SysRoleController.java create mode 100644 evo-admin/src/main/java/com/evo/system/controller/SysStaffController.java create mode 100644 evo-admin/src/main/java/com/evo/system/controller/SysStaffDetailController.java create mode 100644 evo-admin/src/main/java/com/evo/system/controller/SysUserController.java create mode 100644 evo-admin/src/main/java/com/evo/system/controller/SysUserOnlineController.java create mode 100644 evo-admin/src/main/java/com/evo/system/domain/SysCache.java create mode 100644 evo-admin/src/main/java/com/evo/system/domain/SysLogininfor.java create mode 100644 evo-admin/src/main/java/com/evo/system/domain/SysOperLog.java create mode 100644 evo-admin/src/main/java/com/evo/system/domain/SysRoleDept.java create mode 100644 evo-admin/src/main/java/com/evo/system/domain/SysRoleMenu.java create mode 100644 evo-admin/src/main/java/com/evo/system/domain/SysStaff.java create mode 100644 evo-admin/src/main/java/com/evo/system/domain/SysStaffDetail.java create mode 100644 evo-admin/src/main/java/com/evo/system/domain/SysUserOnline.java create mode 100644 evo-admin/src/main/java/com/evo/system/domain/SysUserRole.java create mode 100644 evo-admin/src/main/java/com/evo/system/domain/vo/MetaVo.java create mode 100644 evo-admin/src/main/java/com/evo/system/domain/vo/RouterVo.java create mode 100644 evo-admin/src/main/java/com/evo/system/domain/vo/SysStaffVo.java create mode 100644 evo-admin/src/main/java/com/evo/system/mapper/SysDeptMapper.java create mode 100644 evo-admin/src/main/java/com/evo/system/mapper/SysDictDataMapper.java create mode 100644 evo-admin/src/main/java/com/evo/system/mapper/SysDictTypeMapper.java create mode 100644 evo-admin/src/main/java/com/evo/system/mapper/SysLogininforMapper.java create mode 100644 evo-admin/src/main/java/com/evo/system/mapper/SysMenuMapper.java create mode 100644 evo-admin/src/main/java/com/evo/system/mapper/SysOperLogMapper.java create mode 100644 evo-admin/src/main/java/com/evo/system/mapper/SysRoleDeptMapper.java create mode 100644 evo-admin/src/main/java/com/evo/system/mapper/SysRoleMapper.java create mode 100644 evo-admin/src/main/java/com/evo/system/mapper/SysRoleMenuMapper.java create mode 100644 evo-admin/src/main/java/com/evo/system/mapper/SysStaffDetailMapper.java create mode 100644 evo-admin/src/main/java/com/evo/system/mapper/SysStaffMapper.java create mode 100644 evo-admin/src/main/java/com/evo/system/mapper/SysUserMapper.java create mode 100644 evo-admin/src/main/java/com/evo/system/mapper/SysUserRoleMapper.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/ISysDeptService.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/ISysDictDataService.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/ISysDictTypeService.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/ISysLogininforService.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/ISysMenuService.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/ISysOperLogService.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/ISysRoleService.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/ISysStaffDetailService.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/ISysStaffService.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/ISysUserOnlineService.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/ISysUserService.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/impl/SysDeptServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/impl/SysDictDataServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/impl/SysDictTypeServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/impl/SysLogininforServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/impl/SysMenuServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/impl/SysOperLogServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/impl/SysRoleServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/impl/SysStaffDetailServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/impl/SysStaffServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/impl/SysUserOnlineServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/system/service/impl/SysUserServiceImpl.java create mode 100644 evo-admin/src/main/java/com/evo/task/TaskController.java create mode 100644 evo-admin/src/main/java/com/evo/utils/DateUtil.java create mode 100644 evo-admin/src/main/resources/META-INF/spring-devtools.properties create mode 100644 evo-admin/src/main/resources/application-druid.yml create mode 100644 evo-admin/src/main/resources/application.yml create mode 100644 evo-admin/src/main/resources/banner.txt create mode 100644 evo-admin/src/main/resources/generator.yml create mode 100644 evo-admin/src/main/resources/i18n/messages.properties create mode 100644 evo-admin/src/main/resources/logback.xml create mode 100644 evo-admin/src/main/resources/mapper/attendance/RzAbnormalDetailMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/attendance/RzAbnormalMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/attendance/RzAttendanceDetailMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/attendance/RzAttendanceMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/attendance/RzAttendanceStatisticalMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/attendance/RzSpecialAttendanceMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/attendance/RzSpecialOverTimeMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/equipment/EqButtonMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/equipment/EqImagesMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/equipment/EqSnDetailMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/equipment/EqStatusTimeMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/finance/RzSalaryDetailMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/finance/RzSalaryStatisticsMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/generator/GenTableColumnMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/generator/GenTableMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/personnelMatters/BsOverTimeMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/personnelMatters/EqOverStaffMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/personnelMatters/RzBusinessTripDetailMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/personnelMatters/RzBusinessTripMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/personnelMatters/RzHolidayMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/personnelMatters/RzInterviewerMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/personnelMatters/RzLeaveDetailMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/personnelMatters/RzLeaveMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/personnelMatters/RzOverTimeDetailMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/personnelMatters/RzOverTimeMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/personnelMatters/RzSubsidyMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/restaurant/RzRestaurantDetailMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/restaurant/RzRestaurantImagesMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/restaurant/RzRestaurantStatisticsMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/system/SysDeptMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/system/SysDictDataMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/system/SysDictTypeMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/system/SysLogininforMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/system/SysMenuMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/system/SysOperLogMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/system/SysRoleDeptMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/system/SysRoleMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/system/SysRoleMenuMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/system/SysStaffDetailMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/system/SysStaffMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/system/SysUserMapper.xml create mode 100644 evo-admin/src/main/resources/mapper/system/SysUserRoleMapper.xml create mode 100644 evo-admin/src/main/resources/mybatis/mybatis-config.xml create mode 100644 evo-admin/src/main/resources/vm/java/controller.java.vm create mode 100644 evo-admin/src/main/resources/vm/java/domain.java.vm create mode 100644 evo-admin/src/main/resources/vm/java/mapper.java.vm create mode 100644 evo-admin/src/main/resources/vm/java/service.java.vm create mode 100644 evo-admin/src/main/resources/vm/java/serviceImpl.java.vm create mode 100644 evo-admin/src/main/resources/vm/java/sub-domain.java.vm create mode 100644 evo-admin/src/main/resources/vm/js/api.js.vm create mode 100644 evo-admin/src/main/resources/vm/sql/sql.vm create mode 100644 evo-admin/src/main/resources/vm/vue/index-tree.vue.vm create mode 100644 evo-admin/src/main/resources/vm/vue/index.vue.vm create mode 100644 evo-admin/src/main/resources/vm/vue/v3/index-tree.vue.vm create mode 100644 evo-admin/src/main/resources/vm/vue/v3/index.vue.vm create mode 100644 evo-admin/src/main/resources/vm/xml/mapper.xml.vm create mode 100644 pom.xml create mode 100644 ry.bat create mode 100644 ry.sh 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..745a757 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2018 evo + +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. 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/evo-admin/pom.xml b/evo-admin/pom.xml new file mode 100644 index 0000000..bb9724a --- /dev/null +++ b/evo-admin/pom.xml @@ -0,0 +1,229 @@ + + + + evo + com.evo + 3.8.8 + + 4.0.0 + jar + evo-tech + + + web服务入口 + + + + + + + org.springframework.boot + spring-boot-devtools + true + + + + + io.springfox + springfox-boot-starter + + + + + io.swagger + swagger-models + 1.6.2 + + + + + mysql + mysql-connector-java + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-aop + + + + + com.alibaba + druid-spring-boot-starter + + + + + com.github.oshi + oshi-core + + + + + org.apache.velocity + velocity-engine-core + + + + + 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 + + + + + com.itextpdf + itextpdf + 5.5.13 + + + + org.apache.pdfbox + fontbox + 2.0.9 + + + + + 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 + + + + + org.springframework.boot + spring-boot-starter-websocket + + + + + + + + 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} + + + diff --git a/evo-admin/src/main/java/com/evo/EvoApplication.java b/evo-admin/src/main/java/com/evo/EvoApplication.java new file mode 100644 index 0000000..76686d8 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/EvoApplication.java @@ -0,0 +1,22 @@ +package com.evo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.scheduling.annotation.EnableScheduling; + +/** + * 启动程序 + * + * @author evo + */ +@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) +@EnableScheduling +public class EvoApplication +{ + public static void main(String[] args) + { + SpringApplication.run(EvoApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ ***************************************************************************************************************************** ERP 启动成功 ************************************************************************************************************************ ლ(´ڡ`ლ)゙ \n"); + } +} diff --git a/evo-admin/src/main/java/com/evo/EvoServletInitializer.java b/evo-admin/src/main/java/com/evo/EvoServletInitializer.java new file mode 100644 index 0000000..7361190 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/EvoServletInitializer.java @@ -0,0 +1,18 @@ +package com.evo; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * web容器中进行部署 + * + * @author evo + */ +public class EvoServletInitializer extends SpringBootServletInitializer +{ + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) + { + return application.sources(EvoApplication.class); + } +} diff --git a/evo-admin/src/main/java/com/evo/attendance/controller/PunchTheClockController.java b/evo-admin/src/main/java/com/evo/attendance/controller/PunchTheClockController.java new file mode 100644 index 0000000..4fd9f82 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/controller/PunchTheClockController.java @@ -0,0 +1,62 @@ +package com.evo.attendance.controller; + +import com.evo.attendance.service.PunchTheClockService; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import javax.annotation.Resource; + + +@RestController +@RequestMapping("/api/v1") +public class PunchTheClockController { + + @Resource + private PunchTheClockService punchTheClockService; + + /** + * 刷脸获取打卡按钮权限 + * sn 设备号 + * type 设备识别类型 + * user_id 用户id + * card 人员信息中的卡号 + * confidence 人脸算法识别到的相识度 + * temperature 测量到的温度,未开启测温的设备为空 + * + * 响应: Result 返回请求类型:0:可以打卡,其它值表示无法打卡 + * Msg 对应 Result 的状态,可为空 + * Content 识别后返回的详细信息 + * button 9位长度的字符串,0 表示不可以点击 1 表示可以点击 + * + * String sn,String type,String userId,String card,String confidence + */ + @RequestMapping("/verify_user") + public String verifyUser(@RequestBody String json){ + return punchTheClockService.returnMessage(json); + } + + /** + * 用户点击打卡按钮后请求的接口 + * sn 设备号 + * user_id 人员id + * user_name 用户名 + * user_type 用户类型,对应下发人员时的 user_type + * card_number 卡号 + * recog_type 识别类型: face - 为人脸识别 、card - 刷卡开门,人脸或卡模式 + * recog_time 识别时间(时间格式yyyy-MM-dd HH:mm:ss) + * photo 识别照片,服务端收到后转换成图片步骤请查看 2、服务规范 - 照片解码流程 + * body_temperature 体温 + * confidence 通过的置信度 + * button 1~9 表示点击的是第几个按钮 + * + * 响应:Result 返回请求类型:0成功,其它失败 + * Msg 对应 Result 的文本信息 + * + * String sn,String userId,String userName,String userType,String cardNumber,String recog_type,String recog_time,String photo,String body_temperature,String confidence,String button + */ + @RequestMapping("/record/face") + public String face(@RequestBody String json){ + return punchTheClockService.recordFace(json); + } + +} diff --git a/evo-admin/src/main/java/com/evo/attendance/controller/RzAbnormalController.java b/evo-admin/src/main/java/com/evo/attendance/controller/RzAbnormalController.java new file mode 100644 index 0000000..2c86127 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/controller/RzAbnormalController.java @@ -0,0 +1,106 @@ +package com.evo.attendance.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.evo.attendance.domain.RzAbnormalDetail; +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.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.enums.BusinessType; +import com.evo.attendance.domain.RzAbnormal; +import com.evo.attendance.service.IRzAbnormalService; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.common.core.page.TableDataInfo; + +/** + * 考勤异常Controller + * + * @author evo + * @date 2025-03-10 + */ +@RestController +@RequestMapping("/attendance/abnormal") +public class RzAbnormalController extends BaseController +{ + @Autowired + private IRzAbnormalService rzAbnormalService; + + /** + * 查询考勤异常列表 + */ + @PreAuthorize("@ss.hasPermi('attendance:abnormal:list')") + @GetMapping("/list") + public TableDataInfo list(RzAbnormal rzAbnormal) + { + startPage(); + List list = rzAbnormalService.selectRzAbnormalList(rzAbnormal); + return getDataTable(list); + } + + /** + * 导出考勤异常列表 + */ + @PreAuthorize("@ss.hasPermi('attendance:abnormal:export')") + @Log(title = "考勤异常", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, RzAbnormal rzAbnormal) + { + List list = rzAbnormalService.selectRzAbnormalList(rzAbnormal); + ExcelUtil util = new ExcelUtil(RzAbnormal.class); + util.exportExcel(response, list, "考勤异常数据"); + } + + /** + * 获取考勤异常详细信息 + */ + @PreAuthorize("@ss.hasPermi('attendance:abnormal:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(rzAbnormalService.selectRzAbnormalById(id)); + } + + /** + * 修改考勤异常 + */ + @PreAuthorize("@ss.hasPermi('attendance:abnormal:edit')") + @Log(title = "考勤异常", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody RzAbnormal rzAbnormal) + { + return toAjax(rzAbnormalService.updateRzAbnormal(rzAbnormal)); + } + + /** + * 删除考勤异常 + */ + @PreAuthorize("@ss.hasPermi('attendance:abnormal:remove')") + @Log(title = "考勤异常", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return toAjax(rzAbnormalService.deleteRzAbnormalById(id)); + } + + /** + * 异常详情 + * @param rzAbnormal + * @return + */ + @GetMapping("/listAbnormalDetails") + public List listAbnormalDetails(RzAbnormal rzAbnormal) + { + return rzAbnormalService.listAbnormalDetails(rzAbnormal); + } +} diff --git a/evo-admin/src/main/java/com/evo/attendance/controller/RzAbnormalDetailController.java b/evo-admin/src/main/java/com/evo/attendance/controller/RzAbnormalDetailController.java new file mode 100644 index 0000000..002924b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/controller/RzAbnormalDetailController.java @@ -0,0 +1,93 @@ +package com.evo.attendance.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.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.enums.BusinessType; +import com.evo.attendance.domain.RzAbnormalDetail; +import com.evo.attendance.service.IRzAbnormalDetailService; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.common.core.page.TableDataInfo; + +/** + * 考勤异常详情Controller + * + * @author evo + * @date 2025-03-10 + */ +@RestController +@RequestMapping("/attendance/abnormalDetail") +public class RzAbnormalDetailController extends BaseController +{ + @Autowired + private IRzAbnormalDetailService rzAbnormalDetailService; + + /** + * 查询考勤异常详情列表 + */ + @PreAuthorize("@ss.hasPermi('attendance:abnormalDetail:list')") + @GetMapping("/list") + public TableDataInfo list(RzAbnormalDetail rzAbnormalDetail) + { + startPage(); + List list = rzAbnormalDetailService.selectRzAbnormalDetailList(rzAbnormalDetail); + return getDataTable(list); + } + + /** + * 导出考勤异常详情列表 + */ + @PreAuthorize("@ss.hasPermi('attendance:abnormalDetail:export')") + @Log(title = "考勤异常详情", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, RzAbnormalDetail rzAbnormalDetail) + { + List list = rzAbnormalDetailService.selectRzAbnormalDetailList(rzAbnormalDetail); + ExcelUtil util = new ExcelUtil(RzAbnormalDetail.class); + util.exportExcel(response, list, "考勤异常详情数据"); + } + + /** + * 获取考勤异常详情详细信息 + */ + @PreAuthorize("@ss.hasPermi('attendance:abnormalDetail:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(rzAbnormalDetailService.selectRzAbnormalDetailById(id)); + } + + /** + * 修改考勤异常详情 + */ + @PreAuthorize("@ss.hasPermi('attendance:abnormalDetail:edit')") + @Log(title = "考勤异常详情", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody RzAbnormalDetail rzAbnormalDetail) + { + return toAjax(rzAbnormalDetailService.updateRzAbnormalDetail(rzAbnormalDetail)); + } + + /** + * 删除考勤异常详情 + */ + @PreAuthorize("@ss.hasPermi('attendance:abnormalDetail:remove')") + @Log(title = "考勤异常详情", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return toAjax(rzAbnormalDetailService.deleteRzAbnormalDetailById(id)); + } +} diff --git a/evo-admin/src/main/java/com/evo/attendance/controller/RzAttendanceController.java b/evo-admin/src/main/java/com/evo/attendance/controller/RzAttendanceController.java new file mode 100644 index 0000000..f0633c6 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/controller/RzAttendanceController.java @@ -0,0 +1,105 @@ +package com.evo.attendance.controller; + +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.attendance.domain.RzAttendance; +import com.evo.attendance.service.IRzAttendanceService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 考勤记录Controller + * + * @author chenyj + * @date 2024-09-05 + */ +@RestController +@RequestMapping("/attendance/attendance") +public class RzAttendanceController extends BaseController +{ + @Resource + private IRzAttendanceService rzAttendanceService; + + /** + * 查询考勤记录列表 + */ + @PreAuthorize("@ss.hasPermi('attendance:attendance:list')") + @GetMapping("/list") + public TableDataInfo list(RzAttendance rzAttendance) + { + startPage(); + List list = rzAttendanceService.selectRzAttendanceList(rzAttendance); + return getDataTable(list); + } + + /** + * 导出考勤记录列表 + */ + @PreAuthorize("@ss.hasPermi('attendance:attendance:export')") + @Log(title = "考勤记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, RzAttendance rzAttendance) + { + List list = rzAttendanceService.selectRzAttendanceList(rzAttendance); + ExcelUtil util = new ExcelUtil(RzAttendance.class); + util.exportExcel(response, list, "考勤记录"); + } + + /** + * 获取考勤记录详细信息 + */ + @PreAuthorize("@ss.hasPermi('attendance:attendance:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(rzAttendanceService.selectRzAttendanceById(id)); + } + + /** + * 修改考勤记录 + */ + @PreAuthorize("@ss.hasPermi('attendance:attendance:edit')") + @Log(title = "考勤记录", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody RzAttendance rzAttendance) + { + return toAjax(rzAttendanceService.updateRzAttendance(rzAttendance)); + } + + /** + * 每日上班打卡统计 + * @return + */ + @GetMapping(value = "/attendenceCount") + public int attendenceCount() + { + return rzAttendanceService.attendenceCount(); + } + + /** + * 批量修改考勤记录 + */ + @PreAuthorize("@ss.hasPermi('attendance:attendance:edit')") + @Log(title = "考勤记录", businessType = BusinessType.UPDATE) + @PutMapping(value = "/updateBatchAttendance") + public AjaxResult updateBatchAttendance(@RequestBody RzAttendance rzAttendance) + { + return rzAttendanceService.updateBatchAttendance(rzAttendance); + } + + @GetMapping("/listAttendanceByParams") + public TableDataInfo listAttendanceByParams(RzAttendance rzAttendance) + { + startPage(); + List list = rzAttendanceService.listAttendanceByParams(rzAttendance); + return getDataTable(list); + } + +} diff --git a/evo-admin/src/main/java/com/evo/attendance/controller/RzAttendanceStatisticalController.java b/evo-admin/src/main/java/com/evo/attendance/controller/RzAttendanceStatisticalController.java new file mode 100644 index 0000000..6b66b90 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/controller/RzAttendanceStatisticalController.java @@ -0,0 +1,96 @@ +package com.evo.attendance.controller; + +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.attendance.domain.RzAttendanceStatistical; +import com.evo.attendance.service.IRzAttendanceStatisticalService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 考勤统计Controller + * + * @author chenyj + * @date 2024-09-05 + */ +@RestController +@RequestMapping("/attendance/statistical") +public class RzAttendanceStatisticalController extends BaseController +{ + @Resource + private IRzAttendanceStatisticalService rzAttendanceStatisticalService; + + /** + * 查询考勤统计列表 + */ + @PreAuthorize("@ss.hasPermi('attendance:statistical:list')") + @GetMapping("/list") + public TableDataInfo list(RzAttendanceStatistical rzAttendanceStatistical) + { + startPage(); + List list = rzAttendanceStatisticalService.selectRzAttendanceStatisticalList(rzAttendanceStatistical); + return getDataTable(list); + } + + /** + * 导出考勤统计列表 + */ + @PreAuthorize("@ss.hasPermi('attendance:statistical:export')") + @Log(title = "考勤统计", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, RzAttendanceStatistical rzAttendanceStatistical) + { + List list = rzAttendanceStatisticalService.selectRzAttendanceStatisticalList(rzAttendanceStatistical); + ExcelUtil util = new ExcelUtil(RzAttendanceStatistical.class); + util.exportExcel(response, list, "考勤统计数据"); + } + + /** + * 获取考勤统计详细信息 + */ + @PreAuthorize("@ss.hasPermi('attendance:statistical:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(rzAttendanceStatisticalService.selectRzAttendanceStatisticalById(id)); + } + + /** + * 修改考勤统计 + */ + @PreAuthorize("@ss.hasPermi('attendance:statistical:edit')") + @Log(title = "考勤统计", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody RzAttendanceStatistical rzAttendanceStatistical) + { + return toAjax(rzAttendanceStatisticalService.updateRzAttendanceStatistical(rzAttendanceStatistical)); + } + + /** + * 校正数据 + */ + @PreAuthorize("@ss.hasPermi('attendance:statistics:correct')") + @RequestMapping(value = "correct") + public AjaxResult correct(@RequestBody RzAttendanceStatistical rzAttendanceStatistical) + { + return rzAttendanceStatisticalService.correct(rzAttendanceStatistical); + } + + @PreAuthorize("@ss.hasPermi('attendance:statistics:import')") + @PostMapping("/importData") + public AjaxResult importData(MultipartFile file) throws Exception + { + ExcelUtil util = new ExcelUtil(RzAttendanceStatistical.class); + List attList = util.importExcel(file.getInputStream()); + return rzAttendanceStatisticalService.importRzAttendanceStatistical(attList); + } + +} diff --git a/evo-admin/src/main/java/com/evo/attendance/controller/RzSpecialAttendanceController.java b/evo-admin/src/main/java/com/evo/attendance/controller/RzSpecialAttendanceController.java new file mode 100644 index 0000000..5145407 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/controller/RzSpecialAttendanceController.java @@ -0,0 +1,104 @@ +package com.evo.attendance.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import com.evo.attendance.domain.RzSpecialAttendance; +import com.evo.attendance.service.IRzSpecialAttendanceService; +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.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.common.core.page.TableDataInfo; + +/** + * 加班考勤记录Controller + * + * @author evo + * @date 2025-04-15 + */ +@RestController +@RequestMapping("/attendance/specialAttendance") +public class RzSpecialAttendanceController extends BaseController +{ + @Autowired + private IRzSpecialAttendanceService rzSpecialAttendanceService; + + /** + * 查询加班考勤记录列表 + */ + @PreAuthorize("@ss.hasPermi('attendance:specialAttendance:list')") + @GetMapping("/list") + public TableDataInfo list(RzSpecialAttendance rzSpecialAttendance) + { + startPage(); + List list = rzSpecialAttendanceService.selectRzSpecialAttendanceList(rzSpecialAttendance); + return getDataTable(list); + } + + /** + * 导出加班考勤记录列表 + */ + @PreAuthorize("@ss.hasPermi('attendance:specialAttendance:export')") + @Log(title = "加班考勤记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, RzSpecialAttendance rzSpecialAttendance) + { + List list = rzSpecialAttendanceService.selectRzSpecialAttendanceList(rzSpecialAttendance); + ExcelUtil util = new ExcelUtil(RzSpecialAttendance.class); + util.exportExcel(response, list, "加班考勤记录数据"); + } + + /** + * 获取加班考勤记录详细信息 + */ + @PreAuthorize("@ss.hasPermi('attendance:specialAttendance:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(rzSpecialAttendanceService.selectRzSpecialAttendanceById(id)); + } + + /** + * 新增加班考勤记录 + */ + @PreAuthorize("@ss.hasPermi('attendance:specialAttendance:add')") + @Log(title = "加班考勤记录", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody RzSpecialAttendance rzSpecialAttendance) + { + return toAjax(rzSpecialAttendanceService.insertRzSpecialAttendance(rzSpecialAttendance)); + } + + /** + * 修改加班考勤记录 + */ + @PreAuthorize("@ss.hasPermi('attendance:specialAttendance:edit')") + @Log(title = "加班考勤记录", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody RzSpecialAttendance rzSpecialAttendance) + { + return toAjax(rzSpecialAttendanceService.updateRzSpecialAttendance(rzSpecialAttendance)); + } + + /** + * 删除加班考勤记录 + */ + @PreAuthorize("@ss.hasPermi('attendance:specialAttendance:remove')") + @Log(title = "加班考勤记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return toAjax(rzSpecialAttendanceService.deleteRzSpecialAttendanceById(id)); + } +} diff --git a/evo-admin/src/main/java/com/evo/attendance/controller/RzSpecialOverTimeController.java b/evo-admin/src/main/java/com/evo/attendance/controller/RzSpecialOverTimeController.java new file mode 100644 index 0000000..52b3851 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/controller/RzSpecialOverTimeController.java @@ -0,0 +1,104 @@ +package com.evo.attendance.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import com.evo.attendance.domain.RzSpecialOverTime; +import com.evo.attendance.service.IRzSpecialOverTimeService; +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.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.common.core.page.TableDataInfo; + +/** + * 特殊加班管理Controller + * + * @author evo + * @date 2025-04-16 + */ +@RestController +@RequestMapping("/attendance/specialTime") +public class RzSpecialOverTimeController extends BaseController +{ + @Autowired + private IRzSpecialOverTimeService rzSpecialOverTimeService; + + /** + * 查询特殊加班管理列表 + */ + @PreAuthorize("@ss.hasPermi('attendance:specialTime:list')") + @GetMapping("/list") + public TableDataInfo list(RzSpecialOverTime rzSpecialOverTime) + { + startPage(); + List list = rzSpecialOverTimeService.selectRzSpecialOverTimeList(rzSpecialOverTime); + return getDataTable(list); + } + + /** + * 导出特殊加班管理列表 + */ + @PreAuthorize("@ss.hasPermi('attendance:specialTime:export')") + @Log(title = "特殊加班管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, RzSpecialOverTime rzSpecialOverTime) + { + List list = rzSpecialOverTimeService.selectRzSpecialOverTimeList(rzSpecialOverTime); + ExcelUtil util = new ExcelUtil(RzSpecialOverTime.class); + util.exportExcel(response, list, "特殊加班管理数据"); + } + + /** + * 获取特殊加班管理详细信息 + */ + @PreAuthorize("@ss.hasPermi('attendance:specialTime:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(rzSpecialOverTimeService.selectRzSpecialOverTimeById(id)); + } + + /** + * 新增特殊加班管理 + */ + @PreAuthorize("@ss.hasPermi('attendance:specialTime:add')") + @Log(title = "特殊加班管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody RzSpecialOverTime rzSpecialOverTime) + { + return toAjax(rzSpecialOverTimeService.insertRzSpecialOverTime(rzSpecialOverTime)); + } + + /** + * 修改特殊加班管理 + */ + @PreAuthorize("@ss.hasPermi('attendance:specialTime:edit')") + @Log(title = "特殊加班管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody RzSpecialOverTime rzSpecialOverTime) + { + return toAjax(rzSpecialOverTimeService.updateRzSpecialOverTime(rzSpecialOverTime)); + } + + /** + * 删除特殊加班管理 + */ + @PreAuthorize("@ss.hasPermi('attendance:specialTime:remove')") + @Log(title = "特殊加班管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return toAjax(rzSpecialOverTimeService.deleteRzSpecialOverTimeById(id)); + } +} diff --git a/evo-admin/src/main/java/com/evo/attendance/domain/RzAbnormal.java b/evo-admin/src/main/java/com/evo/attendance/domain/RzAbnormal.java new file mode 100644 index 0000000..eebb7c7 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/domain/RzAbnormal.java @@ -0,0 +1,152 @@ +package com.evo.attendance.domain; + +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; + +/** + * 考勤异常对象 rz_abnormal + * + * @author evo + * @date 2025-03-10 + */ +public class RzAbnormal extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Long id; + + /** 部门 */ + @Excel(name = "部门") + private Long deptId; + + private String deptName; + + /** 员工ID */ + @Excel(name = "员工ID") + private Long userId; + + /** 员工姓名 */ + @Excel(name = "员工姓名") + private String name; + + /** 月份 */ + @JsonFormat(pattern = "yyyy-MM") + @Excel(name = "月份", width = 30, dateFormat = "yyyy-MM") + private Date month; + + /** 次数 */ + @Excel(name = "次数") + private Long number; + + /** 金额 */ + @Excel(name = "金额") + private BigDecimal money; + + /** 删除标识 */ + private String delFlag; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + public Long getDeptId() + { + return deptId; + } + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getUserId() + { + return userId; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public Date getMonth() { + return month; + } + + public void setMonth(Date month) { + this.month = month; + } + + public void setNumber(Long number) + { + this.number = number; + } + + public Long getNumber() + { + return number; + } + public void setMoney(BigDecimal money) + { + this.money = money; + } + + public BigDecimal getMoney() + { + return money; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("deptId", getDeptId()) + .append("userId", getUserId()) + .append("name", getName()) + .append("month", getMonth()) + .append("number", getNumber()) + .append("money", getMoney()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/attendance/domain/RzAbnormalDetail.java b/evo-admin/src/main/java/com/evo/attendance/domain/RzAbnormalDetail.java new file mode 100644 index 0000000..c667dec --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/domain/RzAbnormalDetail.java @@ -0,0 +1,146 @@ +package com.evo.attendance.domain; + +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; + +/** + * 考勤异常详情对象 rz_abnormal_detail + * + * @author evo + * @date 2025-03-10 + */ +public class RzAbnormalDetail extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Long id; + + /** 异常ID */ + @Excel(name = "异常ID") + private Long abnormalId; + + /** 员工姓名 */ + @Excel(name = "员工姓名") + private String name; + + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "考勤时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date clockDate; + + private String clockType; + + public Date getClockDate() { + return clockDate; + } + + public void setClockDate(Date clockDate) { + this.clockDate = clockDate; + } + + /** 打卡时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "打卡时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date abnormalTime; + + /** 激励金额 */ + @Excel(name = "激励金额") + private BigDecimal money; + + /** 删除标识 */ + private String delFlag; + private String remarks; + + public String getClockType() { + return clockType; + } + + public void setClockType(String clockType) { + this.clockType = clockType; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + + public Long getAbnormalId() { + return abnormalId; + } + + public void setAbnormalId(Long abnormalId) { + this.abnormalId = abnormalId; + } + + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setAbnormalTime(Date abnormalTime) + { + this.abnormalTime = abnormalTime; + } + + public Date getAbnormalTime() + { + return abnormalTime; + } + public void setMoney(BigDecimal money) + { + this.money = money; + } + + public String getRemarks() { + return remarks; + } + + public void setRemarks(String remarks) { + this.remarks = remarks; + } + + public BigDecimal getMoney() + { + return money; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("abnormalId", getAbnormalId()) + .append("name", getName()) + .append("abnormalTime", getAbnormalTime()) + .append("money", getMoney()) + .append("remarks", getRemarks()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateTime", getUpdateTime()) + .append("updateBy", getUpdateBy()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/attendance/domain/RzAttendance.java b/evo-admin/src/main/java/com/evo/attendance/domain/RzAttendance.java new file mode 100644 index 0000000..6a4fe07 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/domain/RzAttendance.java @@ -0,0 +1,242 @@ +package com.evo.attendance.domain; + +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 考勤记录对象 rz_attendance + * + * @author chenyj + * @date 2024-09-05 + */ +public class RzAttendance extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 统计id */ + private Long staffId; + + /** 员工姓名 */ + @Excel(name = "员工姓名") + private String name; + + /** 所属部门 */ + @Excel(name = "所属部门") + private String deptName; + private Long deptId; + + /** 考勤日期 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "考勤日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date attendanceDate; + + /** 考勤规则 */ + @Excel(name = "考勤规则") + private String rules; + + private String ycsFlag; + private String ycxFlag; + + /** 上班时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "上班时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date workStartTime; + + /** 下班时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "下班时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date workEndTime; + + /** 工作时长 */ + @Excel(name = "工作时长") + private BigDecimal workSum; + @Excel(name = "考勤时长") + private BigDecimal workHours; + /** 夜班次数 */ + private int nightNumber; + + /** 中班次数 */ + private int middleShiftNumber; + + + /** 备注 */ + @Excel(name = "备注") + private String remarks; + + /** 删除标识 */ + private String delFlag; + + public String getYcsFlag() { + return ycsFlag; + } + + public void setYcsFlag(String ycsFlag) { + this.ycsFlag = ycsFlag; + } + + public String getYcxFlag() { + return ycxFlag; + } + + public void setYcxFlag(String ycxFlag) { + this.ycxFlag = ycxFlag; + } + + public Long getStaffId() { + return staffId; + } + + public void setStaffId(Long staffId) { + this.staffId = staffId; + } + + public BigDecimal getWorkHours() { + return workHours; + } + + public void setWorkHours(BigDecimal workHours) { + this.workHours = workHours; + } + + public int getNightNumber() { + return nightNumber; + } + + public void setNightNumber(int nightNumber) { + this.nightNumber = nightNumber; + } + + public int getMiddleShiftNumber() { + return middleShiftNumber; + } + + public void setMiddleShiftNumber(int middleShiftNumber) { + this.middleShiftNumber = middleShiftNumber; + } + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + + public Long getDeptId() { + return deptId; + } + + public void setDeptId(Long deptId) { + this.deptId = deptId; + } + + public void setAttendanceDate(Date attendanceDate) + { + this.attendanceDate = attendanceDate; + } + + public Date getAttendanceDate() + { + return attendanceDate; + } + public void setRules(String rules) + { + this.rules = rules; + } + + public String getRules() + { + return rules; + } + public void setWorkStartTime(Date workStartTime) + { + this.workStartTime = workStartTime; + } + + public Date getWorkStartTime() + { + return workStartTime; + } + public void setWorkEndTime(Date workEndTime) + { + this.workEndTime = workEndTime; + } + + public Date getWorkEndTime() + { + return workEndTime; + } + public void setWorkSum(BigDecimal workSum) + { + this.workSum = workSum; + } + + public BigDecimal getWorkSum() + { + return workSum; + } + public void setRemarks(String remarks) + { + this.remarks = remarks; + } + + public String getRemarks() + { + return remarks; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("deptName", getDeptId()) + .append("attendanceDate", getAttendanceDate()) + .append("rules", getRules()) + .append("workStartTime", getWorkStartTime()) + .append("workEndTime", getWorkEndTime()) + .append("workSum", getWorkSum()) + .append("remarks", getRemarks()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/attendance/domain/RzAttendanceDetail.java b/evo-admin/src/main/java/com/evo/attendance/domain/RzAttendanceDetail.java new file mode 100644 index 0000000..b4e83f8 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/domain/RzAttendanceDetail.java @@ -0,0 +1,140 @@ +package com.evo.attendance.domain; + +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; + +/** + * 考勤明细对象 rz_attendance_detail + * + * @author chenyj + * @date 2024-09-14 + */ +public class RzAttendanceDetail extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 用户id */ + @Excel(name = "用户id") + private Long staffId; + + /** 姓名 */ + @Excel(name = "姓名") + private String name; + + /** 设备编号 */ + @Excel(name = "设备编号") + private String equipmentCode; + + /** 按钮类型 */ + @Excel(name = "按钮类型") + private String buttonType; + + /** 时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date dateTime; + + /** 周六标识 */ + private String remark; + + /** 删除标记 */ + private String delFlag; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setStaffId(Long staffId) + { + this.staffId = staffId; + } + + public Long getStaffId() + { + return staffId; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setEquipmentCode(String equipmentCode) + { + this.equipmentCode = equipmentCode; + } + + public String getEquipmentCode() + { + return equipmentCode; + } + public void setButtonType(String buttonType) + { + this.buttonType = buttonType; + } + + public String getButtonType() + { + return buttonType; + } + public void setDateTime(Date dateTime) + { + this.dateTime = dateTime; + } + + public Date getDateTime() + { + return dateTime; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("staffId", getStaffId()) + .append("name", getName()) + .append("equipmentCode", getEquipmentCode()) + .append("buttonType", getButtonType()) + .append("dateTime", getDateTime()) + .append("remark", getRemark()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/attendance/domain/RzAttendanceStatistical.java b/evo-admin/src/main/java/com/evo/attendance/domain/RzAttendanceStatistical.java new file mode 100644 index 0000000..2196fe8 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/domain/RzAttendanceStatistical.java @@ -0,0 +1,282 @@ +package com.evo.attendance.domain; + +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +/** + * 考勤统计对象 rz_attendance_statistical + * + * @author chenyj + * @date 2024-09-05 + */ +public class RzAttendanceStatistical extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + @Excel(name = "主键ID") + private Long id; + + /** 员工ID */ + private Long staffId; + + /** 所属月份 */ + @Excel(name = "所属月份", width = 30, dateFormat = "yyyy-MM") + @JsonFormat(pattern = "yyyy-MM") + private Date month; + + /** 所属部门 */ + private Long deptId; + + private List deptIds; + @Excel(name = "所属部门") + private String deptName; + + /** 员工姓名 */ + @Excel(name = "员工姓名") + private String name; + + /** 应出勤(小时) */ + @Excel(name = "应出勤(小时)") + private BigDecimal shouldAttendance; + + /** 实出勤(小时) */ + @Excel(name = "实出勤(小时)") + private BigDecimal realAttendance; + + /** 打卡时长(小时) */ + @Excel(name = "打卡时长(小时)") + private BigDecimal essentialAttendance; + + /** 加班时长(小时) */ + @Excel(name = "加班时长(小时)") + private BigDecimal workOvertimeNumber; + + /** 请假时长(小时) */ + @Excel(name = "请假时长(小时)") + private BigDecimal absenteeism; + + /** 请假时长(小时) */ + @Excel(name = "特殊加班(小时)") + private BigDecimal overTimeHours; + + /** 迟到次数 */ + @Excel(name = "异常次数") + private Long lateNumber; + + /** 早退次数 */ + //@Excel(name = "早退次数") + private Long leaveEarly; + + /** 缺卡次数 */ + //@Excel(name = "缺卡次数") + private Long lessNumber; + + /** 夜班次数 */ + @Excel(name = "夜班次数") + private Long nightNumber; + + /** 中班次数 */ + @Excel(name = "中班次数") + private Long middleShiftNumber; + + /** 删除标识 */ + private String delFlag; + + public BigDecimal getOverTimeHours() { + return overTimeHours; + } + + public void setOverTimeHours(BigDecimal overTimeHours) { + this.overTimeHours = overTimeHours; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeptIds() { + return deptIds; + } + + public void setDeptIds(List deptIds) { + this.deptIds = deptIds; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setStaffId(Long staffId) + { + this.staffId = staffId; + } + + public Long getStaffId() + { + return staffId; + } + public void setMonth(Date month) + { + this.month = month; + } + + public Date getMonth() + { + return month; + } + + public Long getDeptId() { + return deptId; + } + + public void setDeptId(Long deptId) { + this.deptId = deptId; + } + + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setShouldAttendance(BigDecimal shouldAttendance) + { + this.shouldAttendance = shouldAttendance; + } + + public BigDecimal getShouldAttendance() + { + return shouldAttendance; + } + public void setRealAttendance(BigDecimal realAttendance) + { + this.realAttendance = realAttendance; + } + + public BigDecimal getRealAttendance() + { + return realAttendance; + } + public void setEssentialAttendance(BigDecimal essentialAttendance) + { + this.essentialAttendance = essentialAttendance; + } + + public BigDecimal getEssentialAttendance() + { + return essentialAttendance; + } + public void setWorkOvertimeNumber(BigDecimal workOvertimeNumber) + { + this.workOvertimeNumber = workOvertimeNumber; + } + + public BigDecimal getWorkOvertimeNumber() + { + return workOvertimeNumber; + } + public void setAbsenteeism(BigDecimal absenteeism) + { + this.absenteeism = absenteeism; + } + + public BigDecimal getAbsenteeism() + { + return absenteeism; + } + public void setLateNumber(Long lateNumber) + { + this.lateNumber = lateNumber; + } + + public Long getLateNumber() + { + return lateNumber; + } + public void setLeaveEarly(Long leaveEarly) + { + this.leaveEarly = leaveEarly; + } + + public Long getLeaveEarly() + { + return leaveEarly; + } + public void setLessNumber(Long lessNumber) + { + this.lessNumber = lessNumber; + } + + public Long getLessNumber() + { + return lessNumber; + } + public void setNightNumber(Long nightNumber) + { + this.nightNumber = nightNumber; + } + + public Long getNightNumber() + { + return nightNumber; + } + public void setMiddleShiftNumber(Long middleShiftNumber) + { + this.middleShiftNumber = middleShiftNumber; + } + + public Long getMiddleShiftNumber() + { + return middleShiftNumber; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("staffId", getStaffId()) + .append("month", getMonth()) + .append("deptId", getDeptId()) + .append("name", getName()) + .append("shouldAttendance", getShouldAttendance()) + .append("realAttendance", getRealAttendance()) + .append("essentialAttendance", getEssentialAttendance()) + .append("workOvertimeNumber", getWorkOvertimeNumber()) + .append("absenteeism", getAbsenteeism()) + .append("lateNumber", getLateNumber()) + .append("leaveEarly", getLeaveEarly()) + .append("lessNumber", getLessNumber()) + .append("nightNumber", getNightNumber()) + .append("middleShiftNumber", getMiddleShiftNumber()) + .append("delFlag", getDelFlag()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/attendance/domain/RzSpecialAttendance.java b/evo-admin/src/main/java/com/evo/attendance/domain/RzSpecialAttendance.java new file mode 100644 index 0000000..431eb19 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/domain/RzSpecialAttendance.java @@ -0,0 +1,172 @@ +package com.evo.attendance.domain; + +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; + +/** + * 加班考勤记录对象 rz_special_attendance + * + * @author evo + * @date 2025-04-15 + */ +public class RzSpecialAttendance extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 员工ID */ + @Excel(name = "员工ID") + private Long staffId; + + /** 员工姓名 */ + @Excel(name = "员工姓名") + private String name; + + /** 所属部门 */ + @Excel(name = "所属部门") + private Long deptId; + + /** 考勤日期 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "考勤日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date attendanceDate; + + /** 上班时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "上班时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date workStartTime; + + /** 下班时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "下班时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date workEndTime; + + /** 考勤时长 */ + @Excel(name = "考勤时长") + private BigDecimal workHours; + + /** 备注 */ + @Excel(name = "备注") + private String remarks; + + /** 删除标识 */ + private String delFlag; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setStaffId(Long staffId) + { + this.staffId = staffId; + } + + public Long getStaffId() + { + return staffId; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + public Long getDeptId() + { + return deptId; + } + public void setAttendanceDate(Date attendanceDate) + { + this.attendanceDate = attendanceDate; + } + + public Date getAttendanceDate() + { + return attendanceDate; + } + public void setWorkStartTime(Date workStartTime) + { + this.workStartTime = workStartTime; + } + + public Date getWorkStartTime() + { + return workStartTime; + } + public void setWorkEndTime(Date workEndTime) + { + this.workEndTime = workEndTime; + } + + public Date getWorkEndTime() + { + return workEndTime; + } + public void setWorkHours(BigDecimal workHours) + { + this.workHours = workHours; + } + + public BigDecimal getWorkHours() + { + return workHours; + } + public void setRemarks(String remarks) + { + this.remarks = remarks; + } + + public String getRemarks() + { + return remarks; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("staffId", getStaffId()) + .append("name", getName()) + .append("deptId", getDeptId()) + .append("attendanceDate", getAttendanceDate()) + .append("workStartTime", getWorkStartTime()) + .append("workEndTime", getWorkEndTime()) + .append("workHours", getWorkHours()) + .append("remarks", getRemarks()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/attendance/domain/RzSpecialOverTime.java b/evo-admin/src/main/java/com/evo/attendance/domain/RzSpecialOverTime.java new file mode 100644 index 0000000..58a5d38 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/domain/RzSpecialOverTime.java @@ -0,0 +1,135 @@ +package com.evo.attendance.domain; + +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; + +/** + * 特殊加班管理对象 rz_special_over_time + * + * @author evo + * @date 2025-04-16 + */ +public class RzSpecialOverTime extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Long id; + + /** 员工ID */ + @Excel(name = "员工ID") + private Long userId; + + /** 部门 */ + private Long deptId; + @Excel(name = "部门") + private String deptName; + /** 员工姓名 */ + @Excel(name = "员工姓名") + private String name; + + /** 加班月份(到月) */ + @Excel(name = "加班月份", readConverterExp = "到=月") + @JsonFormat(pattern = "yyyy-MM") + private Date overDate; + + /** 加班时长(小时) */ + @Excel(name = "加班时长", readConverterExp = "小=时") + private BigDecimal sickHours; + + /** 删除标识 */ + private String delFlag; + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getUserId() + { + return userId; + } + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + public Long getDeptId() + { + return deptId; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + + public Date getOverDate() { + return overDate; + } + + public void setOverDate(Date overDate) { + this.overDate = overDate; + } + + public void setSickHours(BigDecimal sickHours) + { + this.sickHours = sickHours; + } + + public BigDecimal getSickHours() + { + return sickHours; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("userId", getUserId()) + .append("deptId", getDeptId()) + .append("name", getName()) + .append("sickHours", getSickHours()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/attendance/domain/vo/RzAttendanceData.java b/evo-admin/src/main/java/com/evo/attendance/domain/vo/RzAttendanceData.java new file mode 100644 index 0000000..fae71ce --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/domain/vo/RzAttendanceData.java @@ -0,0 +1,19 @@ +package com.evo.attendance.domain.vo; + +public class RzAttendanceData { + + private String button; + + public String getButton() { + return button; + } + + public void setButton(String button) { + this.button = button; + } + + @Override + public String toString() { + return "RzAttendanceData [button=" + button + "]"; + } +} diff --git a/evo-admin/src/main/java/com/evo/attendance/domain/vo/RzAttendanceVo.java b/evo-admin/src/main/java/com/evo/attendance/domain/vo/RzAttendanceVo.java new file mode 100644 index 0000000..0108026 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/domain/vo/RzAttendanceVo.java @@ -0,0 +1,30 @@ +package com.evo.attendance.domain.vo; + +public class RzAttendanceVo { + + private int Result; + private String Msg; + private RzAttendanceData Content; + public int getResult() { + return Result; + } + public void setResult(int result) { + Result = result; + } + public String getMsg() { + return Msg; + } + public void setMsg(String msg) { + Msg = msg; + } + public RzAttendanceData getContent() { + return Content; + } + public void setContent(RzAttendanceData content) { + Content = content; + } + @Override + public String toString() { + return "RzAttendanceVo [Result=" + Result + ", Msg=" + Msg + ", Content=" + Content + "]"; + } +} diff --git a/evo-admin/src/main/java/com/evo/attendance/mapper/RzAbnormalDetailMapper.java b/evo-admin/src/main/java/com/evo/attendance/mapper/RzAbnormalDetailMapper.java new file mode 100644 index 0000000..2e2c912 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/mapper/RzAbnormalDetailMapper.java @@ -0,0 +1,52 @@ +package com.evo.attendance.mapper; + +import java.util.List; +import com.evo.attendance.domain.RzAbnormalDetail; + +/** + * 考勤异常详情Mapper接口 + * + * @author evo + * @date 2025-03-10 + */ +public interface RzAbnormalDetailMapper +{ + /** + * 查询考勤异常详情 + * + * @param id 考勤异常详情主键 + * @return 考勤异常详情 + */ + public RzAbnormalDetail selectRzAbnormalDetailById(Long id); + + /** + * 查询考勤异常详情列表 + * + * @param rzAbnormalDetail 考勤异常详情 + * @return 考勤异常详情集合 + */ + public List selectRzAbnormalDetailList(RzAbnormalDetail rzAbnormalDetail); + + /** + * 新增考勤异常详情 + * + * @param rzAbnormalDetail 考勤异常详情 + * @return 结果 + */ + public int insertRzAbnormalDetail(RzAbnormalDetail rzAbnormalDetail); + + /** + * 修改考勤异常详情 + * + * @param rzAbnormalDetail 考勤异常详情 + * @return 结果 + */ + public int updateRzAbnormalDetail(RzAbnormalDetail rzAbnormalDetail); + + /** + * 查询考勤异常详情 + * @return 考勤异常详情 + */ + public List selectRzAbnormalDetailByAbnormalId(Long abnormalId); + +} diff --git a/evo-admin/src/main/java/com/evo/attendance/mapper/RzAbnormalMapper.java b/evo-admin/src/main/java/com/evo/attendance/mapper/RzAbnormalMapper.java new file mode 100644 index 0000000..fb9270f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/mapper/RzAbnormalMapper.java @@ -0,0 +1,55 @@ +package com.evo.attendance.mapper; + +import java.util.Date; +import java.util.List; +import com.evo.attendance.domain.RzAbnormal; +import org.apache.ibatis.annotations.Param; + +/** + * 考勤异常Mapper接口 + * + * @author evo + * @date 2025-03-10 + */ +public interface RzAbnormalMapper +{ + /** + * 查询考勤异常 + * + * @param id 考勤异常主键 + * @return 考勤异常 + */ + public RzAbnormal selectRzAbnormalById(Long id); + + /** + * 查询考勤异常列表 + * + * @param rzAbnormal 考勤异常 + * @return 考勤异常集合 + */ + public List selectRzAbnormalList(RzAbnormal rzAbnormal); + + /** + * 新增考勤异常 + * + * @param rzAbnormal 考勤异常 + * @return 结果 + */ + public int insertRzAbnormal(RzAbnormal rzAbnormal); + + /** + * 修改考勤异常 + * + * @param rzAbnormal 考勤异常 + * @return 结果 + */ + public int updateRzAbnormal(RzAbnormal rzAbnormal); + + /** + * 查询当月迟到情况 + * @param userId + * @return + */ + public RzAbnormal selectRzAbnormalByUserId(@Param("userId") Long userId,@Param("month") Date month); + +} diff --git a/evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceDetailMapper.java b/evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceDetailMapper.java new file mode 100644 index 0000000..9882e8f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceDetailMapper.java @@ -0,0 +1,53 @@ +package com.evo.attendance.mapper; + +import com.evo.attendance.domain.RzAttendanceDetail; +import org.apache.ibatis.annotations.Param; + +import java.util.Date; +import java.util.List; + +/** + * 考勤明细Mapper接口 + * + * @author chenyj + * @date 2024-09-14 + */ +public interface RzAttendanceDetailMapper +{ + + /** + * 查询员工最后一次打卡明细 ,按钮切换使用 + * + * @param staffId + * @return 考勤明细集合 + */ + public RzAttendanceDetail selectLastRzAttendanceDetail(@Param("staffId") Long staffId); + + /** + * 新增考勤明细 + * + * @param rzAttendanceDetail 考勤明细 + * @return 结果 + */ + public int insertRzAttendanceDetail(RzAttendanceDetail rzAttendanceDetail); + + /** + * 修改考勤明细 + * @param rzAttendanceDetail + * @return + */ + public int updateRzAttendanceDetail(RzAttendanceDetail rzAttendanceDetail); + + /** + * 查询员工最后一次上班打卡 计算工时 + * + * @param staffId + * @return 考勤明细集合 + */ + public default RzAttendanceDetail selectRzAttendanceDetailByStaffId(@Param("staffId") Long staffId) { + return null; + } + + public List selectRzAttendanceDetailByMonth(Date date); + +} diff --git a/evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceMapper.java b/evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceMapper.java new file mode 100644 index 0000000..1cde57b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceMapper.java @@ -0,0 +1,83 @@ +package com.evo.attendance.mapper; + +import com.evo.attendance.domain.RzAttendance; +import org.apache.ibatis.annotations.Param; +import java.util.Date; +import java.util.List; + +/** + * 考勤记录Mapper接口 + * + * @author chenyj + * @date 2024-09-05 + */ +public interface RzAttendanceMapper +{ + /** + * 查询考勤记录 + * + * @param id 考勤记录主键 + * @return 考勤记录 + */ + public RzAttendance selectRzAttendanceById(Long id); + + /** + * 查询考勤记录列表 + * + * @param rzAttendance 考勤记录 + * @return 考勤记录集合 + */ + public List selectRzAttendanceList(RzAttendance rzAttendance); + /** + * 修改考勤记录 + * + * @param rzAttendance 考勤记录 + * @return 结果 + */ + public int updateRzAttendance(RzAttendance rzAttendance); + /** + * 根据统计ID和时间查询当天的打卡记录 + * @param date + * @return + */ + public RzAttendance queryNowDayAttendanceByStatisticalIdAndDate(@Param("staffId") Long staffId,@Param("date") Date date); + /** + * 每日上班打卡统计 + * @return + */ + public List attendenceCount(); + /** + * 根据员工ID查询最后一次考勤上班记录 + * + * @param staffId 考勤统计ID + * @return 考勤记录 + */ + public RzAttendance selectLastRzAttendanceByStaffId(Long staffId); + /** + * 查询员工的考勤(根据月份) + * @param staffId + * @return + */ + public List queryMonthAttendanceByStaffId(@Param("staffId") Long staffId,@Param("date") Date date); + /** + * 查询考勤记录列表 + * + * @param rzAttendance 考勤记录 + * @return 考勤记录集合 + */ + public List listAttendanceByParams(RzAttendance rzAttendance); + /** + * 批量新增考勤记录 + * + * @param list 考勤记录 + * @return 结果 + */ + public int insertBatchRzAttendance(List list); + + /** + * 查询当天的考勤 + * @return + */ + public List currentDateAllAttendance(); + +} diff --git a/evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceStatisticalMapper.java b/evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceStatisticalMapper.java new file mode 100644 index 0000000..52b1372 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceStatisticalMapper.java @@ -0,0 +1,62 @@ +package com.evo.attendance.mapper; + +import com.evo.attendance.domain.RzAttendanceStatistical; +import org.apache.ibatis.annotations.Param; +import java.util.Date; +import java.util.List; + +/** + * 考勤统计Mapper接口 + * + * @author chenyj + * @date 2024-09-05 + */ +public interface RzAttendanceStatisticalMapper +{ + /** + * 查询考勤统计 + * + * @param id 考勤统计主键 + * @return 考勤统计 + */ + public RzAttendanceStatistical selectRzAttendanceStatisticalById(Long id); + + /** + * 查询考勤统计列表 + * + * @param rzAttendanceStatistical 考勤统计 + * @return 考勤统计集合 + */ + public List selectRzAttendanceStatisticalList(RzAttendanceStatistical rzAttendanceStatistical); + + /** + * 新增考勤统计 + * + * @param rzAttendanceStatistical 考勤统计 + * @return 结果 + */ + public int insertRzAttendanceStatistical(RzAttendanceStatistical rzAttendanceStatistical); + + /** + * 修改考勤统计 + * + * @param rzAttendanceStatistical 考勤统计 + * @return 结果 + */ + public int updateRzAttendanceStatistical(RzAttendanceStatistical rzAttendanceStatistical); + + /** + * 根据员工ID,时间查询统计信息 + * @param staffId + * @param month + * @return + */ + public RzAttendanceStatistical getRzAttendanceStatisticalByDateAndName(@Param("staffId") Long staffId,@Param("month") Date month); + + /** + * 查询考勤月的考勤统计信息 * + * @return 考勤统计集合 + */ + public List queryStatisticalByMonth(Date month); + +} diff --git a/evo-admin/src/main/java/com/evo/attendance/mapper/RzSpecialAttendanceMapper.java b/evo-admin/src/main/java/com/evo/attendance/mapper/RzSpecialAttendanceMapper.java new file mode 100644 index 0000000..97e1397 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/mapper/RzSpecialAttendanceMapper.java @@ -0,0 +1,51 @@ +package com.evo.attendance.mapper; + +import com.evo.attendance.domain.RzSpecialAttendance; +import org.apache.ibatis.annotations.Param; + +import java.util.Date; +import java.util.List; + +/** + * 加班考勤记录Mapper接口 + * + * @author evo + * @date 2025-04-15 + */ +public interface RzSpecialAttendanceMapper +{ + /** + * 查询加班考勤记录 + * + * @param id 加班考勤记录主键 + * @return 加班考勤记录 + */ + public RzSpecialAttendance selectRzSpecialAttendanceById(Long id); + + /** + * 查询加班考勤记录列表 + * + * @param rzSpecialAttendance 加班考勤记录 + * @return 加班考勤记录集合 + */ + public List selectRzSpecialAttendanceList(RzSpecialAttendance rzSpecialAttendance); + + /** + * 新增加班考勤记录 + * + * @param rzSpecialAttendance 加班考勤记录 + * @return 结果 + */ + public int insertRzSpecialAttendance(RzSpecialAttendance rzSpecialAttendance); + + /** + * 修改加班考勤记录 + * + * @param rzSpecialAttendance 加班考勤记录 + * @return 结果 + */ + public int updateRzSpecialAttendance(RzSpecialAttendance rzSpecialAttendance); + + public RzSpecialAttendance selectRzSpecialAttendanceByuserIdAndDate(@Param("staffId") Long staffId,@Param("date") Date date); + +} diff --git a/evo-admin/src/main/java/com/evo/attendance/mapper/RzSpecialOverTimeMapper.java b/evo-admin/src/main/java/com/evo/attendance/mapper/RzSpecialOverTimeMapper.java new file mode 100644 index 0000000..ce32cf2 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/mapper/RzSpecialOverTimeMapper.java @@ -0,0 +1,51 @@ +package com.evo.attendance.mapper; + +import com.evo.attendance.domain.RzSpecialOverTime; +import org.apache.ibatis.annotations.Param; + +import java.util.Date; +import java.util.List; + +/** + * 特殊加班管理Mapper接口 + * + * @author evo + * @date 2025-04-16 + */ +public interface RzSpecialOverTimeMapper +{ + /** + * 查询特殊加班管理 + * + * @param id 特殊加班管理主键 + * @return 特殊加班管理 + */ + public RzSpecialOverTime selectRzSpecialOverTimeById(Long id); + + /** + * 查询特殊加班管理列表 + * + * @param rzSpecialOverTime 特殊加班管理 + * @return 特殊加班管理集合 + */ + public List selectRzSpecialOverTimeList(RzSpecialOverTime rzSpecialOverTime); + + /** + * 新增特殊加班管理 + * + * @param rzSpecialOverTime 特殊加班管理 + * @return 结果 + */ + public int insertRzSpecialOverTime(RzSpecialOverTime rzSpecialOverTime); + + /** + * 修改特殊加班管理 + * + * @param rzSpecialOverTime 特殊加班管理 + * @return 结果 + */ + public int updateRzSpecialOverTime(RzSpecialOverTime rzSpecialOverTime); + + public RzSpecialOverTime selectRzSpecialOverTimeByUserIdAndDate(@Param("userId") Long userId,@Param("date") Date date); + +} diff --git a/evo-admin/src/main/java/com/evo/attendance/service/IRzAbnormalDetailService.java b/evo-admin/src/main/java/com/evo/attendance/service/IRzAbnormalDetailService.java new file mode 100644 index 0000000..0e6b3ce --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/service/IRzAbnormalDetailService.java @@ -0,0 +1,51 @@ +package com.evo.attendance.service; + +import java.util.List; +import com.evo.attendance.domain.RzAbnormalDetail; + +/** + * 考勤异常详情Service接口 + * + * @author evo + * @date 2025-03-10 + */ +public interface IRzAbnormalDetailService +{ + /** + * 查询考勤异常详情 + * + * @param id 考勤异常详情主键 + * @return 考勤异常详情 + */ + public RzAbnormalDetail selectRzAbnormalDetailById(Long id); + + /** + * 查询考勤异常详情列表 + * + * @param rzAbnormalDetail 考勤异常详情 + * @return 考勤异常详情集合 + */ + public List selectRzAbnormalDetailList(RzAbnormalDetail rzAbnormalDetail); + + /** + * 新增考勤异常详情 + * @return 结果 + */ + public void insertRzAbnormalDetail(); + + /** + * 修改考勤异常详情 + * + * @param rzAbnormalDetail 考勤异常详情 + * @return 结果 + */ + public int updateRzAbnormalDetail(RzAbnormalDetail rzAbnormalDetail); + + /** + * 删除考勤异常详情信息 + * + * @param id 考勤异常详情主键 + * @return 结果 + */ + public int deleteRzAbnormalDetailById(Long id); +} diff --git a/evo-admin/src/main/java/com/evo/attendance/service/IRzAbnormalService.java b/evo-admin/src/main/java/com/evo/attendance/service/IRzAbnormalService.java new file mode 100644 index 0000000..912f086 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/service/IRzAbnormalService.java @@ -0,0 +1,52 @@ +package com.evo.attendance.service; + +import java.util.List; +import com.evo.attendance.domain.RzAbnormal; +import com.evo.attendance.domain.RzAbnormalDetail; + +/** + * 考勤异常Service接口 + * + * @author evo + * @date 2025-03-10 + */ +public interface IRzAbnormalService +{ + /** + * 查询考勤异常 + * + * @param id 考勤异常主键 + * @return 考勤异常 + */ + public RzAbnormal selectRzAbnormalById(Long id); + + /** + * 查询考勤异常列表 + * + * @param rzAbnormal 考勤异常 + * @return 考勤异常集合 + */ + public List selectRzAbnormalList(RzAbnormal rzAbnormal); + + /** + * 修改考勤异常 + * + * @param rzAbnormal 考勤异常 + * @return 结果 + */ + public int updateRzAbnormal(RzAbnormal rzAbnormal); + + /** + * 删除考勤异常信息 + * + * @param id 考勤异常主键 + * @return 结果 + */ + public int deleteRzAbnormalById(Long id); + /** + * 异常详情 + * @param rzAbnormal + * @return + */ + public List listAbnormalDetails(RzAbnormal rzAbnormal); +} diff --git a/evo-admin/src/main/java/com/evo/attendance/service/IRzAttendanceService.java b/evo-admin/src/main/java/com/evo/attendance/service/IRzAttendanceService.java new file mode 100644 index 0000000..3187688 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/service/IRzAttendanceService.java @@ -0,0 +1,55 @@ +package com.evo.attendance.service; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.attendance.domain.RzAttendance; +import java.util.List; + +/** + * 考勤记录Service接口 + * + * @author chenyj + * @date 2024-09-05 + */ +public interface IRzAttendanceService +{ + /** + * 查询考勤记录 + * + * @param id 考勤记录主键 + * @return 考勤记录 + */ + public RzAttendance selectRzAttendanceById(Long id); + /** + * 查询考勤记录列表 + * + * @param rzAttendance 考勤记录 + * @return 考勤记录集合 + */ + public List selectRzAttendanceList(RzAttendance rzAttendance); + /** + * 修改考勤记录 + * + * @param rzAttendance 考勤记录 + * @return 结果 + */ + public int updateRzAttendance(RzAttendance rzAttendance); + /** + * 每日上班打卡统计 + * @return + */ + public int attendenceCount(); + /** + * 批量修改考勤记录 + * + * @param rzAttendance 考勤记录 + * @return 结果 + */ + public AjaxResult updateBatchAttendance(RzAttendance rzAttendance); + /** + * 查询考勤记录列表 + * + * @param rzAttendance 考勤记录 + * @return 考勤记录集合 + */ + public List listAttendanceByParams(RzAttendance rzAttendance); +} diff --git a/evo-admin/src/main/java/com/evo/attendance/service/IRzAttendanceStatisticalService.java b/evo-admin/src/main/java/com/evo/attendance/service/IRzAttendanceStatisticalService.java new file mode 100644 index 0000000..2c8fdbf --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/service/IRzAttendanceStatisticalService.java @@ -0,0 +1,50 @@ +package com.evo.attendance.service; + +import com.evo.attendance.domain.RzAttendanceStatistical; +import com.evo.common.core.domain.AjaxResult; +import java.util.List; + +/** + * 考勤统计Service接口 + * + * @author chenyj + * @date 2024-09-05 + */ +public interface IRzAttendanceStatisticalService +{ + /** + * 查询考勤统计 + * + * @param id 考勤统计主键 + * @return 考勤统计 + */ + public RzAttendanceStatistical selectRzAttendanceStatisticalById(Long id); + + /** + * 查询考勤统计列表 + * + * @param rzAttendanceStatistical 考勤统计 + * @return 考勤统计集合 + */ + public List selectRzAttendanceStatisticalList(RzAttendanceStatistical rzAttendanceStatistical); + + /** + * 修改考勤统计 + * + * @param rzAttendanceStatistical 考勤统计 + * @return 结果 + */ + public int updateRzAttendanceStatistical(RzAttendanceStatistical rzAttendanceStatistical); + /** + * 校正数据 + * @return + */ + public AjaxResult correct(RzAttendanceStatistical rzAttendanceStatisticals); + + /** + * 批量导入考勤统计 + * @param list + * @return + */ + public AjaxResult importRzAttendanceStatistical(List list); +} diff --git a/evo-admin/src/main/java/com/evo/attendance/service/IRzSpecialAttendanceService.java b/evo-admin/src/main/java/com/evo/attendance/service/IRzSpecialAttendanceService.java new file mode 100644 index 0000000..0e9a2da --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/service/IRzSpecialAttendanceService.java @@ -0,0 +1,54 @@ +package com.evo.attendance.service; + +import com.evo.attendance.domain.RzSpecialAttendance; + +import java.util.List; + +/** + * 加班考勤记录Service接口 + * + * @author evo + * @date 2025-04-15 + */ +public interface IRzSpecialAttendanceService +{ + /** + * 查询加班考勤记录 + * + * @param id 加班考勤记录主键 + * @return 加班考勤记录 + */ + public RzSpecialAttendance selectRzSpecialAttendanceById(Long id); + + /** + * 查询加班考勤记录列表 + * + * @param rzSpecialAttendance 加班考勤记录 + * @return 加班考勤记录集合 + */ + public List selectRzSpecialAttendanceList(RzSpecialAttendance rzSpecialAttendance); + + /** + * 新增加班考勤记录 + * + * @param rzSpecialAttendance 加班考勤记录 + * @return 结果 + */ + public int insertRzSpecialAttendance(RzSpecialAttendance rzSpecialAttendance); + + /** + * 修改加班考勤记录 + * + * @param rzSpecialAttendance 加班考勤记录 + * @return 结果 + */ + public int updateRzSpecialAttendance(RzSpecialAttendance rzSpecialAttendance); + + /** + * 删除加班考勤记录信息 + * + * @param id 加班考勤记录主键 + * @return 结果 + */ + public int deleteRzSpecialAttendanceById(Long id); +} diff --git a/evo-admin/src/main/java/com/evo/attendance/service/IRzSpecialOverTimeService.java b/evo-admin/src/main/java/com/evo/attendance/service/IRzSpecialOverTimeService.java new file mode 100644 index 0000000..c26a8cd --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/service/IRzSpecialOverTimeService.java @@ -0,0 +1,53 @@ +package com.evo.attendance.service; + +import com.evo.attendance.domain.RzSpecialOverTime; +import java.util.List; + +/** + * 特殊加班管理Service接口 + * + * @author evo + * @date 2025-04-16 + */ +public interface IRzSpecialOverTimeService +{ + /** + * 查询特殊加班管理 + * + * @param id 特殊加班管理主键 + * @return 特殊加班管理 + */ + public RzSpecialOverTime selectRzSpecialOverTimeById(Long id); + + /** + * 查询特殊加班管理列表 + * + * @param rzSpecialOverTime 特殊加班管理 + * @return 特殊加班管理集合 + */ + public List selectRzSpecialOverTimeList(RzSpecialOverTime rzSpecialOverTime); + + /** + * 新增特殊加班管理 + * + * @param rzSpecialOverTime 特殊加班管理 + * @return 结果 + */ + public int insertRzSpecialOverTime(RzSpecialOverTime rzSpecialOverTime); + + /** + * 修改特殊加班管理 + * + * @param rzSpecialOverTime 特殊加班管理 + * @return 结果 + */ + public int updateRzSpecialOverTime(RzSpecialOverTime rzSpecialOverTime); + + /** + * 删除特殊加班管理信息 + * + * @param id 特殊加班管理主键 + * @return 结果 + */ + public int deleteRzSpecialOverTimeById(Long id); +} diff --git a/evo-admin/src/main/java/com/evo/attendance/service/PunchTheClockService.java b/evo-admin/src/main/java/com/evo/attendance/service/PunchTheClockService.java new file mode 100644 index 0000000..293e64b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/service/PunchTheClockService.java @@ -0,0 +1,14 @@ +package com.evo.attendance.service; + +public interface PunchTheClockService { + + /** + * 刷脸获取打卡按钮权限 + */ + public String returnMessage(String json); + /** + * 用户点击打卡按钮后请求的接口 + */ + public String recordFace(String json); + +} diff --git a/evo-admin/src/main/java/com/evo/attendance/service/impl/PunchTheClockServiceImpl.java b/evo-admin/src/main/java/com/evo/attendance/service/impl/PunchTheClockServiceImpl.java new file mode 100644 index 0000000..62aa1d3 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/service/impl/PunchTheClockServiceImpl.java @@ -0,0 +1,559 @@ +package com.evo.attendance.service.impl; + +import com.alibaba.fastjson2.JSONObject; +import com.evo.attendance.domain.*; +import com.evo.attendance.mapper.*; +import com.evo.common.constant.Constants; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.StringUtils; +import com.evo.equipment.domain.EqImages; +import com.evo.equipment.mapper.EqImagesMapper; +import com.evo.attendance.domain.vo.RzAttendanceData; +import com.evo.attendance.domain.vo.RzAttendanceVo; +import com.evo.attendance.service.PunchTheClockService; +import com.evo.personnelMatters.domain.EqOverStaff; +import com.evo.personnelMatters.domain.RzOverTime; +import com.evo.personnelMatters.domain.RzOverTimeDetail; +import com.evo.personnelMatters.domain.SpecialOverTime; +import com.evo.personnelMatters.mapper.BsOverTimeMapper; +import com.evo.personnelMatters.mapper.EqOverStaffMapper; +import com.evo.personnelMatters.mapper.RzOverTimeDetailMapper; +import com.evo.personnelMatters.mapper.RzOverTimeMapper; +import com.evo.system.domain.SysStaff; +import com.evo.system.mapper.SysStaffDetailMapper; +import com.evo.system.mapper.SysStaffMapper; +import com.evo.utils.DateUtil; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.util.Date; + + +@Service +public class PunchTheClockServiceImpl implements PunchTheClockService { + + @Resource + private EqImagesMapper eqImagesMapper; //照片管理 + @Resource + private RzAttendanceMapper rzAttendanceMapper; //考勤记录 + @Resource + private RzAttendanceDetailMapper rzAttendanceDetailMapper; //打卡明细 + @Resource + private SysStaffMapper sysStaffMapper; //员工信息 + @Resource + private SysStaffDetailMapper sysStaffDetailMapper; //员工详情 + @Resource + private RzOverTimeDetailMapper rzOverTimeDetailMapper; //加班详情 + @Resource + private RzOverTimeMapper rzOverTimeMapper; //加班统计 + @Resource + private RzAttendanceStatisticalMapper rzAttendanceStatisticalMapper; //打卡统计 + @Resource + private RzSpecialAttendanceMapper rzSpecialAttendanceMapper; + @Resource + private EqOverStaffMapper eqOverStaffMapper; + @Resource + private BsOverTimeMapper bsOverTimeMapper; + @Resource + private RzSpecialOverTimeMapper rzSpecialOverTimeMapper; + /** + * 刷脸获取打卡按钮权限 + * sn 设备号 + * type 设备识别类型 + * user_id 用户id + * card 人员信息中的卡号 + * confidence 人脸算法识别到的相识度 + * temperature 测量到的温度,未开启测温的设备为空 + * + * 响应: Result 返回请求类型:0:可以打卡,其它值表示无法打卡 + * Msg 对应 Result 的状态,可为空 + * Content 识别后返回的详细信息 + * button 9位长度的字符串,0 表示不可以点击 1 表示可以点击 + * + * String sn,String type,String userId,String card,String confidence + */ + @Override + public String returnMessage(String json){ + //解析收到的数据 + JSONObject jsonObject = JSONObject.parseObject(json); + String userId = jsonObject.getString("user_id"); + //需要推送的数据 + String message = ""; + //需要返回的对象 + RzAttendanceVo cardV = new RzAttendanceVo(); + RzAttendanceData cardD = new RzAttendanceData(); + String sn = jsonObject.getString("sn"); + if(com.evo.equipment.constant.Constants.EQ_DEVICE_OVER_TIME_CODE.equals(sn)){ + boolean flag = DateUtil.isSaturday(new Date(),1); + if(flag){ + cardV.setResult(1); + cardV.setMsg("{\"Result\":1,\"Msg\":\"周日不能打卡\"}"); + cardD.setButton("000000000"); + cardV.setContent(cardD); + //Java对象转换成JSON字符串 + message = JSONObject.toJSONString(cardV); + return message; + } + EqOverStaff eqOverStaff = eqOverStaffMapper.selectEqOverStaffByUserId(Long.valueOf(userId)); + if(StringUtils.isNull(eqOverStaff)){ + cardV.setResult(1); + cardV.setMsg("{\"Result\":1,\"Msg\":\"验证失败,未设置考勤权限\"}"); + cardD.setButton("000000000"); + cardV.setContent(cardD); + //Java对象转换成JSON字符串 + message = JSONObject.toJSONString(cardV); + return message; + } + RzSpecialAttendance rzSpecialAttendance = rzSpecialAttendanceMapper.selectRzSpecialAttendanceByuserIdAndDate(Long.valueOf(userId),new Date()); + if(StringUtils.isNull(rzSpecialAttendance)){ + cardV.setResult(0); + cardV.setMsg("验证通过"); + cardD.setButton("111100000"); + cardV.setContent(cardD); + //Java对象转换成JSON字符串 + message = JSONObject.toJSONString(cardV); + }else{ + cardV.setResult(0); + cardV.setMsg("验证通过"); + cardD.setButton("000011000"); + cardV.setContent(cardD); + //Java对象转换成JSON字符串 + message = JSONObject.toJSONString(cardV); + } + return message; + } + //根据ID查询在职员工信息 + SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.valueOf(userId)); + //员工不存在,说明离职没有打卡权限 + if(StringUtils.isNull(sysStaff)){ + cardV.setResult(1); + cardV.setMsg("{\"Result\":1,\"Msg\":\"验证失败,未设置考勤权限\"}"); + cardD.setButton("000000000"); + cardV.setContent(cardD); + //Java对象转换成JSON字符串 + message = JSONObject.toJSONString(cardV); + return message; + } + //根据id查询当前员工不是员工列表中的人,返回提示 + EqImages userImg = eqImagesMapper.selectEqImagesByStaffId(Long.valueOf(userId)); + if(StringUtils.isNull(userImg)){ + cardV.setResult(1); + cardV.setMsg("{\"Result\":1,\"Msg\":\"验证失败,未设置考勤权限\"}"); + cardD.setButton("000000000"); + cardV.setContent(cardD); + //Java对象转换成JSON字符串 + message = JSONObject.toJSONString(cardV); + return message; + } + //查询员工的最后一次打卡 按钮切换 + RzAttendanceDetail rzAttendanceDetail = rzAttendanceDetailMapper.selectLastRzAttendanceDetail(Long.valueOf(userId)); + //判断最后一次打卡为下班卡或没有打卡记录,则打卡为上班卡 + if(StringUtils.isNull(rzAttendanceDetail) || "下班卡".equals(rzAttendanceDetail.getButtonType()) || "撤销".equals(rzAttendanceDetail.getButtonType())){ + //如果最后一条数据的卡类型为下班卡,则返回上班卡和加班卡权限 + cardV.setResult(0); + cardV.setMsg("验证通过"); + cardD.setButton("111100000"); + cardV.setContent(cardD); + //Java对象转换成JSON字符串 + message = JSONObject.toJSONString(cardV); + }else{ + cardV.setResult(0); + cardV.setMsg("验证通过"); + cardD.setButton("000011000"); + cardV.setContent(cardD); + //Java对象转换成JSON字符串 + message = JSONObject.toJSONString(cardV); + } + return message; + } + /** + * 用户点击打卡按钮后请求的接口 + * sn 设备号 + * user_id 人员id + * user_name 用户名 + * user_type 用户类型,对应下发人员时的 user_type + * card_number 卡号 + * recog_type 识别类型: face - 为人脸识别 、card - 刷卡开门,人脸或卡模式 + * recog_time 识别时间(时间格式yyyy-MM-dd HH:mm:ss) + * photo 识别照片,服务端收到后转换成图片步骤请查看 2、服务规范 - 照片解码流程 + * body_temperature 体温 + * confidence 通过的置信度 + * button 1~9 表示点击的是第几个按钮 + * + * 响应:Result 返回请求类型:0成功,其它失败 + * Msg 对应 Result 的文本信息 + * + * String sn,String userId,String userName,String userType,String cardNumber,String recog_type,String recog_time,String photo,String body_temperature,String confidence,String button + */ + @Override + @Transactional + public String recordFace(String json){ + //解析收到的数据 + JSONObject jsonObject = JSONObject.parseObject(json); + String userId = jsonObject.getString("user_id"); + String sn = jsonObject.getString("sn"); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd"); + Date date = null; //打卡时间 + try{ + date = sdf.parse(jsonObject.getString("recog_time")); + }catch (Exception e){ + e.printStackTrace(); + return "{\"Result\":1,\"Msg\":\"打卡失败\"}"; + } + String rules = ""; //打卡规则 + String button = jsonObject.getString("button"); + switch (button){ + case "1": + rules = "上班卡(单班制)"; + break; + case "2": + rules = "上班卡(双班制)"; + break; + case "3": + rules = "上班卡(三班制)"; + break; + case "4": + rules = "加班卡"; + break; + case "5": + rules = "下班卡"; + break; + default: + rules = "撤销"; + break; + } + + //判断是打特殊加班卡 + if(com.evo.equipment.constant.Constants.EQ_DEVICE_OVER_TIME_CODE.equals(sn)){ + RzSpecialAttendance rzSpecialAttendance = null; + SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.valueOf(userId)); + if("1".equals(button) || "2".equals(button) || "3".equals(button) || "6".equals(button)){ + return "{\"Result\":1,\"Msg\":\"无效打卡\"}"; + } + if("4".equals(button)){ + rzSpecialAttendance = new RzSpecialAttendance(); + rzSpecialAttendance.setAttendanceDate(new Date()); + rzSpecialAttendance.setStaffId(Long.valueOf(userId)); + rzSpecialAttendance.setName(sysStaff.getName()); + rzSpecialAttendance.setWorkStartTime(date); + rzSpecialAttendance.setDeptId(sysStaff.getDeptId()); + rzSpecialAttendance.setDelFlag("0"); + rzSpecialAttendance.setCreateBy("admin"); + rzSpecialAttendance.setCreateTime(new Date()); + rzSpecialAttendanceMapper.insertRzSpecialAttendance(rzSpecialAttendance); + + RzSpecialOverTime rzSpecialOverTime = rzSpecialOverTimeMapper.selectRzSpecialOverTimeByUserIdAndDate(rzSpecialAttendance.getStaffId(),rzSpecialAttendance.getAttendanceDate()); + if(StringUtils.isNull(rzSpecialOverTime)){ + rzSpecialOverTime = new RzSpecialOverTime(); + rzSpecialOverTime.setUserId(Long.valueOf(userId)); + rzSpecialOverTime.setName(sysStaff.getName()); + rzSpecialOverTime.setDeptId(sysStaff.getDeptId()); + rzSpecialOverTime.setDelFlag("0"); + rzSpecialOverTime.setOverDate(date); + rzSpecialOverTime.setCreateTime(new Date()); + rzSpecialOverTime.setCreateBy("admin"); + rzSpecialOverTimeMapper.insertRzSpecialOverTime(rzSpecialOverTime); + } + return "{\"Result\":0,\"Msg\":\"打卡成功\"}"; + }else { + rzSpecialAttendance = rzSpecialAttendanceMapper.selectRzSpecialAttendanceByuserIdAndDate(Long.valueOf(userId),new Date()); + rzSpecialAttendance.setWorkEndTime(date); + SpecialOverTime specialOverTime = bsOverTimeMapper.selectSpecialOverTimeById(); + try{ + Date overDate_s = sdf.parse(sdfd.format(rzSpecialAttendance.getWorkStartTime())+" "+specialOverTime.getWorkStart()); + Date overDate_e = sdf.parse(sdfd.format(date)+" "+specialOverTime.getWorkEnd()); + + Long minutes = 0l; + if(overDate_s.after(rzSpecialAttendance.getWorkStartTime()) && overDate_e.before(date)){ + minutes = (overDate_e.getTime() - overDate_s.getTime())/1000/60; + }else { + if(overDate_s.before(rzSpecialAttendance.getWorkStartTime()) && overDate_e.after(date)){ + minutes = (date.getTime() - rzSpecialAttendance.getWorkStartTime().getTime())/1000/60; + }else{ + if(overDate_e.after(date)){ + minutes = (date.getTime() - overDate_s.getTime())/1000/60; + }else { + minutes = (overDate_e.getTime() - rzSpecialAttendance.getWorkStartTime().getTime())/1000/60; + } + } + } + if(minutes >= 180){ + rzSpecialAttendance.setWorkHours(new BigDecimal(3)); + }else if(minutes >= 120){ + rzSpecialAttendance.setWorkHours(new BigDecimal(2)); + } + rzSpecialAttendanceMapper.updateRzSpecialAttendance(rzSpecialAttendance); + + RzSpecialOverTime rzSpecialOverTime = rzSpecialOverTimeMapper.selectRzSpecialOverTimeByUserIdAndDate(rzSpecialAttendance.getStaffId(),rzSpecialAttendance.getAttendanceDate()); + rzSpecialOverTime.setSickHours(rzSpecialOverTime.getSickHours().add(rzSpecialAttendance.getWorkHours())); + rzSpecialOverTimeMapper.updateRzSpecialOverTime(rzSpecialOverTime); + + RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(rzSpecialAttendance.getStaffId(),rzSpecialAttendance.getAttendanceDate()); + if(StringUtils.isNull(rzAttendanceStatistical.getOverTimeHours())){ + rzAttendanceStatistical.setOverTimeHours(new BigDecimal(0.0)); + } + rzAttendanceStatistical.setOverTimeHours(rzAttendanceStatistical.getOverTimeHours().add(rzSpecialAttendance.getWorkHours())); + rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical); + return "{\"Result\":0,\"Msg\":\"打卡成功\"}"; + }catch (Exception e){ + e.printStackTrace(); + return "{\"Result\":1,\"Msg\":\"打卡失败\"}"; + } + } + } + + //根据ID查询员工信息 ,判断员工是否存在,不存在返回失败 + SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.valueOf(userId));//打卡记录信息 + if(sysStaff == null){ + return "{\"Result\":1,\"Msg\":\"验证失败,未设置考勤权限\"}"; + } + //获取员工的工作时长 + EqImages eqImages = eqImagesMapper.selectEqImagesByStaffId(Long.valueOf(userId)); + //打卡明细 + RzAttendanceDetail attendanceDetail = new RzAttendanceDetail(); + //打卡明细表中插入数据 + attendanceDetail.setButtonType(rules); + attendanceDetail.setName(sysStaff.getName()); + attendanceDetail.setDateTime(date); + attendanceDetail.setDelFlag(Constants.DELETE_FLAG_0); + attendanceDetail.setStaffId(Long.valueOf(userId)); + attendanceDetail.setEquipmentCode(sn); + attendanceDetail.setCreateTime(new Date()); + int i = rzAttendanceDetailMapper.insertRzAttendanceDetail(attendanceDetail); + if(i < 1){ + return "{\"Result\":1,\"Msg\":\"打卡失败\"}"; + } + //考勤加班统计 + RzOverTime rzOverTime = null; + RzOverTimeDetail rzOverTimeDetail = null; + + //打的是加班卡,加班列表中填写数据 + if("4".equals(button)){ + //判断打卡月是否统计过加班 + rzOverTime = rzOverTimeMapper.selectRzOverTimeByNameAndMonth(Long.valueOf(userId),date); + if(rzOverTime == null){ + rzOverTime = new RzOverTime(); + rzOverTime.setUserId(Long.valueOf(userId)); + rzOverTime.setOverHours(new BigDecimal("0.0")); + rzOverTime.setDeptId(sysStaff.getDeptId()); + rzOverTime.setName(sysStaff.getName()); + rzOverTime.setOverTimeMonth(date); + rzOverTime.setDelFlag(Constants.DELETE_FLAG_0); + rzOverTime.setCreateBy("admin"); + rzOverTime.setCreateTime(DateUtils.getNowDate()); + i = rzOverTimeMapper.insertRzOverTime(rzOverTime); + if(i < 1){ + return "{\"Result\":1,\"Msg\":\"打卡失败\"}"; + } + } + rzOverTimeDetail = new RzOverTimeDetail(); + rzOverTimeDetail.setOverTimeId(rzOverTime.getId()); + rzOverTimeDetail.setOverTimeStart(date); + rzOverTimeDetail.setName(sysStaff.getName()); + rzOverTimeDetail.setDelFlag(Constants.DELETE_FLAG_0); + rzOverTimeDetail.setCreateBy("admin"); + rzOverTimeDetail.setCreateTime(DateUtils.getNowDate()); + i = rzOverTimeDetailMapper.insertRzOverTimeDetail(rzOverTimeDetail); + if(i < 1){ + return "{\"Result\":1,\"Msg\":\"打卡失败\"}"; + } + return "{\"Result\":0,\"Msg\":\"打卡成功\"}"; + } + + //员工考勤记录 + RzAttendance attendance = rzAttendanceMapper.queryNowDayAttendanceByStatisticalIdAndDate(Long.valueOf(userId),date); + //判断是撤销卡 + if("6".equals(button)){ + attendance.setRules(""); + i = rzAttendanceMapper.updateRzAttendance(attendance); + if(i < 1){ + return "{\"Result\":1,\"Msg\":\"打卡失败\"}"; + } + return "{\"Result\":0,\"Msg\":\"打卡成功\"}"; + } + + //判断是上班卡 + if("1".equals(button) || "2".equals(button) || "3".equals(button)){ + if(StringUtils.isNotNull(attendance.getWorkStartTime())){ + attendance.setRules(rules); + }else{ + attendance.setRules(rules); + attendance.setWorkStartTime(date); + } + try{ + //判断三种上班卡 + Date db_pre = sdf.parse(sdfd.format(date) + " 08:30:00"); + Date sb_pre = sdf.parse(sdfd.format(date) + " 17:00:00"); + Date sbz_pre = sdf.parse(sdfd.format(date) + " 20:30:00"); + if("上班卡(单班制)".equals(rules) && date.after(db_pre) + || ("上班卡(双班制)".equals(rules) && ((date.after(db_pre) && date.getHours() < 12) || (date.after(sb_pre) && date.getHours() <21))) + || ("上班卡(三班制)".equals(rules) && ((date.after(db_pre) && date.getHours() < 12) || (date.after(sbz_pre) && date.getHours() < 24)))){ + attendance.setYcsFlag("1"); + } + }catch (Exception e){ + e.printStackTrace(); + } + i = rzAttendanceMapper.updateRzAttendance(attendance); + if(i < 1){ + return "{\"Result\":1,\"Msg\":\"打卡失败\"}"; + } + return "{\"Result\":0,\"Msg\":\"打卡成功\"}"; + } + + // 查询员工的最后一次上班打卡信息 + RzAttendanceDetail rzAttendanceDetail = rzAttendanceDetailMapper.selectRzAttendanceDetailByStaffId(Long.valueOf(userId)); + + //下班卡 + //最后一次打卡为加班卡 跨月加班按上个月加班计算 + if("加班卡".equals(rzAttendanceDetail.getButtonType())){ + //修改加班打卡记录 根据员工ID和时间查找 统计数据 + rzOverTime = rzOverTimeMapper.selectRzOverTimeByNameAndMonth(Long.valueOf(userId),rzAttendanceDetail.getDateTime()); + //查找加班详情 加班统计ID和加班开始时间 + rzOverTimeDetail = rzOverTimeDetailMapper.queryRzOverTimeDetailByDateAndOverId(rzOverTime.getId(),rzAttendanceDetail.getDateTime()); + rzOverTimeDetail.setOverTimeEnd(date); + //计算加班时长 小时 + double hours = (rzOverTimeDetail.getOverTimeEnd().getTime() - rzOverTimeDetail.getOverTimeStart().getTime())/1000/60/60; + if(hours > 4){ + rzOverTimeDetail.setOverTimeHours(BigDecimal.valueOf(4)); + }else{ + rzOverTimeDetail.setOverTimeHours(BigDecimal.valueOf(hours)); + } + + i = rzOverTimeDetailMapper.updateRzOverTimeDetail(rzOverTimeDetail); + if(i < 1){ + return "{\"Result\":1,\"Msg\":\"打卡失败\"}"; + } + //加班修改统计 + rzOverTime.setOverHours(rzOverTime.getOverHours().add(rzOverTimeDetail.getOverTimeHours())); + i = rzOverTimeMapper.updateRzOverTime(rzOverTime); + if(i < 1){ + return "{\"Result\":1,\"Msg\":\"打卡失败\"}"; + } + //反写考勤汇总 + RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(Long.valueOf(userId),rzOverTime.getOverTimeMonth()); + rzAttendanceStatistical.setWorkOvertimeNumber(rzOverTime.getOverHours()); + i = rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical); + if(i < 1){ + return"{\"Result\":1,\"Msg\":\"打卡失败\"}"; + } + return "{\"Result\":0,\"Msg\":\"打卡成功\"}"; + } + + BigDecimal res = new BigDecimal("0.0"); //记录工时 + //计算工时 + Long hours = (date.getTime() - rzAttendanceDetail.getDateTime().getTime())/1000/60/60; + //判断不是当天的下班卡 + if(StringUtils.isNull(attendance.getWorkStartTime())){ + //最后一次上班卡打卡时间 + attendance = rzAttendanceMapper.selectLastRzAttendanceByStaffId(Long.valueOf(userId)); + //判断是单班,双班,还是三班 + if("上班卡(三班制)".equals(attendance.getRules())){ + if(hours >= eqImages.getHours().longValue() -1){ + res = eqImages.getHours(); + }else if(hours >= 5){ + res = new BigDecimal(6); + } + //判断打卡时间, 添加夜班次数 打卡时间在晚上7点以后 + if(hours > 8 && attendance.getWorkStartTime().getHours() > 18){ + attendance.setNightNumber(1); + } + }else if("上班卡(双班制)".equals(attendance.getRules())){ + if(hours >= 7.5){ + res = new BigDecimal("8"); + }else if(hours >= 3.5){ + res = new BigDecimal(4); + } + //判断打卡时间, 添加中班次数 打卡时间在下午3点以后 + if(hours > 6.5 && attendance.getWorkStartTime().getHours() > 15){ + attendance.setMiddleShiftNumber(1); + } + }else{ + if(hours >= 8){ + res = new BigDecimal("8"); + }else if(hours >= 3){ + res = new BigDecimal(4); + } + } + }else{ + try{ + if("上班卡(单班制)".equals(rzAttendanceDetail.getButtonType())){ + if(attendance.getWorkStartTime().getTime() - sdf.parse(sdfd.format(date) + " 08:30:00").getTime() > 1000*60*+60 + || sdf.parse(sdfd.format(date) + " 17:30:00").getTime() - date.getTime() > 1000*60*+60){ + if(hours >= 3){ + res = new BigDecimal("4"); + } + }else{ + if(hours >= 8){ + res = new BigDecimal("8.0"); + }else if(hours >= 4){ + res = new BigDecimal(4); + } + } + }else if("上班卡(双班制)".equals(rzAttendanceDetail.getButtonType())){ + if(attendance.getWorkStartTime().getTime() - sdf.parse(sdfd.format(date) + " 08:30:00").getTime() > 1000*60*+60 + || sdf.parse(sdfd.format(date) + " 17:30:00").getTime() - date.getTime() > 1000*60*+60){ + if(hours >= 4){ + res = new BigDecimal("4"); + } + }else{ + if(hours >= 8){ + res = new BigDecimal("8.0"); + }else if(hours >= 4){ + res = new BigDecimal(4); + } + } + }else if("上班卡(三班制)".equals(rzAttendanceDetail.getButtonType())){ + if(attendance.getWorkStartTime().getTime() - sdf.parse(sdfd.format(date) + " 08:30:00").getTime() > 1000*60*+60 + || sdf.parse(sdfd.format(date) + " 20:30:00").getTime() - date.getTime() > 1000*60*+60){ + if(hours >= 5){ + res = new BigDecimal("6"); + } + }else{ + if(hours >= eqImages.getHours().longValue()-1){ + res = eqImages.getHours(); + }else if(hours >= 5){ + res = new BigDecimal(6); + } + } + } + }catch (Exception e){ + + } + } + try{ + //下班卡异常 + Date db_pre = sdf.parse(sdfd.format(date) + " 08:30:00"); + Date sb_pre = sdf.parse(sdfd.format(date) + " 17:00:00"); + Date db_pre_2 = sdf.parse(sdfd.format(date) + " 17:30:00"); + Date sbz_pre = sdf.parse(sdfd.format(date) + " 20:30:00"); + Date sbz_pre_2 = sdf.parse(sdfd.format(date) + " 01:30:00"); + if(("上班卡(单班制)".equals(rzAttendanceDetail.getButtonType()) && date.before(db_pre_2)) + || ("上班卡(双班制)".equals(rzAttendanceDetail.getButtonType()) + && ((date.before(sb_pre) && date.after(db_pre)) || ((date.before(sbz_pre_2)) && date.after(sb_pre)))) + || ("上班卡(三班制)".equals(rzAttendanceDetail.getButtonType()) && ((date.before(sbz_pre) && date.getHours() > 14) || date.before(db_pre)))){ + attendance.setYcxFlag("1"); + } + }catch (Exception e){ + e.printStackTrace(); + } + //修改打卡记录 + attendance.setWorkEndTime(date); + attendance.setWorkSum(res); + i = rzAttendanceMapper.updateRzAttendance(attendance); + if(i < 1){ + return "{\"Result\":1,\"Msg\":\"打卡失败\"}"; + } + //反写考勤汇总 + RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(Long.valueOf(userId),attendance.getAttendanceDate()); + rzAttendanceStatistical.setRealAttendance(rzAttendanceStatistical.getRealAttendance().add(attendance.getWorkSum())); + i = rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical); + if(i < 1){ + return"{\"Result\":1,\"Msg\":\"打卡失败\"}"; + } + return "{\"Result\":0,\"Msg\":\"打卡成功\"}"; + } + +} diff --git a/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAbnormalDetailServiceImpl.java b/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAbnormalDetailServiceImpl.java new file mode 100644 index 0000000..498e2fc --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAbnormalDetailServiceImpl.java @@ -0,0 +1,176 @@ +package com.evo.attendance.service.impl; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; +import com.evo.attendance.domain.RzAbnormal; +import com.evo.attendance.domain.RzAttendance; +import com.evo.attendance.domain.RzAttendanceStatistical; +import com.evo.attendance.mapper.RzAbnormalMapper; +import com.evo.attendance.mapper.RzAttendanceMapper; +import com.evo.attendance.mapper.RzAttendanceStatisticalMapper; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.personnelMatters.domain.RzHoliday; +import com.evo.personnelMatters.mapper.RzHolidayMapper; +import com.evo.utils.DateUtil; +import org.springframework.stereotype.Service; +import com.evo.attendance.mapper.RzAbnormalDetailMapper; +import com.evo.attendance.domain.RzAbnormalDetail; +import com.evo.attendance.service.IRzAbnormalDetailService; +import javax.annotation.Resource; + +/** + * 考勤异常详情Service业务层处理 + * + * @author evo + * @date 2025-03-10 + */ +@Service +public class RzAbnormalDetailServiceImpl implements IRzAbnormalDetailService +{ + @Resource + private RzAbnormalDetailMapper rzAbnormalDetailMapper; + @Resource + private RzAttendanceMapper rzAttendanceMapper; //考勤信息 + @Resource + private RzAbnormalMapper rzAbnormalMapper; //异常汇总 + @Resource + private RzHolidayMapper rzHolidayMapper; //节假日 + @Resource + private RzAttendanceStatisticalMapper rzAttendanceStatisticalMapper; //考勤统计 + /** + * 查询考勤异常详情 + * + * @param id 考勤异常详情主键 + * @return 考勤异常详情 + */ + @Override + public RzAbnormalDetail selectRzAbnormalDetailById(Long id) + { + return rzAbnormalDetailMapper.selectRzAbnormalDetailById(id); + } + + /** + * 查询考勤异常详情列表 + * + * @param rzAbnormalDetail 考勤异常详情 + * @return 考勤异常详情 + */ + @Override + public List selectRzAbnormalDetailList(RzAbnormalDetail rzAbnormalDetail) + { + return rzAbnormalDetailMapper.selectRzAbnormalDetailList(rzAbnormalDetail); + } + + /** + * 新增考勤异常详情 + * @return 结果 + */ + @Override + public void insertRzAbnormalDetail(){ + List res_list = rzAttendanceMapper.currentDateAllAttendance(); + try{ + RzAbnormalDetail rzAbnormalDetail = null; + //查询节假日 + List h_list = rzHolidayMapper.selectRzHolidayList(null); + //判断是否是节假日 + int flag = 0; + for (RzHoliday rzHoliday : h_list) { + if(rzHoliday.getHoliday().compareTo(res_list.get(0).getAttendanceDate()) == 0){ + flag = 1; + break; + } + } + for (RzAttendance rzAttendance : res_list) { + //判断是否是周日 + if(DateUtil.isSaturday(rzAttendance.getAttendanceDate(),1) || flag == 1){ + //判断未打卡 + if(rzAttendance.getWorkStartTime() == null){ + rzAttendance.setRemarks("公休"); + rzAttendanceMapper.updateRzAttendance(rzAttendance); + continue; + } + rzAttendance.setRemarks("加班"); + rzAttendanceMapper.updateRzAttendance(rzAttendance); + continue; + } + //判断今天没有打卡 + if("1".equals(rzAttendance.getYcsFlag()) || "1".equals(rzAttendance.getYcxFlag()) + || rzAttendance.getWorkStartTime() == null || rzAttendance.getWorkEndTime() == null){ + //判断员工当月是否已经有迟到 + RzAbnormal rzAbnormal = rzAbnormalMapper.selectRzAbnormalByUserId(rzAttendance.getStaffId(),new Date()); + if(StringUtils.isNull(rzAbnormal)){ + rzAbnormal = new RzAbnormal(); + rzAbnormal.setDeptId(rzAttendance.getDeptId()); + rzAbnormal.setUserId(rzAttendance.getStaffId()); + rzAbnormal.setName(rzAttendance.getName()); + rzAbnormal.setNumber(0l); + rzAbnormal.setMoney(BigDecimal.valueOf(0)); + rzAbnormal.setMonth(new Date()); + rzAbnormal.setDelFlag("0"); + rzAbnormalMapper.insertRzAbnormal(rzAbnormal); + } + rzAbnormalDetail = new RzAbnormalDetail(); + rzAbnormalDetail.setAbnormalId(rzAbnormal.getId()); + rzAbnormalDetail.setName(rzAttendance.getName()); + rzAbnormalDetail.setClockDate(rzAttendance.getAttendanceDate()); + if("1".equals(rzAttendance.getYcxFlag())){ + rzAbnormalDetail.setAbnormalTime(rzAttendance.getWorkEndTime()); + rzAbnormalDetail.setClockType("下班卡"); + }else if("1".equals(rzAttendance.getYcsFlag())){ + rzAbnormalDetail.setAbnormalTime(rzAttendance.getWorkStartTime()); + rzAbnormalDetail.setClockType("上班卡"); + }else if(rzAttendance.getWorkStartTime() == null){ + rzAbnormalDetail.setClockType("未打卡"); + }else{ + rzAbnormalDetail.setClockType("未打下班卡"); + } + rzAbnormalDetail.setDelFlag("0"); + rzAbnormalDetailMapper.insertRzAbnormalDetail(rzAbnormalDetail); + //反写汇总 + rzAbnormal.setNumber(rzAbnormal.getNumber() + 1); + rzAbnormalMapper.updateRzAbnormal(rzAbnormal); + //反写统计 + RzAttendanceStatistical attendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(rzAttendance.getStaffId(),rzAttendance.getAttendanceDate()); + attendanceStatistical.setLateNumber(attendanceStatistical.getLateNumber() + 1); + rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(attendanceStatistical); + } + } + }catch (Exception e){ + e.printStackTrace(); + } + } + + /** + * 修改考勤异常详情 + * + * @param rzAbnormalDetail 考勤异常详情 + * @return 结果 + */ + @Override + public int updateRzAbnormalDetail(RzAbnormalDetail rzAbnormalDetail) + { + rzAbnormalDetail.setUpdateTime(DateUtils.getNowDate()); + rzAbnormalDetail.setUpdateBy(SecurityUtils.getUsername()); + return rzAbnormalDetailMapper.updateRzAbnormalDetail(rzAbnormalDetail); + } + + + /** + * 删除考勤异常详情信息 + * + * @param id 考勤异常详情主键 + * @return 结果 + */ + @Override + public int deleteRzAbnormalDetailById(Long id) + { + RzAbnormalDetail rzAbnormalDetail = rzAbnormalDetailMapper.selectRzAbnormalDetailById(id); + rzAbnormalDetail.setUpdateTime(DateUtils.getNowDate()); + rzAbnormalDetail.setUpdateBy(SecurityUtils.getUsername()); + rzAbnormalDetail.setDelFlag("1"); + return rzAbnormalDetailMapper.updateRzAbnormalDetail(rzAbnormalDetail); + } +} diff --git a/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAbnormalServiceImpl.java b/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAbnormalServiceImpl.java new file mode 100644 index 0000000..a9b4304 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAbnormalServiceImpl.java @@ -0,0 +1,105 @@ +package com.evo.attendance.service.impl; + +import java.util.ArrayList; +import java.util.List; +import com.evo.attendance.domain.RzAbnormalDetail; +import com.evo.attendance.mapper.RzAbnormalDetailMapper; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.system.mapper.SysDeptMapper; +import org.springframework.stereotype.Service; +import com.evo.attendance.mapper.RzAbnormalMapper; +import com.evo.attendance.domain.RzAbnormal; +import com.evo.attendance.service.IRzAbnormalService; +import javax.annotation.Resource; + +/** + * 考勤异常Service业务层处理 + * + * @author evo + * @date 2025-03-10 + */ +@Service +public class RzAbnormalServiceImpl implements IRzAbnormalService +{ + @Resource + private RzAbnormalMapper rzAbnormalMapper; + @Resource + private SysDeptMapper deptMapper; //部门 + @Resource + private RzAbnormalDetailMapper rzAbnormalDetailMapper; //异常详情 + + /** + * 查询考勤异常 + * + * @param id 考勤异常主键 + * @return 考勤异常 + */ + @Override + public RzAbnormal selectRzAbnormalById(Long id) + { + return rzAbnormalMapper.selectRzAbnormalById(id); + } + + /** + * 查询考勤异常列表 + * + * @param rzAbnormal 考勤异常 + * @return 考勤异常 + */ + @Override + public List selectRzAbnormalList(RzAbnormal rzAbnormal) + { + List res = rzAbnormalMapper.selectRzAbnormalList(rzAbnormal); + for (RzAbnormal re : res) { + re.setDeptName(deptMapper.selectDeptById(re.getDeptId()).getDeptName()); + } + return res; + } + + /** + * 修改考勤异常 + * + * @param rzAbnormal 考勤异常 + * @return 结果 + */ + @Override + public int updateRzAbnormal(RzAbnormal rzAbnormal) + { + rzAbnormal.setUpdateTime(DateUtils.getNowDate()); + rzAbnormal.setUpdateBy(SecurityUtils.getUsername()); + return rzAbnormalMapper.updateRzAbnormal(rzAbnormal); + } + + /** + * 删除考勤异常信息 + * + * @param id 考勤异常主键 + * @return 结果 + */ + @Override + public int deleteRzAbnormalById(Long id) + { + RzAbnormal rzAbnormal = rzAbnormalMapper.selectRzAbnormalById(id); + rzAbnormal.setUpdateTime(DateUtils.getNowDate()); + rzAbnormal.setUpdateBy(SecurityUtils.getUsername()); + rzAbnormal.setDelFlag("1"); + return rzAbnormalMapper.updateRzAbnormal(rzAbnormal); + } + + /** + * 异常详情 + * @param rzAbnormal + * @return + */ + @Override + public List listAbnormalDetails(RzAbnormal rzAbnormal){ + List res_list = new ArrayList(); + RzAbnormal abnormal = rzAbnormalMapper.selectRzAbnormalByUserId(rzAbnormal.getUserId(),rzAbnormal.getMonth()); + if(abnormal == null){ + return res_list; + } + res_list = rzAbnormalDetailMapper.selectRzAbnormalDetailByAbnormalId(abnormal.getId()); + return res_list; + } +} diff --git a/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceServiceImpl.java b/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceServiceImpl.java new file mode 100644 index 0000000..8b9e24b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceServiceImpl.java @@ -0,0 +1,192 @@ +package com.evo.attendance.service.impl; + +import com.evo.common.annotation.DataScope; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.domain.entity.SysDept; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.attendance.domain.RzAttendance; +import com.evo.attendance.mapper.RzAttendanceMapper; +import com.evo.attendance.mapper.RzAttendanceStatisticalMapper; +import com.evo.attendance.service.IRzAttendanceService; +import com.evo.common.utils.StringUtils; +import com.evo.system.mapper.SysDeptMapper; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +/** + * 考勤记录Service业务层处理 + * + * @author chenyj + * @date 2024-09-05 + */ +@Service +public class RzAttendanceServiceImpl implements IRzAttendanceService +{ + @Resource + private RzAttendanceMapper rzAttendanceMapper; + @Resource + private SysDeptMapper deptMapper; //部门 + @Resource + private RzAttendanceStatisticalMapper rzAttendanceStatisticalMapper; //考勤汇总 + + /** + * 查询考勤记录 + * + * @param id 考勤记录主键 + * @return 考勤记录 + */ + @Override + public RzAttendance selectRzAttendanceById(Long id) + { + return rzAttendanceMapper.selectRzAttendanceById(id); + } + + /** + * 查询考勤记录列表 + * + * @param rzAttendance 考勤记录 + * @return 考勤记录 + */ + @DataScope(deptAlias = "d") + @Override + public List selectRzAttendanceList(RzAttendance rzAttendance) + { + List res_list = rzAttendanceMapper.selectRzAttendanceList(rzAttendance); + for (RzAttendance attendance : res_list) { + SysDept sysDept = deptMapper.selectDeptById(attendance.getDeptId()); + attendance.setDeptName(sysDept.getDeptName()); + if(attendance.getAttendanceDate().before(new Date())){ + if(attendance.getWorkStartTime() == null && attendance.getWorkEndTime() == null){ + attendance.setYcsFlag("1"); + } + } + } + return res_list; + } + + /** + * 修改考勤记录 + * + * @param rzAttendance 考勤记录 + * @return 结果 + */ + @Override + public int updateRzAttendance(RzAttendance rzAttendance) + { + //判断考勤时间 + long sj = (rzAttendance.getWorkEndTime().getTime() - rzAttendance.getWorkStartTime().getTime())/1000/60/60; + if(sj >= 8){ + rzAttendance.setWorkSum(new BigDecimal(8)); + }else if(sj >= 4){ + rzAttendance.setWorkSum(new BigDecimal(4)); + } + rzAttendance.setYcsFlag("0"); + rzAttendance.setYcxFlag("0"); + rzAttendance.setUpdateBy(SecurityUtils.getUsername()); + rzAttendance.setUpdateTime(DateUtils.getNowDate()); + return rzAttendanceMapper.updateRzAttendance(rzAttendance); + } + + /** + * 每日上班打卡统计 + * @return + */ + @Override + public int attendenceCount(){ + List list = rzAttendanceMapper.attendenceCount(); + return list.size(); + } + + /** + * 批量修改考勤记录 + * + * @param rzAttendance 考勤记录 + * @return 结果 + */ + @Override + public AjaxResult updateBatchAttendance(RzAttendance rzAttendance){ + if(StringUtils.isNull(rzAttendance.getAttendanceDate())){ + return AjaxResult.error("请选择批量修改的时间!!"); + } + //根据时间查询打卡信息 + List list = rzAttendanceMapper.selectRzAttendanceList(rzAttendance); + //获取当天12点的时间和8:30的时间 + SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat sdft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date mid_date = null; + Date pre_date = null; + try{ + String str_pre = sdfd.format(rzAttendance.getAttendanceDate()) + " 08:30:00"; + pre_date = sdft.parse(str_pre); + String str_mid = sdfd.format(rzAttendance.getAttendanceDate()) + " 12:00:00"; + mid_date = sdft.parse(str_mid); + }catch (Exception e){ + e.printStackTrace(); + } + //循环判断打卡时间,修改打卡时间 + for (RzAttendance attendance : list) { + //判断上班打卡时间存在,且小于12点并且大于早上8:30 + if(attendance.getWorkStartTime() != null && attendance.getWorkStartTime().before(mid_date) && attendance.getWorkStartTime().after(pre_date)){ + //判断没有打卡下班卡 + if(attendance.getWorkEndTime() == null){ + attendance.setWorkStartTime(pre_date); + attendance.setYcsFlag("0"); + rzAttendanceMapper.updateRzAttendance(attendance); + continue; + } + BigDecimal old = attendance.getWorkSum(); + //计算上班的时间 + Long fz = (attendance.getWorkEndTime().getTime() - attendance.getWorkStartTime().getTime())/1000/60; + Double xs = fz/60.0; + BigDecimal res = new BigDecimal("0.0"); + //单班制 + if("上班卡(单班制)".equals(attendance.getRules())){ + if(xs > 9){ + res = new BigDecimal("8.0"); + }else if(xs > 4.5){ + res = BigDecimal.valueOf(xs - 1); + }else if(xs > 1){ + res = BigDecimal.valueOf(xs); + } + }else if("上班卡(双班制)".equals(attendance.getRules())){ + if(xs > 8.5){ + res = new BigDecimal("8.0"); + }else if(xs > 1){ + res = BigDecimal.valueOf(xs); + } + }else{ + if(xs > 12){ + res = new BigDecimal("11.0"); + }else if(xs <= 1){ + res = new BigDecimal("0.0"); + }else{ + res = BigDecimal.valueOf(xs - 1); + } + } + attendance.setWorkStartTime(pre_date); + attendance.setYcsFlag("0"); + attendance.setWorkSum(res); + int i = rzAttendanceMapper.updateRzAttendance(attendance); + if(i < 1){ + continue; + } + } + } + return AjaxResult.success(); + } + /** + * 查询考勤记录列表 + * + * @param rzAttendance 考勤记录 + * @return 考勤记录集合 + */ + public List listAttendanceByParams(RzAttendance rzAttendance){ + return rzAttendanceMapper.listAttendanceByParams(rzAttendance); + } + +} diff --git a/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceStatisticalServiceImpl.java b/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceStatisticalServiceImpl.java new file mode 100644 index 0000000..ad57736 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceStatisticalServiceImpl.java @@ -0,0 +1,136 @@ +package com.evo.attendance.service.impl; + +import com.evo.attendance.domain.RzAttendance; +import com.evo.attendance.mapper.RzAttendanceMapper; +import com.evo.common.annotation.DataScope; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.domain.entity.SysDept; +import com.evo.common.utils.DateUtils; +import com.evo.attendance.domain.RzAttendanceStatistical; +import com.evo.attendance.mapper.RzAttendanceStatisticalMapper; +import com.evo.attendance.service.IRzAttendanceStatisticalService; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.personnelMatters.domain.RzOverTime; +import com.evo.personnelMatters.mapper.RzOverTimeMapper; +import com.evo.system.mapper.SysDeptMapper; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.List; + +/** + * 考勤统计Service业务层处理 + * + * @author chenyj + * @date 2024-09-05 + */ +@Service +public class RzAttendanceStatisticalServiceImpl implements IRzAttendanceStatisticalService +{ + @Resource + private RzAttendanceStatisticalMapper rzAttendanceStatisticalMapper; + @Resource + private SysDeptMapper deptMapper; //部门 + @Resource + private RzAttendanceMapper rzAttendanceMapper; //打卡记录 + @Resource + private RzOverTimeMapper rzOverTimeMapper; + /** + * 查询考勤统计 + * + * @param id 考勤统计主键 + * @return 考勤统计 + */ + @Override + public RzAttendanceStatistical selectRzAttendanceStatisticalById(Long id) + { + return rzAttendanceStatisticalMapper.selectRzAttendanceStatisticalById(id); + } + /** + * 查询考勤统计列表 + * + * @param rzAttendanceStatistical 考勤统计 + * @return 考勤统计 + */ + @Override + @DataScope(deptAlias = "d") + public List selectRzAttendanceStatisticalList(RzAttendanceStatistical rzAttendanceStatistical) + { + List res_list = rzAttendanceStatisticalMapper.selectRzAttendanceStatisticalList(rzAttendanceStatistical); + for (RzAttendanceStatistical attendanceStatistical : res_list) { + SysDept sysDept = deptMapper.selectDeptById(attendanceStatistical.getDeptId()); + attendanceStatistical.setDeptName(sysDept.getDeptName()); + } + return res_list; + } + /** + * 修改考勤统计 + * + * @param rzAttendanceStatistical 考勤统计 + * @return 结果 + */ + @Override + public int updateRzAttendanceStatistical(RzAttendanceStatistical rzAttendanceStatistical) + { + rzAttendanceStatistical.setRealAttendance(rzAttendanceStatistical.getEssentialAttendance().add(rzAttendanceStatistical.getWorkOvertimeNumber())); + rzAttendanceStatistical.setUpdateTime(DateUtils.getNowDate()); + rzAttendanceStatistical.setUpdateBy(SecurityUtils.getUsername()); + return rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical); + } + + /** + * 校正数据 + * @return + */ + @Override + public AjaxResult correct(RzAttendanceStatistical rzAttendanceStatistical) { + if (StringUtils.isNull(rzAttendanceStatistical) || StringUtils.isNull(rzAttendanceStatistical.getMonth())) { + return AjaxResult.error("请输入校正日期!!"); + } + //查询条件月统计的数据 + List ms_list = rzAttendanceStatisticalMapper.queryStatisticalByMonth(rzAttendanceStatistical.getMonth()); + //计算打卡汇总表 + for (RzAttendanceStatistical attendanceStatistical : ms_list) { + //初始化打卡记录 + attendanceStatistical.setEssentialAttendance(new BigDecimal("0.0")); + attendanceStatistical.setWorkOvertimeNumber(new BigDecimal("0.0")); + attendanceStatistical.setMiddleShiftNumber(0l); + attendanceStatistical.setNightNumber(0l); + //查询打卡记录 + RzAttendance rzAttendance = new RzAttendance(); + rzAttendance.setAttendanceDate(rzAttendanceStatistical.getMonth()); + rzAttendance.setStaffId(attendanceStatistical.getStaffId()); + List at_list = rzAttendanceMapper.listAttendanceByParams(rzAttendance); + for (RzAttendance attendance : at_list) { + attendanceStatistical.setEssentialAttendance(attendanceStatistical.getEssentialAttendance().add(attendance.getWorkSum())); + attendanceStatistical.setMiddleShiftNumber(attendanceStatistical.getMiddleShiftNumber() + attendance.getMiddleShiftNumber()); + attendanceStatistical.setNightNumber(attendanceStatistical.getNightNumber() + attendance.getNightNumber()); + } + //获取加班数据 + RzOverTime rzOverTime = rzOverTimeMapper.selectRzOverTimeByNameAndMonth(attendanceStatistical.getStaffId(),rzAttendanceStatistical.getMonth()); + if(StringUtils.isNotNull(rzOverTime)){ + attendanceStatistical.setWorkOvertimeNumber(rzOverTime.getOverHours()); + } + attendanceStatistical.setRealAttendance(attendanceStatistical.getEssentialAttendance().add(attendanceStatistical.getWorkOvertimeNumber())); + rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(attendanceStatistical) ; + } + return AjaxResult.success(); + } + + /** + * 批量导入考勤统计 + * @param list + * @return + */ + @Override + public AjaxResult importRzAttendanceStatistical(List list){ + if(list == null || list.size() == 0){ + return AjaxResult.error("导入数据为空!!"); + } + for (RzAttendanceStatistical rzAttendanceStatistical : list) { + rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical); + } + return AjaxResult.success("导入数据成功!!"); + } +} diff --git a/evo-admin/src/main/java/com/evo/attendance/service/impl/RzSpecialAttendanceServiceImpl.java b/evo-admin/src/main/java/com/evo/attendance/service/impl/RzSpecialAttendanceServiceImpl.java new file mode 100644 index 0000000..dcdd65a --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/service/impl/RzSpecialAttendanceServiceImpl.java @@ -0,0 +1,134 @@ +package com.evo.attendance.service.impl; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +import com.evo.attendance.domain.RzAttendanceStatistical; +import com.evo.attendance.domain.RzSpecialAttendance; +import com.evo.attendance.domain.RzSpecialOverTime; +import com.evo.attendance.mapper.RzAttendanceStatisticalMapper; +import com.evo.attendance.mapper.RzSpecialAttendanceMapper; +import com.evo.attendance.mapper.RzSpecialOverTimeMapper; +import com.evo.attendance.service.IRzSpecialAttendanceService; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; + +/** + * 加班考勤记录Service业务层处理 + * + * @author evo + * @date 2025-04-15 + */ +@Service +public class RzSpecialAttendanceServiceImpl implements IRzSpecialAttendanceService +{ + @Resource + private RzSpecialAttendanceMapper rzSpecialAttendanceMapper; + @Resource + private RzSpecialOverTimeMapper rzSpecialOverTimeMapper; + @Resource + private RzAttendanceStatisticalMapper rzAttendanceStatisticalMapper; + /** + * 查询加班考勤记录 + * + * @param id 加班考勤记录主键 + * @return 加班考勤记录 + */ + @Override + public RzSpecialAttendance selectRzSpecialAttendanceById(Long id) + { + return rzSpecialAttendanceMapper.selectRzSpecialAttendanceById(id); + } + + /** + * 查询加班考勤记录列表 + * + * @param rzSpecialAttendance 加班考勤记录 + * @return 加班考勤记录 + */ + @Override + public List selectRzSpecialAttendanceList(RzSpecialAttendance rzSpecialAttendance) + { + return rzSpecialAttendanceMapper.selectRzSpecialAttendanceList(rzSpecialAttendance); + } + + /** + * 新增加班考勤记录 + * + * @param rzSpecialAttendance 加班考勤记录 + * @return 结果 + */ + @Override + public int insertRzSpecialAttendance(RzSpecialAttendance rzSpecialAttendance) + { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + try{ + rzSpecialAttendance.setAttendanceDate(sdf.parse(sdf.format(rzSpecialAttendance.getWorkStartTime()))); + }catch (Exception e){ + e.printStackTrace(); + } + rzSpecialAttendance.setCreateTime(new Date()); + rzSpecialAttendance.setCreateBy(SecurityUtils.getUsername()); + rzSpecialAttendance.setDelFlag("0"); + rzSpecialAttendance.setCreateTime(DateUtils.getNowDate()); + rzSpecialAttendanceMapper.insertRzSpecialAttendance(rzSpecialAttendance); + + RzSpecialOverTime rzSpecialOverTime = rzSpecialOverTimeMapper.selectRzSpecialOverTimeByUserIdAndDate(rzSpecialAttendance.getStaffId(),rzSpecialAttendance.getAttendanceDate()); + rzSpecialOverTime.setSickHours(rzSpecialOverTime.getSickHours().add(rzSpecialAttendance.getWorkHours())); + rzSpecialOverTimeMapper.updateRzSpecialOverTime(rzSpecialOverTime); + + RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(rzSpecialAttendance.getStaffId(),rzSpecialAttendance.getAttendanceDate()); + rzAttendanceStatistical.setOverTimeHours(rzAttendanceStatistical.getOverTimeHours().add(rzSpecialAttendance.getWorkHours())); + return rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical); + } + + /** + * 修改加班考勤记录 + * + * @param rzSpecialAttendance 加班考勤记录 + * @return 结果 + */ + @Override + public int updateRzSpecialAttendance(RzSpecialAttendance rzSpecialAttendance) + { + RzSpecialAttendance old = rzSpecialAttendanceMapper.selectRzSpecialAttendanceById(rzSpecialAttendance.getId()); + rzSpecialAttendance.setUpdateBy(SecurityUtils.getUsername()); + rzSpecialAttendance.setUpdateTime(DateUtils.getNowDate()); + rzSpecialAttendanceMapper.updateRzSpecialAttendance(rzSpecialAttendance); + + RzSpecialOverTime rzSpecialOverTime = rzSpecialOverTimeMapper.selectRzSpecialOverTimeByUserIdAndDate(rzSpecialAttendance.getStaffId(),rzSpecialAttendance.getAttendanceDate()); + rzSpecialOverTime.setSickHours(rzSpecialOverTime.getSickHours().add(rzSpecialAttendance.getWorkHours()).subtract(old.getWorkHours())); + rzSpecialOverTimeMapper.updateRzSpecialOverTime(rzSpecialOverTime); + + RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(rzSpecialAttendance.getStaffId(),rzSpecialAttendance.getAttendanceDate()); + rzAttendanceStatistical.setOverTimeHours(rzAttendanceStatistical.getOverTimeHours().add(rzSpecialAttendance.getWorkHours()).subtract(old.getWorkHours())); + return rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical); + } + + /** + * 删除加班考勤记录信息 + * + * @param id 加班考勤记录主键 + * @return 结果 + */ + @Override + public int deleteRzSpecialAttendanceById(Long id) + { + RzSpecialAttendance rzSpecialAttendance = rzSpecialAttendanceMapper.selectRzSpecialAttendanceById(id); + rzSpecialAttendance.setUpdateBy(SecurityUtils.getUsername()); + rzSpecialAttendance.setUpdateTime(DateUtils.getNowDate()); + rzSpecialAttendance.setDelFlag("1"); + rzSpecialAttendanceMapper.updateRzSpecialAttendance(rzSpecialAttendance); + + RzSpecialOverTime rzSpecialOverTime = rzSpecialOverTimeMapper.selectRzSpecialOverTimeByUserIdAndDate(rzSpecialAttendance.getStaffId(),rzSpecialAttendance.getAttendanceDate()); + rzSpecialOverTime.setSickHours(rzSpecialOverTime.getSickHours().subtract(rzSpecialAttendance.getWorkHours())); + rzSpecialOverTimeMapper.updateRzSpecialOverTime(rzSpecialOverTime); + + RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(rzSpecialAttendance.getStaffId(),rzSpecialAttendance.getAttendanceDate()); + rzAttendanceStatistical.setOverTimeHours(rzAttendanceStatistical.getOverTimeHours().subtract(rzSpecialAttendance.getWorkHours())); + return rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical); + } +} diff --git a/evo-admin/src/main/java/com/evo/attendance/service/impl/RzSpecialOverTimeServiceImpl.java b/evo-admin/src/main/java/com/evo/attendance/service/impl/RzSpecialOverTimeServiceImpl.java new file mode 100644 index 0000000..e51235a --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/service/impl/RzSpecialOverTimeServiceImpl.java @@ -0,0 +1,104 @@ +package com.evo.attendance.service.impl; + +import java.util.Date; +import java.util.List; +import com.evo.attendance.domain.RzSpecialOverTime; +import com.evo.attendance.mapper.RzSpecialOverTimeMapper; +import com.evo.attendance.service.IRzSpecialOverTimeService; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.system.mapper.SysDeptMapper; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; + +/** + * 特殊加班管理Service业务层处理 + * + * @author evo + * @date 2025-04-16 + */ +@Service +public class RzSpecialOverTimeServiceImpl implements IRzSpecialOverTimeService +{ + @Resource + private RzSpecialOverTimeMapper rzSpecialOverTimeMapper; + @Resource + private SysDeptMapper deptMapper; + + /** + * 查询特殊加班管理 + * + * @param id 特殊加班管理主键 + * @return 特殊加班管理 + */ + @Override + public RzSpecialOverTime selectRzSpecialOverTimeById(Long id) + { + return rzSpecialOverTimeMapper.selectRzSpecialOverTimeById(id); + } + + /** + * 查询特殊加班管理列表 + * + * @param rzSpecialOverTime 特殊加班管理 + * @return 特殊加班管理 + */ + @Override + public List selectRzSpecialOverTimeList(RzSpecialOverTime rzSpecialOverTime) + { + List reslut = rzSpecialOverTimeMapper.selectRzSpecialOverTimeList(rzSpecialOverTime); + for (RzSpecialOverTime specialOverTime : reslut) { + specialOverTime.setDeptName(deptMapper.selectDeptById(specialOverTime.getDeptId()).getDeptName()); + } + return reslut; + } + + /** + * 新增特殊加班管理 + * + * @param rzSpecialOverTime 特殊加班管理 + * @return 结果 + */ + @Override + public int insertRzSpecialOverTime(RzSpecialOverTime rzSpecialOverTime) + { + //根据用户ID查询用户名称 + + rzSpecialOverTime.setCreateTime(new Date()); + rzSpecialOverTime.setCreateBy(SecurityUtils.getUsername()); + rzSpecialOverTime.setDelFlag("0"); + rzSpecialOverTime.setCreateTime(DateUtils.getNowDate()); + return rzSpecialOverTimeMapper.insertRzSpecialOverTime(rzSpecialOverTime); + } + + /** + * 修改特殊加班管理 + * + * @param rzSpecialOverTime 特殊加班管理 + * @return 结果 + */ + @Override + public int updateRzSpecialOverTime(RzSpecialOverTime rzSpecialOverTime) + { + rzSpecialOverTime.setUpdateTime(new Date()); + rzSpecialOverTime.setUpdateBy(SecurityUtils.getUsername()); + rzSpecialOverTime.setUpdateTime(DateUtils.getNowDate()); + return rzSpecialOverTimeMapper.updateRzSpecialOverTime(rzSpecialOverTime); + } + + /** + * 删除特殊加班管理信息 + * + * @param id 特殊加班管理主键 + * @return 结果 + */ + @Override + public int deleteRzSpecialOverTimeById(Long id) + { + RzSpecialOverTime rzSpecialOverTime = rzSpecialOverTimeMapper.selectRzSpecialOverTimeById(id); + rzSpecialOverTime.setDelFlag("1"); + rzSpecialOverTime.setUpdateTime(new Date()); + rzSpecialOverTime.setUpdateBy(SecurityUtils.getUsername()); + return rzSpecialOverTimeMapper.updateRzSpecialOverTime(rzSpecialOverTime); + } +} diff --git a/evo-admin/src/main/java/com/evo/common/annotation/Anonymous.java b/evo-admin/src/main/java/com/evo/common/annotation/Anonymous.java new file mode 100644 index 0000000..ec3a210 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/annotation/Anonymous.java @@ -0,0 +1,19 @@ +package com.evo.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 evo + */ +@Target({ ElementType.METHOD, ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Anonymous +{ +} diff --git a/evo-admin/src/main/java/com/evo/common/annotation/DataScope.java b/evo-admin/src/main/java/com/evo/common/annotation/DataScope.java new file mode 100644 index 0000000..19b3b4b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/annotation/DataScope.java @@ -0,0 +1,33 @@ +package com.evo.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 evo + */ +@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/evo-admin/src/main/java/com/evo/common/annotation/DataSource.java b/evo-admin/src/main/java/com/evo/common/annotation/DataSource.java new file mode 100644 index 0000000..44008cf --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/annotation/DataSource.java @@ -0,0 +1,28 @@ +package com.evo.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.evo.common.enums.DataSourceType; + +/** + * 自定义多数据源切换注解 + * + * 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准 + * + * @author evo + */ +@Target({ ElementType.METHOD, ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +public @interface DataSource +{ + /** + * 切换数据源名称 + */ + public DataSourceType value() default DataSourceType.MASTER; +} diff --git a/evo-admin/src/main/java/com/evo/common/annotation/Excel.java b/evo-admin/src/main/java/com/evo/common/annotation/Excel.java new file mode 100644 index 0000000..1e58bbc --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/annotation/Excel.java @@ -0,0 +1,192 @@ +package com.evo.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.evo.common.utils.poi.ExcelHandlerAdapter; + +/** + * 自定义导出Excel数据注解 + * + * @author evo + */ +@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; + } + } +} diff --git a/evo-admin/src/main/java/com/evo/common/annotation/Excels.java b/evo-admin/src/main/java/com/evo/common/annotation/Excels.java new file mode 100644 index 0000000..88d043f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/annotation/Excels.java @@ -0,0 +1,18 @@ +package com.evo.common.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Excel注解集 + * + * @author evo + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Excels +{ + public Excel[] value(); +} diff --git a/evo-admin/src/main/java/com/evo/common/annotation/Log.java b/evo-admin/src/main/java/com/evo/common/annotation/Log.java new file mode 100644 index 0000000..0a4414e --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/annotation/Log.java @@ -0,0 +1,51 @@ +package com.evo.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.evo.common.enums.BusinessType; +import com.evo.common.enums.OperatorType; + +/** + * 自定义操作日志记录注解 + * + * @author evo + * + */ +@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/evo-admin/src/main/java/com/evo/common/annotation/RateLimiter.java b/evo-admin/src/main/java/com/evo/common/annotation/RateLimiter.java new file mode 100644 index 0000000..4c28dcb --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/annotation/RateLimiter.java @@ -0,0 +1,40 @@ +package com.evo.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.evo.common.constant.CacheConstants; +import com.evo.common.enums.LimitType; + +/** + * 限流注解 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/common/annotation/RepeatSubmit.java b/evo-admin/src/main/java/com/evo/common/annotation/RepeatSubmit.java new file mode 100644 index 0000000..7207fce --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/annotation/RepeatSubmit.java @@ -0,0 +1,31 @@ +package com.evo.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 evo + * + */ +@Inherited +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RepeatSubmit +{ + /** + * 间隔时间(ms),小于此时间视为重复提交 + */ + public int interval() default 5000; + + /** + * 提示消息 + */ + public String message() default "不允许重复提交,请稍候再试"; +} diff --git a/evo-admin/src/main/java/com/evo/common/annotation/Sensitive.java b/evo-admin/src/main/java/com/evo/common/annotation/Sensitive.java new file mode 100644 index 0000000..35a1c0c --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/annotation/Sensitive.java @@ -0,0 +1,24 @@ +package com.evo.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.evo.common.config.serializer.SensitiveJsonSerializer; +import com.evo.common.enums.DesensitizedType; + +/** + * 数据脱敏注解 + * + * @author evo + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +@JacksonAnnotationsInside +@JsonSerialize(using = SensitiveJsonSerializer.class) +public @interface Sensitive +{ + DesensitizedType desensitizedType(); +} diff --git a/evo-admin/src/main/java/com/evo/common/config/EvoConfig.java b/evo-admin/src/main/java/com/evo/common/config/EvoConfig.java new file mode 100644 index 0000000..44cfc15 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/config/EvoConfig.java @@ -0,0 +1,111 @@ +package com.evo.common.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * 读取项目相关配置 + * + * @author evo + */ +@Component +@ConfigurationProperties(prefix = "evo") +public class EvoConfig +{ + /** 项目名称 */ + private String name; + + /** 版本 */ + private String version; + + /** 版权年份 */ + private String copyrightYear; + + /** 上传路径 */ + private static String profile; + + /** 获取地址开关 */ + private static boolean addressEnabled; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getVersion() + { + return version; + } + + public void setVersion(String version) + { + this.version = version; + } + + public String getCopyrightYear() + { + return copyrightYear; + } + + public void setCopyrightYear(String copyrightYear) + { + this.copyrightYear = copyrightYear; + } + + public static String getProfile() + { + return profile; + } + + public void setProfile(String profile) + { + EvoConfig.profile = profile; + } + + public static boolean isAddressEnabled() + { + return addressEnabled; + } + + public void setAddressEnabled(boolean addressEnabled) + { + EvoConfig.addressEnabled = addressEnabled; + } + + /** + * 获取导入上传路径 + */ + 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/evo-admin/src/main/java/com/evo/common/config/SwaggerConfig.java b/evo-admin/src/main/java/com/evo/common/config/SwaggerConfig.java new file mode 100644 index 0000000..2f00287 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/config/SwaggerConfig.java @@ -0,0 +1,124 @@ +package com.evo.common.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 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 evo + */ +@Configuration +public class SwaggerConfig +{ + /** 系统基础配置 */ + @Autowired + private EvoConfig EvoConfig; + + /** 是否开启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.evo.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(EvoConfig.getName(), null, null)) + // 版本 + .version("版本号:" + EvoConfig.getVersion()) + .build(); + } +} diff --git a/evo-admin/src/main/java/com/evo/common/config/serializer/SensitiveJsonSerializer.java b/evo-admin/src/main/java/com/evo/common/config/serializer/SensitiveJsonSerializer.java new file mode 100644 index 0000000..43776ba --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/config/serializer/SensitiveJsonSerializer.java @@ -0,0 +1,67 @@ +package com.evo.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.evo.common.annotation.Sensitive; +import com.evo.common.core.domain.model.LoginUser; +import com.evo.common.enums.DesensitizedType; +import com.evo.common.utils.SecurityUtils; + +/** + * 数据脱敏序列化过滤 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/constant/CacheConstants.java b/evo-admin/src/main/java/com/evo/common/constant/CacheConstants.java new file mode 100644 index 0000000..6f8774f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/constant/CacheConstants.java @@ -0,0 +1,44 @@ +package com.evo.common.constant; + +/** + * 缓存的key 常量 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/constant/Constants.java b/evo-admin/src/main/java/com/evo/common/constant/Constants.java new file mode 100644 index 0000000..fa46e89 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/constant/Constants.java @@ -0,0 +1,120 @@ +package com.evo.common.constant; + +import java.math.BigDecimal; +import java.util.Locale; +import io.jsonwebtoken.Claims; + +/** + * 通用常量信息 + * + * @author evo + */ +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 String TOKEN = "token"; + /** + * 令牌前缀 + */ + public static final String TOKEN_PREFIX = "Bearer "; + /** + * 令牌前缀 + */ + public static final String LOGIN_USER_KEY = "login_user_key"; + /** + * 资源映射路径 前缀 + */ + public static final String RESOURCE_PREFIX = "/profile"; + /** + * 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全) + */ + public static final String[] JSON_WHITELIST_STR = { "org.springframework", "com.evo" }; + + /** + * 业务参数 + */ + public static final String DELETE_FLAG_0 = "0"; //添加信息 + public static final String DELETE_FLAG_1 = "1"; //删除信息 + public static final String JOB_STATIS_0 = "0"; //员工 试用 + public static final String SYS_COMPANY = "sys_company"; //公司简称 + public static final String SYS_CONTRACT = "sys_contract"; //合同年限 + public static final String SYS_LEVEL = "sys_level"; //学历 + public static final String SYS_WORK_STATUS = "sys_worker_status"; //在职状态 + public static final String SYS_RESTAUTANT = "sys_restaurant"; //餐饮字典类型参数 + public static final String SEIZE_A_SEAT_0 = "0"; //占位符 + public static final String SEIZE_A_SEAT_1 = "00"; //占位符 + public static final String SEIZE_A_SEAT_2 = "000"; //占位符 + public static final String SYS_SENIORITY_SUBSIDIES = "50"; //工龄补助 + public static final String SYS_CONTRACT_0 = "50"; //一年期合同补助 + public static final String SYS_CONTRACT_1 = "150"; //三年期合同补助 + public static final String SYS_SOCIAL_SUBSIDIES = "400"; //新农合社保补助 + public static final String SUBSIDY_PROPORTION = "0.05"; //请假补助扣除比例 + public static final String SUBSIDY_PERIOD = "0.80"; //试用期工资 + public static final String SUBSIDY_PERIOD_1 = "0.20"; //试用期工资的余百分比 +} diff --git a/evo-admin/src/main/java/com/evo/common/constant/GenConstants.java b/evo-admin/src/main/java/com/evo/common/constant/GenConstants.java new file mode 100644 index 0000000..4e2cb2a --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/constant/GenConstants.java @@ -0,0 +1,117 @@ +package com.evo.common.constant; + +/** + * 代码生成通用常量 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/constant/HttpStatus.java b/evo-admin/src/main/java/com/evo/common/constant/HttpStatus.java new file mode 100644 index 0000000..e3d3e58 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/constant/HttpStatus.java @@ -0,0 +1,94 @@ +package com.evo.common.constant; + +/** + * 返回状态码 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/constant/ScheduleConstants.java b/evo-admin/src/main/java/com/evo/common/constant/ScheduleConstants.java new file mode 100644 index 0000000..09293b7 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/constant/ScheduleConstants.java @@ -0,0 +1,50 @@ +package com.evo.common.constant; + +/** + * 任务调度通用常量 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/constant/UserConstants.java b/evo-admin/src/main/java/com/evo/common/constant/UserConstants.java new file mode 100644 index 0000000..3de5de4 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/constant/UserConstants.java @@ -0,0 +1,78 @@ +package com.evo.common.constant; + +/** + * 用户常量信息 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/core/controller/BaseController.java b/evo-admin/src/main/java/com/evo/common/core/controller/BaseController.java new file mode 100644 index 0000000..3d8a32b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/controller/BaseController.java @@ -0,0 +1,202 @@ +package com.evo.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.evo.common.constant.HttpStatus; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.domain.model.LoginUser; +import com.evo.common.core.page.PageDomain; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.core.page.TableSupport; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.PageUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.sql.SqlUtil; + +/** + * web层通用数据处理 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/core/domain/AjaxResult.java b/evo-admin/src/main/java/com/evo/common/core/domain/AjaxResult.java new file mode 100644 index 0000000..aa29a7e --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/domain/AjaxResult.java @@ -0,0 +1,216 @@ +package com.evo.common.core.domain; + +import java.util.HashMap; +import java.util.Objects; +import com.evo.common.constant.HttpStatus; +import com.evo.common.utils.StringUtils; + +/** + * 操作消息提醒 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/core/domain/BaseEntity.java b/evo-admin/src/main/java/com/evo/common/core/domain/BaseEntity.java new file mode 100644 index 0000000..e5b294a --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/domain/BaseEntity.java @@ -0,0 +1,118 @@ +package com.evo.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; + +/** + * Entity基类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/core/domain/R.java b/evo-admin/src/main/java/com/evo/common/core/domain/R.java new file mode 100644 index 0000000..7a46b12 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/domain/R.java @@ -0,0 +1,115 @@ +package com.evo.common.core.domain; + +import java.io.Serializable; +import com.evo.common.constant.HttpStatus; + +/** + * 响应信息主体 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/core/domain/TreeEntity.java b/evo-admin/src/main/java/com/evo/common/core/domain/TreeEntity.java new file mode 100644 index 0000000..8f668e7 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/domain/TreeEntity.java @@ -0,0 +1,79 @@ +package com.evo.common.core.domain; + +import java.util.ArrayList; +import java.util.List; + +/** + * Tree基类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/core/domain/TreeSelect.java b/evo-admin/src/main/java/com/evo/common/core/domain/TreeSelect.java new file mode 100644 index 0000000..ee8cf75 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/domain/TreeSelect.java @@ -0,0 +1,77 @@ +package com.evo.common.core.domain; + +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.evo.common.core.domain.entity.SysDept; +import com.evo.common.core.domain.entity.SysMenu; + +/** + * Treeselect树结构实体类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/core/domain/entity/SysDept.java b/evo-admin/src/main/java/com/evo/common/core/domain/entity/SysDept.java new file mode 100644 index 0000000..6215bca --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/domain/entity/SysDept.java @@ -0,0 +1,171 @@ +package com.evo.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.evo.common.core.domain.BaseEntity; + +/** + * 部门表 sys_dept + * + * @author evo + */ +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 String leader; + + /** 联系电话 */ + private String phone; + + /** 部门状态: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; + } + 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; + } + + 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("leader", getLeader()) + .append("phone", getPhone()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/common/core/domain/entity/SysDictData.java b/evo-admin/src/main/java/com/evo/common/core/domain/entity/SysDictData.java new file mode 100644 index 0000000..2824747 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/domain/entity/SysDictData.java @@ -0,0 +1,176 @@ +package com.evo.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.evo.common.annotation.Excel; +import com.evo.common.annotation.Excel.ColumnType; +import com.evo.common.constant.UserConstants; +import com.evo.common.core.domain.BaseEntity; + +/** + * 字典数据表 sys_dict_data + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/core/domain/entity/SysDictType.java b/evo-admin/src/main/java/com/evo/common/core/domain/entity/SysDictType.java new file mode 100644 index 0000000..6eadb98 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/domain/entity/SysDictType.java @@ -0,0 +1,96 @@ +package com.evo.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.evo.common.annotation.Excel; +import com.evo.common.annotation.Excel.ColumnType; +import com.evo.common.core.domain.BaseEntity; + +/** + * 字典类型表 sys_dict_type + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/core/domain/entity/SysMenu.java b/evo-admin/src/main/java/com/evo/common/core/domain/entity/SysMenu.java new file mode 100644 index 0000000..3160c27 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/domain/entity/SysMenu.java @@ -0,0 +1,274 @@ +package com.evo.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.evo.common.core.domain.BaseEntity; + +/** + * 菜单权限表 sys_menu + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/core/domain/entity/SysRole.java b/evo-admin/src/main/java/com/evo/common/core/domain/entity/SysRole.java new file mode 100644 index 0000000..b8ded83 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/domain/entity/SysRole.java @@ -0,0 +1,241 @@ +package com.evo.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.evo.common.annotation.Excel; +import com.evo.common.annotation.Excel.ColumnType; +import com.evo.common.core.domain.BaseEntity; + +/** + * 角色表 sys_role + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/core/domain/entity/SysUser.java b/evo-admin/src/main/java/com/evo/common/core/domain/entity/SysUser.java new file mode 100644 index 0000000..b56b3d7 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/domain/entity/SysUser.java @@ -0,0 +1,311 @@ +package com.evo.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.evo.common.annotation.Excel; +import com.evo.common.annotation.Excel.ColumnType; +import com.evo.common.annotation.Excel.Type; +import com.evo.common.annotation.Excels; +import com.evo.common.core.domain.BaseEntity; +import com.evo.common.xss.Xss; + +/** + * 用户对象 sys_user + * + * @author evo + */ +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; + + /** 角色ID */ + private Long roleId; + + public SysUser() + { + + } + + public SysUser(Long userId) + { + this.userId = userId; + } + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public boolean isAdmin() + { + return isAdmin(this.userId); + } + + public static boolean isAdmin(Long userId) + { + return userId != null && 1L == userId; + } + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + @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 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/evo-admin/src/main/java/com/evo/common/core/domain/model/LoginBody.java b/evo-admin/src/main/java/com/evo/common/core/domain/model/LoginBody.java new file mode 100644 index 0000000..5c92cf3 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/domain/model/LoginBody.java @@ -0,0 +1,69 @@ +package com.evo.common.core.domain.model; + +/** + * 用户登录对象 + * + * @author evo + */ +public class LoginBody +{ + /** + * 用户名 + */ + private String username; + + /** + * 用户密码 + */ + private String password; + + /** + * 验证码 + */ + private String code; + + /** + * 唯一标识 + */ + private String uuid; + + 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/evo-admin/src/main/java/com/evo/common/core/domain/model/LoginUser.java b/evo-admin/src/main/java/com/evo/common/core/domain/model/LoginUser.java new file mode 100644 index 0000000..37f106b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/domain/model/LoginUser.java @@ -0,0 +1,266 @@ +package com.evo.common.core.domain.model; + +import com.alibaba.fastjson2.annotation.JSONField; +import com.evo.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 evo + */ +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/evo-admin/src/main/java/com/evo/common/core/domain/model/RegisterBody.java b/evo-admin/src/main/java/com/evo/common/core/domain/model/RegisterBody.java new file mode 100644 index 0000000..0b1d0be --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/domain/model/RegisterBody.java @@ -0,0 +1,11 @@ +package com.evo.common.core.domain.model; + +/** + * 用户注册对象 + * + * @author evo + */ +public class RegisterBody extends LoginBody +{ + +} diff --git a/evo-admin/src/main/java/com/evo/common/core/page/PageDomain.java b/evo-admin/src/main/java/com/evo/common/core/page/PageDomain.java new file mode 100644 index 0000000..4c75dfd --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/page/PageDomain.java @@ -0,0 +1,101 @@ +package com.evo.common.core.page; + +import com.evo.common.utils.StringUtils; + +/** + * 分页数据 + * + * @author evo + */ +public class PageDomain +{ + /** 当前记录起始索引 */ + private Integer pageNum; + + /** 每页显示记录数 */ + private Integer pageSize; + + /** 排序列 */ + private String orderByColumn; + + /** 排序的方向desc或者asc */ + private String isAsc = "asc"; + + /** 分页参数合理化 */ + private Boolean reasonable = true; + + 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.TRUE; + } + return reasonable; + } + + public void setReasonable(Boolean reasonable) + { + this.reasonable = reasonable; + } +} diff --git a/evo-admin/src/main/java/com/evo/common/core/page/TableDataInfo.java b/evo-admin/src/main/java/com/evo/common/core/page/TableDataInfo.java new file mode 100644 index 0000000..46a2d102 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/page/TableDataInfo.java @@ -0,0 +1,85 @@ +package com.evo.common.core.page; + +import java.io.Serializable; +import java.util.List; + +/** + * 表格分页数据对象 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/core/page/TableSupport.java b/evo-admin/src/main/java/com/evo/common/core/page/TableSupport.java new file mode 100644 index 0000000..a1d747d --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/page/TableSupport.java @@ -0,0 +1,56 @@ +package com.evo.common.core.page; + +import com.evo.common.core.text.Convert; +import com.evo.common.utils.ServletUtils; + +/** + * 表格数据处理 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/core/redis/RedisCache.java b/evo-admin/src/main/java/com/evo/common/core/redis/RedisCache.java new file mode 100644 index 0000000..ff18910 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/redis/RedisCache.java @@ -0,0 +1,268 @@ +package com.evo.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 evo + **/ +@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/evo-admin/src/main/java/com/evo/common/core/text/CharsetKit.java b/evo-admin/src/main/java/com/evo/common/core/text/CharsetKit.java new file mode 100644 index 0000000..84c5500 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/text/CharsetKit.java @@ -0,0 +1,86 @@ +package com.evo.common.core.text; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import com.evo.common.utils.StringUtils; + +/** + * 字符集工具类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/core/text/Convert.java b/evo-admin/src/main/java/com/evo/common/core/text/Convert.java new file mode 100644 index 0000000..3855e61 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/text/Convert.java @@ -0,0 +1,1010 @@ +package com.evo.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.evo.common.utils.StringUtils; +import org.apache.commons.lang3.ArrayUtils; + +/** + * 类型转换器 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/core/text/StrFormatter.java b/evo-admin/src/main/java/com/evo/common/core/text/StrFormatter.java new file mode 100644 index 0000000..4fd85e7 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/core/text/StrFormatter.java @@ -0,0 +1,92 @@ +package com.evo.common.core.text; + +import com.evo.common.utils.StringUtils; + +/** + * 字符串格式化 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/enums/BusinessStatus.java b/evo-admin/src/main/java/com/evo/common/enums/BusinessStatus.java new file mode 100644 index 0000000..3222533 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/enums/BusinessStatus.java @@ -0,0 +1,20 @@ +package com.evo.common.enums; + +/** + * 操作状态 + * + * @author evo + * + */ +public enum BusinessStatus +{ + /** + * 成功 + */ + SUCCESS, + + /** + * 失败 + */ + FAIL, +} diff --git a/evo-admin/src/main/java/com/evo/common/enums/BusinessType.java b/evo-admin/src/main/java/com/evo/common/enums/BusinessType.java new file mode 100644 index 0000000..6b7d3c0 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/enums/BusinessType.java @@ -0,0 +1,59 @@ +package com.evo.common.enums; + +/** + * 业务操作类型 + * + * @author evo + */ +public enum BusinessType +{ + /** + * 其它 + */ + OTHER, + + /** + * 新增 + */ + INSERT, + + /** + * 修改 + */ + UPDATE, + + /** + * 删除 + */ + DELETE, + + /** + * 授权 + */ + GRANT, + + /** + * 导出 + */ + EXPORT, + + /** + * 导入 + */ + IMPORT, + + /** + * 强退 + */ + FORCE, + + /** + * 生成代码 + */ + GENCODE, + + /** + * 清空数据 + */ + CLEAN, +} diff --git a/evo-admin/src/main/java/com/evo/common/enums/DataSourceType.java b/evo-admin/src/main/java/com/evo/common/enums/DataSourceType.java new file mode 100644 index 0000000..578705d --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/enums/DataSourceType.java @@ -0,0 +1,19 @@ +package com.evo.common.enums; + +/** + * 数据源 + * + * @author evo + */ +public enum DataSourceType +{ + /** + * 主库 + */ + MASTER, + + /** + * 从库 + */ + SLAVE +} diff --git a/evo-admin/src/main/java/com/evo/common/enums/DesensitizedType.java b/evo-admin/src/main/java/com/evo/common/enums/DesensitizedType.java new file mode 100644 index 0000000..8878f86 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/enums/DesensitizedType.java @@ -0,0 +1,59 @@ +package com.evo.common.enums; + +import java.util.function.Function; +import com.evo.common.utils.DesensitizedUtil; + +/** + * 脱敏类型 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/enums/HttpMethod.java b/evo-admin/src/main/java/com/evo/common/enums/HttpMethod.java new file mode 100644 index 0000000..26d2e77 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/enums/HttpMethod.java @@ -0,0 +1,36 @@ +package com.evo.common.enums; + +import java.util.HashMap; +import java.util.Map; +import org.springframework.lang.Nullable; + +/** + * 请求方式 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/enums/LimitType.java b/evo-admin/src/main/java/com/evo/common/enums/LimitType.java new file mode 100644 index 0000000..86b7c6a --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/enums/LimitType.java @@ -0,0 +1,20 @@ +package com.evo.common.enums; + +/** + * 限流类型 + * + * @author evo + */ + +public enum LimitType +{ + /** + * 默认策略全局限流 + */ + DEFAULT, + + /** + * 根据请求者IP进行限流 + */ + IP +} diff --git a/evo-admin/src/main/java/com/evo/common/enums/OperatorType.java b/evo-admin/src/main/java/com/evo/common/enums/OperatorType.java new file mode 100644 index 0000000..5dd84ea --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/enums/OperatorType.java @@ -0,0 +1,24 @@ +package com.evo.common.enums; + +/** + * 操作人类别 + * + * @author evo + */ +public enum OperatorType +{ + /** + * 其它 + */ + OTHER, + + /** + * 后台用户 + */ + MANAGE, + + /** + * 手机端用户 + */ + MOBILE +} diff --git a/evo-admin/src/main/java/com/evo/common/enums/UserStatus.java b/evo-admin/src/main/java/com/evo/common/enums/UserStatus.java new file mode 100644 index 0000000..17c6474 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/enums/UserStatus.java @@ -0,0 +1,30 @@ +package com.evo.common.enums; + +/** + * 用户状态 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/exception/CustomException.java b/evo-admin/src/main/java/com/evo/common/exception/CustomException.java new file mode 100644 index 0000000..2f42fd9 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/exception/CustomException.java @@ -0,0 +1,43 @@ +package com.evo.common.exception; + +/** + * 自定义异常 + * + * @author ruoyi + */ +public class CustomException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + private Integer code; + + private String message; + + public CustomException(String message) + { + this.message = message; + } + + public CustomException(String message, Integer code) + { + this.message = message; + this.code = code; + } + + public CustomException(String message, Throwable e) + { + super(message, e); + this.message = message; + } + + @Override + public String getMessage() + { + return message; + } + + public Integer getCode() + { + return code; + } +} diff --git a/evo-admin/src/main/java/com/evo/common/exception/DemoModeException.java b/evo-admin/src/main/java/com/evo/common/exception/DemoModeException.java new file mode 100644 index 0000000..4a1d0d9 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/exception/DemoModeException.java @@ -0,0 +1,15 @@ +package com.evo.common.exception; + +/** + * 演示模式异常 + * + * @author evo + */ +public class DemoModeException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public DemoModeException() + { + } +} diff --git a/evo-admin/src/main/java/com/evo/common/exception/GlobalException.java b/evo-admin/src/main/java/com/evo/common/exception/GlobalException.java new file mode 100644 index 0000000..b723744 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/exception/GlobalException.java @@ -0,0 +1,58 @@ +package com.evo.common.exception; + +/** + * 全局异常 + * + * @author evo + */ +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; + } +} diff --git a/evo-admin/src/main/java/com/evo/common/exception/ServiceException.java b/evo-admin/src/main/java/com/evo/common/exception/ServiceException.java new file mode 100644 index 0000000..27496c6 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/exception/ServiceException.java @@ -0,0 +1,74 @@ +package com.evo.common.exception; + +/** + * 业务异常 + * + * @author evo + */ +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; + } +} diff --git a/evo-admin/src/main/java/com/evo/common/exception/UtilException.java b/evo-admin/src/main/java/com/evo/common/exception/UtilException.java new file mode 100644 index 0000000..628847b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/exception/UtilException.java @@ -0,0 +1,26 @@ +package com.evo.common.exception; + +/** + * 工具类异常 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/exception/base/BaseException.java b/evo-admin/src/main/java/com/evo/common/exception/base/BaseException.java new file mode 100644 index 0000000..4097b25 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/exception/base/BaseException.java @@ -0,0 +1,97 @@ +package com.evo.common.exception.base; + +import com.evo.common.utils.MessageUtils; +import com.evo.common.utils.StringUtils; + +/** + * 基础异常 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/exception/file/FileException.java b/evo-admin/src/main/java/com/evo/common/exception/file/FileException.java new file mode 100644 index 0000000..ad02157 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/exception/file/FileException.java @@ -0,0 +1,19 @@ +package com.evo.common.exception.file; + +import com.evo.common.exception.base.BaseException; + +/** + * 文件信息异常类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/exception/file/FileNameLengthLimitExceededException.java b/evo-admin/src/main/java/com/evo/common/exception/file/FileNameLengthLimitExceededException.java new file mode 100644 index 0000000..9933240 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/exception/file/FileNameLengthLimitExceededException.java @@ -0,0 +1,16 @@ +package com.evo.common.exception.file; + +/** + * 文件名称超长限制异常类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/exception/file/FileSizeLimitExceededException.java b/evo-admin/src/main/java/com/evo/common/exception/file/FileSizeLimitExceededException.java new file mode 100644 index 0000000..12b6468 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/exception/file/FileSizeLimitExceededException.java @@ -0,0 +1,16 @@ +package com.evo.common.exception.file; + +/** + * 文件名大小限制异常类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/exception/file/FileUploadException.java b/evo-admin/src/main/java/com/evo/common/exception/file/FileUploadException.java new file mode 100644 index 0000000..fa3ec23 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/exception/file/FileUploadException.java @@ -0,0 +1,61 @@ +package com.evo.common.exception.file; + +import java.io.PrintStream; +import java.io.PrintWriter; + +/** + * 文件上传异常类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/exception/file/InvalidExtensionException.java b/evo-admin/src/main/java/com/evo/common/exception/file/InvalidExtensionException.java new file mode 100644 index 0000000..3e9a5b4 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/exception/file/InvalidExtensionException.java @@ -0,0 +1,80 @@ +package com.evo.common.exception.file; + +import java.util.Arrays; + +/** + * 文件上传 误异常类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/exception/job/TaskException.java b/evo-admin/src/main/java/com/evo/common/exception/job/TaskException.java new file mode 100644 index 0000000..32bb85f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/exception/job/TaskException.java @@ -0,0 +1,34 @@ +package com.evo.common.exception.job; + +/** + * 计划策略异常 + * + * @author evo + */ +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 + } +} diff --git a/evo-admin/src/main/java/com/evo/common/exception/user/BlackListException.java b/evo-admin/src/main/java/com/evo/common/exception/user/BlackListException.java new file mode 100644 index 0000000..ca14eb5 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/exception/user/BlackListException.java @@ -0,0 +1,16 @@ +package com.evo.common.exception.user; + +/** + * 黑名单IP异常类 + * + * @author evo + */ +public class BlackListException extends UserException +{ + private static final long serialVersionUID = 1L; + + public BlackListException() + { + super("login.blocked", null); + } +} diff --git a/evo-admin/src/main/java/com/evo/common/exception/user/CaptchaException.java b/evo-admin/src/main/java/com/evo/common/exception/user/CaptchaException.java new file mode 100644 index 0000000..5712a53 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/exception/user/CaptchaException.java @@ -0,0 +1,16 @@ +package com.evo.common.exception.user; + +/** + * 验证码错误异常类 + * + * @author evo + */ +public class CaptchaException extends UserException +{ + private static final long serialVersionUID = 1L; + + public CaptchaException() + { + super("user.jcaptcha.error", null); + } +} diff --git a/evo-admin/src/main/java/com/evo/common/exception/user/CaptchaExpireException.java b/evo-admin/src/main/java/com/evo/common/exception/user/CaptchaExpireException.java new file mode 100644 index 0000000..2c512cc --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/exception/user/CaptchaExpireException.java @@ -0,0 +1,16 @@ +package com.evo.common.exception.user; + +/** + * 验证码失效异常类 + * + * @author evo + */ +public class CaptchaExpireException extends UserException +{ + private static final long serialVersionUID = 1L; + + public CaptchaExpireException() + { + super("user.jcaptcha.expire", null); + } +} diff --git a/evo-admin/src/main/java/com/evo/common/exception/user/UserException.java b/evo-admin/src/main/java/com/evo/common/exception/user/UserException.java new file mode 100644 index 0000000..8fdc15a --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/exception/user/UserException.java @@ -0,0 +1,18 @@ +package com.evo.common.exception.user; + +import com.evo.common.exception.base.BaseException; + +/** + * 用户信息异常类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/exception/user/UserNotExistsException.java b/evo-admin/src/main/java/com/evo/common/exception/user/UserNotExistsException.java new file mode 100644 index 0000000..5c81982 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/exception/user/UserNotExistsException.java @@ -0,0 +1,16 @@ +package com.evo.common.exception.user; + +/** + * 用户不存在异常类 + * + * @author evo + */ +public class UserNotExistsException extends UserException +{ + private static final long serialVersionUID = 1L; + + public UserNotExistsException() + { + super("user.not.exists", null); + } +} diff --git a/evo-admin/src/main/java/com/evo/common/exception/user/UserPasswordNotMatchException.java b/evo-admin/src/main/java/com/evo/common/exception/user/UserPasswordNotMatchException.java new file mode 100644 index 0000000..6b173a8 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/exception/user/UserPasswordNotMatchException.java @@ -0,0 +1,16 @@ +package com.evo.common.exception.user; + +/** + * 用户密码不正确或不符合规范异常类 + * + * @author evo + */ +public class UserPasswordNotMatchException extends UserException +{ + private static final long serialVersionUID = 1L; + + public UserPasswordNotMatchException() + { + super("user.password.not.match", null); + } +} diff --git a/evo-admin/src/main/java/com/evo/common/exception/user/UserPasswordRetryLimitExceedException.java b/evo-admin/src/main/java/com/evo/common/exception/user/UserPasswordRetryLimitExceedException.java new file mode 100644 index 0000000..04e04cd --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/exception/user/UserPasswordRetryLimitExceedException.java @@ -0,0 +1,16 @@ +package com.evo.common.exception.user; + +/** + * 用户错误最大次数异常类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/filter/PropertyPreExcludeFilter.java b/evo-admin/src/main/java/com/evo/common/filter/PropertyPreExcludeFilter.java new file mode 100644 index 0000000..5663e60 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/filter/PropertyPreExcludeFilter.java @@ -0,0 +1,24 @@ +package com.evo.common.filter; + +import com.alibaba.fastjson2.filter.SimplePropertyPreFilter; + +/** + * 排除JSON敏感属性 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/filter/RepeatableFilter.java b/evo-admin/src/main/java/com/evo/common/filter/RepeatableFilter.java new file mode 100644 index 0000000..dc81bdf --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/filter/RepeatableFilter.java @@ -0,0 +1,52 @@ +package com.evo.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.evo.common.utils.StringUtils; + +/** + * Repeatable 过滤器 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/filter/RepeatedlyRequestWrapper.java b/evo-admin/src/main/java/com/evo/common/filter/RepeatedlyRequestWrapper.java new file mode 100644 index 0000000..02c50df --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/filter/RepeatedlyRequestWrapper.java @@ -0,0 +1,76 @@ +package com.evo.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.evo.common.utils.http.HttpHelper; +import com.evo.common.constant.Constants; + +/** + * 构建可重复读取inputStream的request + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/filter/XssFilter.java b/evo-admin/src/main/java/com/evo/common/filter/XssFilter.java new file mode 100644 index 0000000..f54e703 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/filter/XssFilter.java @@ -0,0 +1,75 @@ +package com.evo.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.evo.common.utils.StringUtils; +import com.evo.common.enums.HttpMethod; + +/** + * 防止XSS攻击的过滤器 + * + * @author evo + */ +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() + { + + } +} diff --git a/evo-admin/src/main/java/com/evo/common/filter/XssHttpServletRequestWrapper.java b/evo-admin/src/main/java/com/evo/common/filter/XssHttpServletRequestWrapper.java new file mode 100644 index 0000000..52b25ed --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/filter/XssHttpServletRequestWrapper.java @@ -0,0 +1,111 @@ +package com.evo.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.evo.common.utils.StringUtils; +import com.evo.common.utils.html.EscapeUtil; + +/** + * XSS过滤处理 + * + * @author evo + */ +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); + } +} diff --git a/evo-admin/src/main/java/com/evo/common/utils/Arith.java b/evo-admin/src/main/java/com/evo/common/utils/Arith.java new file mode 100644 index 0000000..a0c50ac --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/Arith.java @@ -0,0 +1,114 @@ +package com.evo.common.utils; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +/** + * 精确的浮点数运算 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/utils/DateUtils.java b/evo-admin/src/main/java/com/evo/common/utils/DateUtils.java new file mode 100644 index 0000000..7babefd --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/DateUtils.java @@ -0,0 +1,191 @@ +package com.evo.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 evo + */ +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/evo-admin/src/main/java/com/evo/common/utils/DesensitizedUtil.java b/evo-admin/src/main/java/com/evo/common/utils/DesensitizedUtil.java new file mode 100644 index 0000000..265b828 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/DesensitizedUtil.java @@ -0,0 +1,49 @@ +package com.evo.common.utils; + +/** + * 脱敏工具类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/utils/DictUtils.java b/evo-admin/src/main/java/com/evo/common/utils/DictUtils.java new file mode 100644 index 0000000..01ffc8f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/DictUtils.java @@ -0,0 +1,239 @@ +package com.evo.common.utils; + +import java.util.Collection; +import java.util.List; +import com.alibaba.fastjson2.JSONArray; +import com.evo.common.constant.CacheConstants; +import com.evo.common.core.domain.entity.SysDictData; +import com.evo.common.core.redis.RedisCache; +import com.evo.common.utils.spring.SpringUtils; + +/** + * 字典工具类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/utils/ExceptionUtil.java b/evo-admin/src/main/java/com/evo/common/utils/ExceptionUtil.java new file mode 100644 index 0000000..6419a15 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/ExceptionUtil.java @@ -0,0 +1,39 @@ +package com.evo.common.utils; + +import java.io.PrintWriter; +import java.io.StringWriter; +import org.apache.commons.lang3.exception.ExceptionUtils; + +/** + * 错误信息处理类。 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/utils/LogUtils.java b/evo-admin/src/main/java/com/evo/common/utils/LogUtils.java new file mode 100644 index 0000000..c7357e9 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/LogUtils.java @@ -0,0 +1,18 @@ +package com.evo.common.utils; + +/** + * 处理并记录日志文件 + * + * @author evo + */ +public class LogUtils +{ + public static String getBlock(Object msg) + { + if (msg == null) + { + msg = ""; + } + return "[" + msg.toString() + "]"; + } +} diff --git a/evo-admin/src/main/java/com/evo/common/utils/MessageUtils.java b/evo-admin/src/main/java/com/evo/common/utils/MessageUtils.java new file mode 100644 index 0000000..ca3883a --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/MessageUtils.java @@ -0,0 +1,26 @@ +package com.evo.common.utils; + +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; +import com.evo.common.utils.spring.SpringUtils; + +/** + * 获取i18n资源文件 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/utils/PageUtils.java b/evo-admin/src/main/java/com/evo/common/utils/PageUtils.java new file mode 100644 index 0000000..28f6086 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/PageUtils.java @@ -0,0 +1,35 @@ +package com.evo.common.utils; + +import com.github.pagehelper.PageHelper; +import com.evo.common.core.page.PageDomain; +import com.evo.common.core.page.TableSupport; +import com.evo.common.utils.sql.SqlUtil; + +/** + * 分页工具类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/utils/SecurityUtils.java b/evo-admin/src/main/java/com/evo/common/utils/SecurityUtils.java new file mode 100644 index 0000000..63b0e5b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/SecurityUtils.java @@ -0,0 +1,178 @@ +package com.evo.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.evo.common.constant.Constants; +import com.evo.common.constant.HttpStatus; +import com.evo.common.core.domain.entity.SysRole; +import com.evo.common.core.domain.model.LoginUser; +import com.evo.common.exception.ServiceException; + +/** + * 安全服务工具类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/utils/ServletUtils.java b/evo-admin/src/main/java/com/evo/common/utils/ServletUtils.java new file mode 100644 index 0000000..8615b43 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/ServletUtils.java @@ -0,0 +1,218 @@ +package com.evo.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.evo.common.constant.Constants; +import com.evo.common.core.text.Convert; + +/** + * 客户端工具类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/utils/StringUtils.java b/evo-admin/src/main/java/com/evo/common/utils/StringUtils.java new file mode 100644 index 0000000..0ff7cf5 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/StringUtils.java @@ -0,0 +1,684 @@ +package com.evo.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.evo.common.constant.Constants; +import com.evo.common.core.text.StrFormatter; + +/** + * 字符串工具类 + * + * @author evo + */ +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(); + } +} diff --git a/evo-admin/src/main/java/com/evo/common/utils/Threads.java b/evo-admin/src/main/java/com/evo/common/utils/Threads.java new file mode 100644 index 0000000..59b18f3 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/Threads.java @@ -0,0 +1,99 @@ +package com.evo.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 evo + */ +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/evo-admin/src/main/java/com/evo/common/utils/bean/BeanUtils.java b/evo-admin/src/main/java/com/evo/common/utils/bean/BeanUtils.java new file mode 100644 index 0000000..738eadf --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/bean/BeanUtils.java @@ -0,0 +1,110 @@ +package com.evo.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 evo + */ +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/evo-admin/src/main/java/com/evo/common/utils/bean/BeanValidators.java b/evo-admin/src/main/java/com/evo/common/utils/bean/BeanValidators.java new file mode 100644 index 0000000..202097d --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/bean/BeanValidators.java @@ -0,0 +1,24 @@ +package com.evo.common.utils.bean; + +import java.util.Set; +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.validation.Validator; + +/** + * bean对象属性验证 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/utils/file/FileTypeUtils.java b/evo-admin/src/main/java/com/evo/common/utils/file/FileTypeUtils.java new file mode 100644 index 0000000..4d4c9dc --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/file/FileTypeUtils.java @@ -0,0 +1,76 @@ +package com.evo.common.utils.file; + +import java.io.File; +import org.apache.commons.lang3.StringUtils; + +/** + * 文件类型工具类 + * + * @author evo + */ +public class FileTypeUtils +{ + /** + * 获取文件类型 + *

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

+ * 例如: evo.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; + } +} diff --git a/evo-admin/src/main/java/com/evo/common/utils/file/FileUploadUtils.java b/evo-admin/src/main/java/com/evo/common/utils/file/FileUploadUtils.java new file mode 100644 index 0000000..7cc3b12 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/file/FileUploadUtils.java @@ -0,0 +1,232 @@ +package com.evo.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.evo.common.config.EvoConfig; +import com.evo.common.constant.Constants; +import com.evo.common.exception.file.FileNameLengthLimitExceededException; +import com.evo.common.exception.file.FileSizeLimitExceededException; +import com.evo.common.exception.file.InvalidExtensionException; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.uuid.Seq; + +/** + * 文件上传工具类 + * + * @author evo + */ +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 = EvoConfig.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 = EvoConfig.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/evo-admin/src/main/java/com/evo/common/utils/file/FileUtils.java b/evo-admin/src/main/java/com/evo/common/utils/file/FileUtils.java new file mode 100644 index 0000000..6288e8d --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/file/FileUtils.java @@ -0,0 +1,291 @@ +package com.evo.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.evo.common.config.EvoConfig; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.uuid.IdUtils; +import org.apache.commons.io.FilenameUtils; + +/** + * 文件处理工具类 + * + * @author evo + */ +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, EvoConfig.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/evo.png -- evo.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/evo.png -- evo + * + * @param fileName 路径名称 + * @return 没有文件路径和后缀的名称 + */ + public static String getNameNotSuffix(String fileName) + { + if (fileName == null) + { + return null; + } + String baseName = FilenameUtils.getBaseName(fileName); + return baseName; + } +} diff --git a/evo-admin/src/main/java/com/evo/common/utils/file/ImageUtils.java b/evo-admin/src/main/java/com/evo/common/utils/file/ImageUtils.java new file mode 100644 index 0000000..5251f58 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/file/ImageUtils.java @@ -0,0 +1,98 @@ +package com.evo.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.evo.common.config.EvoConfig; +import com.evo.common.constant.Constants; +import com.evo.common.utils.StringUtils; + +/** + * 图片处理工具类 + * + * @author evo + */ +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 = EvoConfig.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/evo-admin/src/main/java/com/evo/common/utils/file/MimeTypeUtils.java b/evo-admin/src/main/java/com/evo/common/utils/file/MimeTypeUtils.java new file mode 100644 index 0000000..f9d830c --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/file/MimeTypeUtils.java @@ -0,0 +1,59 @@ +package com.evo.common.utils.file; + +/** + * 媒体类型工具类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/utils/html/EscapeUtil.java b/evo-admin/src/main/java/com/evo/common/utils/html/EscapeUtil.java new file mode 100644 index 0000000..79c4132 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/html/EscapeUtil.java @@ -0,0 +1,167 @@ +package com.evo.common.utils.html; + +import com.evo.common.utils.StringUtils; + +/** + * 转义和反转义工具类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/utils/html/HTMLFilter.java b/evo-admin/src/main/java/com/evo/common/utils/html/HTMLFilter.java new file mode 100644 index 0000000..bb0463c --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/html/HTMLFilter.java @@ -0,0 +1,570 @@ +package com.evo.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 evo + */ +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)); + } +} diff --git a/evo-admin/src/main/java/com/evo/common/utils/http/HttpHelper.java b/evo-admin/src/main/java/com/evo/common/utils/http/HttpHelper.java new file mode 100644 index 0000000..e85f072 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/http/HttpHelper.java @@ -0,0 +1,55 @@ +package com.evo.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 evo + */ +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/evo-admin/src/main/java/com/evo/common/utils/http/HttpUtils.java b/evo-admin/src/main/java/com/evo/common/utils/http/HttpUtils.java new file mode 100644 index 0000000..93935e1 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/http/HttpUtils.java @@ -0,0 +1,274 @@ +package com.evo.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 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.evo.common.constant.Constants; +import com.evo.common.utils.StringUtils; + +/** + * 通用http发送方法 + * + * @author evo + */ +public class HttpUtils +{ + private static final Logger log = LoggerFactory.getLogger(HttpUtils.class); + + /** + * 向指定 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; + } + } +} diff --git a/evo-admin/src/main/java/com/evo/common/utils/ip/AddressUtils.java b/evo-admin/src/main/java/com/evo/common/utils/ip/AddressUtils.java new file mode 100644 index 0000000..f56f7ce --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/ip/AddressUtils.java @@ -0,0 +1,56 @@ +package com.evo.common.utils.ip; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.evo.common.config.EvoConfig; +import com.evo.common.constant.Constants; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.http.HttpUtils; + +/** + * 获取地址类 + * + * @author evo + */ +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 (EvoConfig.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/evo-admin/src/main/java/com/evo/common/utils/ip/IpUtils.java b/evo-admin/src/main/java/com/evo/common/utils/ip/IpUtils.java new file mode 100644 index 0000000..9485b86 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/ip/IpUtils.java @@ -0,0 +1,382 @@ +package com.evo.common.utils.ip; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import javax.servlet.http.HttpServletRequest; +import com.evo.common.utils.ServletUtils; +import com.evo.common.utils.StringUtils; + +/** + * 获取IP方法 + * + * @author evo + */ +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; + } +} diff --git a/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelHandlerAdapter.java b/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelHandlerAdapter.java new file mode 100644 index 0000000..c911b71 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelHandlerAdapter.java @@ -0,0 +1,24 @@ +package com.evo.common.utils.poi; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Workbook; + +/** + * Excel数据格式处理适配器 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelUtil.java b/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelUtil.java new file mode 100644 index 0000000..2733761 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelUtil.java @@ -0,0 +1,1812 @@ +package com.evo.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.evo.common.annotation.Excel; +import com.evo.common.annotation.Excel.ColumnType; +import com.evo.common.annotation.Excel.Type; +import com.evo.common.annotation.Excels; +import com.evo.common.config.EvoConfig; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.text.Convert; +import com.evo.common.exception.UtilException; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.DictUtils; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.file.FileTypeUtils; +import com.evo.common.utils.file.FileUtils; +import com.evo.common.utils.file.ImageUtils; +import com.evo.common.utils.reflect.ReflectUtils; + +/** + * Excel相关处理 + * + * @author evo + */ +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 = EvoConfig.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/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelUtilSs.java b/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelUtilSs.java new file mode 100644 index 0000000..c607cd5 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelUtilSs.java @@ -0,0 +1,1040 @@ +package com.evo.common.utils.poi; + +import com.evo.common.annotation.Excel; +import com.evo.common.annotation.Excel.ColumnType; +import com.evo.common.annotation.Excel.Type; +import com.evo.common.annotation.Excels; +import com.evo.common.config.EvoConfig; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.text.Convert; +import com.evo.common.exception.CustomException; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.reflect.ReflectUtils; +import org.apache.poi.hssf.usermodel.HSSFDateUtil; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellRangeAddressList; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFDataValidation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * Excel相关处理 + * + * @author ruoyi + */ +public class ExcelUtilSs{ + private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class); + + /** + * Excel sheet最大行数,默认65536 + */ + public static final int sheetSize = 65536; + + /** + * 工作表名称 + */ + private String sheetName; + + /** + * 工作表标题 + */ + private String title; + + /** + * 工作表表尾 + */ + private String footer; + + /** + * 各个部门工作表名称 + */ + private List sheetNameList; + + /** + * 导出类型(EXPORT:导出数据;IMPORT:导入模板) + */ + private Type type; + + /** + * 工作薄对象 + */ + private Workbook wb; + + /** + * 工作表对象 + */ + private Sheet sheet; + + /** + * 样式列表 + */ + private Map styles; + + /** + * 导入导出数据列表 + */ + private List list; + + /** + * 导入导出各个部门数据列表 + */ + private List> lists; + + /** + * 注解列表 + */ + private List fields; + + /** + * 实体对象 + */ + public Class clazz; + + public ExcelUtilSs(Class clazz) + { + this.clazz = clazz; + } + + // 默认单元格内容为数字时格式 + private static DecimalFormat df = new DecimalFormat("0"); + // 默认单元格格式化日期字符串 + private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + // 格式化数字 + private static DecimalFormat nf = new DecimalFormat("0.00"); + + public void init(List list,List> lists, String sheetName,List sheetNameList,String title,String footer, Type type){ + if (list == null){ + list = new ArrayList(); + } + if(sheetNameList == null){ + sheetNameList = new ArrayList(); + } + this.list = list; + this.lists = lists; + this.sheetName = sheetName; + this.sheetNameList = sheetNameList; + this.title = title; + this.footer = footer; + this.type = type; + createExcelField(); + createWorkbook(); + } + + /** + * 对excel表单默认第一个索引名转换成list + * + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(InputStream is) throws Exception + { + return importExcel(StringUtils.EMPTY, is); + } + + /** + * 对excel表单指定表格索引名转换成list + * + * @param sheetName 表格索引名 + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(String sheetName, InputStream is) throws Exception + { + this.type = Type.IMPORT; + this.wb = WorkbookFactory.create(is); + List list = new ArrayList(); + Sheet sheet = null; + if (StringUtils.isNotEmpty(sheetName)) + { + // 如果指定sheet名,则取指定sheet中的内容. + sheet = wb.getSheet(sheetName); + } + else + { + // 如果传入的sheet名不存在则默认指向第1个sheet. + sheet = wb.getSheetAt(0); + } + + if (sheet == null) + { + throw new IOException("文件sheet不存在"); + } + + int rows = sheet.getPhysicalNumberOfRows(); + + if (rows > 0) + { + // 定义一个map用于存放excel列的序号和field. + Map cellMap = new HashMap(); + // 获取表头 + Row heard = sheet.getRow(0); + 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. + Field[] allFields = clazz.getDeclaredFields(); + // 定义一个map用于存放列的序号和field. + Map fieldsMap = new HashMap(); + for (int col = 0; col < allFields.length; col++) + { + Field field = allFields[col]; + Excel attr = field.getAnnotation(Excel.class); + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + // 设置类的私有字段属性可访问. + field.setAccessible(true); + Integer column = cellMap.get(attr.name()); + fieldsMap.put(column, field); + } + } + for (int i = 1; i < rows; i++) + { + // 从第2行开始取数据,默认第一行是表头. + Row row = sheet.getRow(i); + T entity = null; + for (Map.Entry entry : fieldsMap.entrySet()) + { + Object val = this.getCellValue(row, entry.getKey()); + + // 如果不存在实例则新建. + entity = (entity == null ? clazz.newInstance() : entity); + // 从map中得到对应列的field. + Field field = fieldsMap.get(entry.getKey()); + // 取得类型,并根据对象类型设置值. + Class fieldType = field.getType(); + if (String.class == fieldType) + { + String s = Convert.toStr(val); + if (StringUtils.endsWith(s, ".0")) + { + val = StringUtils.substringBefore(s, ".0"); + } + else + { + val = Convert.toStr(val); + } + } + else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) + { + val = Convert.toInt(val); + } + else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) + { + val = Convert.toLong(val); + } + else if ((Double.TYPE == fieldType) || (Double.class == fieldType)) + { + val = Convert.toDouble(val); + } + else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) + { + val = Convert.toFloat(val); + } + else if (BigDecimal.class == fieldType) + { + val = Convert.toBigDecimal(val); + } + else if (Date.class == fieldType) + { + if (val instanceof String) + { + val = DateUtils.parseDate(val); + } + else if (val instanceof Double) + { + val = DateUtil.getJavaDate((Double) val); + } + } + if (StringUtils.isNotNull(fieldType)) + { + Excel attr = field.getAnnotation(Excel.class); + String propertyName = field.getName(); + if (StringUtils.isNotEmpty(attr.targetAttr())) + { + propertyName = field.getName() + "." + attr.targetAttr(); + } + else if (StringUtils.isNotEmpty(attr.readConverterExp())) + { + val = reverseByExp(String.valueOf(val), attr.readConverterExp()); + } + ReflectUtils.invokeSetter(entity, propertyName, val); + } + } + list.add(entity); + } + } + return list; + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + */ + public AjaxResult exportExcel(List list, List> lists, String sheetName, List sheetNameList, String title, String footer){ + this.init(list,lists,sheetName,sheetNameList,title,footer,Type.EXPORT); + return exportExcel(); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @return 结果 + */ + public AjaxResult exportExcel(){ + OutputStream out = null; + try{ + // 取出一共有多少个sheet. + double sheetNo = 0; + sheetNo = sheetNameList.size(); + for (int index = 0; index <= sheetNo; index++){ + createSheet(sheetNo, index); + //sheet1和后边的sheet表头不一致,所以需要分开处理 + // 产生一行 + Row row = sheet.createRow(0); + sheet.addMergedRegion(new CellRangeAddress(0,0,0,25)); + for(int i = 0; i<26; i++){ + Cell cell = row.createCell(i); + cell.setCellStyle(styles.get("title")); + } + Row row2 = sheet.getRow(0); + Cell cell = row2.getCell(0); + if(index == 0){ + cell.setCellValue(this.title+"("+this.sheetName+")"); + }else{ + cell.setCellValue(this.title+"("+this.sheetNameList.get(index-1)+")"); + } + int column = 0; + // 写入各个字段的列头名称 + row = sheet.createRow(1); + // 写入各个字段的列头名称 + //当index为0时,默认是第一个sheet,需要把list[1]姓名列删掉 + List fields2 = new ArrayList<>(); + fields2.addAll(fields); + for (int i = 0; i < fields2.size();i++){ + Object[] os = fields2.get(i); + Excel excel = (Excel) os[1]; + this.createCell(excel, row, column++,index); + } + // 产生一行 + Row rows = sheet.createRow(list.size()+3); + sheet.addMergedRegion(new CellRangeAddress(list.size()+3,list.size()+3,0,25)); + for(int i = 0; i<26; i++){ + Cell cells = rows.createCell(i); + cells.setCellStyle(styles.get("footer")); + } + Row rows2 = sheet.getRow(list.size()+3); + Cell cells = rows2.getCell(0); + cells.setCellValue(this.footer); + + if (Type.EXPORT.equals(type)){ + fillExcelData(index, row); + } + } + String filename = encodingFilename(sheetName); + out = new FileOutputStream(getAbsoluteFile(filename)); + wb.write(out); + return AjaxResult.success(filename); + }catch (Exception e){ + log.error("导出Excel异常{}", e.getMessage()); + throw new CustomException("导出Excel失败,请联系网站管理员!"); + } + finally{ + if (wb != null) + { + try + { + wb.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + } + if (out != null) + { + try + { + out.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + } + } + } + + /** + * 填充excel数据 + * + * @param index 序号 + * @param row 单元格行 + */ + public void fillExcelData(int index, Row row){ + int startNo = 0; + int endNo = 0; + if(index == 0){ + startNo = index * sheetSize; + endNo = Math.min(startNo + sheetSize, list.size()); + } else{ + endNo = Math.min(startNo + sheetSize, lists.get(index-1).size()); + } + for (int i = startNo; i < endNo; i++){ + row = sheet.createRow(i + 2 - startNo); + // 得到导出对象. + T vo = (T) list.get(i); + int column = 0; + //当index为0时,默认是第一个sheet,需要把list[1]姓名列删掉 + List fields2 = new ArrayList<>(); + fields2.addAll(fields); + for (Object[] os : fields2){ + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + // 设置实体类私有属性可访问 + field.setAccessible(true); + this.addCell(excel, row, vo, field, column++,index); + } + } + } + + /** + * 创建表格样式 + * + * @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); + 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("宋体"); + dataFont.setFontHeightInPoints((short) 10); + style.setFont(dataFont); +// style.setWrapText(true);//自动换行 + styles.put("data", style); + + style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font dataFonts = wb.createFont(); + dataFont.setFontName("宋体"); + dataFont.setFontHeightInPoints((short) 9); + style.setFont(dataFonts); + styles.put("datas", style); + + style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); +// style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex()); +// style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + Font headerFont = wb.createFont(); + headerFont.setFontName("宋体"); + headerFont.setFontHeightInPoints((short) 11); +// headerFont.setBold(true); +// headerFont.setColor(IndexedColors.WHITE.getIndex()); + style.setFont(headerFont); + style.setWrapText(true);//自动换行 + styles.put("header", style); + + style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("datas")); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font footerFont = wb.createFont(); + footerFont.setFontName("宋体"); + footerFont.setFontHeightInPoints((short) 12); + style.setFont(footerFont); + styles.put("footer", style); + + style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font titleFont = wb.createFont(); + titleFont.setFontName("宋体"); + titleFont.setFontHeightInPoints((short) 18); + style.setFont(titleFont); + styles.put("title", style); + + return styles; + } + + /** + * 创建单元格 + */ + public Cell createCell(Excel attr, Row row, int column,int index){ + // 创建列 + Cell cell = row.createCell(column); + // 写入列信息 + cell.setCellValue(attr.name()); + setDataValidation(attr, row, column,index); + cell.setCellStyle(styles.get("header")); + return cell; + } + + /** + * 设置单元格信息 + * + * @param value 单元格值 + * @param attr 注解相关 + * @param cell 单元格信息 + */ + public void setCellVo(Object value, Excel attr, Cell cell) + { + if (ColumnType.STRING == attr.cellType()) + { + cell.setCellType(CellType.NUMERIC); + cell.setCellValue(StringUtils.isNull(value) ? attr.defaultValue() : value + attr.suffix()); + } + else if (ColumnType.NUMERIC == attr.cellType()) + { + cell.setCellType(CellType.NUMERIC); + cell.setCellValue(Integer.parseInt(value + "")); + } + } + + /** + * 创建表格样式 + */ + public void setDataValidation(Excel attr, Row row, int column,int index){ + if(index == 0){ + if (attr.name().indexOf("注:") >= 0){ + sheet.setColumnWidth(column, 6000); + }else{ + if(column==0){ + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width()) * 120)); + }else if(column==2||column==3||column==4||column==6||column==7||column==9||column==11){ + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width()) * 115)); + }else{ + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width()) * 130)); + } + row.setHeight((short) (attr.height() * 50)); + } + // 如果设置了提示信息则鼠标放上去提示. + if (StringUtils.isNotEmpty(attr.prompt())){ + // 这里默认设了2-101列提示. + setXSSFPrompt(sheet, "", attr.prompt(), 1, 100, column, column); + } + // 如果设置了combo属性则本列只能选择不能输入 + if (attr.combo().length > 0){ + // 这里默认设了2-101列只能选择不能输入. + setXSSFValidation(sheet, attr.combo(), 1, 100, column, column); + } + }else{ + if (attr.name().indexOf("注:") >= 0){ + sheet.setColumnWidth(column, 6000); + }else{ + if(column==0){ + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width()) * 120)); + }else if(column==2||column==3||column==4||column==6||column==7||column==9||column==11){ + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width()) * 100)); + }else{ + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width()) * 110)); + } + row.setHeight((short) (attr.height() * 50)); + } + // 如果设置了提示信息则鼠标放上去提示. + if (StringUtils.isNotEmpty(attr.prompt())){ + // 这里默认设了2-101列提示. + setXSSFPrompt(sheet, "", attr.prompt(), 1, 100, column, column); + } + // 如果设置了combo属性则本列只能选择不能输入 + if (attr.combo().length > 0){ + // 这里默认设了2-101列只能选择不能输入. + setXSSFValidation(sheet, attr.combo(), 1, 100, column, column); + } + } + } + + /** + * 添加单元格 + */ + public Cell addCell(Excel attr, Row row, T vo, Field field, int column,int index){ + Cell cell = null; + try{ + // 设置行高 + row.setHeight((short) (attr.height() * 30)); + // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列. + if (attr.isExport()){ + // 创建cell + cell = row.createCell(column); + cell.setCellStyle(styles.get("data")); + + // 用于读取对象中的属性 + Object value = getTargetValue(vo, field, attr); + String dateFormat = attr.dateFormat(); + String readConverterExp = attr.readConverterExp(); + if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)){ + cell.setCellValue(DateUtils.parseDateToStr(dateFormat, (Date) value)); + }else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)){ + cell.setCellValue(convertByExp(String.valueOf(value), readConverterExp)); + }else{ + // 设置列类型 + setCellVo(value, attr, cell); + } + } + } + catch (Exception e) + { + log.error("导出Excel失败{}", e); + } + return cell; + } + + /** + * 设置 POI XSSFSheet 单元格提示 + * + * @param sheet 表单 + * @param promptTitle 提示标题 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setXSSFPrompt(Sheet sheet, String promptTitle, String promptContent, int firstRow, int endRow, + int firstCol, int endCol) + { + DataValidationHelper helper = sheet.getDataValidationHelper(); + DataValidationConstraint constraint = helper.createCustomConstraint("DD1"); + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + DataValidation dataValidation = helper.createValidation(constraint, regions); + dataValidation.createPromptBox(promptTitle, promptContent); + dataValidation.setShowPromptBox(true); + sheet.addValidationData(dataValidation); + } + + /** + * 设置某些列的值只能输入预制的数据,显示下拉框. + * + * @param sheet 要设置的sheet. + * @param textlist 下拉框显示的内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + * @return 设置好的sheet. + */ + public void setXSSFValidation(Sheet sheet, String[] textlist, int firstRow, int endRow, int firstCol, int endCol) + { + DataValidationHelper helper = sheet.getDataValidationHelper(); + // 加载下拉列表内容 + DataValidationConstraint constraint = helper.createExplicitListConstraint(textlist); + // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列 + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + // 数据有效性对象 + DataValidation dataValidation = helper.createValidation(constraint, regions); + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) + { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } + else + { + dataValidation.setSuppressDropDownArrow(false); + } + + sheet.addValidationData(dataValidation); + } + + /** + * 解析导出值 0=男,1=女,2=未知 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @return 解析后值 + * @throws Exception + */ + public static String convertByExp(String propertyValue, String converterExp) throws Exception + { + try + { + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (itemArray[0].equals(propertyValue)) + { + return itemArray[1]; + } + } + } + catch (Exception e) + { + throw e; + } + return propertyValue; + } + + /** + * 反向解析值 男=0,女=1,未知=2 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @return 解析后值 + * @throws Exception + */ + public static String reverseByExp(String propertyValue, String converterExp) throws Exception + { + try + { + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (itemArray[1].equals(propertyValue)) + { + return itemArray[0]; + } + } + } + catch (Exception e) + { + throw e; + } + return propertyValue; + } + + /** + * 编码文件名 + */ + public String encodingFilename(String filename) + { +// filename = UUID.randomUUID().toString() + "_" + filename + ".xlsx"; + filename = filename + ".xlsx"; + return filename; + } + + /** + * 获取下载路径 + * + * @param filename 文件名称 + */ + public String getAbsoluteFile(String filename) + { + String downloadPath = EvoConfig.getDownloadPath() + filename; + File desc = new File(downloadPath); + if (!desc.getParentFile().exists()) + { + desc.getParentFile().mkdirs(); + } + return downloadPath; + } + + /** + * 获取bean中的属性值 + * + * @param vo 实体对象 + * @param field 字段 + * @param excel 注解 + * @return 最终的属性值 + * @throws Exception + */ + private Object getTargetValue(T vo, Field field, Excel excel) throws Exception{ + Object o = field.get(vo); + if (StringUtils.isNotEmpty(excel.targetAttr())){ + String target = excel.targetAttr(); + if (target.indexOf(".") > -1){ + String[] targets = target.split("[.]"); + for (String name : targets){ + o = getValue(o, name); + } + }else{ + o = getValue(o, target); + } + } + return o; + } + + /** + * 以类的属性的get方法方法形式获取值 + * + * @param o + * @param name + * @return value + * @throws Exception + */ + private Object getValue(Object o, String name) throws Exception + { + if (StringUtils.isNotEmpty(name)) + { + Class clazz = o.getClass(); + String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1); + Method method = clazz.getMethod(methodName); + o = method.invoke(o); + } + return o; + } + + /** + * 得到所有定义字段 + */ + private void createExcelField() + { + this.fields = new ArrayList(); + List tempFields = new ArrayList<>(); + tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); + tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); + for (Field field : tempFields) + { + // 单注解 + if (field.isAnnotationPresent(Excel.class)) + { + putToField(field, field.getAnnotation(Excel.class)); + } + + // 多注解 + if (field.isAnnotationPresent(Excels.class)) + { + Excels attrs = field.getAnnotation(Excels.class); + Excel[] excels = attrs.value(); + for (Excel excel : excels) + { + putToField(field, excel); + } + } + } + } + + /** + * 放到字段集合中 + */ + private void putToField(Field field, Excel attr) + { + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + this.fields.add(new Object[] { field, attr }); + } + } + + /** + * 创建一个工作簿 + */ + public void createWorkbook() + { + this.wb = new SXSSFWorkbook(500); + } + + /** + * 创建工作表 + * + * @param sheetNo sheet数量 + * @param index 序号 + */ + public void createSheet(double sheetNo, int index){ + this.sheet = wb.createSheet(); + this.styles = createStyles(wb); + // 设置工作表的名称. + if (index == 0){ + wb.setSheetName(index, sheetName); + }else{ + wb.setSheetName(index, sheetNameList.get(index-1)); + } + sheet.getPrintSetup().setPaperSize(PrintSetup.A4_PAPERSIZE); + //设置横向打印 + sheet.getPrintSetup().setLandscape(true); + } + + /** + * 获取单元格值 + * + * @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.getCellTypeEnum() == CellType.NUMERIC || cell.getCellTypeEnum() == CellType.FORMULA) + { + val = cell.getNumericCellValue(); + if (HSSFDateUtil.isCellDateFormatted(cell)) + { + val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换 + } + else + { + if ((Double) val % 1 > 0) + { + val = new DecimalFormat("0.00").format(val); + } + else + { + val = new DecimalFormat("0").format(val); + } + } + } + else if (cell.getCellTypeEnum() == CellType.STRING) + { + val = cell.getStringCellValue(); + } + else if (cell.getCellTypeEnum() == CellType.BOOLEAN) + { + val = cell.getBooleanCellValue(); + } + else if (cell.getCellTypeEnum() == CellType.ERROR) + { + val = cell.getErrorCellValue(); + } + + } + } + catch (Exception e) + { + return val; + } + return val; + } + + public static ArrayList> readExcel2007(Sheet sheet) { + if(sheet==null){ + return null; + } + try { + ArrayList> rowList = new ArrayList>(); + ArrayList colList; + Row row; + Cell cell; + Object value; + for (int i = sheet.getFirstRowNum(), rowCount = 0; rowCount < sheet.getPhysicalNumberOfRows(); i++) { + row = sheet.getRow(i); + colList = new ArrayList(); + if (row == null) { + // 当读取行为空时 + if (i != sheet.getPhysicalNumberOfRows()) {// 判断是否是最后一行 + rowList.add(colList); + } + continue; + } else { + rowCount++; + } + for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) { + cell = row.getCell(j); + if (cell == null || cell.getCellType() == CellType.BLANK) { + // 当该单元格为空 + if (j != row.getLastCellNum()) {// 判断是否是该行中最后一个单元格 + colList.add(""); + } + continue; + } + switch (cell.getCellType()) { + case STRING: + // System.out.println(i + "行" + j + " 列 is String + // type"); + value = cell.getStringCellValue(); + break; + case NUMERIC: + if ("@".equals(cell.getCellStyle().getDataFormatString())) { + value = df.format(cell.getNumericCellValue()); + } else if ("General".equals(cell.getCellStyle().getDataFormatString())) { + value = nf.format(cell.getNumericCellValue()); + } else { + value = sdf.format(HSSFDateUtil.getJavaDate(cell.getNumericCellValue())); + } + // System.out.println(i + "行" + j + // + " 列 is Number type ; DateFormt:" + // + value.toString()); + break; + case BOOLEAN: + // System.out.println(i + "行" + j + " 列 is Boolean + // type"); + value = Boolean.valueOf(cell.getBooleanCellValue()); + break; + case BLANK: + // System.out.println(i + "行" + j + " 列 is Blank type"); + value = ""; + break; + default: + // System.out.println(i + "行" + j + " 列 is default + // type"); + value = cell.toString(); + }// end switch + colList.add(value); + } // end for j + rowList.add(colList); + } // end for i + + return rowList; + } catch (Exception e) { + System.out.println("exception"); + return null; + } + } + + public static DecimalFormat getDf() { + return df; + } + + public static void setDf(DecimalFormat df) { + ExcelUtilSs.df = df; + } + + public static SimpleDateFormat getSdf() { + return sdf; + } + + public static void setSdf(SimpleDateFormat sdf) { + ExcelUtilSs.sdf = sdf; + } + + public static DecimalFormat getNf() { + return nf; + } + + public static void setNf(DecimalFormat nf) { + ExcelUtilSs.nf = nf; + } +} diff --git a/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelUtils.java b/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelUtils.java new file mode 100644 index 0000000..4041997 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelUtils.java @@ -0,0 +1,1009 @@ +package com.evo.common.utils.poi; + +import com.evo.common.annotation.Excel; +import com.evo.common.annotation.Excel.Type; +import com.evo.common.annotation.Excel.ColumnType; +import com.evo.common.annotation.Excels; +import com.evo.common.config.EvoConfig; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.exception.CustomException; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.StringUtils; +import org.apache.poi.hssf.usermodel.HSSFDateUtil; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellRangeAddressList; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFDataValidation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * Excel相关处理 + * + * @author ruoyi + */ +public class ExcelUtils{ + private static final Logger log = LoggerFactory.getLogger(ExcelUtils.class); + + /** + * Excel sheet最大行数,默认65536 + */ + public static final int sheetSize = 65536; + + /** + * 工作表名称 + */ + private String sheetName; + + /** + * 工作表名称 + */ + private String sheetName2; + + /** + * 工作表名称 + */ + private String sheetName3; + + /** + * 工作表名称 + */ + private String sheetName4; + /** + * 工作表名称 + */ + private String sheetName5; + /** + * 工作表名称 + */ + private String sheetName6; + + /** + * 工作表标题 + */ + private String title; + /** + * 标准件标题 + */ + private String titles; + + /** + * 文件名 + */ + private String code; + + /** + * 导出类型(EXPORT:导出数据;IMPORT:导入模板) + */ + private Type type; + + /** + * 工作薄对象 + */ + private Workbook wb; + + /** + * 工作表对象 + */ + private Sheet sheet; + + /** + * 样式列表 + */ + private Map styles; + + /** + * 导入导出数据列表 + */ + private List list; + + /** + * 导入导出数据列表 + */ + private List list2; + /** + * 导入导出数据列表 + */ + private List list3; + /** + * 导入导出数据列表 + */ + private List list4; + /** + * 导入导出数据列表 + */ + private List list5; + /** + * 导入导出数据列表 + */ + private List list6; + + /** + * 注解列表 + */ + private List fields; + + /** + * 实体对象 + */ + public Class clazz; + + public ExcelUtils(Class clazz) + { + this.clazz = clazz; + } + + // 默认单元格内容为数字时格式 + private static DecimalFormat df = new DecimalFormat("0"); + // 默认单元格格式化日期字符串 + private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + // 格式化数字 + private static DecimalFormat nf = new DecimalFormat("0"); + + public void init(List list,List list2,List list3,List list4,List list5,List list6,String sheetName,String sheetName2,String sheetName3,String sheetName4,String sheetName5,String sheetName6,String title,String titles,String code, Type type) + { + if (list == null){ + list = new ArrayList(); + } + if (list2 == null){ + list2 = new ArrayList(); + } + if (list3 == null){ + list3 = new ArrayList(); + } + if (list4 == null){ + list4 = new ArrayList(); + } + if (list5 == null){ + list5 = new ArrayList(); + } + if (list6 == null){ + list6 = new ArrayList(); + } + this.list = list; + this.sheetName = sheetName; + this.list2 = list2; + this.sheetName2 = sheetName2; + this.list3 = list3; + this.sheetName3 = sheetName3; + this.list4 = list4; + this.sheetName4 = sheetName4; + this.list5 = list5; + this.sheetName5 = sheetName5; + this.list6 = list6; + this.sheetName6 = sheetName6; + this.type = type; + this.title = title; + this.titles = titles; + this.code = code; + createExcelField(); + createWorkbook(); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + */ + public AjaxResult exportExcel(List list, List list2, List list3, List list4, List list5, List list6, String sheetName, String sheetName2, String sheetName3, String sheetName4, String sheetName5, String sheetName6, String title, String titles, String code) + { + this.init(list,list2,list3,list4,list5,list6,sheetName,sheetName2,sheetName3,sheetName4,sheetName5,sheetName6,title,titles,code,Type.EXPORT); + return exportExcel(); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @return 结果 + */ + public AjaxResult exportExcel(){ + OutputStream out = null; + try{ + // 取出一共有多少个sheet. + double sheetNo = 0; + if(StringUtils.isNotEmpty(sheetName2)){ + sheetNo = 1; + } + if(StringUtils.isNotEmpty(sheetName3)){ + sheetNo = 2; + } + if(StringUtils.isNotEmpty(sheetName4)){ + sheetNo = 3; + } + if(StringUtils.isNotEmpty(sheetName5)){ + sheetNo = 4; + } + if(StringUtils.isNotEmpty(sheetName6)){ + sheetNo = 5; + } + for (int index = 0; index <= sheetNo; index++){ + createSheet(sheetNo, index); + // 产生一行 + Row row = sheet.createRow(0); + sheet.addMergedRegion(new CellRangeAddress(0,0,0,8)); + for(int i = 0; i<9; i++){ + Cell cell = row.createCell(i); + cell.setCellStyle(styles.get("title")); + } + Row row2 = sheet.getRow(0); + Cell cell = row2.getCell(0); + if(index==0){ + cell.setCellValue(this.title+"("+sheetName+")"); + }else if(index==1){ + cell.setCellValue(this.title+"("+sheetName2+")"); + }else if(index==2){ + cell.setCellValue(this.titles+"("+sheetName3+")"); + }else if(index==3){ + cell.setCellValue(this.title+"("+sheetName4+")"); + }else if(index==4){ + cell.setCellValue(this.title+"("+sheetName5+")"); + }else{ + cell.setCellValue(this.title+"("+sheetName6+")"); + } + int column = 0; + // 写入各个字段的列头名称 + row = sheet.createRow(1); + for (Object[] os : fields){ + Excel excel = (Excel) os[1]; + this.createCell(excel, row, column++); + } + if (Type.EXPORT.equals(type)){ + fillExcelData(index, row); + } + } + + String filename = encodingFilename(this.code+"-"+sheetName); + out = new FileOutputStream(getAbsoluteFile(filename)); + wb.write(out); + return AjaxResult.success(filename); + } + catch (Exception e){ + log.error("导出Excel异常{}", e.getMessage()); + throw new CustomException("导出Excel失败,请联系网站管理员!"); + } + finally{ + if (wb != null){ + try{ + wb.close(); + } + catch (IOException e1){ + e1.printStackTrace(); + } + } + if (out != null){ + try{ + out.close(); + } + catch (IOException e1){ + e1.printStackTrace(); + } + } + } + } + + /** + * 填充excel数据 + * + * @param index 序号 + * @param row 单元格行 + */ + public void fillExcelData(int index, Row row){ + int startNo = 0; + int endNo = Math.min(startNo + sheetSize, list.size()); + int endNo2 = Math.min(startNo + sheetSize, list2.size()); + int endNo3 = Math.min(startNo + sheetSize, list3.size()); + int endNo4 = Math.min(startNo + sheetSize, list4.size()); + int endNo5 = Math.min(startNo + sheetSize, list5.size()); + int endNo6 = Math.min(startNo + sheetSize, list6.size()); + if(index == 0){ + for (int i = startNo; i < endNo; i++){ + row = sheet.createRow(i + 2); + // 得到导出对象. + T vo = (T) list.get(i); + int column = 0; + for (Object[] os : fields){ + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + // 设置实体类私有属性可访问 + field.setAccessible(true); + this.addCell(excel, row, vo, field, column++); + } + } + }else if(index == 1){ + for (int i = 0; i < endNo2; i++){ + row = sheet.createRow(i + 2); + // 得到导出对象. + T vo = (T) list2.get(i); + int column = 0; + for (Object[] os : fields){ + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + // 设置实体类私有属性可访问 + field.setAccessible(true); + this.addCell(excel, row, vo, field, column++); + } + } + }else if(index == 2){ + for (int i = 0; i < endNo3; i++){ + row = sheet.createRow(i + 2); + // 得到导出对象. + T vo = (T) list3.get(i); + int column = 0; + for (Object[] os : fields){ + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + // 设置实体类私有属性可访问 + field.setAccessible(true); + this.addCell(excel, row, vo, field, column++); + } + } + }else if(index == 3){ + for (int i = 0; i < endNo4; i++){ + row = sheet.createRow(i + 2); + // 得到导出对象. + T vo = (T) list4.get(i); + int column = 0; + for (Object[] os : fields){ + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + // 设置实体类私有属性可访问 + field.setAccessible(true); + this.addCell(excel, row, vo, field, column++); + } + } + }else if(index == 4){ + for (int i = 0; i < endNo5; i++){ + row = sheet.createRow(i + 2); + // 得到导出对象. + T vo = (T) list5.get(i); + int column = 0; + for (Object[] os : fields){ + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + // 设置实体类私有属性可访问 + field.setAccessible(true); + this.addCell(excel, row, vo, field, column++); + } + } + }else if(index == 5){ + for (int i = 0; i < endNo6; i++){ + row = sheet.createRow(i + 2); + // 得到导出对象. + T vo = (T) list6.get(i); + int column = 0; + for (Object[] os : fields){ + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + // 设置实体类私有属性可访问 + field.setAccessible(true); + this.addCell(excel, row, vo, field, column++); + } + } + } + + } + + /** + * 创建表格样式 + * + * @param wb 工作薄对象 + * @return 样式列表 + */ + private Map createStyles(Workbook wb){ + // 写入各条记录,每条记录对应excel表中的一行 + Map styles = new HashMap(); + + CellStyle style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + Font dataFont = wb.createFont(); + dataFont.setFontName("宋体"); + dataFont.setFontHeightInPoints((short) 11); + style.setFont(dataFont); + styles.put("data", style); + + style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.LEFT); + 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 dataFonts = wb.createFont(); + dataFonts.setFontName("宋体"); + dataFonts.setFontHeightInPoints((short) 11); + style.setFont(dataFonts); + styles.put("datas", style); + + style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); +// style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex()); +// style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + Font headerFont = wb.createFont(); + headerFont.setFontName("宋体"); + headerFont.setFontHeightInPoints((short) 12); +// headerFont.setBold(true); +// headerFont.setColor(IndexedColors.WHITE.getIndex()); + style.setFont(headerFont); + styles.put("header", style); + + style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); +// style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex()); +// style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + Font titleFont = wb.createFont(); + titleFont.setFontName("宋体"); + titleFont.setFontHeightInPoints((short) 18); +// headerFont.setBold(true); +// headerFont.setColor(IndexedColors.WHITE.getIndex()); + style.setFont(titleFont); + styles.put("title", style); + + return styles; + } + + /** + * 创建单元格 + */ + public Cell createCell(Excel attr, Row row, int column){ + // 创建列 + Cell cell = row.createCell(column); + // 写入列信息 + cell.setCellValue(attr.name()); + setDataValidation(attr, row, column); + cell.setCellStyle(styles.get("header")); + return cell; + } + + /** + * 设置单元格信息 + * + * @param value 单元格值 + * @param attr 注解相关 + * @param cell 单元格信息 + */ + public void setCellVo(Object value, Excel attr, Cell cell){ + if (ColumnType.STRING == attr.cellType()){ + cell.setCellType(CellType.NUMERIC); + cell.setCellValue(StringUtils.isNull(value) ? attr.defaultValue() : value + attr.suffix()); + } + else if (ColumnType.NUMERIC == attr.cellType()){ + cell.setCellType(CellType.NUMERIC); + cell.setCellValue(Integer.parseInt(value + "")); + } + } + + /** + * 创建表格样式 + */ + public void setDataValidation(Excel attr, Row row, int column){ + if (attr.name().indexOf("注:") >= 0){ + sheet.setColumnWidth(column, 6000); + }else{ + if(column == 0){ + // 设置列宽(第一列宽度) + sheet.setColumnWidth(column, (int) ((attr.width()) * 140)); + row.setHeight((short) (attr.height() * 26)); + }else if(column>0 && column<3){ + // 设置列宽(第二列和第三列宽度) + sheet.setColumnWidth(column, (int) ((attr.width() + 1) * 320)); + row.setHeight((short) (attr.height() * 26)); + }else if(column>2 && column<7){ + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width() + 0.2) * 200)); + row.setHeight((short) (attr.height() * 26)); + }else{ + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width() + 0.2) * 180)); + row.setHeight((short) (attr.height() * 26)); + } + } + // 如果设置了提示信息则鼠标放上去提示. + if (StringUtils.isNotEmpty(attr.prompt())) + { + // 这里默认设了2-101列提示. + setXSSFPrompt(sheet, "", attr.prompt(), 1, 100, column, column); + } + // 如果设置了combo属性则本列只能选择不能输入 + if (attr.combo().length > 0) + { + // 这里默认设了2-101列只能选择不能输入. + setXSSFValidation(sheet, attr.combo(), 1, 100, column, column); + } + } + + /** + * 添加单元格 + */ + public Cell addCell(Excel attr, Row row, T vo, Field field, int column){ + Cell cell = null; + try{ + // 设置行高 + row.setHeight((short) (attr.height() * 26)); + // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列. + if (attr.isExport()){ + // 创建cell + cell = row.createCell(column); + if(column>0&&column<3){ + cell.setCellStyle(styles.get("datas")); + }else{ + cell.setCellStyle(styles.get("data")); + } + + // 用于读取对象中的属性 + Object value = getTargetValue(vo, field, attr); + String dateFormat = attr.dateFormat(); + String readConverterExp = attr.readConverterExp(); + if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)){ + cell.setCellValue(DateUtils.parseDateToStr(dateFormat, (Date) value)); + } + else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)){ + cell.setCellValue(convertByExp(String.valueOf(value), readConverterExp)); + } + else{ + // 设置列类型 + setCellVo(value, attr, cell); + } + } + } + catch (Exception e) + { + log.error("导出Excel失败{}", e); + } + return cell; + } + + /** + * 设置 POI XSSFSheet 单元格提示 + * + * @param sheet 表单 + * @param promptTitle 提示标题 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setXSSFPrompt(Sheet sheet, String promptTitle, String promptContent, int firstRow, int endRow, + int firstCol, int endCol) + { + DataValidationHelper helper = sheet.getDataValidationHelper(); + DataValidationConstraint constraint = helper.createCustomConstraint("DD1"); + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + DataValidation dataValidation = helper.createValidation(constraint, regions); + dataValidation.createPromptBox(promptTitle, promptContent); + dataValidation.setShowPromptBox(true); + sheet.addValidationData(dataValidation); + } + + /** + * 设置某些列的值只能输入预制的数据,显示下拉框. + * + * @param sheet 要设置的sheet. + * @param textlist 下拉框显示的内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + * @return 设置好的sheet. + */ + public void setXSSFValidation(Sheet sheet, String[] textlist, int firstRow, int endRow, int firstCol, int endCol) + { + DataValidationHelper helper = sheet.getDataValidationHelper(); + // 加载下拉列表内容 + DataValidationConstraint constraint = helper.createExplicitListConstraint(textlist); + // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列 + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + // 数据有效性对象 + DataValidation dataValidation = helper.createValidation(constraint, regions); + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) + { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } + else + { + dataValidation.setSuppressDropDownArrow(false); + } + + sheet.addValidationData(dataValidation); + } + + /** + * 解析导出值 0=男,1=女,2=未知 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @return 解析后值 + * @throws Exception + */ + public static String convertByExp(String propertyValue, String converterExp) throws Exception + { + try + { + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (itemArray[0].equals(propertyValue)) + { + return itemArray[1]; + } + } + } + catch (Exception e) + { + throw e; + } + return propertyValue; + } + + /** + * 反向解析值 男=0,女=1,未知=2 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @return 解析后值 + * @throws Exception + */ + public static String reverseByExp(String propertyValue, String converterExp) throws Exception + { + try + { + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (itemArray[1].equals(propertyValue)) + { + return itemArray[0]; + } + } + } + catch (Exception e) + { + throw e; + } + return propertyValue; + } + + /** + * 编码文件名 + */ + public String encodingFilename(String filename){ +// filename = UUID.randomUUID().toString() + "_" + filename + ".xlsx"; + filename = filename + ".xlsx"; + return filename; + } + + /** + * 获取下载路径 + * + * @param filename 文件名称 + */ + public String getAbsoluteFile(String filename) + { + String downloadPath = EvoConfig.getDownloadPath() + filename; + File desc = new File(downloadPath); + if (!desc.getParentFile().exists()) + { + desc.getParentFile().mkdirs(); + } + return downloadPath; + } + + /** + * 获取bean中的属性值 + * + * @param vo 实体对象 + * @param field 字段 + * @param excel 注解 + * @return 最终的属性值 + * @throws Exception + */ + private Object getTargetValue(T vo, Field field, Excel excel) throws Exception + { + Object o = field.get(vo); + if (StringUtils.isNotEmpty(excel.targetAttr())) + { + String target = excel.targetAttr(); + if (target.indexOf(".") > -1) + { + String[] targets = target.split("[.]"); + for (String name : targets) + { + o = getValue(o, name); + } + } + else + { + o = getValue(o, target); + } + } + return o; + } + + /** + * 以类的属性的get方法方法形式获取值 + * + * @param o + * @param name + * @return value + * @throws Exception + */ + private Object getValue(Object o, String name) throws Exception + { + if (StringUtils.isNotEmpty(name)) + { + Class clazz = o.getClass(); + String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1); + Method method = clazz.getMethod(methodName); + o = method.invoke(o); + } + return o; + } + + /** + * 得到所有定义字段 + */ + private void createExcelField() + { + this.fields = new ArrayList(); + List tempFields = new ArrayList<>(); + tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); + tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); + for (Field field : tempFields) + { + // 单注解 + if (field.isAnnotationPresent(Excel.class)) + { + putToField(field, field.getAnnotation(Excel.class)); + } + + // 多注解 + if (field.isAnnotationPresent(Excels.class)) + { + Excels attrs = field.getAnnotation(Excels.class); + Excel[] excels = attrs.value(); + for (Excel excel : excels) + { + putToField(field, excel); + } + } + } + } + + /** + * 放到字段集合中 + */ + private void putToField(Field field, Excel attr) + { + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + this.fields.add(new Object[] { field, attr }); + } + } + + /** + * 创建一个工作簿 + */ + public void createWorkbook() + { + this.wb = new SXSSFWorkbook(500); + } + + /** + * 创建工作表 + * + * @param sheetNo sheet数量 + * @param index 序号 + */ + public void createSheet(double sheetNo, int index){ + this.sheet = wb.createSheet(); + this.styles = createStyles(wb); + // 设置工作表的名称. + if (index == 0){ + wb.setSheetName(index, sheetName); + }else if(index == 1){ + wb.setSheetName(index, sheetName2); + }else if(index == 2){ + wb.setSheetName(index, sheetName3); + }else if(index == 3){ + wb.setSheetName(index, sheetName4); + }else if(index == 4){ + wb.setSheetName(index, sheetName5); + }else if(index == 5){ + wb.setSheetName(index, sheetName6); + } + //设置横向打印 + sheet.getPrintSetup().setLandscape(true); + } + + /** + * 获取单元格值 + * + * @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.getCellTypeEnum() == CellType.NUMERIC || cell.getCellTypeEnum() == CellType.FORMULA) + { + val = cell.getNumericCellValue(); + if (HSSFDateUtil.isCellDateFormatted(cell)) + { + val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换 + } + else + { + if ((Double) val % 1 > 0) + { + val = new DecimalFormat("0.00").format(val); + } + else + { + val = new DecimalFormat("0").format(val); + } + } + } + else if (cell.getCellTypeEnum() == CellType.STRING) + { + val = cell.getStringCellValue(); + } + else if (cell.getCellTypeEnum() == CellType.BOOLEAN) + { + val = cell.getBooleanCellValue(); + } + else if (cell.getCellTypeEnum() == CellType.ERROR) + { + val = cell.getErrorCellValue(); + } + + } + } + catch (Exception e) + { + return val; + } + return val; + } + + public static ArrayList> readExcel2007(Sheet sheet) { + if(sheet==null){ + return null; + } + try { + ArrayList> rowList = new ArrayList>(); + ArrayList colList; + Row row; + Cell cell; + Object value; + for (int i = sheet.getFirstRowNum(), rowCount = 0; rowCount < sheet.getPhysicalNumberOfRows(); i++) { + row = sheet.getRow(i); + colList = new ArrayList(); + if (row == null) { + // 当读取行为空时 + if (i != sheet.getPhysicalNumberOfRows()) {// 判断是否是最后一行 + rowList.add(colList); + } + continue; + } else { + rowCount++; + } + for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) { + cell = row.getCell(j); + if (cell == null || cell.getCellType() == CellType.BLANK) { + // 当该单元格为空 + if (j != row.getLastCellNum()) {// 判断是否是该行中最后一个单元格 + colList.add(""); + } + continue; + } + switch (cell.getCellType()) { + case STRING: + // System.out.println(i + "行" + j + " 列 is String + // type"); + value = cell.getStringCellValue(); + break; + case NUMERIC: + if ("@".equals(cell.getCellStyle().getDataFormatString())) { + value = df.format(cell.getNumericCellValue()); + } else if ("General".equals(cell.getCellStyle().getDataFormatString())) { + value = nf.format(cell.getNumericCellValue()); + } else { + value = sdf.format(HSSFDateUtil.getJavaDate(cell.getNumericCellValue())); + } + // System.out.println(i + "行" + j + // + " 列 is Number type ; DateFormt:" + // + value.toString()); + break; + case BOOLEAN: + // System.out.println(i + "行" + j + " 列 is Boolean + // type"); + value = Boolean.valueOf(cell.getBooleanCellValue()); + break; + case BLANK: + // System.out.println(i + "行" + j + " 列 is Blank type"); + value = ""; + break; + default: + // System.out.println(i + "行" + j + " 列 is default + // type"); + value = cell.toString(); + }// end switch + colList.add(value); + } // end for j + rowList.add(colList); + } // end for i + + return rowList; + } catch (Exception e) { + System.out.println("exception"); + return null; + } + } + + public static DecimalFormat getDf() { + return df; + } + + public static void setDf(DecimalFormat df) { + ExcelUtils.df = df; + } + + public static SimpleDateFormat getSdf() { + return sdf; + } + + public static void setSdf(SimpleDateFormat sdf) { + ExcelUtils.sdf = sdf; + } + + public static DecimalFormat getNf() { + return nf; + } + + public static void setNf(DecimalFormat nf) { + ExcelUtils.nf = nf; + } +} diff --git a/evo-admin/src/main/java/com/evo/common/utils/reflect/ReflectUtils.java b/evo-admin/src/main/java/com/evo/common/utils/reflect/ReflectUtils.java new file mode 100644 index 0000000..2a6ca0c --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/reflect/ReflectUtils.java @@ -0,0 +1,410 @@ +package com.evo.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.evo.common.core.text.Convert; +import com.evo.common.utils.DateUtils; + +/** + * 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数. + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/common/utils/sign/Base64.java b/evo-admin/src/main/java/com/evo/common/utils/sign/Base64.java new file mode 100644 index 0000000..d26e6a4 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/sign/Base64.java @@ -0,0 +1,291 @@ +package com.evo.common.utils.sign; + +/** + * Base64工具类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/utils/sign/Md5Utils.java b/evo-admin/src/main/java/com/evo/common/utils/sign/Md5Utils.java new file mode 100644 index 0000000..269681d --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/sign/Md5Utils.java @@ -0,0 +1,67 @@ +package com.evo.common.utils.sign; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Md5加密方法 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/utils/spring/SpringUtils.java b/evo-admin/src/main/java/com/evo/common/utils/spring/SpringUtils.java new file mode 100644 index 0000000..f8ac726 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/spring/SpringUtils.java @@ -0,0 +1,158 @@ +package com.evo.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.evo.common.utils.StringUtils; + +/** + * spring工具类 方便在非spring管理环境中获取bean + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/common/utils/sql/SqlUtil.java b/evo-admin/src/main/java/com/evo/common/utils/sql/SqlUtil.java new file mode 100644 index 0000000..b8a9fe4 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/sql/SqlUtil.java @@ -0,0 +1,70 @@ +package com.evo.common.utils.sql; + +import com.evo.common.exception.UtilException; +import com.evo.common.utils.StringUtils; + +/** + * sql操作工具类 + * + * @author evo + */ +public class SqlUtil +{ + /** + * 定义常用的 sql关键字 + */ + public static String SQL_REGEX = "and |extractvalue|updatexml|sleep|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |union |like |+|/*|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/evo-admin/src/main/java/com/evo/common/utils/uuid/IdUtils.java b/evo-admin/src/main/java/com/evo/common/utils/uuid/IdUtils.java new file mode 100644 index 0000000..9944b7e --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/uuid/IdUtils.java @@ -0,0 +1,49 @@ +package com.evo.common.utils.uuid; + +/** + * ID生成器工具类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/utils/uuid/Seq.java b/evo-admin/src/main/java/com/evo/common/utils/uuid/Seq.java new file mode 100644 index 0000000..688c915 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/uuid/Seq.java @@ -0,0 +1,86 @@ +package com.evo.common.utils.uuid; + +import java.util.concurrent.atomic.AtomicInteger; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.StringUtils; + +/** + * @author evo 序列生成类 + */ +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/evo-admin/src/main/java/com/evo/common/utils/uuid/UUID.java b/evo-admin/src/main/java/com/evo/common/utils/uuid/UUID.java new file mode 100644 index 0000000..42bbcbb --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/uuid/UUID.java @@ -0,0 +1,484 @@ +package com.evo.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.evo.common.exception.UtilException; + +/** + * 提供通用唯一识别码(universally unique identifier)(UUID)实现 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/common/xss/Xss.java b/evo-admin/src/main/java/com/evo/common/xss/Xss.java new file mode 100644 index 0000000..fa15916 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/xss/Xss.java @@ -0,0 +1,27 @@ +package com.evo.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 evo + */ +@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/evo-admin/src/main/java/com/evo/common/xss/XssValidator.java b/evo-admin/src/main/java/com/evo/common/xss/XssValidator.java new file mode 100644 index 0000000..ea4c397 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/xss/XssValidator.java @@ -0,0 +1,39 @@ +package com.evo.common.xss; + +import com.evo.common.utils.StringUtils; +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 自定义xss校验注解实现 + * + * @author evo + */ +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(); + } +} diff --git a/evo-admin/src/main/java/com/evo/equipment/constant/Constants.java b/evo-admin/src/main/java/com/evo/equipment/constant/Constants.java new file mode 100644 index 0000000..7136b47 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/constant/Constants.java @@ -0,0 +1,21 @@ +package com.evo.equipment.constant; + +/** + * 通用常量信息 + * + * @author evo + */ +public class Constants +{ + public static final String BUTTON_ADDRESS = "D:/java/button"; //按钮存放地址 + public static final String STAFF_IMAGE_ADDRESS = "D:/java/image/"; //打卡人员图片存储地址 + public static final String STAFF_IMAGE_ADDRESS_ZIP = "D:/java/"; //打卡人员图片存储地址 + public static final String STAFF_BUTTON_URL = "http://192.168.5.12:8088/button/"; //打卡按钮图片存服务器获取地址 + public static final String STAFF_IMAGE_URL = "http://192.168.5.12:8088/image/"; //打卡人员图片存服务器获取地址 + public static final String STAFF_FUND_ADDRESS = "D:/lableExcel/"; //公积金存储地址 + public static final String EQ_DEVICE_CODE = "T71474"; //餐饮打卡机设备号 + public static final String EQ_DEVICE_PUBLIC_CODE = "ET74333"; //公共打卡机 + public static final String STAFF_IMAGE_URL_OVER_TIME = "http://192.168.5.12:8088/image/"; //打卡人员图片存服务器获取地址 + public static final String EQ_DEVICE_OVER_TIME_CODE = "ET74336"; //加班打卡机 +} + diff --git a/evo-admin/src/main/java/com/evo/equipment/controller/EqButtonController.java b/evo-admin/src/main/java/com/evo/equipment/controller/EqButtonController.java new file mode 100644 index 0000000..0c4f468 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/controller/EqButtonController.java @@ -0,0 +1,142 @@ +package com.evo.equipment.controller; + +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.SecurityUtils; +import com.evo.equipment.domain.EqButton; +import com.evo.equipment.service.IEqButtonService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.io.BufferedOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +/** + * 按钮信息Controller + * + * @author chenyj + * @date 2024-08-15 + */ +@RestController +@RequestMapping("/equipment/button") +public class EqButtonController extends BaseController +{ + @Autowired + private IEqButtonService eqButtonService; + + + + /** + * 查询按钮信息列表 + */ + @PreAuthorize("@ss.hasPermi('equipment:button:list')") + @GetMapping("/list") + public TableDataInfo list(EqButton eqButton) + { + startPage(); + List list = eqButtonService.selectEqButtonList(eqButton); + return getDataTable(list); + } + + /** + * 获取按钮信息详细信息 + */ + @PreAuthorize("@ss.hasPermi('equipment:button:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(eqButtonService.selectEqButtonById(id)); + } + + /** + * 新增按钮信息 + */ + @PreAuthorize("@ss.hasPermi('equipment:button:add')") + @RequestMapping("/uploadImage") + @ResponseBody + public AjaxResult uploadContractPDF(@RequestParam("name") String name, @RequestParam("file") MultipartFile filePath) { + String originalFilename = filePath.getOriginalFilename(); + if (originalFilename != null) { + //校验文件后缀 jpg jpeg pdf 格式的文件不允许上传 + String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1); + if (!"jpg".equals(suffix) && !"jpeg".equals(suffix) && !"png".equals(suffix) && !"pdf".equals(suffix)) { + return AjaxResult.error("禁止非法文件上传"); + } else { + EqButton eqButton = eqButtonService.selectEqButtonByName(name); + if(eqButton != null){ + return AjaxResult.error("添加按钮信息重复!"); + } + FileOutputStream fos = null; + BufferedOutputStream bos = null; + InputStream is = null; + try { + is = filePath.getInputStream(); + //在对应的文件夹下生成新的图片 + fos = new FileOutputStream(com.evo.equipment.constant.Constants.BUTTON_ADDRESS + "/" + originalFilename); + bos = new BufferedOutputStream(fos); + // 读取输入流并写入文件 + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = is.read(buffer)) != -1) { + bos.write(buffer, 0, bytesRead); + } + bos.flush(); + //插入表 + eqButton = new EqButton(); + eqButton.setCreateBy(SecurityUtils.getUsername()); + eqButton.setName(name); + eqButton.setImage(com.evo.equipment.constant.Constants.STAFF_BUTTON_URL + originalFilename); + eqButtonService.insertEqButton(eqButton); + } catch (IOException e) { + e.printStackTrace(); + return AjaxResult.error(); + }finally { + try{ + if(fos != null){ + fos.close(); + } + if(bos != null){ + bos.close(); + } + if(is != null){ + is.close(); + } + }catch (Exception e){ + e.printStackTrace(); + } + } + } + } + return AjaxResult.success(); + } + + /** + * 修改按钮信息 + */ + @PreAuthorize("@ss.hasPermi('equipment:button:edit')") + @Log(title = "按钮信息", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody EqButton eqButton) + { + return toAjax(eqButtonService.updateEqButton(eqButton)); + } + + /** + * 删除按钮信息 + */ + @PreAuthorize("@ss.hasPermi('equipment:button:remove')") + @Log(title = "按钮信息", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return eqButtonService.deleteEqButtonById(id,SecurityUtils.getUsername()); + } +} diff --git a/evo-admin/src/main/java/com/evo/equipment/controller/EqImagesController.java b/evo-admin/src/main/java/com/evo/equipment/controller/EqImagesController.java new file mode 100644 index 0000000..285efd7 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/controller/EqImagesController.java @@ -0,0 +1,91 @@ +package com.evo.equipment.controller; + +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.equipment.domain.EqImages; +import com.evo.equipment.service.IEqImagesService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.math.BigDecimal; +import java.util.List; + +/** + * 照片管理Controller + * + * @author chenyj + * @date 2024-08-28 + */ +@RestController +@RequestMapping("/equipment/images") +public class EqImagesController extends BaseController +{ + @Resource + private IEqImagesService eqImagesService; + + /** + * 查询照片管理列表 + */ + @PreAuthorize("@ss.hasPermi('equipment:images:list')") + @GetMapping("/list") + public TableDataInfo list(EqImages eqImages) + { + startPage(); + List list = eqImagesService.selectEqImagesList(eqImages); + return getDataTable(list); + } + + /** + * 导出模板 + */ + @PreAuthorize("@ss.hasPermi('equipment:images:export')") + @Log(title = "员工导入", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response) + { + ExcelUtil util = new ExcelUtil(EqImages.class); + util.exportExcel(response,null,"name"); + } + + /** + * 删除照片管理 + */ + @PreAuthorize("@ss.hasPermi('equipment:images:remove')") + @Log(title = "照片管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return toAjax(eqImagesService.deleteEqImagesById(id)); + } + + /** + * 上传员工照片 + */ + @RequestMapping("/uploadDispatchings") + @ResponseBody + public AjaxResult uploadPDF(@RequestParam("userId") Long userId, @RequestParam("staffName") String staffName, @RequestParam("timeClock") String timeClock,@RequestParam("hours") BigDecimal hours, @RequestParam("file") MultipartFile filePath){ + //新增员工图片 + EqImages eqImages = new EqImages(); + eqImages.setUserId(userId); + eqImages.setStaffName(staffName); + eqImages.setHours(hours); + eqImages.setTimeClock(timeClock); + return eqImagesService.insertEqImages(eqImages,filePath); + } + + /** + * 批量上传员工照片 + */ + @RequestMapping("/uploadBatchFile") + @ResponseBody + public AjaxResult uploadBatchFile(@RequestParam("file") MultipartFile filePath){ + + return eqImagesService.uploadBatchFile(filePath); + } +} diff --git a/evo-admin/src/main/java/com/evo/equipment/controller/EqSnDetailController.java b/evo-admin/src/main/java/com/evo/equipment/controller/EqSnDetailController.java new file mode 100644 index 0000000..4df0d8c --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/controller/EqSnDetailController.java @@ -0,0 +1,40 @@ +package com.evo.equipment.controller; + +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.page.TableDataInfo; +import com.evo.equipment.domain.EqSnDetail; +import com.evo.equipment.service.IEqSnDetailService; +import org.springframework.beans.factory.annotation.Autowired; +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 java.util.List; + +/** + * 考勤设备信息Controller + * + * @author chenyj + * @date 2024-08-07 + */ +@RestController +@RequestMapping("/equipment/snDetail") +public class EqSnDetailController extends BaseController +{ + @Autowired + private IEqSnDetailService EqSnDetailService; + + /** + * 查询考勤设备信息列表 + */ + @PreAuthorize("@ss.hasPermi('equipment:snDetail:list')") + @GetMapping("/list") + public TableDataInfo list(EqSnDetail EqSnDetail) + { + startPage(); + List list = EqSnDetailService.selectEqSnDetailList(EqSnDetail); + return getDataTable(list); + } + +} diff --git a/evo-admin/src/main/java/com/evo/equipment/controller/EqStatusTimeController.java b/evo-admin/src/main/java/com/evo/equipment/controller/EqStatusTimeController.java new file mode 100644 index 0000000..df57a7f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/controller/EqStatusTimeController.java @@ -0,0 +1,86 @@ +package com.evo.equipment.controller; + +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.SecurityUtils; +import com.evo.equipment.domain.EqStatusTime; +import com.evo.equipment.service.IEqStatusTimeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 状态时间Controller + * + * @author chenyj + * @date 2024-08-19 + */ +@RestController +@RequestMapping("/equipment/statusTime") +public class EqStatusTimeController extends BaseController +{ + @Autowired + private IEqStatusTimeService eqStatusTimeService; + + /** + * 查询状态时间列表 + */ + @PreAuthorize("@ss.hasPermi('equipment:statusTime:list')") + @GetMapping("/list") + public TableDataInfo list(EqStatusTime eqStatusTime) + { + startPage(); + List list = eqStatusTimeService.selectEqStatusTimeList(eqStatusTime); + return getDataTable(list); + } + + /** + * 获取状态时间详细信息 + */ + @PreAuthorize("@ss.hasPermi('equipment:statusTime:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(eqStatusTimeService.selectEqStatusTimeById(id)); + } + + /** + * 新增状态时间 + */ + @PreAuthorize("@ss.hasPermi('equipment:statusTime:add')") + @Log(title = "状态时间", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody EqStatusTime eqStatusTime) + { + eqStatusTime.setCreateBy(SecurityUtils.getUsername()); + return eqStatusTimeService.insertEqStatusTime(eqStatusTime); + } + + /** + * 修改状态时间 + */ + @PreAuthorize("@ss.hasPermi('equipment:statusTime:edit')") + @Log(title = "状态时间", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody EqStatusTime eqStatusTime) + { + eqStatusTime.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(eqStatusTimeService.updateEqStatusTime(eqStatusTime)); + } + + /** + * 删除状态时间 + */ + @PreAuthorize("@ss.hasPermi('equipment:statusTime:remove')") + @Log(title = "状态时间", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return toAjax(eqStatusTimeService.deleteEqStatusTimeById(id,SecurityUtils.getUsername())); + } +} diff --git a/evo-admin/src/main/java/com/evo/equipment/domain/EqButton.java b/evo-admin/src/main/java/com/evo/equipment/domain/EqButton.java new file mode 100644 index 0000000..b745d17 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/domain/EqButton.java @@ -0,0 +1,110 @@ +package com.evo.equipment.domain; + +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 按钮信息对象 eq_button + * + * @author chenyj + * @date 2024-08-15 + */ +public class EqButton extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 序号 */ + @Excel(name = "序号") + private String num; + + /** 按钮名称 */ + @Excel(name = "按钮名称") + private String name; + + /** 图标地址 */ + @Excel(name = "图标地址") + private String image; + + /** 删除标识 */ + private String delFlag; + + /** 备注 */ + @Excel(name = "备注") + private String remarks; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setNum(String num) + { + this.num = num; + } + + public String getNum() + { + return num; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setImage(String image) + { + this.image = image; + } + + public String getImage() + { + return image; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + public void setRemarks(String remarks) + { + this.remarks = remarks; + } + + public String getRemarks() + { + return remarks; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("num", getNum()) + .append("name", getName()) + .append("image", getImage()) + .append("delFlag", getDelFlag()) + .append("remarks", getRemarks()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/equipment/domain/EqImages.java b/evo-admin/src/main/java/com/evo/equipment/domain/EqImages.java new file mode 100644 index 0000000..9820fb7 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/domain/EqImages.java @@ -0,0 +1,120 @@ +package com.evo.equipment.domain; + +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.math.BigDecimal; + +/** + * 照片管理对象 eq_images + * + * @author chenyj + * @date 2024-08-28 + */ +public class EqImages extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Long id; + + /** 人员ID */ + @Excel(name = "员工ID") + private Long userId; + + /** 员工姓名 */ + @Excel(name = "员工姓名") + private String staffName; + + /** 照片地址 */ + @Excel(name = "照片地址") + private String imageUrl; + + @Excel(name = "工作时长") + private BigDecimal hours; + + @Excel(name = "打卡机") + private String timeClock; + + /** 删除标识 */ + private String delFlag; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public void setStaffName(String staffName) + { + this.staffName = staffName; + } + + public String getStaffName() + { + return staffName; + } + public void setImageUrl(String imageUrl) + { + this.imageUrl = imageUrl; + } + + public String getImageUrl() + { + return imageUrl; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + public BigDecimal getHours() { + return hours; + } + + public String getTimeClock() { + return timeClock; + } + + public void setTimeClock(String timeClock) { + this.timeClock = timeClock; + } + + public void setHours(BigDecimal hours) { + this.hours = hours; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("staffName", getStaffName()) + .append("imageUrl", getImageUrl()) + .append("timeClock", getTimeClock()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/equipment/domain/EqSnDetail.java b/evo-admin/src/main/java/com/evo/equipment/domain/EqSnDetail.java new file mode 100644 index 0000000..7a0dc91 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/domain/EqSnDetail.java @@ -0,0 +1,142 @@ +package com.evo.equipment.domain; + +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; + +/** + * 考勤设备信息对象 rz_sn_detail + * + * @author chenyj + * @date 2024-08-07 + */ +public class EqSnDetail extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 设备号 */ + @Excel(name = "设备号") + private String sn; + + /** 内部版本号 */ + @Excel(name = "内部版本号") + private String versionCode; + + /** 设备页面版本号 */ + @Excel(name = "设备页面版本号") + private String versionName; + + /** 设备ip */ + @Excel(name = "设备ip") + private String ip; + + /** 设备连接时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "设备连接时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date snTime; + + /** 设备连接状态 */ + @Excel(name = "设备连接状态") + private String type; + + /** 删除标识 */ + private String delFlag; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setSn(String sn) + { + this.sn = sn; + } + + public String getSn() + { + return sn; + } + public void setVersionCode(String versionCode) + { + this.versionCode = versionCode; + } + + public String getVersionCode() + { + return versionCode; + } + public void setVersionName(String versionName) + { + this.versionName = versionName; + } + + public String getVersionName() + { + return versionName; + } + public void setIp(String ip) + { + this.ip = ip; + } + + public String getIp() + { + return ip; + } + public void setSnTime(Date snTime) + { + this.snTime = snTime; + } + + public Date getSnTime() + { + return snTime; + } + public void setType(String type) + { + this.type = type; + } + + public String getType() + { + return type; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("sn", getSn()) + .append("versionCode", getVersionCode()) + .append("versionName", getVersionName()) + .append("ip", getIp()) + .append("snTime", getSnTime()) + .append("type", getType()) + .append("delFlag", getDelFlag()) + .append("createTime", getCreateTime()) + .append("createBy", getCreateBy()) + .append("updateTime", getUpdateTime()) + .append("updateBy", getUpdateBy()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/equipment/domain/EqStatusTime.java b/evo-admin/src/main/java/com/evo/equipment/domain/EqStatusTime.java new file mode 100644 index 0000000..9063f6d --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/domain/EqStatusTime.java @@ -0,0 +1,83 @@ +package com.evo.equipment.domain; + +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 状态时间对象 eq_status_time + * + * @author chenyj + * @date 2024-08-19 + */ +public class EqStatusTime extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 状态 */ + @Excel(name = "状态") + private String status; + + /** 时长(毫秒) */ + @Excel(name = "时长", readConverterExp = "毫=秒") + private Long time; + + /** 删除标识 */ + private String delFlag; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setStatus(String status) + { + this.status = status; + } + + public String getStatus() + { + return status; + } + public void setTime(Long time) + { + this.time = time; + } + + public Long getTime() + { + return time; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("status", getStatus()) + .append("time", getTime()) + .append("remark", getRemark()) + .append("delFlag", getDelFlag()) + .append("createTime", getCreateTime()) + .append("createBy", getCreateBy()) + .append("updateTime", getUpdateTime()) + .append("updateBy", getUpdateBy()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/equipment/domain/vo/CwBottonDto.java b/evo-admin/src/main/java/com/evo/equipment/domain/vo/CwBottonDto.java new file mode 100644 index 0000000..14c8a9f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/domain/vo/CwBottonDto.java @@ -0,0 +1,19 @@ +package com.evo.equipment.domain.vo; + +public class CwBottonDto { + + private String icon; + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + @Override + public String toString() { + return "CwBottonDto [icon=" + icon + "]"; + } +} diff --git a/evo-admin/src/main/java/com/evo/equipment/domain/vo/CwButtonData.java b/evo-admin/src/main/java/com/evo/equipment/domain/vo/CwButtonData.java new file mode 100644 index 0000000..8c1a4f3 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/domain/vo/CwButtonData.java @@ -0,0 +1,26 @@ +package com.evo.equipment.domain.vo; + +import java.util.List; + +public class CwButtonData { + + private String cmd; + private List value; + public String getCmd() { + return cmd; + } + public void setCmd(String cmd) { + this.cmd = cmd; + } + public List getValue() { + return value; + } + public void setValue(List value) { + this.value = value; + } + @Override + public String toString() { + return "CwButtonData [cmd=" + cmd + ", value=" + value + "]"; + } + +} diff --git a/evo-admin/src/main/java/com/evo/equipment/domain/vo/CwButtonVo.java b/evo-admin/src/main/java/com/evo/equipment/domain/vo/CwButtonVo.java new file mode 100644 index 0000000..6d8e4aa --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/domain/vo/CwButtonVo.java @@ -0,0 +1,56 @@ +package com.evo.equipment.domain.vo; + +public class CwButtonVo { + + private String cmd; + private String form; + private String to; + private CwButtonData data; + + + public String getCmd() { + return cmd; + } + + + public void setCmd(String cmd) { + this.cmd = cmd; + } + + + public String getForm() { + return form; + } + + + public void setForm(String form) { + this.form = form; + } + + + public String getTo() { + return to; + } + + + public void setTo(String to) { + this.to = to; + } + + + public CwButtonData getData() { + return data; + } + + + public void setData(CwButtonData data) { + this.data = data; + } + + + @Override + public String toString() { + return "CwButtonVo [cmd=" + cmd + ", form=" + form + ", to=" + to + ", data=" + data + "]"; + } + +} diff --git a/evo-admin/src/main/java/com/evo/equipment/domain/vo/RzStatusTimeData.java b/evo-admin/src/main/java/com/evo/equipment/domain/vo/RzStatusTimeData.java new file mode 100644 index 0000000..18eed51 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/domain/vo/RzStatusTimeData.java @@ -0,0 +1,68 @@ +package com.evo.equipment.domain.vo; + +public class RzStatusTimeData { + + private String cmd; + private int type_1; + private int type_2; + private int type_3; + private int type_4; + private int type_5; + private int type_6; + private int type_7; + public String getCmd() { + return cmd; + } + public void setCmd(String cmd) { + this.cmd = cmd; + } + public int getType_1() { + return type_1; + } + public void setType_1(int type_1) { + this.type_1 = type_1; + } + public int getType_2() { + return type_2; + } + public void setType_2(int type_2) { + this.type_2 = type_2; + } + public int getType_3() { + return type_3; + } + public void setType_3(int type_3) { + this.type_3 = type_3; + } + public int getType_4() { + return type_4; + } + public void setType_4(int type_4) { + this.type_4 = type_4; + } + public int getType_5() { + return type_5; + } + public void setType_5(int type_5) { + this.type_5 = type_5; + } + public int getType_6() { + return type_6; + } + public void setType_6(int type_6) { + this.type_6 = type_6; + } + public int getType_7() { + return type_7; + } + public void setType_7(int type_7) { + this.type_7 = type_7; + } + + @Override + public String toString() { + return "RzStatusTimeData [cmd=" + cmd + ", type_1=" + type_1 + ", type_2=" + type_2 + ", type_3=" + type_3 + + ", type_4=" + type_4 + ", type_5=" + type_5 + ", type_6=" + type_6 + ", type_7=" + type_7 + "]"; + } + +} diff --git a/evo-admin/src/main/java/com/evo/equipment/domain/vo/RzStatusTimeVo.java b/evo-admin/src/main/java/com/evo/equipment/domain/vo/RzStatusTimeVo.java new file mode 100644 index 0000000..d2ceebb --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/domain/vo/RzStatusTimeVo.java @@ -0,0 +1,39 @@ +package com.evo.equipment.domain.vo; + +public class RzStatusTimeVo { + + private String cmd; + private String form; + private String to; + private RzStatusTimeData data; + public String getCmd() { + return cmd; + } + public void setCmd(String cmd) { + this.cmd = cmd; + } + public String getForm() { + return form; + } + public void setForm(String form) { + this.form = form; + } + public String getTo() { + return to; + } + public void setTo(String to) { + this.to = to; + } + public RzStatusTimeData getData() { + return data; + } + public void setData(RzStatusTimeData data) { + this.data = data; + } + + @Override + public String toString() { + return "RzStatusTimeVo [cmd=" + cmd + ", form=" + form + ", to=" + to + ", data=" + data + "]"; + } + +} diff --git a/evo-admin/src/main/java/com/evo/equipment/domain/vo/StaffData.java b/evo-admin/src/main/java/com/evo/equipment/domain/vo/StaffData.java new file mode 100644 index 0000000..9826e2b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/domain/vo/StaffData.java @@ -0,0 +1,133 @@ +package com.evo.equipment.domain.vo; + +import java.util.List; + +public class StaffData { + + private String cmd; + private String user_id; + private String name; + private String tts_name; + private int edit_mode; + private String face_template; + private String effect_time; + private String id_valid; + private String Ic; + private float confidence_level; + private String phone; + private int mode; + private List valid_cycle; + private int user_type; + + public String getCmd() { + return cmd; + } + + public void setCmd(String cmd) { + this.cmd = cmd; + } + + public String getUser_id() { + return user_id; + } + + public void setUser_id(String user_id) { + this.user_id = user_id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getTts_name() { + return tts_name; + } + + public void setTts_name(String tts_name) { + this.tts_name = tts_name; + } + + public int getEdit_mode() { + return edit_mode; + } + + public void setEdit_mode(int edit_mode) { + this.edit_mode = edit_mode; + } + + public String getFace_template() { + return face_template; + } + + public void setFace_template(String face_template) { + this.face_template = face_template; + } + + public String getEffect_time() { + return effect_time; + } + + public void setEffect_time(String effect_time) { + this.effect_time = effect_time; + } + + public String getId_valid() { + return id_valid; + } + + public void setId_valid(String id_valid) { + this.id_valid = id_valid; + } + + public String getIc() { + return Ic; + } + + public void setIc(String ic) { + Ic = ic; + } + + public float getConfidence_level() { + return confidence_level; + } + + public void setConfidence_level(float confidence_level) { + this.confidence_level = confidence_level; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public int getMode() { + return mode; + } + + public void setMode(int mode) { + this.mode = mode; + } + + public List getValid_cycle() { + return valid_cycle; + } + + public void setValid_cycle(List valid_cycle) { + this.valid_cycle = valid_cycle; + } + + public int getUser_type() { + return user_type; + } + + public void setUser_type(int user_type) { + this.user_type = user_type; + } +} diff --git a/evo-admin/src/main/java/com/evo/equipment/domain/vo/StaffDto.java b/evo-admin/src/main/java/com/evo/equipment/domain/vo/StaffDto.java new file mode 100644 index 0000000..f74ccc2 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/domain/vo/StaffDto.java @@ -0,0 +1,50 @@ +package com.evo.equipment.domain.vo; + +public class StaffDto { + + private String cmd; + private String form; + private String to; + private String extra; + private StaffData data; + + public String getCmd() { + return cmd; + } + + public void setCmd(String cmd) { + this.cmd = cmd; + } + + public String getForm() { + return form; + } + + public void setForm(String form) { + this.form = form; + } + + public String getTo() { + return to; + } + + public void setTo(String to) { + this.to = to; + } + + public String getExtra() { + return extra; + } + + public void setExtra(String extra) { + this.extra = extra; + } + + public StaffData getData() { + return data; + } + + public void setData(StaffData data) { + this.data = data; + } +} diff --git a/evo-admin/src/main/java/com/evo/equipment/mapper/EqButtonMapper.java b/evo-admin/src/main/java/com/evo/equipment/mapper/EqButtonMapper.java new file mode 100644 index 0000000..29a11bd --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/mapper/EqButtonMapper.java @@ -0,0 +1,54 @@ +package com.evo.equipment.mapper; + +import com.evo.equipment.domain.EqButton; + +import java.util.List; + +/** + * 按钮信息Mapper接口 + * + * @author chenyj + * @date 2024-08-15 + */ +public interface EqButtonMapper +{ + /** + * 查询按钮信息 + * + * @param id 按钮信息主键 + * @return 按钮信息 + */ + public EqButton selectEqButtonById(Long id); + + /** + * 查询按钮信息列表 + * + * @param eqButton 按钮信息 + * @return 按钮信息集合 + */ + public List selectEqButtonList(EqButton eqButton); + + /** + * 新增按钮信息 + * + * @param eqButton 按钮信息 + * @return 结果 + */ + public int insertEqButton(EqButton eqButton); + + /** + * 修改按钮信息 + * + * @param eqButton 按钮信息 + * @return 结果 + */ + public int updateEqButton(EqButton eqButton); + /** + * 查询按钮信息 + * + * @param name 按钮信息主键 + * @return 按钮信息 + */ + public EqButton selectEqButtonByName(String name); + +} diff --git a/evo-admin/src/main/java/com/evo/equipment/mapper/EqImagesMapper.java b/evo-admin/src/main/java/com/evo/equipment/mapper/EqImagesMapper.java new file mode 100644 index 0000000..f5dd461 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/mapper/EqImagesMapper.java @@ -0,0 +1,54 @@ +package com.evo.equipment.mapper; + +import com.evo.equipment.domain.EqImages; + +import java.util.List; + +/** + * 照片管理Mapper接口 + * + * @author chenyj + * @date 2024-08-28 + */ +public interface EqImagesMapper +{ + /** + * 查询照片管理 + * + * @param id 照片管理主键 + * @return 照片管理 + */ + public EqImages selectEqImagesById(Long id); + + /** + * 查询照片管理列表 + * + * @param eqImages 照片管理 + * @return 照片管理集合 + */ + public List selectEqImagesList(EqImages eqImages); + + /** + * 新增照片管理 + * + * @param eqImages 照片管理 + * @return 结果 + */ + public int insertEqImages(EqImages eqImages); + + /** + * 修改照片管理 + * + * @param eqImages 照片管理 + * @return 结果 + */ + public int updateEqImages(EqImages eqImages); + + /** + * 根据员工ID查询照片管理 + * + * @param userId + * @return 照片管理 + */ + public EqImages selectEqImagesByStaffId(Long userId); +} diff --git a/evo-admin/src/main/java/com/evo/equipment/mapper/EqSnDetailMapper.java b/evo-admin/src/main/java/com/evo/equipment/mapper/EqSnDetailMapper.java new file mode 100644 index 0000000..cb12064 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/mapper/EqSnDetailMapper.java @@ -0,0 +1,45 @@ +package com.evo.equipment.mapper; + +import com.evo.equipment.domain.EqSnDetail; + +import java.util.List; + +/** + * 考勤设备信息Mapper接口 + * + * @author chenyj + * @date 2024-08-07 + */ +public interface EqSnDetailMapper +{ + /** + * 查询考勤设备信息列表 + * + * @param EqSnDetail 考勤设备信息 + * @return 考勤设备信息集合 + */ + public List selectEqSnDetailList(EqSnDetail EqSnDetail); + + /** + * 新增考勤设备信息 + * + * @param EqSnDetail 考勤设备信息 + * @return 结果 + */ + public int insertEqSnDetail(EqSnDetail EqSnDetail); + + /** + * 修改考勤设备信息 + * + * @param EqSnDetail 考勤设备信息 + * @return 结果 + */ + public int updateEqSnDetail(EqSnDetail EqSnDetail); + + /** + * 根据设备编号查询设备 + * @param sn + * @return + */ + public EqSnDetail selectEqSnDetailBySn(String sn); +} diff --git a/evo-admin/src/main/java/com/evo/equipment/mapper/EqStatusTimeMapper.java b/evo-admin/src/main/java/com/evo/equipment/mapper/EqStatusTimeMapper.java new file mode 100644 index 0000000..909a725 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/mapper/EqStatusTimeMapper.java @@ -0,0 +1,54 @@ +package com.evo.equipment.mapper; + +import com.evo.equipment.domain.EqStatusTime; + +import java.util.List; + +/** + * 状态时间Mapper接口 + * + * @author chenyj + * @date 2024-08-19 + */ +public interface EqStatusTimeMapper +{ + /** + * 查询状态时间 + * + * @param id 状态时间主键 + * @return 状态时间 + */ + public EqStatusTime selectEqStatusTimeById(Long id); + + /** + * 查询状态时间列表 + * + * @param eqStatusTime 状态时间 + * @return 状态时间集合 + */ + public List selectEqStatusTimeList(EqStatusTime eqStatusTime); + + /** + * 新增状态时间 + * + * @param eqStatusTime 状态时间 + * @return 结果 + */ + public int insertEqStatusTime(EqStatusTime eqStatusTime); + + /** + * 修改状态时间 + * + * @param eqStatusTime 状态时间 + * @return 结果 + */ + public int updateEqStatusTime(EqStatusTime eqStatusTime); + /** + * 查询状态时间 + * + * @param status 状态时间主键 + * @return 状态时间 + */ + public EqStatusTime selectEqStatusTimeByStatus(String status); + +} diff --git a/evo-admin/src/main/java/com/evo/equipment/service/IEqButtonService.java b/evo-admin/src/main/java/com/evo/equipment/service/IEqButtonService.java new file mode 100644 index 0000000..de6b582 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/service/IEqButtonService.java @@ -0,0 +1,63 @@ +package com.evo.equipment.service; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.equipment.domain.EqButton; + +import java.util.List; + +/** + * 按钮信息Service接口 + * + * @author chenyj + * @date 2024-08-15 + */ +public interface IEqButtonService +{ + /** + * 查询按钮信息 + * + * @param id 按钮信息主键 + * @return 按钮信息 + */ + public EqButton selectEqButtonById(Long id); + + /** + * 查询按钮信息列表 + * + * @param eqButton 按钮信息 + * @return 按钮信息集合 + */ + public List selectEqButtonList(EqButton eqButton); + + /** + * 新增按钮信息 + * + * @param eqButton 按钮信息 + * @return 结果 + */ + public AjaxResult insertEqButton(EqButton eqButton); + + /** + * 修改按钮信息 + * + * @param eqButton 按钮信息 + * @return 结果 + */ + public int updateEqButton(EqButton eqButton); + + /** + * 删除按钮信息信息 + * + * @param id 按钮信息主键 + * @return 结果 + */ + public AjaxResult deleteEqButtonById(Long id,String operName); + + /** + * 查询按钮信息 + * + * @param name 按钮信息主键 + * @return 按钮信息 + */ + public EqButton selectEqButtonByName(String name); +} diff --git a/evo-admin/src/main/java/com/evo/equipment/service/IEqImagesService.java b/evo-admin/src/main/java/com/evo/equipment/service/IEqImagesService.java new file mode 100644 index 0000000..f0a24a0 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/service/IEqImagesService.java @@ -0,0 +1,49 @@ +package com.evo.equipment.service; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.equipment.domain.EqImages; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + * 照片管理Service接口 + * + * @author chenyj + * @date 2024-08-28 + */ +public interface IEqImagesService +{ + + /** + * 查询照片管理列表 + * + * @param eqImages 照片管理 + * @return 照片管理集合 + */ + public List selectEqImagesList(EqImages eqImages); + + /** + * 新增照片管理 + * + * @param eqImages 照片管理 + * @return 结果 + */ + public AjaxResult insertEqImages(EqImages eqImages, MultipartFile filePath); + + /** + * 删除照片管理信息 + * + * @param id 照片管理主键 + * @return 结果 + */ + public int deleteEqImagesById(Long id); + + /** + * 批量上传照片 + * @param filePath + * @return + */ + public AjaxResult uploadBatchFile(MultipartFile filePath); + +} diff --git a/evo-admin/src/main/java/com/evo/equipment/service/IEqSnDetailService.java b/evo-admin/src/main/java/com/evo/equipment/service/IEqSnDetailService.java new file mode 100644 index 0000000..6b648a2 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/service/IEqSnDetailService.java @@ -0,0 +1,46 @@ +package com.evo.equipment.service; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.equipment.domain.EqSnDetail; + +import java.util.List; + +/** + * 考勤设备信息Service接口 + * + * @author chenyj + * @date 2024-08-07 + */ +public interface IEqSnDetailService +{ + /** + * 查询考勤设备信息列表 + * + * @param EqSnDetail 考勤设备信息 + * @return 考勤设备信息集合 + */ + public List selectEqSnDetailList(EqSnDetail EqSnDetail); + + /** + * 新增考勤设备信息 + * + * @param EqSnDetail 考勤设备信息 + * @return 结果 + */ + public AjaxResult insertEqSnDetail(EqSnDetail EqSnDetail); + + /** + * 修改考勤设备信息 + * + * @param EqSnDetail 考勤设备信息 + * @return 结果 + */ + public int updateEqSnDetail(EqSnDetail EqSnDetail); + + /** + * 根据设备编号查询设备 + * @param sn + * @return + */ + public EqSnDetail selectEqSnDetailBySn(String sn); +} diff --git a/evo-admin/src/main/java/com/evo/equipment/service/IEqStatusTimeService.java b/evo-admin/src/main/java/com/evo/equipment/service/IEqStatusTimeService.java new file mode 100644 index 0000000..b2294b4 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/service/IEqStatusTimeService.java @@ -0,0 +1,55 @@ +package com.evo.equipment.service; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.equipment.domain.EqStatusTime; + +import java.util.List; + +/** + * 状态时间Service接口 + * + * @author chenyj + * @date 2024-08-19 + */ +public interface IEqStatusTimeService +{ + /** + * 查询状态时间 + * + * @param id 状态时间主键 + * @return 状态时间 + */ + public EqStatusTime selectEqStatusTimeById(Long id); + + /** + * 查询状态时间列表 + * + * @param eqStatusTime 状态时间 + * @return 状态时间集合 + */ + public List selectEqStatusTimeList(EqStatusTime eqStatusTime); + + /** + * 新增状态时间 + * + * @param eqStatusTime 状态时间 + * @return 结果 + */ + public AjaxResult insertEqStatusTime(EqStatusTime eqStatusTime); + + /** + * 修改状态时间 + * + * @param eqStatusTime 状态时间 + * @return 结果 + */ + public int updateEqStatusTime(EqStatusTime eqStatusTime); + + /** + * 删除状态时间信息 + * + * @param id 状态时间主键 + * @return 结果 + */ + public int deleteEqStatusTimeById(Long id,String operName); +} diff --git a/evo-admin/src/main/java/com/evo/equipment/service/impl/EqButtonServiceImpl.java b/evo-admin/src/main/java/com/evo/equipment/service/impl/EqButtonServiceImpl.java new file mode 100644 index 0000000..5eb4e44 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/service/impl/EqButtonServiceImpl.java @@ -0,0 +1,208 @@ +package com.evo.equipment.service.impl; + +import com.alibaba.fastjson2.JSONObject; +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.equipment.domain.EqButton; +import com.evo.equipment.domain.EqSnDetail; +import com.evo.equipment.domain.vo.CwBottonDto; +import com.evo.equipment.domain.vo.CwButtonData; +import com.evo.equipment.domain.vo.CwButtonVo; +import com.evo.equipment.mapper.EqButtonMapper; +import com.evo.equipment.mapper.EqSnDetailMapper; +import com.evo.equipment.service.IEqButtonService; +import com.evo.framework.websocket.WebSocketUsers; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; + +/** + * 按钮信息Service业务层处理 + * + * @author chenyj + * @date 2024-11-15 + */ +@Service +public class EqButtonServiceImpl implements IEqButtonService +{ + @Resource + private EqButtonMapper eqButtonMapper; + @Resource + private EqSnDetailMapper EqSnDetailMapper; //考勤设备 + + /** + * 查询按钮信息 + * + * @param id 按钮信息主键 + * @return 按钮信息 + */ + @Override + public EqButton selectEqButtonById(Long id) + { + return eqButtonMapper.selectEqButtonById(id); + } + + /** + * 查询按钮信息列表 + * + * @param eqButton 按钮信息 + * @return 按钮信息 + */ + @Override + public List selectEqButtonList(EqButton eqButton) + { + return eqButtonMapper.selectEqButtonList(eqButton); + } + + /** + * 新增按钮信息 + * + * @param eqButton 按钮信息 + * @return 结果 + */ + @Override + public AjaxResult insertEqButton(EqButton eqButton) + { + //判断按钮的序号 + if("上班卡(单班制)".equals(eqButton.getName())){ + eqButton.setNum("1"); + }else if("上班卡(双班制)".equals(eqButton.getName())){ + eqButton.setNum("2"); + }else if("上班卡(三班制)".equals(eqButton.getName())){ + eqButton.setNum("3"); + }else if("加班卡".equals(eqButton.getName())){ + eqButton.setNum("4"); + }else if("下班卡".equals(eqButton.getName())){ + eqButton.setNum("5"); + }else if("撤销".equals(eqButton.getName())){ + eqButton.setNum("6"); + }else{ + return AjaxResult.error(); + } + eqButton.setCreateTime(DateUtils.getNowDate()); + eqButton.setDelFlag(Constants.DELETE_FLAG_0); + int i = eqButtonMapper.insertEqButton(eqButton); + if(i < 1){ + return AjaxResult.error(); + } + //下发按钮到打卡机器 ,获取所有打卡机 + List sn_list = EqSnDetailMapper.selectEqSnDetailList(null); + //获取所有打卡按钮 + List bt_list = eqButtonMapper.selectEqButtonList(null); + //需要返回的对象 + CwButtonVo cbv = null; + //发送的数据 + CwButtonData cbd = null; + //按钮对象 + CwBottonDto cwBottonDto = null; + //按钮集合 + List list2 = null; + for (EqSnDetail snDetail : sn_list) { + cbv = new CwButtonVo(); + cbd = new CwButtonData(); + list2 = new ArrayList(); + //该接口固定为to_device,发送给设备用于识别对应哪个指令 + cbv.setCmd("to_device"); + //无用值,空串 + cbv.setForm(""); + //设备号 + cbv.setTo(snDetail.getSn()); + //发送的数据 + cbd.setCmd("setButtons"); + for (EqButton button : bt_list) { + cwBottonDto = new CwBottonDto(); + cwBottonDto.setIcon(button.getImage()); + list2.add(cwBottonDto); + } + cbd.setValue(list2); + cbv.setData(cbd); + //调用websocket,推送给设备 + WebSocketUsers.sendMessageToUsersByText(JSONObject.toJSONString(cbv)); + } + + return AjaxResult.success(); + } + + /** + * 修改按钮信息 + * + * @param eqButton 按钮信息 + * @return 结果 + */ + @Override + public int updateEqButton(EqButton eqButton) + { + eqButton.setUpdateTime(DateUtils.getNowDate()); + eqButton.setUpdateBy(SecurityUtils.getUsername()); + return eqButtonMapper.updateEqButton(eqButton); + } + + /** + * 删除按钮信息信息 + * + * @param id 按钮信息主键 + * @return 结果 + */ + @Override + public AjaxResult deleteEqButtonById(Long id,String operName) + { + EqButton eqButton = eqButtonMapper.selectEqButtonById(id); + eqButton.setDelFlag(Constants.DELETE_FLAG_1); + eqButton.setUpdateTime(DateUtils.getNowDate()); + eqButton.setUpdateBy(operName); + int i =eqButtonMapper.updateEqButton(eqButton); + if(i < 1){ + return AjaxResult.error(); + } + //下发机器 ,获取所有打卡机 + List sn_list = EqSnDetailMapper.selectEqSnDetailList(null); + //获取所有打卡按钮 + List bt_list = eqButtonMapper.selectEqButtonList(null); + //需要返回的对象 + CwButtonVo cbv = null; + //发送的数据 + CwButtonData cbd = null; + //按钮对象 + CwBottonDto cwBottonDto = null; + //按钮集合 + List list2 = null; + for (EqSnDetail snDetail : sn_list) { + cbv = new CwButtonVo(); + cbd = new CwButtonData(); + list2 = new ArrayList(); + //该接口固定为to_device,发送给设备用于识别对应哪个指令 + cbv.setCmd("to_device"); + //无用值,空串 + cbv.setForm(""); + //设备号 + cbv.setTo(snDetail.getSn()); + //发送的数据 + cbd.setCmd("setButtons"); + for (EqButton button : bt_list) { + cwBottonDto = new CwBottonDto(); + cwBottonDto.setIcon(button.getImage()); + list2.add(cwBottonDto); + } + cbd.setValue(list2); + cbv.setData(cbd); + //调用websocket,推送给设备 + WebSocketUsers.sendMessageToUsersByText(JSONObject.toJSONString(cbv)); + } + return AjaxResult.success(); + } + + /** + * 查询按钮信息 + * + * @param name 按钮信息主键 + * @return 按钮信息 + */ + @Override + public EqButton selectEqButtonByName(String name){ + return eqButtonMapper.selectEqButtonByName(name); + } + +} diff --git a/evo-admin/src/main/java/com/evo/equipment/service/impl/EqImagesServiceImpl.java b/evo-admin/src/main/java/com/evo/equipment/service/impl/EqImagesServiceImpl.java new file mode 100644 index 0000000..b719e1c --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/service/impl/EqImagesServiceImpl.java @@ -0,0 +1,329 @@ +package com.evo.equipment.service.impl; + +import com.alibaba.fastjson2.JSONObject; +import com.evo.equipment.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.equipment.domain.EqImages; +import com.evo.equipment.domain.vo.StaffData; +import com.evo.equipment.domain.vo.StaffDto; +import com.evo.equipment.mapper.EqImagesMapper; +import com.evo.equipment.service.IEqImagesService; +import com.evo.framework.websocket.WebSocketUsers; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.usermodel.WorkbookFactory; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import javax.annotation.Resource; +import java.io.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +/** + * 照片管理Service业务层处理 + * + * @author chenyj + * @date 2024-08-28 + */ +@Service +public class EqImagesServiceImpl implements IEqImagesService +{ + @Resource + private EqImagesMapper eqImagesMapper; + + + /** + * 查询照片管理列表 + * + * @param eqImages 照片管理 + * @return 照片管理 + */ + @Override + public List selectEqImagesList(EqImages eqImages) + { + return eqImagesMapper.selectEqImagesList(eqImages); + } + + /** + * 新增照片管理 + * + * @param eqImages 照片管理 + * @return 结果 + */ + @Override + public AjaxResult insertEqImages(EqImages eqImages, MultipartFile filePath) + { + //根据员工ID查询是否已经添加照片 + EqImages image = eqImagesMapper.selectEqImagesByStaffId(eqImages.getUserId()); + if(StringUtils.isNotNull(image)){ + return AjaxResult.error(); + } + String originalFilename = filePath.getOriginalFilename(); + //校验文件后缀 + String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1); // 输出 "txt" + //判断是否是图片文件 + if(!"jpg".equals(suffix)&&!"jpeg".equals(suffix)&&!"png".equals(suffix)){ + return AjaxResult.error("禁止非法文件上传!"); + }else{ + //保存图片 + InputStream is = null; + FileOutputStream fos = null; + BufferedOutputStream bos = null; + try { + is = filePath.getInputStream(); + byte[] bytes = new byte[is.available()]; + is.read(bytes); + File file = new File(Constants.STAFF_IMAGE_ADDRESS+originalFilename); + fos = new FileOutputStream(file); + bos = new BufferedOutputStream(fos); + bos.write(bytes); + } catch (Exception e) { + e.printStackTrace(); + return AjaxResult.error(); + }finally { + try{ + if(StringUtils.isNotNull(bos)){ + bos.flush(); + bos.close(); + } + if(StringUtils.isNotNull(fos)){ + fos.close(); + } + if(StringUtils.isNotNull(is)){ + is.close(); + } + }catch (Exception e){ + e.printStackTrace(); + } + } + } + /** 上传打卡机 */ + //需要返回的对象 + StaffDto cau = new StaffDto(); + //发送的数据 + StaffData caud = new StaffData(); + + //定义公共打卡机 + List dkj_list = new ArrayList(); + dkj_list.add(Constants.EQ_DEVICE_CODE); //食堂 + dkj_list.add(Constants.EQ_DEVICE_PUBLIC_CODE); //公共 + dkj_list.add(eqImages.getTimeClock()); + + for (String s : dkj_list) { + //该接口固定为to_device,发送给设备用于识别对应哪个指令 + cau.setCmd("to_device"); + //无用值,空串 + cau.setForm(""); + //设备号 + cau.setTo(s); + //给服务端预留的补充字段,设备端不处理这个字段内容。设备在响应这条指令时原样返回 + cau.setExtra(""); + //发送的数据 + caud.setCmd("addUser"); + caud.setUser_id(eqImages.getUserId()+""); + caud.setName(eqImages.getStaffName()); + caud.setTts_name(""); + caud.setFace_template(Constants.STAFF_IMAGE_URL+originalFilename); + caud.setEffect_time(""); + caud.setId_valid(""); + caud.setIc(""); + caud.setPhone(""); + caud.setMode(0); + cau.setData(caud); + //调用websocket,推送给设备 + WebSocketUsers.sendMessageToUsersByText(JSONObject.toJSONString(cau)); + } + + //写入数据库 + eqImages.setImageUrl(Constants.STAFF_IMAGE_URL+originalFilename); + eqImages.setCreateBy(SecurityUtils.getUsername()); + eqImages.setCreateTime(DateUtils.getNowDate()); + eqImages.setDelFlag("0"); + int i = eqImagesMapper.insertEqImages(eqImages); + if(i < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } + + /** + * 删除照片管理信息 + * + * @param id 照片管理主键 + * @return 结果 + */ + @Override + public int deleteEqImagesById(Long id) + { + EqImages eqImages = eqImagesMapper.selectEqImagesById(id); + //需要推送的数据 + String message = ""; + //需要返回的对象 + StaffDto cau = new StaffDto(); + //发送的数据 + StaffData caud = new StaffData(); + //该接口固定为to_device,发送给设备用于识别对应哪个指令 + cau.setCmd("to_device"); + //无用值,空串 + cau.setForm(""); + //设备号 + cau.setTo(eqImages.getTimeClock()); + //给服务端预留的补充字段,设备端不处理这个字段内容。设备在响应这条指令时原样返回 + cau.setExtra(""); + //发送的数据 + caud.setCmd("delUser"); + caud.setUser_type(0); + caud.setUser_id(eqImages.getUserId()+""); + cau.setData(caud); + //调用websocket,推送给设备 + WebSocketUsers.sendMessageToUsersByText(JSONObject.toJSONString(cau)); + //删除照片 + String img_name = eqImages.getImageUrl().substring(eqImages.getImageUrl().lastIndexOf("/")+1); + File file = new File(Constants.STAFF_IMAGE_ADDRESS + img_name); + if(file.exists()){ + file.delete(); + } + eqImages.setDelFlag("1"); + eqImages.setUpdateTime(DateUtils.getNowDate()); + eqImages.setUpdateBy(SecurityUtils.getUsername()); + return eqImagesMapper.updateEqImages(eqImages); + } + + /** + * 批量上传照片 + * @param filePath + * @return + */ + public AjaxResult uploadBatchFile(MultipartFile filePath){ + //获取文件名称 + String originalFilename = filePath.getOriginalFilename(); + //校验文件后缀 + String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1); // 输出 "txt" + //判断是否是图片文件 + if(!"zip".equals(suffix)){ + return AjaxResult.error("禁止非法文件上传!"); + }else{ + //保存图片 + InputStream is = null; + FileOutputStream fos = null; + BufferedOutputStream bos = null; + try { + is = filePath.getInputStream(); + byte[] bytes = new byte[is.available()]; + is.read(bytes); + File file = new File(Constants.STAFF_IMAGE_ADDRESS+originalFilename); + fos = new FileOutputStream(file); + bos = new BufferedOutputStream(fos); + bos.write(bytes); + //解压压缩包 + ZipInputStream zip = new ZipInputStream(new FileInputStream(Constants.STAFF_IMAGE_ADDRESS+originalFilename)); + ZipEntry entry; + File c_file = new File(Constants.STAFF_IMAGE_ADDRESS_ZIP); + while((entry = zip.getNextEntry()) != null){ + if(entry.isDirectory()){ + File file1 = new File(c_file,entry.toString()); + }else{ + FileOutputStream filefos = new FileOutputStream(new File(c_file,entry.toString())); + int b; + while ((b = zip.read()) != -1){ + filefos.write(b); + } + //关闭流 + filefos.close(); + zip.closeEntry(); + } + } + zip.close(); + //读取excel文件,把信息解析生成地址 + File files = new File(Constants.STAFF_IMAGE_ADDRESS+"name.xlsx"); + if(!files.exists()){ + files = new File(Constants.STAFF_IMAGE_ADDRESS+"name.xls"); + } + Workbook wb = WorkbookFactory.create(files); + Sheet sheet = wb.getSheetAt(0); + EqImages eqImages = null; + /** 上传打卡机 */ + //需要返回的对象 + StaffDto cau = null; + //发送的数据 + StaffData caud = null; + + //定义公共打卡机 + List dkj_list = null; + + //循环获取数据 + for(int p = 1; p <= sheet.getLastRowNum(); p++){ + //得到行 + Row row = sheet.getRow(p); + if(StringUtils.isNotNull(row)){ + dkj_list = new ArrayList(); + dkj_list.add(Constants.EQ_DEVICE_CODE); //食堂 + dkj_list.add(Constants.EQ_DEVICE_PUBLIC_CODE); //公共 + dkj_list.add(row.getCell(4).getStringCellValue()); + cau = new StaffDto(); + caud = new StaffData(); + for (String s : dkj_list) { + //该接口固定为to_device,发送给设备用于识别对应哪个指令 + cau.setCmd("to_device"); + //无用值,空串 + cau.setForm(""); + //设备号 + cau.setTo(s); + //给服务端预留的补充字段,设备端不处理这个字段内容。设备在响应这条指令时原样返回 + cau.setExtra(""); + //发送的数据 + caud.setCmd("addUser"); + caud.setUser_id(row.getCell(0).getNumericCellValue()+""); + caud.setName(row.getCell(1).getStringCellValue()); + caud.setTts_name(""); + caud.setFace_template(Constants.STAFF_IMAGE_URL+row.getCell(2).getStringCellValue()); + caud.setEffect_time(""); + caud.setId_valid(""); + caud.setIc(""); + caud.setPhone(""); + caud.setMode(0); + cau.setData(caud); + //调用websocket,推送给设备 + WebSocketUsers.sendMessageToUsersByText(JSONObject.toJSONString(cau)); + } + eqImages = new EqImages(); + Double formatString = row.getCell(0).getNumericCellValue(); + eqImages.setUserId(formatString.longValue()); + eqImages.setStaffName(row.getCell(1).getStringCellValue()); + eqImages.setImageUrl(Constants.STAFF_IMAGE_URL+row.getCell(2).getStringCellValue()); + eqImages.setDelFlag("0"); + eqImages.setCreateBy(SecurityUtils.getUsername()); + eqImages.setCreateTime(new Date()); + eqImagesMapper.insertEqImages(eqImages); + } + } + } catch (Exception e) { + e.printStackTrace(); + return AjaxResult.error(); + }finally { + try{ + if(StringUtils.isNotNull(bos)){ + bos.flush(); + bos.close(); + } + if(StringUtils.isNotNull(fos)){ + fos.close(); + } + if(StringUtils.isNotNull(is)){ + is.close(); + } + }catch (Exception e){ + e.printStackTrace(); + } + } + } + return AjaxResult.success(); + } +} diff --git a/evo-admin/src/main/java/com/evo/equipment/service/impl/EqSnDetailServiceImpl.java b/evo-admin/src/main/java/com/evo/equipment/service/impl/EqSnDetailServiceImpl.java new file mode 100644 index 0000000..677afb1 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/service/impl/EqSnDetailServiceImpl.java @@ -0,0 +1,84 @@ +package com.evo.equipment.service.impl; + +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.StringUtils; +import com.evo.equipment.domain.EqSnDetail; +import com.evo.equipment.mapper.EqSnDetailMapper; +import com.evo.equipment.service.IEqSnDetailService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 考勤设备信息Service业务层处理 + * + * @author chenyj + * @date 2024-08-07 + */ +@Service +public class EqSnDetailServiceImpl implements IEqSnDetailService +{ + @Resource + private EqSnDetailMapper EqSnDetailMapper; + + /** + * 查询考勤设备信息列表 + * + * @param EqSnDetail 考勤设备信息 + * @return 考勤设备信息 + */ + @Override + public List selectEqSnDetailList(EqSnDetail EqSnDetail) + { + return EqSnDetailMapper.selectEqSnDetailList(EqSnDetail); + } + + /** + * 新增考勤设备信息 + * + * @param EqSnDetail 考勤设备信息 + * @return 结果 + */ + @Override + public AjaxResult insertEqSnDetail(EqSnDetail EqSnDetail) + { + //判断设备是否添加 + EqSnDetail sbSn = EqSnDetailMapper.selectEqSnDetailBySn(EqSnDetail.getSn()); + if(StringUtils.isNotNull(sbSn)){ + return AjaxResult.error(); + } + EqSnDetail.setCreateTime(DateUtils.getNowDate()); + EqSnDetail.setDelFlag(Constants.DELETE_FLAG_0); + int i = EqSnDetailMapper.insertEqSnDetail(EqSnDetail); + if(i < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } + + /** + * 修改考勤设备信息 + * + * @param EqSnDetail 考勤设备信息 + * @return 结果 + */ + @Override + public int updateEqSnDetail(EqSnDetail EqSnDetail) + { + EqSnDetail.setUpdateTime(DateUtils.getNowDate()); + return EqSnDetailMapper.updateEqSnDetail(EqSnDetail); + } + + /** + * 根据设备编号查询设备 + * @param sn + * @return + */ + @Override + public EqSnDetail selectEqSnDetailBySn(String sn){ + return EqSnDetailMapper.selectEqSnDetailBySn(sn); + } +} diff --git a/evo-admin/src/main/java/com/evo/equipment/service/impl/EqStatusTimeServiceImpl.java b/evo-admin/src/main/java/com/evo/equipment/service/impl/EqStatusTimeServiceImpl.java new file mode 100644 index 0000000..d31e582 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/equipment/service/impl/EqStatusTimeServiceImpl.java @@ -0,0 +1,155 @@ +package com.evo.equipment.service.impl; + +import com.alibaba.fastjson2.JSONObject; +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.StringUtils; +import com.evo.equipment.domain.EqSnDetail; +import com.evo.equipment.domain.EqStatusTime; +import com.evo.equipment.domain.vo.RzStatusTimeData; +import com.evo.equipment.domain.vo.RzStatusTimeVo; +import com.evo.equipment.mapper.EqSnDetailMapper; +import com.evo.equipment.mapper.EqStatusTimeMapper; +import com.evo.equipment.service.IEqStatusTimeService; +import com.evo.framework.websocket.WebSocketUsers; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import java.util.List; + +/** + * 状态时间Service业务层处理 + * + * @author chenyj + * @date 2024-08-19 + */ +@Service +public class EqStatusTimeServiceImpl implements IEqStatusTimeService +{ + @Resource + private EqStatusTimeMapper eqStatusTimeMapper; + @Resource + private EqSnDetailMapper EqSnDetailMapper; //设备信息 + + /** + * 查询状态时间 + * + * @param id 状态时间主键 + * @return 状态时间 + */ + @Override + public EqStatusTime selectEqStatusTimeById(Long id) + { + return eqStatusTimeMapper.selectEqStatusTimeById(id); + } + + /** + * 查询状态时间列表 + * + * @param eqStatusTime 状态时间 + * @return 状态时间 + */ + @Override + public List selectEqStatusTimeList(EqStatusTime eqStatusTime) + { + return eqStatusTimeMapper.selectEqStatusTimeList(eqStatusTime); + } + + /** + * 新增状态时间 + * + * @param eqStatusTime 状态时间 + * @return 结果 + */ + @Override + public AjaxResult insertEqStatusTime(EqStatusTime eqStatusTime) + { + EqStatusTime stime = eqStatusTimeMapper.selectEqStatusTimeByStatus(eqStatusTime.getStatus()); + if(StringUtils.isNotNull(stime)){ + return AjaxResult.error(); + } + //发送信息到机器 + sendMessageToDevice(eqStatusTime); + eqStatusTime.setCreateTime(DateUtils.getNowDate()); + eqStatusTime.setDelFlag(Constants.DELETE_FLAG_0); + int i = eqStatusTimeMapper.insertEqStatusTime(eqStatusTime); + if(i < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } + + /** + * 修改状态时间 + * + * @param eqStatusTime 状态时间 + * @return 结果 + */ + @Override + public int updateEqStatusTime(EqStatusTime eqStatusTime) + { + //判断不是删除执行 + if(Constants.DELETE_FLAG_0.equals(eqStatusTime.getDelFlag())){ + //发送信息到机器 + sendMessageToDevice(eqStatusTime); + } + eqStatusTime.setUpdateTime(DateUtils.getNowDate()); + return eqStatusTimeMapper.updateEqStatusTime(eqStatusTime); + } + + /** + * 删除状态时间信息 + * + * @param id 状态时间主键 + * @return 结果 + */ + @Override + public int deleteEqStatusTimeById(Long id,String operName) + { + EqStatusTime eqStatusTime = eqStatusTimeMapper.selectEqStatusTimeById(id); + eqStatusTime.setDelFlag(Constants.DELETE_FLAG_1); + eqStatusTime.setUpdateBy(operName); + return updateEqStatusTime(eqStatusTime); + } + + /** + * 发送状态信息到机器 + * @param eqStatusTime + */ + private void sendMessageToDevice(EqStatusTime eqStatusTime){ + //需要返回的对象 + RzStatusTimeVo cttv = new RzStatusTimeVo(); + //发送的数据 + RzStatusTimeData cttd = new RzStatusTimeData(); + //获取所有设备 + List list = EqSnDetailMapper.selectEqSnDetailList(null); + for (EqSnDetail eqSnDetail : list) { + //该接口固定为to_device,发送给设备用于识别对应哪个指令 + cttv.setCmd("to_device"); + //无用值,空串 + cttv.setForm(""); + //设备号 + cttv.setTo(eqSnDetail.getSn()); + //发送的数据 + cttd.setCmd("setTimeout"); + if("待机状态".equals(eqStatusTime.getStatus())){ + cttd.setType_1(eqStatusTime.getTime().intValue()); + }else if("人脸识别状态".equals(eqStatusTime.getStatus())){ + cttd.setType_2(eqStatusTime.getTime().intValue()); + }else if("功能选择状态".equals(eqStatusTime.getStatus())){ + cttd.setType_3(eqStatusTime.getTime().intValue()); + }else if("打卡等待状态".equals(eqStatusTime.getStatus())){ + cttd.setType_4(eqStatusTime.getTime().intValue()); + }else if("打卡完成状态".equals(eqStatusTime.getStatus())){ + cttd.setType_5(eqStatusTime.getTime().intValue()); + }else if("打卡失败状态".equals(eqStatusTime.getStatus())){ + cttd.setType_6(eqStatusTime.getTime().intValue()); + }else{ + cttd.setType_7(eqStatusTime.getTime().intValue()); + } + cttv.setData(cttd); + //调用websocket,推送给设备 + WebSocketUsers.sendMessageToUsersByText(JSONObject.toJSONString(cttv)); + } + } +} diff --git a/evo-admin/src/main/java/com/evo/finance/controller/RzSalaryDetailController.java b/evo-admin/src/main/java/com/evo/finance/controller/RzSalaryDetailController.java new file mode 100644 index 0000000..4260a1b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/finance/controller/RzSalaryDetailController.java @@ -0,0 +1,495 @@ +package com.evo.finance.controller; + +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.List; +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.entity.SysDept; +import com.evo.common.core.domain.entity.SysDictData; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.poi.ExcelUtilSs; +import com.evo.finance.domain.vo.SalaryVo; +import com.evo.system.mapper.SysDictDataMapper; +import com.evo.system.service.ISysDeptService; +import org.springframework.beans.BeanUtils; +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.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.enums.BusinessType; +import com.evo.finance.domain.RzSalaryDetail; +import com.evo.finance.service.IRzSalaryDetailService; +import com.evo.common.core.page.TableDataInfo; +import javax.annotation.Resource; + +/** + * 工资详情Controller + * + * @author evo + * @date 2024-11-26 + */ +@RestController +@RequestMapping("/finance/financeDetail") +public class RzSalaryDetailController extends BaseController +{ + @Autowired + private IRzSalaryDetailService rzSalaryDetailService; + @Autowired + private ISysDeptService deptService; //部门 + @Resource + private SysDictDataMapper sysDictDataMapper; //数据字典 + + /** + * 查询工资详情列表 + */ + @PreAuthorize("@ss.hasPermi('finance:financeDetail:list')") + @GetMapping("/list") + public TableDataInfo list(RzSalaryDetail rzSalaryDetail) + { + startPage(); + List list = rzSalaryDetailService.selectRzSalaryDetailList(rzSalaryDetail); + return getDataTable(list); + } + + /** + * 获取工资详情详细信息 + */ + @PreAuthorize("@ss.hasPermi('finance:financeDetail:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(rzSalaryDetailService.selectRzSalaryDetailById(id)); + } + + /** + * 新增工资详情 + */ + @PreAuthorize("@ss.hasPermi('finance:financeDetail:add')") + @Log(title = "工资详情", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody RzSalaryDetail rzSalaryDetail) + { + return rzSalaryDetailService.insertRzSalaryDetail(rzSalaryDetail); + } + + /** + * 修改工资详情 + */ + @PreAuthorize("@ss.hasPermi('finance:financeDetail:edit')") + @Log(title = "工资详情", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody RzSalaryDetail rzSalaryDetail) + { + return toAjax(rzSalaryDetailService.updateRzSalaryDetail(rzSalaryDetail)); + } + + /** + * 删除工资详情 + */ + @PreAuthorize("@ss.hasPermi('finance:financeDetail:remove')") + @Log(title = "工资详情", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return toAjax(rzSalaryDetailService.deleteRzSalaryDetailById(id)); + } + + /** + * 导出工资详情列表 + */ + @PreAuthorize("@ss.hasPermi('finance:financeDetail:export')") + @Log(title = "工资详情", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public AjaxResult export(RzSalaryDetail rzSalaryDetail) + { + ExcelUtilSs util = new ExcelUtilSs(SalaryVo.class); + //创建总表 + List list = new ArrayList(); + //创建各个公司的数据 + List> lists = new ArrayList<>(); + //创建各个部门sheetname集合 + List sheetNameList = new ArrayList<>(); + //汇总表表头 + String title = new SimpleDateFormat("yyyy-MM").format(rzSalaryDetail.getMonth())+"月工资汇总表"; + //获取所有的最小独立部门 + List dept_list = deptService.queryAllDeptForMin(); + //员工工资信息 + SalaryVo salaryVo = null; + //工资数据转化的保存 + List list0 =new ArrayList(); + for (SysDept sysDept : dept_list) { + sheetNameList.add(sysDept.getDeptName()); + //部门小计 + SalaryVo xj_salaryVo = new SalaryVo(); + xj_salaryVo.setName("小计:"); + //查询部门下的数据 + List pay_list = rzSalaryDetailService.selectSalaryDetailByDeptId(sysDept.getDeptId(),rzSalaryDetail.getMonth()); + for (RzSalaryDetail salaryDetail : pay_list) { + salaryVo = new SalaryVo(); + if(StringUtils.isNull(xj_salaryVo.getBasicSalary())){ + xj_salaryVo.setBasicSalary(new BigDecimal("0.00")); + } + xj_salaryVo.setBasicSalary(xj_salaryVo.getBasicSalary().add(salaryDetail.getBasicSalary())); + if(StringUtils.isNull(xj_salaryVo.getOvertimeSalary())){ + xj_salaryVo.setOvertimeSalary(new BigDecimal("0.00")); + } + xj_salaryVo.setOvertimeSalary(xj_salaryVo.getOvertimeSalary().add(salaryDetail.getOvertimeSalary())); + if(StringUtils.isNull(xj_salaryVo.getLevelSubsidies())){ + xj_salaryVo.setLevelSubsidies(new BigDecimal("0.00")); + } + xj_salaryVo.setLevelSubsidies(xj_salaryVo.getLevelSubsidies().add(salaryDetail.getLevelSubsidies())); + if(StringUtils.isNull(xj_salaryVo.getContractSubsidies())){ + xj_salaryVo.setContractSubsidies(new BigDecimal("0.00")); + } + xj_salaryVo.setContractSubsidies(xj_salaryVo.getContractSubsidies().add(salaryDetail.getContractSubsidies())); + if(StringUtils.isNull(xj_salaryVo.getSenioritySalary())){ + xj_salaryVo.setSenioritySalary(new BigDecimal("0.00")); + } + xj_salaryVo.setSenioritySalary(xj_salaryVo.getSenioritySalary().add(salaryDetail.getSenioritySalary())); + if(StringUtils.isNull(xj_salaryVo.getSocialSubsidies())){ + xj_salaryVo.setSocialSubsidies(new BigDecimal("0.00")); + } + xj_salaryVo.setSocialSubsidies(xj_salaryVo.getSocialSubsidies().add(salaryDetail.getSocialSubsidies())); + if(StringUtils.isNull(xj_salaryVo.getFullSubsidies())){ + xj_salaryVo.setFullSubsidies(new BigDecimal("0.00")); + } + xj_salaryVo.setFullSubsidies(xj_salaryVo.getFullSubsidies().add(salaryDetail.getFullSubsidies())); + if(StringUtils.isNull(xj_salaryVo.getNightSubsidies())){ + xj_salaryVo.setNightSubsidies(new BigDecimal("0.00")); + } + xj_salaryVo.setNightSubsidies(xj_salaryVo.getNightSubsidies().add(salaryDetail.getNightSubsidies())); + if(StringUtils.isNull(xj_salaryVo.getDinnerSubsidies())){ + xj_salaryVo.setDinnerSubsidies(new BigDecimal("0.00")); + } + xj_salaryVo.setDinnerSubsidies(xj_salaryVo.getDinnerSubsidies().add(salaryDetail.getDinnerSubsidies())); + if(StringUtils.isNull(xj_salaryVo.getSubsidyOrBonus())){ + xj_salaryVo.setSubsidyOrBonus(new BigDecimal("0.00")); + } + xj_salaryVo.setSubsidyOrBonus(xj_salaryVo.getSubsidyOrBonus().add(salaryDetail.getSubsidyOrBonus())); + if(StringUtils.isNull(xj_salaryVo.getAbsenteeismSalary())){ + xj_salaryVo.setAbsenteeismSalary(new BigDecimal("0.00")); + } + xj_salaryVo.setAbsenteeismSalary(xj_salaryVo.getAbsenteeismSalary().add(salaryDetail.getAbsenteeismSalary())); + if(StringUtils.isNull(xj_salaryVo.getAbsenteeismSubsidies())){ + xj_salaryVo.setAbsenteeismSubsidies(new BigDecimal("0.00")); + } + xj_salaryVo.setAbsenteeismSubsidies(xj_salaryVo.getAbsenteeismSubsidies().add(salaryDetail.getAbsenteeismSubsidies())); + if(StringUtils.isNull(xj_salaryVo.getMealFee())){ + xj_salaryVo.setMealFee(new BigDecimal("0.00")); + } + xj_salaryVo.setMealFee(xj_salaryVo.getMealFee().add(salaryDetail.getMealFee())); + if(StringUtils.isNull(xj_salaryVo.getDeductions())){ + xj_salaryVo.setDeductions(new BigDecimal("0.00")); + } + xj_salaryVo.setDeductions(xj_salaryVo.getDeductions().add(salaryDetail.getDeductions())); + if(StringUtils.isNull(xj_salaryVo.getSalary())){ + xj_salaryVo.setSalary(new BigDecimal("0.00")); + } + xj_salaryVo.setSalary(xj_salaryVo.getSalary().add(salaryDetail.getSalary())); + if(StringUtils.isNull(xj_salaryVo.getPayInsurance())){ + xj_salaryVo.setPayInsurance(new BigDecimal("0.00")); + } + xj_salaryVo.setPayInsurance(xj_salaryVo.getPayInsurance().add(salaryDetail.getPayInsurance())); + if(StringUtils.isNull(xj_salaryVo.getSalaryBeforeTax())){ + xj_salaryVo.setSalaryBeforeTax(new BigDecimal("0.00")); + } + xj_salaryVo.setSalaryBeforeTax(xj_salaryVo.getSalaryBeforeTax().add(salaryDetail.getSalaryBeforeTax())); + if(StringUtils.isNull(xj_salaryVo.getTotalWages())){ + xj_salaryVo.setTotalWages(new BigDecimal("0.00")); + } + xj_salaryVo.setTotalWages(xj_salaryVo.getTotalWages().add(salaryDetail.getTotalWages())); + if(StringUtils.isNull(xj_salaryVo.getAnnualExemptionAmount())){ + xj_salaryVo.setAnnualExemptionAmount(new BigDecimal("0.00")); + } + xj_salaryVo.setAnnualExemptionAmount(xj_salaryVo.getAnnualExemptionAmount().add(salaryDetail.getAnnualExemptionAmount())); + if(StringUtils.isNull(xj_salaryVo.getSpecialDeduction())){ + xj_salaryVo.setSpecialDeduction(new BigDecimal("0.00")); + } + xj_salaryVo.setSpecialDeduction(xj_salaryVo.getSpecialDeduction().add(salaryDetail.getSpecialDeduction())); + if(StringUtils.isNull(xj_salaryVo.getSlowDownTheDeduction())){ + xj_salaryVo.setSlowDownTheDeduction(new BigDecimal("0.00")); + } + xj_salaryVo.setSlowDownTheDeduction(xj_salaryVo.getSlowDownTheDeduction().add(salaryDetail.getSlowDownTheDeduction())); + if(StringUtils.isNull(xj_salaryVo.getAggregatePersonalIncomeTax())){ + xj_salaryVo.setAggregatePersonalIncomeTax(new BigDecimal("0.00")); + } + xj_salaryVo.setAggregatePersonalIncomeTax(xj_salaryVo.getAggregatePersonalIncomeTax().add(salaryDetail.getAggregatePersonalIncomeTax())); + if(StringUtils.isNull(xj_salaryVo.getTaxPayable())){ + xj_salaryVo.setTaxPayable(new BigDecimal("0.00")); + } + xj_salaryVo.setTaxPayable(xj_salaryVo.getTaxPayable().add(salaryDetail.getTaxPayable())); + if(StringUtils.isNull(xj_salaryVo.getNetPayroll())){ + xj_salaryVo.setNetPayroll(new BigDecimal("0.00")); + } + xj_salaryVo.setNetPayroll(xj_salaryVo.getNetPayroll().add(salaryDetail.getNetPayroll())); + BeanUtils.copyProperties(salaryDetail, salaryVo); + salaryVo.setDeptName(sysDept.getDeptName()); + list0.add(salaryVo); + } + list0.add(xj_salaryVo); + lists.add(list0); + list.add(xj_salaryVo); + } + //计算伊特总计数据 + SalaryVo gj_salaryVo = new SalaryVo(); + for (SalaryVo salaryVoz : list) { + if(StringUtils.isNull(gj_salaryVo.getBasicSalary())){ + gj_salaryVo.setBasicSalary(new BigDecimal("0.00")); + } + gj_salaryVo.setBasicSalary(gj_salaryVo.getBasicSalary().add(salaryVoz.getBasicSalary())); + if(StringUtils.isNull(gj_salaryVo.getOvertimeSalary())){ + gj_salaryVo.setOvertimeSalary(new BigDecimal("0.00")); + } + gj_salaryVo.setOvertimeSalary(gj_salaryVo.getOvertimeSalary().add(salaryVoz.getOvertimeSalary())); + if(StringUtils.isNull(gj_salaryVo.getLevelSubsidies())){ + gj_salaryVo.setLevelSubsidies(new BigDecimal("0.00")); + } + gj_salaryVo.setLevelSubsidies(gj_salaryVo.getLevelSubsidies().add(salaryVoz.getLevelSubsidies())); + if(StringUtils.isNull(gj_salaryVo.getContractSubsidies())){ + gj_salaryVo.setContractSubsidies(new BigDecimal("0.00")); + } + gj_salaryVo.setContractSubsidies(gj_salaryVo.getContractSubsidies().add(salaryVoz.getContractSubsidies())); + if(StringUtils.isNull(gj_salaryVo.getSenioritySalary())){ + gj_salaryVo.setSenioritySalary(new BigDecimal("0.00")); + } + gj_salaryVo.setSenioritySalary(gj_salaryVo.getSenioritySalary().add(salaryVoz.getSenioritySalary())); + if(StringUtils.isNull(gj_salaryVo.getSocialSubsidies())){ + gj_salaryVo.setSocialSubsidies(new BigDecimal("0.00")); + } + gj_salaryVo.setSocialSubsidies(gj_salaryVo.getSocialSubsidies().add(salaryVoz.getSocialSubsidies())); + if(StringUtils.isNull(gj_salaryVo.getFullSubsidies())){ + gj_salaryVo.setFullSubsidies(new BigDecimal("0.00")); + } + gj_salaryVo.setFullSubsidies(gj_salaryVo.getFullSubsidies().add(salaryVoz.getFullSubsidies())); + if(StringUtils.isNull(gj_salaryVo.getNightSubsidies())){ + gj_salaryVo.setNightSubsidies(new BigDecimal("0.00")); + } + gj_salaryVo.setNightSubsidies(gj_salaryVo.getNightSubsidies().add(salaryVoz.getNightSubsidies())); + if(StringUtils.isNull(gj_salaryVo.getDinnerSubsidies())){ + gj_salaryVo.setDinnerSubsidies(new BigDecimal("0.00")); + } + gj_salaryVo.setDinnerSubsidies(gj_salaryVo.getDinnerSubsidies().add(salaryVoz.getDinnerSubsidies())); + if(StringUtils.isNull(gj_salaryVo.getSubsidyOrBonus())){ + gj_salaryVo.setSubsidyOrBonus(new BigDecimal("0.00")); + } + gj_salaryVo.setSubsidyOrBonus(gj_salaryVo.getSubsidyOrBonus().add(salaryVoz.getSubsidyOrBonus())); + if(StringUtils.isNull(gj_salaryVo.getAbsenteeismSalary())){ + gj_salaryVo.setAbsenteeismSalary(new BigDecimal("0.00")); + } + gj_salaryVo.setAbsenteeismSalary(gj_salaryVo.getAbsenteeismSalary().add(salaryVoz.getAbsenteeismSalary())); + if(StringUtils.isNull(gj_salaryVo.getAbsenteeismSubsidies())){ + gj_salaryVo.setAbsenteeismSubsidies(new BigDecimal("0.00")); + } + gj_salaryVo.setAbsenteeismSubsidies(gj_salaryVo.getAbsenteeismSubsidies().add(salaryVoz.getAbsenteeismSubsidies())); + if(StringUtils.isNull(gj_salaryVo.getMealFee())){ + gj_salaryVo.setMealFee(new BigDecimal("0.00")); + } + gj_salaryVo.setMealFee(gj_salaryVo.getMealFee().add(salaryVoz.getMealFee())); + if(StringUtils.isNull(gj_salaryVo.getDeductions())){ + gj_salaryVo.setDeductions(new BigDecimal("0.00")); + } + gj_salaryVo.setDeductions(gj_salaryVo.getDeductions().add(salaryVoz.getDeductions())); + if(StringUtils.isNull(gj_salaryVo.getSalary())){ + gj_salaryVo.setSalary(new BigDecimal("0.00")); + } + gj_salaryVo.setSalary(gj_salaryVo.getSalary().add(salaryVoz.getSalary())); + if(StringUtils.isNull(gj_salaryVo.getPayInsurance())){ + gj_salaryVo.setPayInsurance(new BigDecimal("0.00")); + } + gj_salaryVo.setPayInsurance(gj_salaryVo.getPayInsurance().add(salaryVoz.getPayInsurance())); + if(StringUtils.isNull(gj_salaryVo.getSalaryBeforeTax())){ + gj_salaryVo.setSalaryBeforeTax(new BigDecimal("0.00")); + } + gj_salaryVo.setSalaryBeforeTax(gj_salaryVo.getSalaryBeforeTax().add(salaryVoz.getSalaryBeforeTax())); + if(StringUtils.isNull(gj_salaryVo.getTotalWages())){ + gj_salaryVo.setTotalWages(new BigDecimal("0.00")); + } + gj_salaryVo.setTotalWages(gj_salaryVo.getTotalWages().add(salaryVoz.getTotalWages())); + if(StringUtils.isNull(gj_salaryVo.getAnnualExemptionAmount())){ + gj_salaryVo.setAnnualExemptionAmount(new BigDecimal("0.00")); + } + gj_salaryVo.setAnnualExemptionAmount(gj_salaryVo.getAnnualExemptionAmount().add(salaryVoz.getAnnualExemptionAmount())); + if(StringUtils.isNull(gj_salaryVo.getSpecialDeduction())){ + gj_salaryVo.setSpecialDeduction(new BigDecimal("0.00")); + } + gj_salaryVo.setSpecialDeduction(gj_salaryVo.getSpecialDeduction().add(salaryVoz.getSpecialDeduction())); + if(StringUtils.isNull(gj_salaryVo.getSlowDownTheDeduction())){ + gj_salaryVo.setSlowDownTheDeduction(new BigDecimal("0.00")); + } + gj_salaryVo.setSlowDownTheDeduction(gj_salaryVo.getSlowDownTheDeduction().add(salaryVoz.getSlowDownTheDeduction())); + if(StringUtils.isNull(gj_salaryVo.getAggregatePersonalIncomeTax())){ + gj_salaryVo.setAggregatePersonalIncomeTax(new BigDecimal("0.00")); + } + gj_salaryVo.setAggregatePersonalIncomeTax(gj_salaryVo.getAggregatePersonalIncomeTax().add(salaryVoz.getAggregatePersonalIncomeTax())); + if(StringUtils.isNull(gj_salaryVo.getTaxPayable())){ + gj_salaryVo.setTaxPayable(new BigDecimal("0.00")); + } + gj_salaryVo.setTaxPayable(gj_salaryVo.getTaxPayable().add(salaryVoz.getTaxPayable())); + if(StringUtils.isNull(gj_salaryVo.getNetPayroll())){ + gj_salaryVo.setNetPayroll(new BigDecimal("0.00")); + } + gj_salaryVo.setNetPayroll(gj_salaryVo.getNetPayroll().add(salaryVoz.getNetPayroll())); + } + gj_salaryVo.setName("伊特总计:"); + list.add(gj_salaryVo); + + //创建总表的对象 + SalaryVo payRollZong = new SalaryVo(); + payRollZong.setName("总计:"); + BeanUtils.copyProperties(gj_salaryVo, payRollZong); + //查询非伊特数据 + List cy_list = sysDictDataMapper.selectDictDataByType(Constants.SYS_COMPANY); + for (SysDictData sysDictData : cy_list) { + if(!"YT".equals(sysDictData.getDictValue())){ + sheetNameList.add(sysDictData.getDictLabel()); + //部门小计 + SalaryVo xj_salaryVo = new SalaryVo(); + xj_salaryVo.setName("小计:"); + //查询非伊特下的数据 + List f_list = rzSalaryDetailService.selectSalaryDetailByWbFlag(sysDictData.getDictValue(),rzSalaryDetail.getMonth()); + for (RzSalaryDetail salaryDetail : f_list) { + salaryVo = new SalaryVo(); + if(StringUtils.isNull(xj_salaryVo.getBasicSalary())){ + xj_salaryVo.setBasicSalary(new BigDecimal("0.00")); + } + xj_salaryVo.setBasicSalary(xj_salaryVo.getBasicSalary().add(salaryDetail.getBasicSalary())); + if(StringUtils.isNull(xj_salaryVo.getOvertimeSalary())){ + xj_salaryVo.setOvertimeSalary(new BigDecimal("0.00")); + } + xj_salaryVo.setOvertimeSalary(xj_salaryVo.getOvertimeSalary().add(salaryDetail.getOvertimeSalary())); + if(StringUtils.isNull(xj_salaryVo.getLevelSubsidies())){ + xj_salaryVo.setLevelSubsidies(new BigDecimal("0.00")); + } + xj_salaryVo.setLevelSubsidies(xj_salaryVo.getLevelSubsidies().add(salaryDetail.getLevelSubsidies())); + if(StringUtils.isNull(xj_salaryVo.getContractSubsidies())){ + xj_salaryVo.setContractSubsidies(new BigDecimal("0.00")); + } + xj_salaryVo.setContractSubsidies(xj_salaryVo.getContractSubsidies().add(salaryDetail.getContractSubsidies())); + if(StringUtils.isNull(xj_salaryVo.getSenioritySalary())){ + xj_salaryVo.setSenioritySalary(new BigDecimal("0.00")); + } + xj_salaryVo.setSenioritySalary(xj_salaryVo.getSenioritySalary().add(salaryDetail.getSenioritySalary())); + if(StringUtils.isNull(xj_salaryVo.getSocialSubsidies())){ + xj_salaryVo.setSocialSubsidies(new BigDecimal("0.00")); + } + xj_salaryVo.setSocialSubsidies(xj_salaryVo.getSocialSubsidies().add(salaryDetail.getSocialSubsidies())); + if(StringUtils.isNull(xj_salaryVo.getFullSubsidies())){ + xj_salaryVo.setFullSubsidies(new BigDecimal("0.00")); + } + xj_salaryVo.setFullSubsidies(xj_salaryVo.getFullSubsidies().add(salaryDetail.getFullSubsidies())); + if(StringUtils.isNull(xj_salaryVo.getNightSubsidies())){ + xj_salaryVo.setNightSubsidies(new BigDecimal("0.00")); + } + xj_salaryVo.setNightSubsidies(xj_salaryVo.getNightSubsidies().add(salaryDetail.getNightSubsidies())); + if(StringUtils.isNull(xj_salaryVo.getDinnerSubsidies())){ + xj_salaryVo.setDinnerSubsidies(new BigDecimal("0.00")); + } + xj_salaryVo.setDinnerSubsidies(xj_salaryVo.getDinnerSubsidies().add(salaryDetail.getDinnerSubsidies())); + if(StringUtils.isNull(xj_salaryVo.getSubsidyOrBonus())){ + xj_salaryVo.setSubsidyOrBonus(new BigDecimal("0.00")); + } + xj_salaryVo.setSubsidyOrBonus(xj_salaryVo.getSubsidyOrBonus().add(salaryDetail.getSubsidyOrBonus())); + if(StringUtils.isNull(xj_salaryVo.getAbsenteeismSalary())){ + xj_salaryVo.setAbsenteeismSalary(new BigDecimal("0.00")); + } + xj_salaryVo.setAbsenteeismSalary(xj_salaryVo.getAbsenteeismSalary().add(salaryDetail.getAbsenteeismSalary())); + if(StringUtils.isNull(xj_salaryVo.getAbsenteeismSubsidies())){ + xj_salaryVo.setAbsenteeismSubsidies(new BigDecimal("0.00")); + } + xj_salaryVo.setAbsenteeismSubsidies(xj_salaryVo.getAbsenteeismSubsidies().add(salaryDetail.getAbsenteeismSubsidies())); + if(StringUtils.isNull(xj_salaryVo.getMealFee())){ + xj_salaryVo.setMealFee(new BigDecimal("0.00")); + } + xj_salaryVo.setMealFee(xj_salaryVo.getMealFee().add(salaryDetail.getMealFee())); + if(StringUtils.isNull(xj_salaryVo.getDeductions())){ + xj_salaryVo.setDeductions(new BigDecimal("0.00")); + } + xj_salaryVo.setDeductions(xj_salaryVo.getDeductions().add(salaryDetail.getDeductions())); + if(StringUtils.isNull(xj_salaryVo.getSalary())){ + xj_salaryVo.setSalary(new BigDecimal("0.00")); + } + xj_salaryVo.setSalary(xj_salaryVo.getSalary().add(salaryDetail.getSalary())); + if(StringUtils.isNull(xj_salaryVo.getPayInsurance())){ + xj_salaryVo.setPayInsurance(new BigDecimal("0.00")); + } + xj_salaryVo.setPayInsurance(xj_salaryVo.getPayInsurance().add(salaryDetail.getPayInsurance())); + if(StringUtils.isNull(xj_salaryVo.getSalaryBeforeTax())){ + xj_salaryVo.setSalaryBeforeTax(new BigDecimal("0.00")); + } + xj_salaryVo.setSalaryBeforeTax(xj_salaryVo.getSalaryBeforeTax().add(salaryDetail.getSalaryBeforeTax())); + if(StringUtils.isNull(xj_salaryVo.getTotalWages())){ + xj_salaryVo.setTotalWages(new BigDecimal("0.00")); + } + xj_salaryVo.setTotalWages(xj_salaryVo.getTotalWages().add(salaryDetail.getTotalWages())); + if(StringUtils.isNull(xj_salaryVo.getAnnualExemptionAmount())){ + xj_salaryVo.setAnnualExemptionAmount(new BigDecimal("0.00")); + } + xj_salaryVo.setAnnualExemptionAmount(xj_salaryVo.getAnnualExemptionAmount().add(salaryDetail.getAnnualExemptionAmount())); + if(StringUtils.isNull(xj_salaryVo.getSpecialDeduction())){ + xj_salaryVo.setSpecialDeduction(new BigDecimal("0.00")); + } + xj_salaryVo.setSpecialDeduction(xj_salaryVo.getSpecialDeduction().add(salaryDetail.getSpecialDeduction())); + if(StringUtils.isNull(xj_salaryVo.getSlowDownTheDeduction())){ + xj_salaryVo.setSlowDownTheDeduction(new BigDecimal("0.00")); + } + xj_salaryVo.setSlowDownTheDeduction(xj_salaryVo.getSlowDownTheDeduction().add(salaryDetail.getSlowDownTheDeduction())); + if(StringUtils.isNull(xj_salaryVo.getAggregatePersonalIncomeTax())){ + xj_salaryVo.setAggregatePersonalIncomeTax(new BigDecimal("0.00")); + } + xj_salaryVo.setAggregatePersonalIncomeTax(xj_salaryVo.getAggregatePersonalIncomeTax().add(salaryDetail.getAggregatePersonalIncomeTax())); + if(StringUtils.isNull(xj_salaryVo.getTaxPayable())){ + xj_salaryVo.setTaxPayable(new BigDecimal("0.00")); + } + xj_salaryVo.setTaxPayable(xj_salaryVo.getTaxPayable().add(salaryDetail.getTaxPayable())); + if(StringUtils.isNull(xj_salaryVo.getNetPayroll())){ + xj_salaryVo.setNetPayroll(new BigDecimal("0.00")); + } + xj_salaryVo.setNetPayroll(xj_salaryVo.getNetPayroll().add(salaryDetail.getNetPayroll())); + BeanUtils.copyProperties(salaryDetail, salaryVo); + salaryVo.setDeptName(deptService.selectDeptById(salaryDetail.getDeptId()).getDeptName()); + list0.add(salaryVo); + } + list.add(xj_salaryVo); + payRollZong.setBasicSalary(xj_salaryVo.getBasicSalary().add(payRollZong.getBasicSalary())); + payRollZong.setOvertimeSalary(xj_salaryVo.getOvertimeSalary().add(payRollZong.getOvertimeSalary())); + payRollZong.setLevelSubsidies(xj_salaryVo.getLevelSubsidies().add(payRollZong.getLevelSubsidies())); + payRollZong.setContractSubsidies(xj_salaryVo.getContractSubsidies().add(payRollZong.getContractSubsidies())); + payRollZong.setSenioritySalary(xj_salaryVo.getSenioritySalary().add(payRollZong.getSenioritySalary())); + payRollZong.setSocialSubsidies(xj_salaryVo.getSocialSubsidies().add(payRollZong.getSocialSubsidies())); + payRollZong.setFullSubsidies(xj_salaryVo.getFullSubsidies().add(payRollZong.getFullSubsidies())); + payRollZong.setNightSubsidies(xj_salaryVo.getNightSubsidies().add(payRollZong.getNightSubsidies())); + payRollZong.setDinnerSubsidies(xj_salaryVo.getDinnerSubsidies().add(payRollZong.getDinnerSubsidies())); + payRollZong.setSubsidyOrBonus(xj_salaryVo.getSubsidyOrBonus().add(payRollZong.getSubsidyOrBonus())); + payRollZong.setAbsenteeismSalary(xj_salaryVo.getAbsenteeismSalary().add(payRollZong.getAbsenteeismSalary())); + payRollZong.setAbsenteeismSubsidies(xj_salaryVo.getAbsenteeismSubsidies().add(payRollZong.getAbsenteeismSubsidies())); + payRollZong.setMealFee(xj_salaryVo.getMealFee().add(payRollZong.getMealFee())); + payRollZong.setDeductions(xj_salaryVo.getDeductions().add(payRollZong.getDeductions())); + payRollZong.setSalary(xj_salaryVo.getSalary().add(payRollZong.getSalary())); + payRollZong.setPayInsurance(xj_salaryVo.getPayInsurance().add(payRollZong.getPayInsurance())); + payRollZong.setSalaryBeforeTax(xj_salaryVo.getSalaryBeforeTax().add(payRollZong.getSalaryBeforeTax())); + payRollZong.setTotalWages(xj_salaryVo.getTotalWages().add(payRollZong.getTotalWages())); + payRollZong.setAnnualExemptionAmount(xj_salaryVo.getAnnualExemptionAmount().add(payRollZong.getAnnualExemptionAmount())); + payRollZong.setSpecialDeduction(xj_salaryVo.getSpecialDeduction().add(payRollZong.getSpecialDeduction())); + payRollZong.setSlowDownTheDeduction(xj_salaryVo.getSlowDownTheDeduction().add(payRollZong.getSlowDownTheDeduction())); + payRollZong.setAggregatePersonalIncomeTax(xj_salaryVo.getAggregatePersonalIncomeTax().add(payRollZong.getAggregatePersonalIncomeTax())); + payRollZong.setTaxPayable(xj_salaryVo.getTaxPayable().add(payRollZong.getTaxPayable())); + payRollZong.setNetPayroll(xj_salaryVo.getNetPayroll().add(payRollZong.getNetPayroll())); + } + } + list.add(payRollZong); + //表尾 + String footer = "制表: "+"审核: "+"经理签字: "+"总经理签字: "; + return util.exportExcel(list,lists,"总表",sheetNameList,title,footer); + } + +} diff --git a/evo-admin/src/main/java/com/evo/finance/controller/RzSalaryStatisticsController.java b/evo-admin/src/main/java/com/evo/finance/controller/RzSalaryStatisticsController.java new file mode 100644 index 0000000..7ff8dd9 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/finance/controller/RzSalaryStatisticsController.java @@ -0,0 +1,54 @@ +package com.evo.finance.controller; + +import java.util.List; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.enums.BusinessType; +import com.evo.finance.domain.RzSalaryStatistics; +import com.evo.finance.service.IRzSalaryStatisticsService; +import com.evo.common.core.page.TableDataInfo; + +/** + * 工资统计Controller + * + * @author evo + * @date 2024-11-26 + */ +@RestController +@RequestMapping("/finance/financeStatistics") +public class RzSalaryStatisticsController extends BaseController +{ + @Autowired + private IRzSalaryStatisticsService rzSalaryStatisticsService; + + /** + * 查询工资统计列表 + */ + @PreAuthorize("@ss.hasPermi('finance:financeStatistics:list')") + @GetMapping("/list") + public TableDataInfo list(RzSalaryStatistics rzSalaryStatistics) + { + startPage(); + List list = rzSalaryStatisticsService.selectRzSalaryStatisticsList(rzSalaryStatistics); + return getDataTable(list); + } + + /** + * 删除工资统计 + */ + @PreAuthorize("@ss.hasPermi('finance:financeStatistics:remove')") + @Log(title = "工资统计", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return rzSalaryStatisticsService.deleteRzSalaryStatisticsById(id); + } +} diff --git a/evo-admin/src/main/java/com/evo/finance/domain/RzSalaryDetail.java b/evo-admin/src/main/java/com/evo/finance/domain/RzSalaryDetail.java new file mode 100644 index 0000000..fcf146d --- /dev/null +++ b/evo-admin/src/main/java/com/evo/finance/domain/RzSalaryDetail.java @@ -0,0 +1,662 @@ +package com.evo.finance.domain; + +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; + +/** + * 工资详情对象 rz_salary_detail + * + * @author evo + * @date 2024-11-26 + */ +public class RzSalaryDetail extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 员工ID */ + @Excel(name = "员工ID") + private Long staffId; + + /** 员工姓名 */ + @Excel(name = "员工姓名") + private String name; + + /** 工资月份 */ + @JsonFormat(pattern = "yyyy-MM") + @Excel(name = "工资月份", width = 30, dateFormat = "yyyy-MM") + private Date month; + + /** 所属公司 */ + @Excel(name = "所属公司") + private String wbFlag; + + /** 部门名称 */ + private Long deptId; + @Excel(name = "部门名称") + private String deptName; + /** 月工资 */ + @Excel(name = "月工资") + private BigDecimal monthSalary; + /** 基本工资 */ + @Excel(name = "基本工资") + private BigDecimal basicSalary; + + /** 岗位工资 */ + @Excel(name = "岗位工资") + private BigDecimal jobSalary; + + /** 日薪 */ + @Excel(name = "日薪") + private BigDecimal dailyWage; + + /** 时薪 */ + @Excel(name = "时薪") + private BigDecimal hoursSalary; + + /** 加班工资 */ + @Excel(name = "加班工资") + private BigDecimal overtimeSalary; + + /** 学历补助 */ + @Excel(name = "学历补助") + private BigDecimal levelSubsidies; + + /** 合同补助 */ + @Excel(name = "合同补助") + private BigDecimal contractSubsidies; + + /** 工龄工资 */ + @Excel(name = "工龄工资") + private BigDecimal senioritySalary; + + /** 社保补助 */ + @Excel(name = "社保补助") + private BigDecimal socialSubsidies; + + /** 全勤奖 */ + @Excel(name = "全勤奖") + private BigDecimal fullSubsidies; + + @Excel(name = "中班补助") + private BigDecimal middleSubsidies; + + /** 夜班补助 */ + @Excel(name = "夜班补助") + private BigDecimal nightSubsidies; + + /** 夜餐补助 */ + @Excel(name = "夜餐补助") + private BigDecimal dinnerSubsidies; + + /** 其他补助 */ + @Excel(name = "其他补助") + private BigDecimal subsidyOrBonus; + + /** 缺勤扣款 */ + @Excel(name = "缺勤扣款") + private BigDecimal absenteeismSalary; + + /** 补助扣款 */ + @Excel(name = "补助扣款") + private BigDecimal absenteeismSubsidies; + + /** 餐费扣款 */ + @Excel(name = "餐费扣款") + private BigDecimal mealFee; + + /** 其他扣款 */ + @Excel(name = "其他扣款") + private BigDecimal deductions; + + /** 应发工资 */ + @Excel(name = "应发工资") + private BigDecimal salary; + + /** 代缴保险 */ + @Excel(name = "代缴保险") + private BigDecimal payInsurance; + + /** 养老保险 */ + @Excel(name = "养老保险") + private BigDecimal endowmentInsurance; + + /** 医疗保险 */ + @Excel(name = "医疗保险") + private BigDecimal medicalInsurance; + + /** 工伤保险 */ + @Excel(name = "工伤保险") + private BigDecimal employmentInjuryInsurance; + + /** 生育保险 */ + @Excel(name = "生育保险") + private BigDecimal maternityInsurance; + + /** 失业保险 */ + @Excel(name = "失业保险") + private BigDecimal unemploymentInsurance; + + /** 公积金 */ + @Excel(name = "公积金") + private BigDecimal accumulationFund; + + /** 税前工资 */ + @Excel(name = "税前工资") + private BigDecimal salaryBeforeTax; + + /** 累计已发工资 */ + @Excel(name = "累计已发工资") + private BigDecimal totalWages; + + /** 年度免征额 */ + @Excel(name = "年度免征额") + private BigDecimal annualExemptionAmount; + + /** 累计专项附加扣除 */ + @Excel(name = "累计专项附加扣除") + private BigDecimal specialDeduction; + + /** 应纳税所得额 */ + @Excel(name = "应纳税所得额") + private BigDecimal taxableIncome; + + /** 税率 */ + @Excel(name = "税率") + private BigDecimal taxRate; + + /** 速算扣除数 */ + @Excel(name = "速算扣除数") + private BigDecimal slowDownTheDeduction; + + /** 累计已缴税额 */ + @Excel(name = "累计已缴税额") + private BigDecimal aggregatePersonalIncomeTax; + + /** 本月应缴个税 */ + @Excel(name = "本月应缴个税") + private BigDecimal taxPayable; + + /** 实发工资 */ + @Excel(name = "实发工资") + private BigDecimal netPayroll; + + /** 备注 */ + @Excel(name = "备注") + private String remarks; + + /** 删除标识 */ + private String delFlag; + + public BigDecimal getMonthSalary() { + return monthSalary; + } + + public void setMonthSalary(BigDecimal monthSalary) { + this.monthSalary = monthSalary; + } + + public BigDecimal getMiddleSubsidies() { + return middleSubsidies; + } + + public void setMiddleSubsidies(BigDecimal middleSubsidies) { + this.middleSubsidies = middleSubsidies; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setStaffId(Long staffId) + { + this.staffId = staffId; + } + + public Long getStaffId() + { + return staffId; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setMonth(Date month) + { + this.month = month; + } + + public Date getMonth() + { + return month; + } + public void setWbFlag(String wbFlag) + { + this.wbFlag = wbFlag; + } + + public String getWbFlag() + { + return wbFlag; + } + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + public Long getDeptId() + { + return deptId; + } + public void setBasicSalary(BigDecimal basicSalary) + { + this.basicSalary = basicSalary; + } + + public BigDecimal getBasicSalary() + { + return basicSalary; + } + public void setJobSalary(BigDecimal jobSalary) + { + this.jobSalary = jobSalary; + } + + public BigDecimal getJobSalary() + { + return jobSalary; + } + public void setDailyWage(BigDecimal dailyWage) + { + this.dailyWage = dailyWage; + } + + public BigDecimal getDailyWage() + { + return dailyWage; + } + public void setHoursSalary(BigDecimal hoursSalary) + { + this.hoursSalary = hoursSalary; + } + + public BigDecimal getHoursSalary() + { + return hoursSalary; + } + public void setOvertimeSalary(BigDecimal overtimeSalary) + { + this.overtimeSalary = overtimeSalary; + } + + public BigDecimal getOvertimeSalary() + { + return overtimeSalary; + } + public void setLevelSubsidies(BigDecimal levelSubsidies) + { + this.levelSubsidies = levelSubsidies; + } + + public BigDecimal getLevelSubsidies() + { + return levelSubsidies; + } + public void setContractSubsidies(BigDecimal contractSubsidies) + { + this.contractSubsidies = contractSubsidies; + } + + public BigDecimal getContractSubsidies() + { + return contractSubsidies; + } + public void setSenioritySalary(BigDecimal senioritySalary) + { + this.senioritySalary = senioritySalary; + } + + public BigDecimal getSenioritySalary() + { + return senioritySalary; + } + public void setSocialSubsidies(BigDecimal socialSubsidies) + { + this.socialSubsidies = socialSubsidies; + } + + public BigDecimal getSocialSubsidies() + { + return socialSubsidies; + } + public void setFullSubsidies(BigDecimal fullSubsidies) + { + this.fullSubsidies = fullSubsidies; + } + + public BigDecimal getFullSubsidies() + { + return fullSubsidies; + } + public void setNightSubsidies(BigDecimal nightSubsidies) + { + this.nightSubsidies = nightSubsidies; + } + + public BigDecimal getNightSubsidies() + { + return nightSubsidies; + } + public void setDinnerSubsidies(BigDecimal dinnerSubsidies) + { + this.dinnerSubsidies = dinnerSubsidies; + } + + public BigDecimal getDinnerSubsidies() + { + return dinnerSubsidies; + } + public void setSubsidyOrBonus(BigDecimal subsidyOrBonus) + { + this.subsidyOrBonus = subsidyOrBonus; + } + + public BigDecimal getSubsidyOrBonus() + { + return subsidyOrBonus; + } + public void setAbsenteeismSalary(BigDecimal absenteeismSalary) + { + this.absenteeismSalary = absenteeismSalary; + } + + public BigDecimal getAbsenteeismSalary() + { + return absenteeismSalary; + } + public void setAbsenteeismSubsidies(BigDecimal absenteeismSubsidies) + { + this.absenteeismSubsidies = absenteeismSubsidies; + } + + public BigDecimal getAbsenteeismSubsidies() + { + return absenteeismSubsidies; + } + public void setMealFee(BigDecimal mealFee) + { + this.mealFee = mealFee; + } + + public BigDecimal getMealFee() + { + return mealFee; + } + public void setDeductions(BigDecimal deductions) + { + this.deductions = deductions; + } + + public BigDecimal getDeductions() + { + return deductions; + } + public void setSalary(BigDecimal salary) + { + this.salary = salary; + } + + public BigDecimal getSalary() + { + return salary; + } + public void setPayInsurance(BigDecimal payInsurance) + { + this.payInsurance = payInsurance; + } + + public BigDecimal getPayInsurance() + { + return payInsurance; + } + public void setEndowmentInsurance(BigDecimal endowmentInsurance) + { + this.endowmentInsurance = endowmentInsurance; + } + + public BigDecimal getEndowmentInsurance() + { + return endowmentInsurance; + } + public void setMedicalInsurance(BigDecimal medicalInsurance) + { + this.medicalInsurance = medicalInsurance; + } + + public BigDecimal getMedicalInsurance() + { + return medicalInsurance; + } + public void setEmploymentInjuryInsurance(BigDecimal employmentInjuryInsurance) + { + this.employmentInjuryInsurance = employmentInjuryInsurance; + } + + public BigDecimal getEmploymentInjuryInsurance() + { + return employmentInjuryInsurance; + } + public void setMaternityInsurance(BigDecimal maternityInsurance) + { + this.maternityInsurance = maternityInsurance; + } + + public BigDecimal getMaternityInsurance() + { + return maternityInsurance; + } + public void setUnemploymentInsurance(BigDecimal unemploymentInsurance) + { + this.unemploymentInsurance = unemploymentInsurance; + } + + public BigDecimal getUnemploymentInsurance() + { + return unemploymentInsurance; + } + public void setAccumulationFund(BigDecimal accumulationFund) + { + this.accumulationFund = accumulationFund; + } + + public BigDecimal getAccumulationFund() + { + return accumulationFund; + } + public void setSalaryBeforeTax(BigDecimal salaryBeforeTax) + { + this.salaryBeforeTax = salaryBeforeTax; + } + + public BigDecimal getSalaryBeforeTax() + { + return salaryBeforeTax; + } + public void setTotalWages(BigDecimal totalWages) + { + this.totalWages = totalWages; + } + + public BigDecimal getTotalWages() + { + return totalWages; + } + public void setAnnualExemptionAmount(BigDecimal annualExemptionAmount) + { + this.annualExemptionAmount = annualExemptionAmount; + } + + public BigDecimal getAnnualExemptionAmount() + { + return annualExemptionAmount; + } + public void setSpecialDeduction(BigDecimal specialDeduction) + { + this.specialDeduction = specialDeduction; + } + + public BigDecimal getSpecialDeduction() + { + return specialDeduction; + } + public void setTaxableIncome(BigDecimal taxableIncome) + { + this.taxableIncome = taxableIncome; + } + + public BigDecimal getTaxableIncome() + { + return taxableIncome; + } + public void setTaxRate(BigDecimal taxRate) + { + this.taxRate = taxRate; + } + + public BigDecimal getTaxRate() + { + return taxRate; + } + public void setSlowDownTheDeduction(BigDecimal slowDownTheDeduction) + { + this.slowDownTheDeduction = slowDownTheDeduction; + } + + public BigDecimal getSlowDownTheDeduction() + { + return slowDownTheDeduction; + } + public void setAggregatePersonalIncomeTax(BigDecimal aggregatePersonalIncomeTax) + { + this.aggregatePersonalIncomeTax = aggregatePersonalIncomeTax; + } + + public BigDecimal getAggregatePersonalIncomeTax() + { + return aggregatePersonalIncomeTax; + } + public void setTaxPayable(BigDecimal taxPayable) + { + this.taxPayable = taxPayable; + } + + public BigDecimal getTaxPayable() + { + return taxPayable; + } + public void setNetPayroll(BigDecimal netPayroll) + { + this.netPayroll = netPayroll; + } + + public BigDecimal getNetPayroll() + { + return netPayroll; + } + public void setRemarks(String remarks) + { + this.remarks = remarks; + } + + public String getRemarks() + { + return remarks; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("staffId", getStaffId()) + .append("name", getName()) + .append("month", getMonth()) + .append("wbFlag", getWbFlag()) + .append("deptId", getDeptId()) + .append("basicSalary", getBasicSalary()) + .append("jobSalary", getJobSalary()) + .append("dailyWage", getDailyWage()) + .append("hoursSalary", getHoursSalary()) + .append("overtimeSalary", getOvertimeSalary()) + .append("levelSubsidies", getLevelSubsidies()) + .append("contractSubsidies", getContractSubsidies()) + .append("senioritySalary", getSenioritySalary()) + .append("socialSubsidies", getSocialSubsidies()) + .append("fullSubsidies", getFullSubsidies()) + .append("nightSubsidies", getNightSubsidies()) + .append("dinnerSubsidies", getDinnerSubsidies()) + .append("subsidyOrBonus", getSubsidyOrBonus()) + .append("absenteeismSalary", getAbsenteeismSalary()) + .append("absenteeismSubsidies", getAbsenteeismSubsidies()) + .append("mealFee", getMealFee()) + .append("deductions", getDeductions()) + .append("salary", getSalary()) + .append("payInsurance", getPayInsurance()) + .append("endowmentInsurance", getEndowmentInsurance()) + .append("medicalInsurance", getMedicalInsurance()) + .append("employmentInjuryInsurance", getEmploymentInjuryInsurance()) + .append("maternityInsurance", getMaternityInsurance()) + .append("unemploymentInsurance", getUnemploymentInsurance()) + .append("accumulationFund", getAccumulationFund()) + .append("salaryBeforeTax", getSalaryBeforeTax()) + .append("totalWages", getTotalWages()) + .append("annualExemptionAmount", getAnnualExemptionAmount()) + .append("specialDeduction", getSpecialDeduction()) + .append("taxableIncome", getTaxableIncome()) + .append("taxRate", getTaxRate()) + .append("slowDownTheDeduction", getSlowDownTheDeduction()) + .append("aggregatePersonalIncomeTax", getAggregatePersonalIncomeTax()) + .append("taxPayable", getTaxPayable()) + .append("netPayroll", getNetPayroll()) + .append("remarks", getRemarks()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/finance/domain/RzSalaryStatistics.java b/evo-admin/src/main/java/com/evo/finance/domain/RzSalaryStatistics.java new file mode 100644 index 0000000..24ae9e1 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/finance/domain/RzSalaryStatistics.java @@ -0,0 +1,113 @@ +package com.evo.finance.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; + +/** + * 工资统计对象 rz_salary_statistics + * + * @author evo + * @date 2024-11-26 + */ +public class RzSalaryStatistics extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 工资月份 */ + @JsonFormat(pattern = "yyyy-MM") + @Excel(name = "工资月份", width = 30, dateFormat = "yyyy-MM") + private Date month; + + /** 统计人数 */ + @Excel(name = "统计人数") + private int number; + + /** 审核状态 */ + @Excel(name = "审核状态") + private String status; + + /** 备注 */ + @Excel(name = "备注") + private String remarks; + + /** 删除标识 */ + private String delFlag; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setMonth(Date month) + { + this.month = month; + } + + public Date getMonth() + { + return month; + } + public void setNumber(int number) + { + this.number = number; + } + + public int getNumber() + { + return number; + } + public void setStatus(String status) + { + this.status = status; + } + + public String getStatus() + { + return status; + } + public void setRemarks(String remarks) + { + this.remarks = remarks; + } + + public String getRemarks() + { + return remarks; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("month", getMonth()) + .append("number", getNumber()) + .append("status", getStatus()) + .append("remarks", getRemarks()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/finance/domain/vo/SalaryVo.java b/evo-admin/src/main/java/com/evo/finance/domain/vo/SalaryVo.java new file mode 100644 index 0000000..fed6e1a --- /dev/null +++ b/evo-admin/src/main/java/com/evo/finance/domain/vo/SalaryVo.java @@ -0,0 +1,293 @@ +package com.evo.finance.domain.vo; + +import com.evo.common.annotation.Excel; +import java.math.BigDecimal; + +public class SalaryVo { + + @Excel(name = "部门名称") + private String deptName; + /** 员工姓名 */ + @Excel(name = "员工姓名") + private String name; + /** 基本工资 */ + @Excel(name = "月工资") + private BigDecimal basicSalary; + /** 加班工资 */ + @Excel(name = "加班工资") + private BigDecimal overtimeSalary; + /** 学历补助 */ + @Excel(name = "学历补助") + private BigDecimal levelSubsidies; + /** 合同补助 */ + @Excel(name = "合同补助") + private BigDecimal contractSubsidies; + /** 工龄工资 */ + @Excel(name = "工龄工资") + private BigDecimal senioritySalary; + /** 社保补助 */ + @Excel(name = "社保补助") + private BigDecimal socialSubsidies; + /** 全勤奖 */ + @Excel(name = "全勤奖") + private BigDecimal fullSubsidies; + /** 夜班补助 */ + @Excel(name = "夜班补助") + private BigDecimal nightSubsidies; + /** 夜餐补助 */ + @Excel(name = "夜餐补助") + private BigDecimal dinnerSubsidies; + /** 其他补助 */ + @Excel(name = "其他补助") + private BigDecimal subsidyOrBonus; + /** 缺勤扣款 */ + @Excel(name = "缺勤扣款") + private BigDecimal absenteeismSalary; + /** 补助扣款 */ + @Excel(name = "补助扣款") + private BigDecimal absenteeismSubsidies; + /** 餐费扣款 */ + @Excel(name = "餐费扣款") + private BigDecimal mealFee; + /** 其他扣款 */ + @Excel(name = "其他扣款") + private BigDecimal deductions; + /** 应发工资 */ + @Excel(name = "应发工资") + private BigDecimal salary; + /** 代缴保险 */ + @Excel(name = "代缴保险") + private BigDecimal payInsurance; + /** 税前工资 */ + @Excel(name = "税前工资") + private BigDecimal salaryBeforeTax; + /** 累计已发工资 */ + @Excel(name = "累计已发工资") + private BigDecimal totalWages; + /** 年度免征额 */ + @Excel(name = "年度免征额") + private BigDecimal annualExemptionAmount; + /** 累计专项附加扣除 */ + @Excel(name = "累计专项附加扣除") + private BigDecimal specialDeduction; + /** 速算扣除数 */ + @Excel(name = "速算扣除数") + private BigDecimal slowDownTheDeduction; + /** 累计已缴税额 */ + @Excel(name = "累计已缴税额") + private BigDecimal aggregatePersonalIncomeTax; + /** 本月应缴个税 */ + @Excel(name = "本月应缴个税") + private BigDecimal taxPayable; + /** 实发工资 */ + @Excel(name = "实发工资") + private BigDecimal netPayroll; + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public BigDecimal getBasicSalary() { + return basicSalary; + } + + public void setBasicSalary(BigDecimal basicSalary) { + this.basicSalary = basicSalary; + } + + public BigDecimal getOvertimeSalary() { + return overtimeSalary; + } + + public void setOvertimeSalary(BigDecimal overtimeSalary) { + this.overtimeSalary = overtimeSalary; + } + + public BigDecimal getLevelSubsidies() { + return levelSubsidies; + } + + public void setLevelSubsidies(BigDecimal levelSubsidies) { + this.levelSubsidies = levelSubsidies; + } + + public BigDecimal getContractSubsidies() { + return contractSubsidies; + } + + public void setContractSubsidies(BigDecimal contractSubsidies) { + this.contractSubsidies = contractSubsidies; + } + + public BigDecimal getSenioritySalary() { + return senioritySalary; + } + + public void setSenioritySalary(BigDecimal senioritySalary) { + this.senioritySalary = senioritySalary; + } + + public BigDecimal getSocialSubsidies() { + return socialSubsidies; + } + + public void setSocialSubsidies(BigDecimal socialSubsidies) { + this.socialSubsidies = socialSubsidies; + } + + public BigDecimal getFullSubsidies() { + return fullSubsidies; + } + + public void setFullSubsidies(BigDecimal fullSubsidies) { + this.fullSubsidies = fullSubsidies; + } + + public BigDecimal getNightSubsidies() { + return nightSubsidies; + } + + public void setNightSubsidies(BigDecimal nightSubsidies) { + this.nightSubsidies = nightSubsidies; + } + + public BigDecimal getDinnerSubsidies() { + return dinnerSubsidies; + } + + public void setDinnerSubsidies(BigDecimal dinnerSubsidies) { + this.dinnerSubsidies = dinnerSubsidies; + } + + public BigDecimal getSubsidyOrBonus() { + return subsidyOrBonus; + } + + public void setSubsidyOrBonus(BigDecimal subsidyOrBonus) { + this.subsidyOrBonus = subsidyOrBonus; + } + + public BigDecimal getAbsenteeismSalary() { + return absenteeismSalary; + } + + public void setAbsenteeismSalary(BigDecimal absenteeismSalary) { + this.absenteeismSalary = absenteeismSalary; + } + + public BigDecimal getAbsenteeismSubsidies() { + return absenteeismSubsidies; + } + + public void setAbsenteeismSubsidies(BigDecimal absenteeismSubsidies) { + this.absenteeismSubsidies = absenteeismSubsidies; + } + + public BigDecimal getMealFee() { + return mealFee; + } + + public void setMealFee(BigDecimal mealFee) { + this.mealFee = mealFee; + } + + public BigDecimal getDeductions() { + return deductions; + } + + public void setDeductions(BigDecimal deductions) { + this.deductions = deductions; + } + + public BigDecimal getSalary() { + return salary; + } + + public void setSalary(BigDecimal salary) { + this.salary = salary; + } + + public BigDecimal getPayInsurance() { + return payInsurance; + } + + public void setPayInsurance(BigDecimal payInsurance) { + this.payInsurance = payInsurance; + } + + public BigDecimal getSalaryBeforeTax() { + return salaryBeforeTax; + } + + public void setSalaryBeforeTax(BigDecimal salaryBeforeTax) { + this.salaryBeforeTax = salaryBeforeTax; + } + + public BigDecimal getTotalWages() { + return totalWages; + } + + public void setTotalWages(BigDecimal totalWages) { + this.totalWages = totalWages; + } + + public BigDecimal getAnnualExemptionAmount() { + return annualExemptionAmount; + } + + public void setAnnualExemptionAmount(BigDecimal annualExemptionAmount) { + this.annualExemptionAmount = annualExemptionAmount; + } + + public BigDecimal getSpecialDeduction() { + return specialDeduction; + } + + public void setSpecialDeduction(BigDecimal specialDeduction) { + this.specialDeduction = specialDeduction; + } + + public BigDecimal getSlowDownTheDeduction() { + return slowDownTheDeduction; + } + + public void setSlowDownTheDeduction(BigDecimal slowDownTheDeduction) { + this.slowDownTheDeduction = slowDownTheDeduction; + } + + public BigDecimal getAggregatePersonalIncomeTax() { + return aggregatePersonalIncomeTax; + } + + public void setAggregatePersonalIncomeTax(BigDecimal aggregatePersonalIncomeTax) { + this.aggregatePersonalIncomeTax = aggregatePersonalIncomeTax; + } + + public BigDecimal getTaxPayable() { + return taxPayable; + } + + public void setTaxPayable(BigDecimal taxPayable) { + this.taxPayable = taxPayable; + } + + public BigDecimal getNetPayroll() { + return netPayroll; + } + + public void setNetPayroll(BigDecimal netPayroll) { + this.netPayroll = netPayroll; + } +} diff --git a/evo-admin/src/main/java/com/evo/finance/mapper/RzSalaryDetailMapper.java b/evo-admin/src/main/java/com/evo/finance/mapper/RzSalaryDetailMapper.java new file mode 100644 index 0000000..bface97 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/finance/mapper/RzSalaryDetailMapper.java @@ -0,0 +1,70 @@ +package com.evo.finance.mapper; + +import java.util.Date; +import java.util.List; +import com.evo.finance.domain.RzSalaryDetail; +import org.apache.ibatis.annotations.Param; + +/** + * 工资详情Mapper接口 + * + * @author evo + * @date 2024-11-26 + */ +public interface RzSalaryDetailMapper +{ + /** + * 查询工资详情 + * + * @param id 工资详情主键 + * @return 工资详情 + */ + public RzSalaryDetail selectRzSalaryDetailById(Long id); + + /** + * 查询工资详情列表 + * + * @param rzSalaryDetail 工资详情 + * @return 工资详情集合 + */ + public List selectRzSalaryDetailList(RzSalaryDetail rzSalaryDetail); + + /** + * 新增工资详情 + * + * @param rzSalaryDetail 工资详情 + * @return 结果 + */ + public int insertRzSalaryDetail(RzSalaryDetail rzSalaryDetail); + + /** + * 修改工资详情 + * + * @param rzSalaryDetail 工资详情 + * @return 结果 + */ + public int updateRzSalaryDetail(RzSalaryDetail rzSalaryDetail); + /** + * 查询工资详情 + * + * @param staffId 工资详情主键 + * @return 工资详情 + */ + public RzSalaryDetail selectRzSalaryDetailByStaffId(Long staffId); + + /** + * 根据月份查询工资详情列表 + * + * @param month 工资详情 + * @return 工资详情集合 + */ + public List selectRzSalaryDetailByMonth(Date month); + /** + * 根据部门查询工资单 + * @return + */ + public List selectSalaryDetailByDeptId(@Param("deptId") Long deptId, @Param("date") Date date); + + public List selectSalaryDetailByWbFlag(@Param("wbFlag")String wbFlag,@Param("date")Date date); + +} diff --git a/evo-admin/src/main/java/com/evo/finance/mapper/RzSalaryStatisticsMapper.java b/evo-admin/src/main/java/com/evo/finance/mapper/RzSalaryStatisticsMapper.java new file mode 100644 index 0000000..eb7c196 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/finance/mapper/RzSalaryStatisticsMapper.java @@ -0,0 +1,54 @@ +package com.evo.finance.mapper; + +import java.util.Date; +import java.util.List; +import com.evo.finance.domain.RzSalaryStatistics; + +/** + * 工资统计Mapper接口 + * + * @author evo + * @date 2024-11-26 + */ +public interface RzSalaryStatisticsMapper +{ + /** + * 查询工资统计 + * + * @param id 工资统计主键 + * @return 工资统计 + */ + public RzSalaryStatistics selectRzSalaryStatisticsById(Long id); + + /** + * 查询工资统计列表 + * + * @param rzSalaryStatistics 工资统计 + * @return 工资统计集合 + */ + public List selectRzSalaryStatisticsList(RzSalaryStatistics rzSalaryStatistics); + + /** + * 新增工资统计 + * + * @param rzSalaryStatistics 工资统计 + * @return 结果 + */ + public int insertRzSalaryStatistics(RzSalaryStatistics rzSalaryStatistics); + + /** + * 修改工资统计 + * + * @param rzSalaryStatistics 工资统计 + * @return 结果 + */ + public int updateRzSalaryStatistics(RzSalaryStatistics rzSalaryStatistics); + + /** + * 根据工资计算月份查询统计信息 + * @param month + * @return + */ + public RzSalaryStatistics selectRzSalaryStatisticsByMonth(Date month); + +} diff --git a/evo-admin/src/main/java/com/evo/finance/service/IRzSalaryDetailService.java b/evo-admin/src/main/java/com/evo/finance/service/IRzSalaryDetailService.java new file mode 100644 index 0000000..71b0604 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/finance/service/IRzSalaryDetailService.java @@ -0,0 +1,69 @@ +package com.evo.finance.service; + +import java.util.Date; +import java.util.List; +import com.evo.common.core.domain.AjaxResult; +import com.evo.finance.domain.RzSalaryDetail; +import org.apache.ibatis.annotations.Param; + +/** + * 工资详情Service接口 + * + * @author evo + * @date 2024-11-26 + */ +public interface IRzSalaryDetailService +{ + /** + * 查询工资详情 + * + * @param id 工资详情主键 + * @return 工资详情 + */ + public RzSalaryDetail selectRzSalaryDetailById(Long id); + + /** + * 查询工资详情列表 + * + * @param rzSalaryDetail 工资详情 + * @return 工资详情集合 + */ + public List selectRzSalaryDetailList(RzSalaryDetail rzSalaryDetail); + + /** + * 新增工资详情 + * + * @param rzSalaryDetail 工资详情 + * @return 结果 + */ + public AjaxResult insertRzSalaryDetail(RzSalaryDetail rzSalaryDetail); + + /** + * 修改工资详情 + * + * @param rzSalaryDetail 工资详情 + * @return 结果 + */ + public int updateRzSalaryDetail(RzSalaryDetail rzSalaryDetail); + + /** + * 删除工资详情信息 + * + * @param id 工资详情主键 + * @return 结果 + */ + public int deleteRzSalaryDetailById(Long id); + + /** + * 根据部门查询工资单 + * @param deptId + * @return + */ + public List selectSalaryDetailByDeptId(Long deptId,Date date); + /** + * 根据标识查询非伊特工资单 + * @return + */ + public List selectSalaryDetailByWbFlag(String wbFlag,Date date); + +} diff --git a/evo-admin/src/main/java/com/evo/finance/service/IRzSalaryStatisticsService.java b/evo-admin/src/main/java/com/evo/finance/service/IRzSalaryStatisticsService.java new file mode 100644 index 0000000..f9b2e53 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/finance/service/IRzSalaryStatisticsService.java @@ -0,0 +1,31 @@ +package com.evo.finance.service; + +import java.util.List; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.finance.domain.RzSalaryStatistics; + +/** + * 工资统计Service接口 + * + * @author evo + * @date 2024-11-26 + */ +public interface IRzSalaryStatisticsService +{ + /** + * 查询工资统计列表 + * + * @param rzSalaryStatistics 工资统计 + * @return 工资统计集合 + */ + public List selectRzSalaryStatisticsList(RzSalaryStatistics rzSalaryStatistics); + + /** + * 删除工资统计信息 + * + * @param id 工资统计主键 + * @return 结果 + */ + public AjaxResult deleteRzSalaryStatisticsById(Long id); +} diff --git a/evo-admin/src/main/java/com/evo/finance/service/impl/RzSalaryDetailServiceImpl.java b/evo-admin/src/main/java/com/evo/finance/service/impl/RzSalaryDetailServiceImpl.java new file mode 100644 index 0000000..fe3a615 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/finance/service/impl/RzSalaryDetailServiceImpl.java @@ -0,0 +1,543 @@ +package com.evo.finance.service.impl; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import com.evo.attendance.domain.RzAttendance; +import com.evo.attendance.domain.RzAttendanceStatistical; +import com.evo.attendance.domain.RzSpecialOverTime; +import com.evo.attendance.mapper.RzAttendanceMapper; +import com.evo.attendance.mapper.RzAttendanceStatisticalMapper; +import com.evo.attendance.mapper.RzSpecialOverTimeMapper; +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.finance.domain.RzSalaryStatistics; +import com.evo.finance.mapper.RzSalaryStatisticsMapper; +import com.evo.personnelMatters.domain.RzHoliday; +import com.evo.personnelMatters.mapper.RzHolidayMapper; +import com.evo.restaurant.domain.RzRestaurantStatistics; +import com.evo.restaurant.mapper.RzRestaurantStatisticsMapper; +import com.evo.system.domain.SysStaff; +import com.evo.system.domain.SysStaffDetail; +import com.evo.system.mapper.SysDeptMapper; +import com.evo.system.mapper.SysStaffDetailMapper; +import com.evo.system.mapper.SysStaffMapper; +import com.evo.utils.DateUtil; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Service; +import com.evo.finance.mapper.RzSalaryDetailMapper; +import com.evo.finance.domain.RzSalaryDetail; +import com.evo.finance.service.IRzSalaryDetailService; +import org.springframework.transaction.annotation.Transactional; +import javax.annotation.Resource; + +/** + * 工资详情Service业务层处理 + * + * @author evo + * @date 2024-11-26 + */ +@Service +public class RzSalaryDetailServiceImpl implements IRzSalaryDetailService +{ + @Resource + private RzSalaryDetailMapper rzSalaryDetailMapper; + @Resource + private RzSalaryStatisticsMapper rzSalaryStatisticsMapper; //工资统计 + @Resource + private SysStaffMapper sysStaffMapper; //员工信息 + @Resource + private SysStaffDetailMapper sysStaffDetailMapper; //员工详情 + @Resource + private RzHolidayMapper rzHolidayMapper; //节假日 + @Resource + private RzAttendanceStatisticalMapper rzAttendanceStatisticalMapper; //打卡统计 + @Resource + private RzRestaurantStatisticsMapper rzRestaurantStatisticsMapper; //餐饮统计 + @Resource + private RzAttendanceMapper rzAttendanceMapper; //考勤日期 + @Resource + private SysDeptMapper deptMapper; //部门 + @Resource + private RzSpecialOverTimeMapper rzSpecialOverTimeMapper; + + /** + * 查询工资详情 + * + * @param id 工资详情主键 + * @return 工资详情 + */ + @Override + public RzSalaryDetail selectRzSalaryDetailById(Long id) + { + return rzSalaryDetailMapper.selectRzSalaryDetailById(id); + } + /** + * 查询工资详情列表 + * + * @param rzSalaryDetail 工资详情 + * @return 工资详情 + */ + @Override + public List selectRzSalaryDetailList(RzSalaryDetail rzSalaryDetail) + { + List res_list = rzSalaryDetailMapper.selectRzSalaryDetailList(rzSalaryDetail); + for (RzSalaryDetail salaryDetail : res_list) { + salaryDetail.setDeptName(deptMapper.selectDeptById(salaryDetail.getDeptId()).getDeptName()); + } + return res_list; + } + + /** + * 新增工资详情 + * + * @param rzSalaryDetail 工资详情 + * @return 结果 + */ + @Override + @Transactional + public AjaxResult insertRzSalaryDetail(RzSalaryDetail rzSalaryDetail) + { + if(StringUtils.isNull(rzSalaryDetail.getMonth())){ + return AjaxResult.error("工资月份为不填项!!"); + } + //根据统计月份判断工资是否计算过 + RzSalaryStatistics rzSalaryStatistics = rzSalaryStatisticsMapper.selectRzSalaryStatisticsByMonth(rzSalaryDetail.getMonth()); + if(StringUtils.isNotNull(rzSalaryStatistics)){ + return AjaxResult.error("本月工资已经生成,请删除后在重新进行!!"); + } + //根据月份查询需要发工资的员工 + //处理工资月份 获取最晚入职时间 + Calendar calendar = Calendar.getInstance(); + calendar.setTime(rzSalaryDetail.getMonth()); + calendar.add(Calendar.MONTH,1); + //获取需要计算工资的员工信息 入职时间和离职时间 + List st_list = sysStaffMapper.querySysStaffListOfMonth(calendar.getTime(),rzSalaryDetail.getMonth()); + if(StringUtils.isNull(st_list) && st_list.size() == 0){ + return AjaxResult.error("没有要计算工资的员工"); + } + //添加工资统计 + rzSalaryStatistics = new RzSalaryStatistics(); + rzSalaryStatistics.setMonth(rzSalaryDetail.getMonth()); + rzSalaryStatistics.setNumber(st_list.size()); + rzSalaryStatistics.setDelFlag(Constants.DELETE_FLAG_0); + rzSalaryStatistics.setStatus("待审核"); + rzSalaryStatistics.setCreateTime(new Date()); + rzSalaryStatistics.setCreateBy(SecurityUtils.getUsername()); + int i = rzSalaryStatisticsMapper.insertRzSalaryStatistics(rzSalaryStatistics); + if(i < 1){ + return AjaxResult.error(); + } + SimpleDateFormat sdfm = new SimpleDateFormat("yyyy-MM"); + SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd"); + //获取社保缴纳分割日期: 10日 + String str = sdfm.format(rzSalaryDetail.getMonth())+"-10"; + Date sbrq = null; + try{ + sbrq = sdfd.parse(str); + }catch (Exception e){ + e.printStackTrace(); + } + for (SysStaff sysStaff : st_list) { + rzSalaryDetail.setStaffId(sysStaff.getUserId()); //员工ID + rzSalaryDetail.setDeptId(sysStaff.getDeptId()); //部门 + rzSalaryDetail.setName(sysStaff.getName()); //姓名 + rzSalaryDetail.setWbFlag(sysStaff.getCompanyName()); //公司 + //计算获得的工资 + SysStaffDetail salaryDetail = calculateSalary(sysStaff,rzSalaryDetail.getMonth(),sbrq); + rzSalaryDetail.setMonthSalary(salaryDetail.getBasicSalary()); //基本工资 + rzSalaryDetail.setAbsenteeismSalary(salaryDetail.getAbsenteeismSalary()); //请假扣除工资 + rzSalaryDetail.setOvertimeSalary(salaryDetail.getOverWages()); //加班工资 + rzSalaryDetail.setNightSubsidies(salaryDetail.getNightShiftSubsidies()); //夜班补助 + rzSalaryDetail.setDinnerSubsidies(salaryDetail.getDinnerSubsidies()); //夜餐补助 + rzSalaryDetail.setMiddleSubsidies(salaryDetail.getMiddleSubsidies()); //中班补助 + //查询员工详情 + SysStaffDetail sysStaffDetail = sysStaffDetailMapper.selectSysStaffDetailByStaffId(sysStaff.getUserId()); + rzSalaryDetail.setFullSubsidies(sysStaffDetail.getFullFrequentlySubsidies()); //全勤奖 + rzSalaryDetail.setLevelSubsidies(sysStaffDetail.getLevelOfEducationSubsidies()); //学历 + rzSalaryDetail.setContractSubsidies(sysStaffDetail.getContractSubsidies()); //合同 + rzSalaryDetail.setSocialSubsidies(sysStaffDetail.getSocialSecuritySubsidies()); //社保 + rzSalaryDetail.setSubsidyOrBonus(sysStaffDetail.getOtherSubsidies().add(sysStaffDetail.getFixedAllowance())); //其他补助 + //补助扣除 TODO 福利扣除百分比 + rzSalaryDetail.setAbsenteeismSubsidies(sysStaffDetail.getLevelOfEducationSubsidies().add(sysStaffDetail.getContractSubsidies()) + .add(sysStaffDetail.getSenioritySubsidies()).add(sysStaffDetail.getSocialSecuritySubsidies()).multiply(salaryDetail.getAbsenteeismSubsidies())); + rzSalaryDetail.setDeductions(sysStaffDetail.getDeductions()); //其他扣款 + //计算工龄,以每月10号社保缴纳计算 + int years = sbrq.getYear() - sysStaff.getEmploymentDate().getYear(); + int months = sbrq.getMonth() - sysStaff.getEmploymentDate().getMonth(); + int days = sbrq.getDate() - sysStaff.getEmploymentDate().getDate(); + if(months < 0){ + years -= 1; + } + if(months == 0 && days < 0){ + years -= 1; + } + if(years > 10){ + rzSalaryDetail.setSenioritySalary(sysStaffDetail.getSenioritySubsidies().multiply(new BigDecimal("10.0"))); //工龄 + }else{ + rzSalaryDetail.setSenioritySalary(sysStaffDetail.getSenioritySubsidies().multiply(new BigDecimal(years))); //工龄 + } + //餐费 + RzRestaurantStatistics rzRestaurantStatistics = rzRestaurantStatisticsMapper.selectRzRestaurantStatisticsByUserIdAndDate(sysStaff.getUserId(),rzSalaryDetail.getMonth()); + rzSalaryDetail.setMealFee(rzRestaurantStatistics.getPersonalSumConsumption()); //餐费扣除 + //计算应发工资 合算月工资+学历补助+合同补助+社保补助+工龄工资+全勤奖+加班工资+夜班补助+夜餐补助+其他补助 + BigDecimal sum = rzSalaryDetail.getMonthSalary().add(rzSalaryDetail.getOvertimeSalary()).add(rzSalaryDetail.getNightSubsidies()).add(rzSalaryDetail.getDinnerSubsidies()) + .add(rzSalaryDetail.getFullSubsidies()).add(rzSalaryDetail.getLevelSubsidies()).add(rzSalaryDetail.getContractSubsidies()).add(rzSalaryDetail.getSocialSubsidies()) + .add(rzSalaryDetail.getSenioritySalary()).add(rzSalaryDetail.getSubsidyOrBonus()).subtract(rzSalaryDetail.getAbsenteeismSalary()) + .subtract(rzSalaryDetail.getMealFee()).subtract(rzSalaryDetail.getAbsenteeismSubsidies()); + rzSalaryDetail.setSalary(sum); + //五险一金 + rzSalaryDetail.setAccumulationFund(sysStaffDetail.getAccumulationFund()); //公积金 + rzSalaryDetail.setUnemploymentInsurance(sysStaffDetail.getUnemploymentInsurance()); //失业保险 + rzSalaryDetail.setMaternityInsurance(sysStaffDetail.getMaternityInsurance()); //生育保险 + rzSalaryDetail.setMedicalInsurance(sysStaffDetail.getMedicalInsurance()); //医疗保险 + rzSalaryDetail.setEndowmentInsurance(sysStaffDetail.getEndowmentInsurance()); //养老保险 + rzSalaryDetail.setEmploymentInjuryInsurance(sysStaffDetail.getEmploymentInjuryInsurance()); //工伤保险 + //税前工资 应发 - 社保 + rzSalaryDetail.setSalaryBeforeTax(rzSalaryDetail.getSalary().subtract(rzSalaryDetail.getAccumulationFund()).subtract(rzSalaryDetail.getUnemploymentInsurance()) + .subtract(rzSalaryDetail.getMaternityInsurance()).subtract(rzSalaryDetail.getMedicalInsurance()) + .subtract(rzSalaryDetail.getEndowmentInsurance()).subtract(rzSalaryDetail.getEmploymentInjuryInsurance()).subtract(salaryDetail.getCountInsurance())); + + //获取统计月份 + int curr_month = rzSalaryDetail.getMonth().getMonth(); + //获取工资统计月份,查询上个月的纳税公司 得到年度免征额 + RzSalaryDetail old_rzSalary = rzSalaryDetailMapper.selectRzSalaryDetailByStaffId(sysStaff.getUserId()); + if(curr_month == 12){ + rzSalaryDetail.setAnnualExemptionAmount(new BigDecimal("5000.00")); + }else{ + //判断员工为 新入职,公司纳税主题改变,同一主题超一年的,同一主题不超一年但跨年的 + if(StringUtils.isNull(old_rzSalary) || !old_rzSalary.getWbFlag().equals(sysStaff.getCompanyName()) + || (rzSalaryDetail.getMonth().getTime() - old_rzSalary.getMonth().getTime())/1000/60/60/24 > 365 + || (old_rzSalary.getMonth().getMonth() < 12 && old_rzSalary.getMonth().getMonth() > rzSalaryDetail.getMonth().getMonth())){ + rzSalaryDetail.setAnnualExemptionAmount(new BigDecimal("5000.00")); + }else{ + rzSalaryDetail.setAnnualExemptionAmount(new BigDecimal("5000.00").add(old_rzSalary.getAnnualExemptionAmount())); + } + } + // 本年累计已发工资(本年累计已发工资+本月税前工资) + rzSalaryDetail.setTotalWages(sysStaffDetail.getTotalWages().add(rzSalaryDetail.getSalaryBeforeTax())); + // 专项附加扣除(六项附加扣除额相加) + rzSalaryDetail.setSpecialDeduction(sysStaffDetail.getChildrenEducation().add(sysStaffDetail.getSupportTheOld()).add(sysStaffDetail.getHousingLoans()) + .add(sysStaffDetail.getHousingRents()).add(sysStaffDetail.getAdultEducation()).add(sysStaffDetail.getTreatmentForSeriousDisease())); + + // 判断应纳税所得额额度(额度不一样税率不一样) + if (rzSalaryDetail.getTaxableIncome().doubleValue() > 0 && rzSalaryDetail.getTaxableIncome().doubleValue() <= 36000l) { + // 此阶税率为百分之3,速减数为0 + rzSalaryDetail.setTaxRate(new BigDecimal("0.03")); + // 速算扣除数(速算扣除数跟税率同步) + rzSalaryDetail.setSlowDownTheDeduction(new BigDecimal("0")); + } else if (rzSalaryDetail.getTaxableIncome().doubleValue() > 36000l && rzSalaryDetail.getTaxableIncome().doubleValue() <= 144000L) { + // 此阶税率为百分之3,速减数为0 + rzSalaryDetail.setTaxRate(new BigDecimal("0.10")); + // 速算扣除数(速算扣除数跟税率同步) + rzSalaryDetail.setSlowDownTheDeduction(new BigDecimal("2520")); + } else if (rzSalaryDetail.getTaxableIncome().doubleValue() > 144000L && rzSalaryDetail.getTaxableIncome().doubleValue() <= 300000l) { + // 此阶税率为百分之3,速减数为0 + rzSalaryDetail.setTaxRate(new BigDecimal("0.20")); + // 速算扣除数(速算扣除数跟税率同步) + rzSalaryDetail.setSlowDownTheDeduction(new BigDecimal("16920")); + } else if (rzSalaryDetail.getTaxableIncome().doubleValue() > 300000l && rzSalaryDetail.getTaxableIncome().doubleValue() <= 420000l) { + // 此阶税率为百分之3,速减数为0 + rzSalaryDetail.setTaxRate(new BigDecimal("0.25")); + // 速算扣除数(速算扣除数跟税率同步) + rzSalaryDetail.setSlowDownTheDeduction(new BigDecimal("31920")); + } else if (rzSalaryDetail.getTaxableIncome().doubleValue() > 420000l && rzSalaryDetail.getTaxableIncome().doubleValue() <= 660000l) { + // 此阶税率为百分之3,速减数为0 + rzSalaryDetail.setTaxRate(new BigDecimal("0.30")); + // 速算扣除数(速算扣除数跟税率同步) + rzSalaryDetail.setSlowDownTheDeduction(new BigDecimal("52920")); + } else if (rzSalaryDetail.getTaxableIncome().doubleValue() > 660000l && rzSalaryDetail.getTaxableIncome().doubleValue() <= 960000l) { + // 此阶税率为百分之3,速减数为0 + rzSalaryDetail.setTaxRate(new BigDecimal("0.35")); + // 速算扣除数(速算扣除数跟税率同步) + rzSalaryDetail.setSlowDownTheDeduction(new BigDecimal("85920")); + } else if (rzSalaryDetail.getTaxableIncome().doubleValue() > 960000l) { + // 此阶税率为百分之3,速减数为0 + rzSalaryDetail.setTaxRate(new BigDecimal("0.45")); + // 速算扣除数(速算扣除数跟税率同步) + rzSalaryDetail.setSlowDownTheDeduction(new BigDecimal("181920")); + } else { + // 应纳税所得额小于0(免征额+专项扣除>应发工资时) + // 此阶税率为百分之0,速减数为0 + rzSalaryDetail.setTaxRate(new BigDecimal("0.00")); + // 速算扣除数(速算扣除数跟税率同步) + rzSalaryDetail.setSlowDownTheDeduction(new BigDecimal("0")); + } + + //判断是否外包,外包公司员工不做税(月薪50000不上税) + if("外包".equals(sysStaff.getCompanyName())){ + // 实发工资 = 税前工资 + rzSalaryDetail.setNetPayroll(rzSalaryDetail.getSalaryBeforeTax()); + }else { + // 应纳税额 (本年累计已发工资-年度免征额-累计专项扣除-本月专项扣除) + BigDecimal tax = rzSalaryDetail.getTotalWages().subtract(rzSalaryDetail.getSpecialDeduction()).subtract(rzSalaryDetail.getAnnualExemptionAmount()); + if(tax.doubleValue() <= 0.0){ + rzSalaryDetail.setTaxableIncome(new BigDecimal("0.00")); + }else{ + rzSalaryDetail.setTaxableIncome(tax); + } + // 判断税前工资是否大于5000,如果小于,则不在计算个税 + if (rzSalaryDetail.getSalaryBeforeTax().doubleValue() > 5000.00){ + // 本月应缴税额(本月应纳税所得额*税率-速减数-本年累计已预缴个税) + rzSalaryDetail.setTaxPayable( + rzSalaryDetail.getTaxableIncome().multiply(rzSalaryDetail.getTaxRate()).subtract(rzSalaryDetail.getSlowDownTheDeduction()).subtract(sysStaffDetail.getAggregatePersonalIncomeTax())); + if (rzSalaryDetail.getTaxPayable().doubleValue() <= 0) { + rzSalaryDetail.setTaxPayable(new BigDecimal("0.00")); + } + } else { + // 应纳税所得额 + rzSalaryDetail.setTaxableIncome(new BigDecimal("0.00")); + rzSalaryDetail.setTaxPayable(new BigDecimal("0.00")); + } + // 实发工资(税前工资-本月应缴个人所得税) + rzSalaryDetail.setNetPayroll(rzSalaryDetail.getSalaryBeforeTax().subtract(rzSalaryDetail.getTaxPayable())); + // 本年累计已缴税额 + rzSalaryDetail.setAggregatePersonalIncomeTax(sysStaffDetail.getAggregatePersonalIncomeTax().add(rzSalaryDetail.getTaxPayable())); + } + rzSalaryDetail.setCreateTime(DateUtils.getNowDate()); + rzSalaryDetail.setDelFlag(Constants.DELETE_FLAG_0); + rzSalaryDetail.setCreateBy(SecurityUtils.getUsername()); + // 保存工资信息 + i = rzSalaryDetailMapper.insertRzSalaryDetail(rzSalaryDetail); + if(i < 1){ + return AjaxResult.error(); + } + //判断统计月缴费公司和上一次是否一个公司 + if(StringUtils.isNull(old_rzSalary) || old_rzSalary.getWbFlag().equals(sysStaff.getCompanyName())){ + // 把本年累计个税 + sysStaffDetail.setAggregatePersonalIncomeTax(rzSalaryDetail.getAggregatePersonalIncomeTax()); + // 把本年累计专项扣除保存到员工信息表中 + sysStaffDetail.setSpecialDeduction(sysStaffDetail.getSpecialDeduction().add(rzSalaryDetail.getSpecialDeduction())); + // 把本年累计已发工资保存到员工信息表中 + sysStaffDetail.setTotalWages(rzSalaryDetail.getTotalWages()); + i = sysStaffDetailMapper.updateSysStaffDetail(sysStaffDetail); + if(i < 1){ + return AjaxResult.error(); + } + }else{ + //删除原来的数据 + sysStaffDetail.setDelFlag(Constants.DELETE_FLAG_1); + i = sysStaffDetailMapper.updateSysStaffDetail(sysStaffDetail); + //新建详情数据 + // 把本年累计已缴个税保存到员工信息表中 + sysStaffDetail.setAggregatePersonalIncomeTax(rzSalaryDetail.getTaxPayable()); + // 把本年累计专项扣除保存到员工信息表中 + sysStaffDetail.setSpecialDeduction(rzSalaryDetail.getSpecialDeduction()); + // 把本年累计已发工资保存到员工信息表中 + sysStaffDetail.setTotalWages(rzSalaryDetail.getSalaryBeforeTax()); + sysStaffDetail.setId(null); + i = sysStaffDetailMapper.insertSysStaffDetail(sysStaffDetail); + if(i < 1){ + return AjaxResult.error(); + } + } + } + return AjaxResult.success(); + } + + /** + * 计算员工的工资信息 + * @param sysStaff 员工信息 + * @param month 统计月份 + * @param date 统计月10日 + * @return + */ + private SysStaffDetail calculateSalary(SysStaff sysStaff, Date month,Date date){ + //获取统计月份 + Calendar calendar = Calendar.getInstance(); + calendar.setTime(month); + //获取全年天数 - 节假日天数 + int days = calendar.getActualMaximum(Calendar.DAY_OF_YEAR); + SimpleDateFormat sdfm = new SimpleDateFormat("yyyy-MM"); + SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd"); + //判断假期和特殊上班时间 + List h_list = rzHolidayMapper.selectRzHolidayList(null); + try{ + //获取统计月所在年的开始和结束时间,统计一年的工作日期 + String start = sdfm.format(month).split("-")[0] + "-01-01"; + String end = sdfm.format(month).split("-")[0] + "-12-31"; + days -= DateUtil.isWeeked(sdfd.parse(start),sdfd.parse(end),1); + for (RzHoliday rzHoliday : h_list) { + if(rzHoliday.getHoliday().after(sdfd.parse(sdfm.format(month)+"-01")) + && rzHoliday.getHoliday().before(sdfd.parse(sdfm.format(month)+"-" + calendar.get(Calendar.DAY_OF_MONTH)))){ + if("1".equals(rzHoliday.getSpecialFlag())){ + days += 1; + } + } + } + }catch (Exception e){ + e.printStackTrace(); + } + //记录工资详情 + SysStaffDetail sysStaffDetail = sysStaffDetailMapper.selectSysStaffDetailByStaffId(sysStaff.getUserId()); + //补助扣除比例 + BigDecimal bfb = new BigDecimal("0.00"); + //获取考勤统计 + RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(sysStaff.getUserId(),month); + //判断入职日期,社保缴纳日期以前入职,计算补助扣除比例 + if(sysStaff.getEmploymentDate().before(date)){ + //计算请假百分比 + BigDecimal b = rzAttendanceStatistical.getAbsenteeism().divide(new BigDecimal("4")); + bfb = b.multiply(new BigDecimal(Constants.SUBSIDY_PROPORTION)); + sysStaffDetail.setAbsenteeismSubsidies(bfb); + }else{ + sysStaffDetail.setAbsenteeismSubsidies(new BigDecimal("1.00")); + } + sysStaffDetail.setNightShiftSubsidies(sysStaffDetail.getNightShiftSubsidies().multiply(new BigDecimal(rzAttendanceStatistical.getNightNumber()))); + sysStaffDetail.setDinnerSubsidies(sysStaffDetail.getDinnerSubsidies().multiply(new BigDecimal(rzAttendanceStatistical.getNightNumber()))); + //是否打卡 + if("否".equals(sysStaff.getClockIn())){ + return sysStaffDetail; + } + //查询员工考勤月的考勤 + List att_list = rzAttendanceMapper.queryMonthAttendanceByStaffId(sysStaff.getUserId(),month); + //判断是日工资 + if(sysStaffDetail.getDailyWage().doubleValue() > 0) { + //额薪资日期在工资月下一个月 + calendar.set(Calendar.MONTH,1); + //全额薪资日期在工资月以前 + if(sysStaff.getWagesRatioDate().before(month)) { + sysStaffDetail.setBasicSalary(sysStaffDetail.getDailyWage().divide(new BigDecimal("8.0"),2, RoundingMode.HALF_UP) + .multiply(rzAttendanceStatistical.getRealAttendance().add(rzAttendanceStatistical.getWorkOvertimeNumber()))); + }else if(sysStaff.getWagesRatioDate().after(calendar.getTime())) { + sysStaffDetail.setBasicSalary(sysStaffDetail.getDailyWage().divide(new BigDecimal("8.0"),2, RoundingMode.HALF_UP) + .multiply(rzAttendanceStatistical.getRealAttendance().add(rzAttendanceStatistical.getWorkOvertimeNumber())).multiply(new BigDecimal(Constants.SUBSIDY_PERIOD))); + }else { + //根据转正日期,查询员工的打卡信息 + BigDecimal att_work = new BigDecimal("0.0"); + for (RzAttendance rzAttendance : att_list) { + if(rzAttendance.getAttendanceDate().before(sysStaff.getWagesRatioDate())) { + att_work = att_work.add(rzAttendance.getWorkSum()); + } + } + //未转正需要扣除的工资 + BigDecimal work = sysStaffDetail.getDailyWage().divide(new BigDecimal("8.0"),2, RoundingMode.HALF_UP).multiply(att_work).multiply(new BigDecimal(Constants.SUBSIDY_PERIOD_1)); + sysStaffDetail.setBasicSalary(sysStaffDetail.getDailyWage().divide(new BigDecimal("8.0"),2, RoundingMode.HALF_UP) + .multiply(rzAttendanceStatistical.getRealAttendance().add(rzAttendanceStatistical.getWorkOvertimeNumber())).subtract(work)); + } + sysStaffDetail.setOverWages(sysStaffDetail.getDailyWage().divide(new BigDecimal("8.0"),2, RoundingMode.HALF_UP).multiply(rzAttendanceStatistical.getWorkOvertimeNumber())); + sysStaffDetail.setAbsenteeismSalary(new BigDecimal("0.00")); + sysStaffDetail.setMiddleSubsidies(sysStaffDetail.getMiddleSubsidies().multiply(new BigDecimal(rzAttendanceStatistical.getMiddleShiftNumber()))); + } + //判断是小时工 + if(sysStaffDetail.getHoursSalary().doubleValue() > 0) { + //额薪资日期在工资月下一个月 + calendar.set(Calendar.MONTH,1); + //全额薪资日期在工资月以前 + if(sysStaff.getWagesRatioDate().before(month)) { + sysStaffDetail.setBasicSalary(sysStaffDetail.getHoursSalary().multiply(rzAttendanceStatistical.getRealAttendance().add(rzAttendanceStatistical.getWorkOvertimeNumber()))); + }else if(sysStaff.getWagesRatioDate().after(calendar.getTime())) { + sysStaffDetail.setBasicSalary(sysStaffDetail.getHoursSalary().multiply(rzAttendanceStatistical.getRealAttendance().add(rzAttendanceStatistical.getWorkOvertimeNumber())).multiply(new BigDecimal(Constants.SUBSIDY_PERIOD))); + }else { + //根据转正日期,查询员工的打卡信息 + BigDecimal att_work = new BigDecimal("0.0"); + for (RzAttendance rzAttendance : att_list) { + if(rzAttendance.getAttendanceDate().before(sysStaff.getWagesRatioDate())) { + att_work = att_work.add(rzAttendance.getWorkSum()); + } + } + //未转正需要扣除的工资 + BigDecimal work = sysStaffDetail.getHoursSalary().multiply(att_work).multiply(new BigDecimal(Constants.SUBSIDY_PERIOD_1)); + sysStaffDetail.setBasicSalary(sysStaffDetail.getHoursSalary().multiply(rzAttendanceStatistical.getRealAttendance().add(rzAttendanceStatistical.getWorkOvertimeNumber())).subtract(work)); + } + sysStaffDetail.setOverWages(sysStaffDetail.getHoursSalary().multiply(rzAttendanceStatistical.getWorkOvertimeNumber())); + sysStaffDetail.setAbsenteeismSalary(new BigDecimal("0.00")); + sysStaffDetail.setMiddleSubsidies(sysStaffDetail.getMiddleSubsidies().multiply(new BigDecimal(rzAttendanceStatistical.getMiddleShiftNumber()))); + } + //判断是月工资 + if(sysStaffDetail.getBasicSalary().doubleValue() > 0 || sysStaffDetail.getJobsSalary().longValue() > 0) { + //额薪资日期在工资月下一个月 + calendar.set(Calendar.MONTH,1); + //全额薪资日期在工资月以前 + if(sysStaff.getWagesRatioDate().before(month)) { + sysStaffDetail.setBasicSalary(sysStaffDetail.getBasicSalary().add(sysStaffDetail.getJobsSalary())); + }else if(sysStaff.getWagesRatioDate().after(calendar.getTime())) { + BigDecimal hours = sysStaffDetail.getBasicSalary().add(sysStaffDetail.getJobsSalary()).divide(rzAttendanceStatistical.getShouldAttendance(),2, RoundingMode.HALF_UP); + sysStaffDetail.setBasicSalary(hours.multiply(rzAttendanceStatistical.getRealAttendance()).multiply(new BigDecimal(Constants.SUBSIDY_PERIOD))); + }else { + //根据转正日期,查询员工的打卡信息 + BigDecimal att_work = new BigDecimal("0.0"); + for (RzAttendance rzAttendance : att_list) { + if(rzAttendance.getAttendanceDate().before(sysStaff.getWagesRatioDate())) { + att_work = att_work.add(rzAttendance.getWorkSum()); + } + } + //未转正需要扣除的工资 + BigDecimal work = sysStaffDetail.getBasicSalary().add(sysStaffDetail.getJobsSalary()).divide(rzAttendanceStatistical.getShouldAttendance(),2, RoundingMode.HALF_UP) + .multiply(att_work).multiply(new BigDecimal(Constants.SUBSIDY_PERIOD_1)); + sysStaffDetail.setBasicSalary(sysStaffDetail.getBasicSalary().add(sysStaffDetail.getJobsSalary()).subtract(work)); + } + //计算月工资的每小时,工资 + BigDecimal evrymoney = sysStaffDetail.getBasicSalary().multiply(new BigDecimal("11.00")) + .add(sysStaffDetail.getBasicSalary().multiply(new BigDecimal(Constants.SUBSIDY_PERIOD))) + .divide(new BigDecimal(days).multiply(new BigDecimal("8.00")),2, RoundingMode.HALF_UP); + sysStaffDetail.setAbsenteeismSalary(evrymoney.multiply(rzAttendanceStatistical.getShouldAttendance().subtract(rzAttendanceStatistical.getRealAttendance()))); + sysStaffDetail.setMiddleSubsidies(new BigDecimal("0.00")); + //根据用户获取当前的加班情况 + RzSpecialOverTime rSpecialOverTime = rzSpecialOverTimeMapper.selectRzSpecialOverTimeByUserIdAndDate(sysStaff.getUserId(),month); + if(StringUtils.isNull(rSpecialOverTime)){ + sysStaffDetail.setOverWages(new BigDecimal("0.00")); + }else{ + sysStaffDetail.setOverWages(evrymoney.multiply(rSpecialOverTime.getSickHours())); + } + } + //判断员工的上班时长,设置保险的补交 + BigDecimal baifenbi = rzAttendanceStatistical.getRealAttendance().divide(rzAttendanceStatistical.getShouldAttendance(),2, RoundingMode.HALF_UP); + if(baifenbi.compareTo(new BigDecimal("0.20")) > 0 && baifenbi.compareTo(new BigDecimal("0.40")) <= 0){ + sysStaffDetail.setCountInsurance(sysStaffDetail.getCountInsurance().multiply(new BigDecimal("0.70"))); + }else if(baifenbi.compareTo(new BigDecimal("0.40")) > 0 && baifenbi.compareTo(new BigDecimal("0.60")) <= 0){ + sysStaffDetail.setCountInsurance(sysStaffDetail.getCountInsurance().multiply(new BigDecimal("0.50"))); + }else if(baifenbi.compareTo(new BigDecimal("0.60")) > 0){ + sysStaffDetail.setCountInsurance(sysStaffDetail.getCountInsurance()); + }else{ + sysStaffDetail.setCountInsurance(new BigDecimal("0.00")); + } + return sysStaffDetail; + } + /** + * 修改工资详情 + * + * @param rzSalaryDetail 工资详情 + * @return 结果 + */ + @Override + public int updateRzSalaryDetail(RzSalaryDetail rzSalaryDetail) + { + rzSalaryDetail.setUpdateTime(DateUtils.getNowDate()); + rzSalaryDetail.setUpdateBy(SecurityUtils.getUsername()); + return rzSalaryDetailMapper.updateRzSalaryDetail(rzSalaryDetail); + } + /** + * 删除工资详情信息 + * + * @param id 工资详情主键 + * @return 结果 + */ + @Override + public int deleteRzSalaryDetailById(Long id) + { + RzSalaryDetail rzSalaryDetail = rzSalaryDetailMapper.selectRzSalaryDetailById(id); + rzSalaryDetail.setDelFlag(Constants.DELETE_FLAG_1); + rzSalaryDetail.setUpdateTime(DateUtils.getNowDate()); + rzSalaryDetail.setUpdateBy(SecurityUtils.getUsername()); + return rzSalaryDetailMapper.updateRzSalaryDetail(rzSalaryDetail); + } + /** + * 根据公司名称查询工资单 + * @return + */ + @Override + public List selectSalaryDetailByDeptId(Long deptId,Date date){ + return rzSalaryDetailMapper.selectSalaryDetailByDeptId(deptId,date); + } + @Override + public List selectSalaryDetailByWbFlag(String wbFlag,Date date){ + return rzSalaryDetailMapper.selectSalaryDetailByWbFlag(wbFlag,date); + } +} diff --git a/evo-admin/src/main/java/com/evo/finance/service/impl/RzSalaryStatisticsServiceImpl.java b/evo-admin/src/main/java/com/evo/finance/service/impl/RzSalaryStatisticsServiceImpl.java new file mode 100644 index 0000000..46fe17e --- /dev/null +++ b/evo-admin/src/main/java/com/evo/finance/service/impl/RzSalaryStatisticsServiceImpl.java @@ -0,0 +1,89 @@ +package com.evo.finance.service.impl; + +import java.util.List; +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.finance.domain.RzSalaryDetail; +import com.evo.finance.mapper.RzSalaryDetailMapper; +import com.evo.system.domain.SysStaffDetail; +import com.evo.system.mapper.SysStaffDetailMapper; +import org.springframework.stereotype.Service; +import com.evo.finance.mapper.RzSalaryStatisticsMapper; +import com.evo.finance.domain.RzSalaryStatistics; +import com.evo.finance.service.IRzSalaryStatisticsService; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; + +/** + * 工资统计Service业务层处理 + * + * @author evo + * @date 2024-11-26 + */ +@Service +public class RzSalaryStatisticsServiceImpl implements IRzSalaryStatisticsService +{ + @Resource + private RzSalaryStatisticsMapper rzSalaryStatisticsMapper; + @Resource + private RzSalaryDetailMapper rzSalaryDetailMapper; //工资详情 + @Resource + private SysStaffDetailMapper sysStaffDetailMapper; //员工详情 + /** + * 查询工资统计列表 + * + * @param rzSalaryStatistics 工资统计 + * @return 工资统计 + */ + @Override + public List selectRzSalaryStatisticsList(RzSalaryStatistics rzSalaryStatistics) + { + return rzSalaryStatisticsMapper.selectRzSalaryStatisticsList(rzSalaryStatistics); + } + + /** + * 删除工资统计信息 + * + * @param id 工资统计主键 + * @return 结果 + */ + @Override + @Transactional + public AjaxResult deleteRzSalaryStatisticsById(Long id) + { + RzSalaryStatistics rzSalaryStatistics = rzSalaryStatisticsMapper.selectRzSalaryStatisticsById(id); + //根据月份查询员工的工资统计 + List gz_list = rzSalaryDetailMapper.selectRzSalaryDetailByMonth(rzSalaryStatistics.getMonth()); + for (RzSalaryDetail rzSalaryDetail : gz_list) { + //根据员工ID查询员工详情,修改员工详情 + SysStaffDetail sysStaffDetail = sysStaffDetailMapper.selectSysStaffDetailByStaffId(rzSalaryDetail.getStaffId()); + //修改个人详情 + sysStaffDetail.setAggregatePersonalIncomeTax(sysStaffDetail.getAggregatePersonalIncomeTax().subtract(rzSalaryDetail.getTaxPayable())); + sysStaffDetail.setSpecialDeduction(sysStaffDetail.getSpecialDeduction().subtract(rzSalaryDetail.getSpecialDeduction())); + sysStaffDetail.setTotalWages(sysStaffDetail.getTotalWages().subtract(rzSalaryDetail.getSalaryBeforeTax())); + int i = sysStaffDetailMapper.updateSysStaffDetail(sysStaffDetail); + if(i < 1){ + return AjaxResult.error(); + } + //删除个人员工工资详情 + rzSalaryDetail.setDelFlag(Constants.DELETE_FLAG_1); + rzSalaryDetail.setUpdateBy(SecurityUtils.getUsername()); + rzSalaryDetail.setUpdateTime(DateUtils.getNowDate()); + i = rzSalaryDetailMapper.updateRzSalaryDetail(rzSalaryDetail); + if(i < 1){ + return AjaxResult.error(); + } + } + rzSalaryStatistics.setDelFlag(Constants.DELETE_FLAG_1); + rzSalaryStatistics.setUpdateTime(DateUtils.getNowDate()); + rzSalaryStatistics.setUpdateBy(SecurityUtils.getUsername()); + int p = rzSalaryStatisticsMapper.updateRzSalaryStatistics(rzSalaryStatistics); + if(p< 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } +} diff --git a/evo-admin/src/main/java/com/evo/framework/aspectj/DataScopeAspect.java b/evo-admin/src/main/java/com/evo/framework/aspectj/DataScopeAspect.java new file mode 100644 index 0000000..7fc2832 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/aspectj/DataScopeAspect.java @@ -0,0 +1,184 @@ +package com.evo.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.evo.common.annotation.DataScope; +import com.evo.common.core.domain.BaseEntity; +import com.evo.common.core.domain.entity.SysRole; +import com.evo.common.core.domain.entity.SysUser; +import com.evo.common.core.domain.model.LoginUser; +import com.evo.common.core.text.Convert; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.framework.security.context.PermissionContextHolder; + +/** + * 数据过滤处理 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/aspectj/DataSourceAspect.java b/evo-admin/src/main/java/com/evo/framework/aspectj/DataSourceAspect.java new file mode 100644 index 0000000..6f724fd --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/aspectj/DataSourceAspect.java @@ -0,0 +1,72 @@ +package com.evo.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.evo.common.annotation.DataSource; +import com.evo.common.utils.StringUtils; +import com.evo.framework.datasource.DynamicDataSourceContextHolder; + +/** + * 多数据源处理 + * + * @author evo + */ +@Aspect +@Order(1) +@Component +public class DataSourceAspect +{ + protected Logger logger = LoggerFactory.getLogger(getClass()); + + @Pointcut("@annotation(com.evo.common.annotation.DataSource)" + + "|| @within(com.evo.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/evo-admin/src/main/java/com/evo/framework/aspectj/LogAspect.java b/evo-admin/src/main/java/com/evo/framework/aspectj/LogAspect.java new file mode 100644 index 0000000..36c2fb7 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/aspectj/LogAspect.java @@ -0,0 +1,255 @@ +package com.evo.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.evo.common.annotation.Log; +import com.evo.common.core.domain.entity.SysUser; +import com.evo.common.core.domain.model.LoginUser; +import com.evo.common.enums.BusinessStatus; +import com.evo.common.enums.HttpMethod; +import com.evo.common.filter.PropertyPreExcludeFilter; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.ServletUtils; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.ip.IpUtils; +import com.evo.framework.manager.AsyncManager; +import com.evo.framework.manager.factory.AsyncFactory; +import com.evo.system.domain.SysOperLog; + +/** + * 操作日志记录处理 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/aspectj/RateLimiterAspect.java b/evo-admin/src/main/java/com/evo/framework/aspectj/RateLimiterAspect.java new file mode 100644 index 0000000..36e0044 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/aspectj/RateLimiterAspect.java @@ -0,0 +1,89 @@ +package com.evo.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.evo.common.annotation.RateLimiter; +import com.evo.common.enums.LimitType; +import com.evo.common.exception.ServiceException; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.ip.IpUtils; + +/** + * 限流处理 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/config/ApplicationConfig.java b/evo-admin/src/main/java/com/evo/framework/config/ApplicationConfig.java new file mode 100644 index 0000000..05a94cf --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/config/ApplicationConfig.java @@ -0,0 +1,30 @@ +package com.evo.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 evo + */ +@Configuration +// 表示通过aop框架暴露该代理对象,AopContext能够访问 +@EnableAspectJAutoProxy(exposeProxy = true) +// 指定要扫描的Mapper类的包的路径 +@MapperScan("com.evo.**.mapper") +public class ApplicationConfig +{ + /** + * 时区配置 + */ + @Bean + public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() + { + return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault()); + } +} diff --git a/evo-admin/src/main/java/com/evo/framework/config/DruidConfig.java b/evo-admin/src/main/java/com/evo/framework/config/DruidConfig.java new file mode 100644 index 0000000..ab605df --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/config/DruidConfig.java @@ -0,0 +1,126 @@ +package com.evo.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.evo.common.enums.DataSourceType; +import com.evo.common.utils.spring.SpringUtils; +import com.evo.framework.config.properties.DruidProperties; +import com.evo.framework.datasource.DynamicDataSource; + +/** + * druid 配置多数据源 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/config/FastJson2JsonRedisSerializer.java b/evo-admin/src/main/java/com/evo/framework/config/FastJson2JsonRedisSerializer.java new file mode 100644 index 0000000..1c74468 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/config/FastJson2JsonRedisSerializer.java @@ -0,0 +1,52 @@ +package com.evo.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.evo.common.constant.Constants; + +/** + * Redis使用FastJson序列化 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/framework/config/FilterConfig.java b/evo-admin/src/main/java/com/evo/framework/config/FilterConfig.java new file mode 100644 index 0000000..821b6a7 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/config/FilterConfig.java @@ -0,0 +1,58 @@ +package com.evo.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.evo.common.filter.RepeatableFilter; +import com.evo.common.filter.XssFilter; +import com.evo.common.utils.StringUtils; + +/** + * Filter配置 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/config/I18nConfig.java b/evo-admin/src/main/java/com/evo/framework/config/I18nConfig.java new file mode 100644 index 0000000..148eeaf --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/config/I18nConfig.java @@ -0,0 +1,43 @@ +package com.evo.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.evo.common.constant.Constants; + +/** + * 资源文件配置加载 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/config/MyBatisConfig.java b/evo-admin/src/main/java/com/evo/framework/config/MyBatisConfig.java new file mode 100644 index 0000000..db4e168 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/config/MyBatisConfig.java @@ -0,0 +1,132 @@ +package com.evo.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.evo.common.utils.StringUtils; + +/** + * Mybatis支持*匹配扫描包 + * + * @author evo + */ +@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(); + } +} diff --git a/evo-admin/src/main/java/com/evo/framework/config/RedisConfig.java b/evo-admin/src/main/java/com/evo/framework/config/RedisConfig.java new file mode 100644 index 0000000..850d778 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/config/RedisConfig.java @@ -0,0 +1,69 @@ +package com.evo.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 evo + */ +@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/evo-admin/src/main/java/com/evo/framework/config/ResourcesConfig.java b/evo-admin/src/main/java/com/evo/framework/config/ResourcesConfig.java new file mode 100644 index 0000000..9cf0bea --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/config/ResourcesConfig.java @@ -0,0 +1,73 @@ +package com.evo.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.evo.common.config.EvoConfig; +import com.evo.common.constant.Constants; +import com.evo.framework.interceptor.RepeatSubmitInterceptor; + +/** + * 通用配置 + * + * @author evo + */ +@Configuration +public class ResourcesConfig implements WebMvcConfigurer +{ + @Autowired + private RepeatSubmitInterceptor repeatSubmitInterceptor; + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) + { + /** 本地文件上传路径 */ + registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**") + .addResourceLocations("file:" + EvoConfig.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); + } +} diff --git a/evo-admin/src/main/java/com/evo/framework/config/SecurityConfig.java b/evo-admin/src/main/java/com/evo/framework/config/SecurityConfig.java new file mode 100644 index 0000000..072a00c --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/config/SecurityConfig.java @@ -0,0 +1,144 @@ +package com.evo.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.evo.framework.config.properties.PermitAllUrlProperties; +import com.evo.framework.security.filter.JwtAuthenticationTokenFilter; +import com.evo.framework.security.handle.AuthenticationEntryPointImpl; +import com.evo.framework.security.handle.LogoutSuccessHandlerImpl; + +/** + * spring security配置 + * + * @author evo + */ +@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 允许匿名访问 + requests.antMatchers("/login", "/register", "/captchaImage").permitAll() + .antMatchers("/common/download").permitAll() + // 静态资源,可匿名访问 + .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() + .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() + .antMatchers("/websocket/**").permitAll() + .antMatchers("/api/v1/verify_user").permitAll() + .antMatchers("/api/v1/record/face").permitAll() + .antMatchers("/api/v2/verify_user_yt").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/evo-admin/src/main/java/com/evo/framework/config/ServerConfig.java b/evo-admin/src/main/java/com/evo/framework/config/ServerConfig.java new file mode 100644 index 0000000..9aaafa7 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/config/ServerConfig.java @@ -0,0 +1,32 @@ +package com.evo.framework.config; + +import javax.servlet.http.HttpServletRequest; +import org.springframework.stereotype.Component; +import com.evo.common.utils.ServletUtils; + +/** + * 服务相关配置 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/config/ThreadPoolConfig.java b/evo-admin/src/main/java/com/evo/framework/config/ThreadPoolConfig.java new file mode 100644 index 0000000..4d6f019 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/config/ThreadPoolConfig.java @@ -0,0 +1,63 @@ +package com.evo.framework.config; + +import com.evo.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 evo + **/ +@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/evo-admin/src/main/java/com/evo/framework/config/properties/DruidProperties.java b/evo-admin/src/main/java/com/evo/framework/config/properties/DruidProperties.java new file mode 100644 index 0000000..538f1b9 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/config/properties/DruidProperties.java @@ -0,0 +1,89 @@ +package com.evo.framework.config.properties; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import com.alibaba.druid.pool.DruidDataSource; + +/** + * druid 配置属性 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/config/properties/PermitAllUrlProperties.java b/evo-admin/src/main/java/com/evo/framework/config/properties/PermitAllUrlProperties.java new file mode 100644 index 0000000..655a2d8 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/config/properties/PermitAllUrlProperties.java @@ -0,0 +1,73 @@ +package com.evo.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.evo.common.annotation.Anonymous; + +/** + * 设置Anonymous注解允许匿名访问的url + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/datasource/DynamicDataSource.java b/evo-admin/src/main/java/com/evo/framework/datasource/DynamicDataSource.java new file mode 100644 index 0000000..cc7f169 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/datasource/DynamicDataSource.java @@ -0,0 +1,26 @@ +package com.evo.framework.datasource; + +import java.util.Map; +import javax.sql.DataSource; +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; + +/** + * 动态数据源 + * + * @author evo + */ +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(); + } +} diff --git a/evo-admin/src/main/java/com/evo/framework/datasource/DynamicDataSourceContextHolder.java b/evo-admin/src/main/java/com/evo/framework/datasource/DynamicDataSourceContextHolder.java new file mode 100644 index 0000000..e5b6e52 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/datasource/DynamicDataSourceContextHolder.java @@ -0,0 +1,45 @@ +package com.evo.framework.datasource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 数据源切换处理 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/framework/interceptor/RepeatSubmitInterceptor.java b/evo-admin/src/main/java/com/evo/framework/interceptor/RepeatSubmitInterceptor.java new file mode 100644 index 0000000..ad81a9f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/interceptor/RepeatSubmitInterceptor.java @@ -0,0 +1,56 @@ +package com.evo.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.evo.common.annotation.RepeatSubmit; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.ServletUtils; + +/** + * 防止重复提交拦截器 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/interceptor/impl/SameUrlDataInterceptor.java b/evo-admin/src/main/java/com/evo/framework/interceptor/impl/SameUrlDataInterceptor.java new file mode 100644 index 0000000..1b1f990 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/interceptor/impl/SameUrlDataInterceptor.java @@ -0,0 +1,110 @@ +package com.evo.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.evo.common.annotation.RepeatSubmit; +import com.evo.common.constant.CacheConstants; +import com.evo.common.core.redis.RedisCache; +import com.evo.common.filter.RepeatedlyRequestWrapper; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.http.HttpHelper; +import com.evo.framework.interceptor.RepeatSubmitInterceptor; + +/** + * 判断请求url和数据是否和上一次相同, + * 如果和上次相同,则是重复提交表单。 有效时间为10秒内。 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/manager/AsyncManager.java b/evo-admin/src/main/java/com/evo/framework/manager/AsyncManager.java new file mode 100644 index 0000000..20a5d23 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/manager/AsyncManager.java @@ -0,0 +1,55 @@ +package com.evo.framework.manager; + +import java.util.TimerTask; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import com.evo.common.utils.Threads; +import com.evo.common.utils.spring.SpringUtils; + +/** + * 异步任务管理器 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/framework/manager/ShutdownManager.java b/evo-admin/src/main/java/com/evo/framework/manager/ShutdownManager.java new file mode 100644 index 0000000..e502fd6 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/manager/ShutdownManager.java @@ -0,0 +1,39 @@ +package com.evo.framework.manager; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import javax.annotation.PreDestroy; + +/** + * 确保应用退出时能关闭后台线程 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/manager/factory/AsyncFactory.java b/evo-admin/src/main/java/com/evo/framework/manager/factory/AsyncFactory.java new file mode 100644 index 0000000..3e748fb --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/manager/factory/AsyncFactory.java @@ -0,0 +1,102 @@ +package com.evo.framework.manager.factory; + +import java.util.TimerTask; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.evo.common.constant.Constants; +import com.evo.common.utils.LogUtils; +import com.evo.common.utils.ServletUtils; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.ip.AddressUtils; +import com.evo.common.utils.ip.IpUtils; +import com.evo.common.utils.spring.SpringUtils; +import com.evo.system.domain.SysLogininfor; +import com.evo.system.domain.SysOperLog; +import com.evo.system.service.ISysLogininforService; +import com.evo.system.service.ISysOperLogService; +import eu.bitwalker.useragentutils.UserAgent; + +/** + * 异步工厂(产生任务用) + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/framework/security/context/AuthenticationContextHolder.java b/evo-admin/src/main/java/com/evo/framework/security/context/AuthenticationContextHolder.java new file mode 100644 index 0000000..dc9da20 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/security/context/AuthenticationContextHolder.java @@ -0,0 +1,28 @@ +package com.evo.framework.security.context; + +import org.springframework.security.core.Authentication; + +/** + * 身份验证信息 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/framework/security/context/PermissionContextHolder.java b/evo-admin/src/main/java/com/evo/framework/security/context/PermissionContextHolder.java new file mode 100644 index 0000000..52b29f5 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/security/context/PermissionContextHolder.java @@ -0,0 +1,27 @@ +package com.evo.framework.security.context; + +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import com.evo.common.core.text.Convert; + +/** + * 权限信息 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/framework/security/filter/JwtAuthenticationTokenFilter.java b/evo-admin/src/main/java/com/evo/framework/security/filter/JwtAuthenticationTokenFilter.java new file mode 100644 index 0000000..f6063e8 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/security/filter/JwtAuthenticationTokenFilter.java @@ -0,0 +1,44 @@ +package com.evo.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.evo.common.core.domain.model.LoginUser; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.framework.web.service.TokenService; + +/** + * token过滤器 验证token有效性 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/security/handle/AuthenticationEntryPointImpl.java b/evo-admin/src/main/java/com/evo/framework/security/handle/AuthenticationEntryPointImpl.java new file mode 100644 index 0000000..2dc2eaa --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/security/handle/AuthenticationEntryPointImpl.java @@ -0,0 +1,34 @@ +package com.evo.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.evo.common.constant.HttpStatus; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.ServletUtils; +import com.evo.common.utils.StringUtils; + +/** + * 认证失败处理类 返回未授权 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/security/handle/LogoutSuccessHandlerImpl.java b/evo-admin/src/main/java/com/evo/framework/security/handle/LogoutSuccessHandlerImpl.java new file mode 100644 index 0000000..e6f5618 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/security/handle/LogoutSuccessHandlerImpl.java @@ -0,0 +1,53 @@ +package com.evo.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.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.domain.model.LoginUser; +import com.evo.common.utils.MessageUtils; +import com.evo.common.utils.ServletUtils; +import com.evo.common.utils.StringUtils; +import com.evo.framework.manager.AsyncManager; +import com.evo.framework.manager.factory.AsyncFactory; +import com.evo.framework.web.service.TokenService; + +/** + * 自定义退出处理类 返回成功 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/web/exception/GlobalExceptionHandler.java b/evo-admin/src/main/java/com/evo/framework/web/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..7c6fd61 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/web/exception/GlobalExceptionHandler.java @@ -0,0 +1,145 @@ +package com.evo.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.evo.common.constant.HttpStatus; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.text.Convert; +import com.evo.common.exception.DemoModeException; +import com.evo.common.exception.ServiceException; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.html.EscapeUtil; + +/** + * 全局异常处理器 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/web/service/PermissionService.java b/evo-admin/src/main/java/com/evo/framework/web/service/PermissionService.java new file mode 100644 index 0000000..1c7c5dd --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/web/service/PermissionService.java @@ -0,0 +1,159 @@ +package com.evo.framework.web.service; + +import java.util.Set; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.entity.SysRole; +import com.evo.common.core.domain.model.LoginUser; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.framework.security.context.PermissionContextHolder; + +/** + * evo首创 自定义权限实现,ss取自SpringSecurity首字母 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/web/service/SysLoginService.java b/evo-admin/src/main/java/com/evo/framework/web/service/SysLoginService.java new file mode 100644 index 0000000..5ea9eaa --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/web/service/SysLoginService.java @@ -0,0 +1,129 @@ +package com.evo.framework.web.service; + +import javax.annotation.Resource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; +import com.evo.common.constant.Constants; +import com.evo.common.constant.UserConstants; +import com.evo.common.core.domain.entity.SysUser; +import com.evo.common.core.domain.model.LoginUser; +import com.evo.common.core.redis.RedisCache; +import com.evo.common.exception.ServiceException; +import com.evo.common.exception.user.UserNotExistsException; +import com.evo.common.exception.user.UserPasswordNotMatchException; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.MessageUtils; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.ip.IpUtils; +import com.evo.framework.manager.AsyncManager; +import com.evo.framework.manager.factory.AsyncFactory; +import com.evo.framework.security.context.AuthenticationContextHolder; +import com.evo.system.service.ISysUserService; + +/** + * 登录校验方法 + * + * @author evo + */ +@Component +public class SysLoginService +{ + @Autowired + private TokenService tokenService; + + @Resource + private AuthenticationManager authenticationManager; + + @Autowired + private ISysUserService userService; + /** + * 登录验证 + * + * @param username 用户名 + * @param password 密码 + * @return 结果 + */ + public String login(String username, String password) + { + // 登录前置校验 + 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); + } + + /** + * 登录前置校验 + * @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(); + } + } + + /** + * 记录登录信息 + * + * @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/evo-admin/src/main/java/com/evo/framework/web/service/SysPasswordService.java b/evo-admin/src/main/java/com/evo/framework/web/service/SysPasswordService.java new file mode 100644 index 0000000..a0b7f70 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/web/service/SysPasswordService.java @@ -0,0 +1,86 @@ +package com.evo.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.evo.common.constant.CacheConstants; +import com.evo.common.core.domain.entity.SysUser; +import com.evo.common.core.redis.RedisCache; +import com.evo.common.exception.user.UserPasswordNotMatchException; +import com.evo.common.exception.user.UserPasswordRetryLimitExceedException; +import com.evo.common.utils.SecurityUtils; +import com.evo.framework.security.context.AuthenticationContextHolder; + +/** + * 登录密码方法 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/web/service/SysPermissionService.java b/evo-admin/src/main/java/com/evo/framework/web/service/SysPermissionService.java new file mode 100644 index 0000000..d1edd88 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/web/service/SysPermissionService.java @@ -0,0 +1,83 @@ +package com.evo.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.evo.common.core.domain.entity.SysRole; +import com.evo.common.core.domain.entity.SysUser; +import com.evo.system.service.ISysMenuService; +import com.evo.system.service.ISysRoleService; + +/** + * 用户权限处理 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/web/service/SysRegisterService.java b/evo-admin/src/main/java/com/evo/framework/web/service/SysRegisterService.java new file mode 100644 index 0000000..32ced03 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/web/service/SysRegisterService.java @@ -0,0 +1,104 @@ +package com.evo.framework.web.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.evo.common.constant.CacheConstants; +import com.evo.common.constant.Constants; +import com.evo.common.constant.UserConstants; +import com.evo.common.core.domain.entity.SysUser; +import com.evo.common.core.domain.model.RegisterBody; +import com.evo.common.core.redis.RedisCache; +import com.evo.common.exception.user.CaptchaException; +import com.evo.common.exception.user.CaptchaExpireException; +import com.evo.common.utils.MessageUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.framework.manager.AsyncManager; +import com.evo.framework.manager.factory.AsyncFactory; +import com.evo.system.service.ISysUserService; + +/** + * 注册校验方法 + * + * @author evo + */ +@Component +public class SysRegisterService +{ + @Autowired + private ISysUserService userService; + + @Autowired + private RedisCache redisCache; + + /** + * 注册 + */ + public String register(RegisterBody registerBody) + { + String msg = "", username = registerBody.getUsername(), password = registerBody.getPassword(); + SysUser sysUser = new SysUser(); + sysUser.setUserName(username); + + 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/evo-admin/src/main/java/com/evo/framework/web/service/TokenService.java b/evo-admin/src/main/java/com/evo/framework/web/service/TokenService.java new file mode 100644 index 0000000..222c012 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/web/service/TokenService.java @@ -0,0 +1,231 @@ +package com.evo.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.evo.common.constant.CacheConstants; +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.model.LoginUser; +import com.evo.common.core.redis.RedisCache; +import com.evo.common.utils.ServletUtils; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.ip.AddressUtils; +import com.evo.common.utils.ip.IpUtils; +import com.evo.common.utils.uuid.IdUtils; +import eu.bitwalker.useragentutils.UserAgent; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; + +/** + * token验证处理 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/web/service/UserDetailsServiceImpl.java b/evo-admin/src/main/java/com/evo/framework/web/service/UserDetailsServiceImpl.java new file mode 100644 index 0000000..ebed900 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/web/service/UserDetailsServiceImpl.java @@ -0,0 +1,66 @@ +package com.evo.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.evo.common.core.domain.entity.SysUser; +import com.evo.common.core.domain.model.LoginUser; +import com.evo.common.enums.UserStatus; +import com.evo.common.exception.ServiceException; +import com.evo.common.utils.MessageUtils; +import com.evo.common.utils.StringUtils; +import com.evo.system.service.ISysUserService; + +/** + * 用户验证处理 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/framework/websocket/SemaphoreUtils.java b/evo-admin/src/main/java/com/evo/framework/websocket/SemaphoreUtils.java new file mode 100644 index 0000000..4b00165 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/websocket/SemaphoreUtils.java @@ -0,0 +1,59 @@ +package com.evo.framework.websocket; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.Semaphore; + +/** + * 信号量相关处理 + * + * @author ruoyi + */ +public class SemaphoreUtils +{ + /** + * SemaphoreUtils 日志控制器 + */ + private static final Logger LOGGER = LoggerFactory.getLogger(SemaphoreUtils.class); + + /** + * 获取信号量 + * + * @param semaphore + * @return + */ + public static boolean tryAcquire(Semaphore semaphore) + { + boolean flag = false; + + try + { + flag = semaphore.tryAcquire(); + } + catch (Exception e) + { + LOGGER.error("获取信号量异常", e); + } + + return flag; + } + + /** + * 释放信号量 + * + * @param semaphore + */ + public static void release(Semaphore semaphore) + { + + try + { + semaphore.release(); + } + catch (Exception e) + { + LOGGER.error("释放信号量异常", e); + } + } +} diff --git a/evo-admin/src/main/java/com/evo/framework/websocket/WebSocketConfig.java b/evo-admin/src/main/java/com/evo/framework/websocket/WebSocketConfig.java new file mode 100644 index 0000000..654650a --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/websocket/WebSocketConfig.java @@ -0,0 +1,22 @@ +package com.evo.framework.websocket; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/** + * websocket 配置 + * + * @author ruoyi + */ +@ConditionalOnProperty(name = "spring.profiles.active", havingValue = "") +@Configuration +public class WebSocketConfig +{ + @Bean + public ServerEndpointExporter serverEndpointExporter() + { + return new ServerEndpointExporter(); + } +} diff --git a/evo-admin/src/main/java/com/evo/framework/websocket/WebSocketServer.java b/evo-admin/src/main/java/com/evo/framework/websocket/WebSocketServer.java new file mode 100644 index 0000000..670f970 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/websocket/WebSocketServer.java @@ -0,0 +1,166 @@ +package com.evo.framework.websocket; + +import com.alibaba.fastjson2.JSONObject; +import com.evo.common.constant.Constants; +import com.evo.equipment.domain.EqSnDetail; +import com.evo.equipment.service.IEqSnDetailService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.stereotype.Component; +import javax.websocket.*; +import javax.websocket.server.ServerEndpoint; +import java.util.Date; +import java.util.concurrent.Semaphore; + +/** + * websocket 消息处理 + * + * @author ruoyi + */ +@ConditionalOnClass(value = WebSocketServer.class) +@Component +@ServerEndpoint("/websocket/message") +public class WebSocketServer{ + + private static IEqSnDetailService snDetailService; + + @Autowired + public void setBrandService(IEqSnDetailService snDetailService) { + WebSocketServer.snDetailService = snDetailService; + } + + /** + * WebSocketServer 日志控制器 + */ + private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketServer.class); + + /** + * 默认最多允许同时在线人数100 + */ + public static int socketMaxOnlineCount = 100; + + private static Semaphore socketSemaphore = new Semaphore(socketMaxOnlineCount); + + /** + * 连接建立成功调用的方法 + */ + @OnOpen + public void onOpen(Session session) throws Exception{ + boolean semaphoreFlag = false; + // 尝试获取信号量 + semaphoreFlag = SemaphoreUtils.tryAcquire(socketSemaphore); + if (!semaphoreFlag){ + // 未获取到信号量 + LOGGER.error("\n 当前在线人数超过限制数- {}", socketMaxOnlineCount); + WebSocketUsers.sendMessageToUserByText(session, "当前在线人数超过限制数:" + socketMaxOnlineCount); + session.close(); + }else{ + // 添加用户 + WebSocketUsers.put(session.getId(), session); + LOGGER.info("\n 建立连接 - {}", session); + LOGGER.info("\n 当前人数 - {}", WebSocketUsers.getUsers().size()); + } + } + + /** + * 连接关闭时处理 + */ + @OnClose + public void onClose(Session session) + { + LOGGER.info("\n 关闭连接 - {}", session); + // 移除用户 + WebSocketUsers.remove(session.getId()); + // 获取到信号量则需释放 + SemaphoreUtils.release(socketSemaphore); + } + + /** + * 抛出异常时处理 + */ + @OnError + public void onError(Session session, Throwable exception) throws Exception + { + if (session.isOpen()) + { + // 关闭连接 + session.close(); + } + String sessionId = session.getId(); + LOGGER.info("\n 连接异常 - {}", sessionId); + LOGGER.info("\n 异常信息 - {}", exception); + // 移出用户 + WebSocketUsers.remove(sessionId); + // 获取到信号量则需释放 + SemaphoreUtils.release(socketSemaphore); + } + + /** + * 服务器接收到客户端消息时调用的方法 + */ + @OnMessage + public void onMessage(String message, Session session){ + + //解析客户端发送的消息 + JSONObject jsonObject = JSONObject.parseObject(message); + System.out.println("shuju:"+jsonObject); + String cmd = jsonObject.getString("cmd"); + if(null != cmd&&cmd.equals("ping")){ + //心跳请求 + String s = "{\"cmd\":\"pong\"}"; + //单发user 返回 pong + WebSocketUsers.sendMessageToUserByText(session,s); + } + if(null != cmd&&cmd.equals("declare")){ + //客户端声明,判断设备信息表中是否有此设备的信息,如果有则修改,如果没有则新增 + //请求的数据 + String type = jsonObject.getString("type"); + //设备号 + String sn = jsonObject.getString("sn"); + //内部版本号 + String version_code = jsonObject.getString("version_code"); + //设备识别页面显示的版本号 + String version_name = jsonObject.getString("version_name"); + //ip地址 + String ip = jsonObject.getString("ip"); + //设备当前时间,秒级别时间戳 + String timestamp = jsonObject.getString("timestamp"); + //根据设备号查询 + EqSnDetail snDetail = snDetailService.selectEqSnDetailBySn(sn); + + //格式化时间 + Date date = new Date(); + if(null != timestamp){ + date.setTime(Long.valueOf(timestamp)*1000); + } + if(null != snDetail){ + //说明添加过此设备,修改 + snDetail.setVersionCode(version_code); + snDetail.setVersionName(version_name); + snDetail.setIp(ip); + snDetail.setSnTime(date); + snDetail.setType("已连接"); + //修改 + snDetailService.updateEqSnDetail(snDetail); + }else{ + //说明没有添加过此设备,添加 + snDetail = new EqSnDetail(); + //设备号 + snDetail.setSn(sn); + snDetail.setVersionCode(version_code); + snDetail.setVersionName(version_name); + snDetail.setIp(ip); + snDetail.setSnTime(date); + snDetail.setType("已连接"); + snDetail.setDelFlag(Constants.DELETE_FLAG_0); + //添加 + snDetailService.insertEqSnDetail(snDetail); + } + }else{ + //接受设备端返回的数据,先不做处理 + System.out.println("设备返回信息:"+message); + } + } +} diff --git a/evo-admin/src/main/java/com/evo/framework/websocket/WebSocketUsers.java b/evo-admin/src/main/java/com/evo/framework/websocket/WebSocketUsers.java new file mode 100644 index 0000000..5738c6f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/framework/websocket/WebSocketUsers.java @@ -0,0 +1,135 @@ +package com.evo.framework.websocket; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.websocket.Session; +import java.io.IOException; +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * websocket 客户端用户集 + * + * @author ruoyi + */ +public class WebSocketUsers +{ + /** + * WebSocketUsers 日志控制器 + */ + private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketUsers.class); + + /** + * 用户集 + */ + private static Map USERS = new ConcurrentHashMap(); + + /** + * 存储用户 + * + * @param key 唯一键 + * @param session 用户信息 + */ + public static void put(String key, Session session) + { + USERS.put(key, session); + } + + /** + * 移除用户 + * + * @param session 用户信息 + * + * @return 移除结果 + */ + public static boolean remove(Session session) + { + String key = null; + boolean flag = USERS.containsValue(session); + if (flag){ + Set> entries = USERS.entrySet(); + for (Map.Entry entry : entries){ + Session value = entry.getValue(); + if (value.equals(session)){ + key = entry.getKey(); + break; + } + } + } + else{ + return true; + } + return remove(key); + } + + /** + * 移出用户 + * + * @param key 键 + */ + public static boolean remove(String key) + { + LOGGER.info("\n 正在移出用户 - {}", key); + Session remove = USERS.remove(key); + if (remove != null){ + boolean containsValue = USERS.containsValue(remove); + LOGGER.info("\n 移出结果 - {}", containsValue ? "失败" : "成功"); + return containsValue; + } + else + { + return true; + } + } + + /** + * 获取在线用户列表 + * + * @return 返回用户集合 + */ + public static Map getUsers() + { + return USERS; + } + + /** + * 群发消息文本消息 + * + * @param message 消息内容 + */ + public static void sendMessageToUsersByText(String message){ + Collection values = USERS.values(); + for (Session value : values){ + sendMessageToUserByText(value, message); + } + } + + /** + * 发送文本消息 + * + * @param session 自己的用户名 + * @param message 消息内容 + */ + public static void sendMessageToUserByText(Session session, String message) + { + if (session != null) + { + try + { + session.getBasicRemote().sendText(message); + System.out.println("发送成功:"+message); + } + catch (IOException e) + { + LOGGER.error("\n[发送消息异常]", e); + } + } + else + { + LOGGER.info("\n[你已离线]"); + } + } +} diff --git a/evo-admin/src/main/java/com/evo/generator/config/GenConfig.java b/evo-admin/src/main/java/com/evo/generator/config/GenConfig.java new file mode 100644 index 0000000..c6852e7 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/generator/config/GenConfig.java @@ -0,0 +1,73 @@ +package com.evo.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 evo + */ +@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/evo-admin/src/main/java/com/evo/generator/controller/GenController.java b/evo-admin/src/main/java/com/evo/generator/controller/GenController.java new file mode 100644 index 0000000..10ccd37 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/generator/controller/GenController.java @@ -0,0 +1,258 @@ +package com.evo.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.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.core.text.Convert; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.sql.SqlUtil; +import com.evo.generator.domain.GenTable; +import com.evo.generator.domain.GenTableColumn; +import com.evo.generator.service.IGenTableColumnService; +import com.evo.generator.service.IGenTableService; + +/** + * 代码生成 操作处理 + * + * @author evo + */ +@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=\"evo.zip\""); + response.addHeader("Content-Length", "" + data.length); + response.setContentType("application/octet-stream; charset=UTF-8"); + IOUtils.write(data, response.getOutputStream()); + } +} diff --git a/evo-admin/src/main/java/com/evo/generator/domain/GenTable.java b/evo-admin/src/main/java/com/evo/generator/domain/GenTable.java new file mode 100644 index 0000000..36971b5 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/generator/domain/GenTable.java @@ -0,0 +1,385 @@ +package com.evo.generator.domain; + +import java.util.List; +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import org.apache.commons.lang3.ArrayUtils; +import com.evo.common.constant.GenConstants; +import com.evo.common.core.domain.BaseEntity; +import com.evo.common.utils.StringUtils; + +/** + * 业务表 gen_table + * + * @author evo + */ +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); + } +} diff --git a/evo-admin/src/main/java/com/evo/generator/domain/GenTableColumn.java b/evo-admin/src/main/java/com/evo/generator/domain/GenTableColumn.java new file mode 100644 index 0000000..0cffc2f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/generator/domain/GenTableColumn.java @@ -0,0 +1,373 @@ +package com.evo.generator.domain; + +import javax.validation.constraints.NotBlank; +import com.evo.common.core.domain.BaseEntity; +import com.evo.common.utils.StringUtils; + +/** + * 代码生成业务字段表 gen_table_column + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/generator/mapper/GenTableColumnMapper.java b/evo-admin/src/main/java/com/evo/generator/mapper/GenTableColumnMapper.java new file mode 100644 index 0000000..09e40db --- /dev/null +++ b/evo-admin/src/main/java/com/evo/generator/mapper/GenTableColumnMapper.java @@ -0,0 +1,60 @@ +package com.evo.generator.mapper; + +import java.util.List; +import com.evo.generator.domain.GenTableColumn; + +/** + * 业务字段 数据层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/generator/mapper/GenTableMapper.java b/evo-admin/src/main/java/com/evo/generator/mapper/GenTableMapper.java new file mode 100644 index 0000000..3186f85 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/generator/mapper/GenTableMapper.java @@ -0,0 +1,91 @@ +package com.evo.generator.mapper; + +import java.util.List; +import com.evo.generator.domain.GenTable; + +/** + * 业务 数据层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/generator/service/GenTableColumnServiceImpl.java b/evo-admin/src/main/java/com/evo/generator/service/GenTableColumnServiceImpl.java new file mode 100644 index 0000000..c0d26a9 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/generator/service/GenTableColumnServiceImpl.java @@ -0,0 +1,68 @@ +package com.evo.generator.service; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.evo.common.core.text.Convert; +import com.evo.generator.domain.GenTableColumn; +import com.evo.generator.mapper.GenTableColumnMapper; + +/** + * 业务字段 服务层实现 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/generator/service/GenTableServiceImpl.java b/evo-admin/src/main/java/com/evo/generator/service/GenTableServiceImpl.java new file mode 100644 index 0000000..500587d --- /dev/null +++ b/evo-admin/src/main/java/com/evo/generator/service/GenTableServiceImpl.java @@ -0,0 +1,531 @@ +package com.evo.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.evo.common.constant.Constants; +import com.evo.common.constant.GenConstants; +import com.evo.common.core.text.CharsetKit; +import com.evo.common.exception.ServiceException; +import com.evo.common.utils.StringUtils; +import com.evo.generator.domain.GenTable; +import com.evo.generator.domain.GenTableColumn; +import com.evo.generator.mapper.GenTableColumnMapper; +import com.evo.generator.mapper.GenTableMapper; +import com.evo.generator.util.GenUtils; +import com.evo.generator.util.VelocityInitializer; +import com.evo.generator.util.VelocityUtils; + +/** + * 业务 服务层实现 + * + * @author evo + */ +@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); + } +} diff --git a/evo-admin/src/main/java/com/evo/generator/service/IGenTableColumnService.java b/evo-admin/src/main/java/com/evo/generator/service/IGenTableColumnService.java new file mode 100644 index 0000000..4e0637b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/generator/service/IGenTableColumnService.java @@ -0,0 +1,44 @@ +package com.evo.generator.service; + +import java.util.List; +import com.evo.generator.domain.GenTableColumn; + +/** + * 业务字段 服务层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/generator/service/IGenTableService.java b/evo-admin/src/main/java/com/evo/generator/service/IGenTableService.java new file mode 100644 index 0000000..351095f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/generator/service/IGenTableService.java @@ -0,0 +1,130 @@ +package com.evo.generator.service; + +import java.util.List; +import java.util.Map; +import com.evo.generator.domain.GenTable; + +/** + * 业务 服务层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/generator/util/GenUtils.java b/evo-admin/src/main/java/com/evo/generator/util/GenUtils.java new file mode 100644 index 0000000..55bf8a8 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/generator/util/GenUtils.java @@ -0,0 +1,257 @@ +package com.evo.generator.util; + +import java.util.Arrays; +import org.apache.commons.lang3.RegExUtils; +import com.evo.common.constant.GenConstants; +import com.evo.common.utils.StringUtils; +import com.evo.generator.config.GenConfig; +import com.evo.generator.domain.GenTable; +import com.evo.generator.domain.GenTableColumn; + +/** + * 代码生成器 工具类 + * + * @author evo + */ +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, "(?:表|伊特)", ""); + } + + /** + * 获取数据库类型字段 + * + * @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/evo-admin/src/main/java/com/evo/generator/util/VelocityInitializer.java b/evo-admin/src/main/java/com/evo/generator/util/VelocityInitializer.java new file mode 100644 index 0000000..065974f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/generator/util/VelocityInitializer.java @@ -0,0 +1,34 @@ +package com.evo.generator.util; + +import java.util.Properties; +import org.apache.velocity.app.Velocity; +import com.evo.common.constant.Constants; + +/** + * VelocityEngine工厂 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/generator/util/VelocityUtils.java b/evo-admin/src/main/java/com/evo/generator/util/VelocityUtils.java new file mode 100644 index 0000000..1fee5f6 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/generator/util/VelocityUtils.java @@ -0,0 +1,408 @@ +package com.evo.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.evo.common.constant.GenConstants; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.StringUtils; +import com.evo.generator.domain.GenTable; +import com.evo.generator.domain.GenTableColumn; + +/** + * 模板处理工具类 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzBusinessTripController.java b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzBusinessTripController.java new file mode 100644 index 0000000..645a35a --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzBusinessTripController.java @@ -0,0 +1,98 @@ +package com.evo.personnelMatters.controller; + +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.personnelMatters.domain.RzBusinessTrip; +import com.evo.personnelMatters.service.IRzBusinessTripService; +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.util.List; + +/** + * 出差管理Controller + * + * @author chenyj + * @date 2024-08-30 + */ +@RestController +@RequestMapping("/personnelMatters/businessTrip") +public class RzBusinessTripController extends BaseController +{ + @Autowired + private IRzBusinessTripService rzBusinessTripService; + + /** + * 查询出差管理列表 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:businessTrip:list')") + @GetMapping("/list") + public TableDataInfo list(RzBusinessTrip rzBusinessTrip) + { + startPage(); + List list = rzBusinessTripService.selectRzBusinessTripList(rzBusinessTrip); + return getDataTable(list); + } + + /** + * 导出出差管理列表 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:businessTrip:export')") + @Log(title = "出差管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, RzBusinessTrip rzBusinessTrip) + { + List list = rzBusinessTripService.selectRzBusinessTripList(rzBusinessTrip); + ExcelUtil util = new ExcelUtil(RzBusinessTrip.class); + util.exportExcel(response, list, "出差管理数据"); + } + + /** + * 获取出差管理详细信息 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:businessTrip:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(rzBusinessTripService.selectRzBusinessTripById(id)); + } + + /** + * 新增出差管理 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:businessTrip:add')") + @Log(title = "出差管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody RzBusinessTrip rzBusinessTrip) + { + return rzBusinessTripService.insertRzBusinessTrip(rzBusinessTrip); + } + + /** + * 修改出差管理 + */ + @PreAuthorize("@ss.hasPermi('spersonnelMatters:businessTrip:edit')") + @Log(title = "出差管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody RzBusinessTrip rzBusinessTrip) + { + return toAjax(rzBusinessTripService.updateRzBusinessTrip(rzBusinessTrip)); + } + + /** + * 删除出差管理 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:businessTrip:remove')") + @Log(title = "出差管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return rzBusinessTripService.deleteRzBusinessTripById(id); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzBusinessTripDetailController.java b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzBusinessTripDetailController.java new file mode 100644 index 0000000..e259365 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzBusinessTripDetailController.java @@ -0,0 +1,82 @@ +package com.evo.personnelMatters.controller; + +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.personnelMatters.domain.RzBusinessTripDetail; +import com.evo.personnelMatters.service.IRzBusinessTripDetailService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import java.util.List; + +/** + * 出差详情Controller + * + * @author chenyj + * @date 2024-09-04 + */ +@RestController +@RequestMapping("/personnelMatters/businessTripDetail") +public class RzBusinessTripDetailController extends BaseController +{ + @Resource + private IRzBusinessTripDetailService rzTripDetailService; + + /** + * 查询出差详情列表 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:businessTripDetail:list')") + @GetMapping("/list") + public TableDataInfo list(RzBusinessTripDetail rzTripDetail) + { + startPage(); + List list = rzTripDetailService.selectRzTripDetailList(rzTripDetail); + return getDataTable(list); + } + + /** + * 获取出差详情详细信息 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:businessTripDetail:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(rzTripDetailService.selectRzTripDetailById(id)); + } + + /** + * 新增出差详情 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:businessTripDetail:add')") + @Log(title = "出差详情", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody RzBusinessTripDetail rzTripDetail) + { + return rzTripDetailService.insertRzTripDetail(rzTripDetail); + } + + /** + * 修改出差详情 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:businessTripDetail:edit')") + @Log(title = "出差详情", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody RzBusinessTripDetail rzTripDetail) + { + return rzTripDetailService.updateRzTripDetail(rzTripDetail); + } + + /** + * 删除出差详情 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:businessTripDetail:remove')") + @Log(title = "出差详情", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return rzTripDetailService.deleteRzTripDetailById(id); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzHolidayController.java b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzHolidayController.java new file mode 100644 index 0000000..06309e9 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzHolidayController.java @@ -0,0 +1,85 @@ +package com.evo.personnelMatters.controller; + +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.SecurityUtils; +import com.evo.personnelMatters.domain.RzHoliday; +import com.evo.personnelMatters.service.IRzHolidayService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import java.util.List; + +/** + * 假期管理Controller + * + * @author chenyj + * @date 2024-08-03 + */ +@RestController +@RequestMapping("/personnelMatters/holiday") +public class RzHolidayController extends BaseController +{ + @Autowired + private IRzHolidayService rzHolidayService; + + /** + * 查询假期管理列表 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:holiday:list')") + @GetMapping("/list") + public TableDataInfo list(RzHoliday rzHoliday) + { + startPage(); + List list = rzHolidayService.selectRzHolidayList(rzHoliday); + return getDataTable(list); + } + + /** + * 获取假期管理详细信息 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:holiday:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(rzHolidayService.selectRzHolidayById(id)); + } + + /** + * 新增假期管理 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:holiday:add')") + @Log(title = "假期管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody RzHoliday rzHoliday) + { + rzHoliday.setCreateBy(SecurityUtils.getUsername()); + return rzHolidayService.insertRzHoliday(rzHoliday); + } + + /** + * 修改假期管理 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:holiday:edit')") + @Log(title = "假期管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody RzHoliday rzHoliday) + { + rzHoliday.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(rzHolidayService.updateRzHoliday(rzHoliday)); + } + + /** + * 删除假期管理 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:holiday:remove')") + @Log(title = "假期管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return toAjax(rzHolidayService.deleteRzHoliday(id,SecurityUtils.getUsername())); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzInterviewerController.java b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzInterviewerController.java new file mode 100644 index 0000000..9ed6cb6 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzInterviewerController.java @@ -0,0 +1,98 @@ +package com.evo.personnelMatters.controller; + +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.personnelMatters.domain.RzInterviewer; +import com.evo.personnelMatters.service.IRzInterviewerService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 面试信息Controller + * + * @author chenyj + * @date 2024-09-07 + */ +@RestController +@RequestMapping("/personnelMatters/interviewer") +public class RzInterviewerController extends BaseController +{ + @Resource + private IRzInterviewerService rzInterviewerService; + + /** + * 查询面试信息列表 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:interviewer:list')") + @GetMapping("/list") + public TableDataInfo list(RzInterviewer rzInterviewer) + { + startPage(); + List list = rzInterviewerService.selectRzInterviewerList(rzInterviewer); + return getDataTable(list); + } + + /** + * 导出面试信息列表 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:interviewer:export')") + @Log(title = "面试信息", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, RzInterviewer rzInterviewer) + { + List list = rzInterviewerService.selectRzInterviewerList(rzInterviewer); + ExcelUtil util = new ExcelUtil(RzInterviewer.class); + util.exportExcel(response, list, "面试信息"); + } + + /** + * 获取面试信息详细信息 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:interviewer:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(rzInterviewerService.selectRzInterviewerById(id)); + } + + /** + * 新增面试信息 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:interviewer:add')") + @Log(title = "面试信息", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody RzInterviewer rzInterviewer) + { + return toAjax(rzInterviewerService.insertRzInterviewer(rzInterviewer)); + } + + /** + * 修改面试信息 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:interviewer:edit')") + @Log(title = "面试信息", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody RzInterviewer rzInterviewer) + { + return toAjax(rzInterviewerService.updateRzInterviewer(rzInterviewer)); + } + + /** + * 删除面试信息 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:interviewer:remove')") + @Log(title = "面试信息", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return toAjax(rzInterviewerService.deleteRzInterviewerById(id)); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzLeaveController.java b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzLeaveController.java new file mode 100644 index 0000000..a1c849f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzLeaveController.java @@ -0,0 +1,107 @@ +package com.evo.personnelMatters.controller; + +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.personnelMatters.domain.RzLeave; +import com.evo.personnelMatters.domain.RzLeaveDetail; +import com.evo.personnelMatters.service.IRzLeaveService; +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.util.List; + +/** + * 请假管理Controller + * + * @author chenyj + * @date 2024-08-03 + */ +@RestController +@RequestMapping("/personnelMatters/leave") +public class RzLeaveController extends BaseController +{ + @Autowired + private IRzLeaveService rzLeaveService; + + /** + * 查询请假管理列表 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:leave:list')") + @GetMapping("/list") + public TableDataInfo list(RzLeave rzLeave) + { + startPage(); + List list = rzLeaveService.selectRzLeaveList(rzLeave); + return getDataTable(list); + } + + /** + * 导出请假管理列表 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:leave:export')") + @Log(title = "请假管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, RzLeave rzLeave) + { + List list = rzLeaveService.selectRzLeaveList(rzLeave); + ExcelUtil util = new ExcelUtil(RzLeave.class); + util.exportExcel(response, list, "请假数据"); + } + + /** + * 获取请假管理详细信息 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:leave:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(rzLeaveService.selectRzLeaveById(id)); + } + + /** + * 新增请假管理 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:leave:add')") + @Log(title = "请假管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody RzLeave rzLeave) + { + return rzLeaveService.insertRzLeave(rzLeave); + } + + /** + * 修改请假管理 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:leave:edit')") + @Log(title = "请假管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody RzLeave rzLeave) + { + return rzLeaveService.updateRzLeave(rzLeave); + } + + /** + * 删除请假管理 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:leave:remove')") + @Log(title = "请假管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return rzLeaveService.deleteRzLeave(id,SecurityUtils.getUsername()); + } + + @GetMapping("/listLeaveDetails") + public List listLeaveDetails(RzLeave rzLeave) + { + return rzLeaveService.listLeaveDetails(rzLeave); + } + + +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzLeaveDetailController.java b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzLeaveDetailController.java new file mode 100644 index 0000000..92e59bf --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzLeaveDetailController.java @@ -0,0 +1,82 @@ +package com.evo.personnelMatters.controller; + +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.personnelMatters.domain.RzLeaveDetail; +import com.evo.personnelMatters.service.IRzLeaveDetailService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import java.util.List; + +/** + * 请假管理详情Controller + * + * @author chenyj + * @date 2024-11-03 + */ +@RestController +@RequestMapping("/personnelMatters/leaveDetail") +public class RzLeaveDetailController extends BaseController +{ + @Autowired + private IRzLeaveDetailService rzLeaveDetailService; + + /** + * 查询请假管理详情列表 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:leaveDetail:list')") + @GetMapping("/list") + public TableDataInfo list(RzLeaveDetail rzLeaveDetail) + { + startPage(); + List list = rzLeaveDetailService.selectRzLeaveDetailList(rzLeaveDetail); + return getDataTable(list); + } + + /** + * 获取请假管理详情详细信息 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:leaveDetail:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(rzLeaveDetailService.selectRzLeaveDetailById(id)); + } + + /** + * 新增请假管理详情 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:leaveDetail:add')") + @Log(title = "请假管理详情", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody RzLeaveDetail rzLeaveDetail) + { + return rzLeaveDetailService.insertRzLeaveDetail(rzLeaveDetail); + } + + /** + * 修改请假管理详情 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:leaveDetail:edit')") + @Log(title = "请假管理详情", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody RzLeaveDetail rzLeaveDetail) + { + return rzLeaveDetailService.updateRzLeaveDetail(rzLeaveDetail); + } + + /** + * 删除请假管理详情 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:leaveDetail:remove')") + @Log(title = "请假管理详情", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return rzLeaveDetailService.deleteRzLeaveDetailById(id); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzOverTimeController.java b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzOverTimeController.java new file mode 100644 index 0000000..935ab78 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzOverTimeController.java @@ -0,0 +1,107 @@ +package com.evo.personnelMatters.controller; + +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.personnelMatters.domain.RzOverTime; +import com.evo.personnelMatters.domain.RzOverTimeDetail; +import com.evo.personnelMatters.service.IRzOverTimeService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 加班管理Controller + * + * @author chenyj + * @date 2024-09-03 + */ +@RestController +@RequestMapping("/personnelMatters/overTime") +public class RzOverTimeController extends BaseController +{ + @Resource + private IRzOverTimeService rzOverTimeService; + + /** + * 查询加班管理列表 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:overTime:list')") + @GetMapping("/list") + public TableDataInfo list(RzOverTime rzOverTime) + { + startPage(); + List list = rzOverTimeService.selectRzOverTimeList(rzOverTime); + return getDataTable(list); + } + + /** + * 导出加班管理列表 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:overTime:export')") + @Log(title = "加班管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, RzOverTime rzOverTime) + { + List list = rzOverTimeService.selectRzOverTimeList(rzOverTime); + ExcelUtil util = new ExcelUtil(RzOverTime.class); + util.exportExcel(response, list, "加班管理数据"); + } + + /** + * 获取加班管理详细信息 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:overTime:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(rzOverTimeService.selectRzOverTimeById(id)); + } + + /** + * 新增加班管理 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:overTime:add')") + @Log(title = "加班管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody RzOverTime rzOverTime) + { + return rzOverTimeService.insertRzOverTime(rzOverTime); + } + + /** + * 修改加班管理 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:overTime:edit')") + @Log(title = "加班管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody RzOverTime rzOverTime) + { + return toAjax(rzOverTimeService.updateRzOverTime(rzOverTime)); + } + + /** + * 删除加班管理 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:overTime:remove')") + @Log(title = "加班管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return rzOverTimeService.deleteRzOverTimeById(id); + } + + /** + * 根据员工ID和月份查询加班详情列表 + */ + @GetMapping("/listDetailByStaffIdAndMonth") + public List listDetailByStaffIdAndMonth(RzOverTime rzOverTime) + { + return rzOverTimeService.selectRzOverTimeDetailListByUserIdAndMonth(rzOverTime); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzOverTimeDetailController.java b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzOverTimeDetailController.java new file mode 100644 index 0000000..43330fc --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzOverTimeDetailController.java @@ -0,0 +1,83 @@ +package com.evo.personnelMatters.controller; + +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.personnelMatters.domain.RzOverTimeDetail; +import com.evo.personnelMatters.service.IRzOverTimeDetailService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 加班详情Controller + * + * @author chenyj + * @date 2024-09-09 + */ +@RestController +@RequestMapping("/personnelMatters/overTimeDetail") +public class RzOverTimeDetailController extends BaseController +{ + @Resource + private IRzOverTimeDetailService rzOverTimeDetailService; + + /** + * 查询加班详情列表 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:overTimeDetail:list')") + @GetMapping("/list") + public TableDataInfo list(RzOverTimeDetail rzOverTimeDetail) + { + startPage(); + List list = rzOverTimeDetailService.selectRzOverTimeDetailList(rzOverTimeDetail); + return getDataTable(list); + } + + /** + * 获取加班详情详细信息 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:overTimeDetail:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(rzOverTimeDetailService.selectRzOverTimeDetailById(id)); + } + + /** + * 新增加班详情 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:overTimeDetail:add')") + @Log(title = "加班详情", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody RzOverTimeDetail rzOverTimeDetail) + { + return rzOverTimeDetailService.insertRzOverTimeDetail(rzOverTimeDetail); + } + + /** + * 修改加班详情 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:overTimeDetail:edit')") + @Log(title = "加班详情", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody RzOverTimeDetail rzOverTimeDetail) + { + return rzOverTimeDetailService.updateRzOverTimeDetail(rzOverTimeDetail); + } + + /** + * 删除加班详情 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:overTimeDetail:remove')") + @Log(title = "加班详情", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return rzOverTimeDetailService.deleteRzOverTimeDetailById(id); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzSubsidyController.java b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzSubsidyController.java new file mode 100644 index 0000000..8d68ddf --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzSubsidyController.java @@ -0,0 +1,97 @@ +package com.evo.personnelMatters.controller; + +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.personnelMatters.domain.RzSubsidy; +import com.evo.personnelMatters.service.IRzSubsidyService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 补助管理Controller + * + * @author chenyj + * @date 2024-08-27 + */ +@RestController +@RequestMapping("/personnelMatters/subsidy") +public class RzSubsidyController extends BaseController +{ + @Resource + private IRzSubsidyService rzSubsidyService; + + /** + * 查询补助管理列表 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:subsidy:list')") + @GetMapping("/list") + public TableDataInfo list(RzSubsidy rzSubsidy) + { + startPage(); + List list = rzSubsidyService.selectRzSubsidyList(rzSubsidy); + return getDataTable(list); + } + + /** + * 导出补助管理列表 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:subsidy:export')") + @Log(title = "补助管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, RzSubsidy rzSubsidy) + { + List list = rzSubsidyService.selectRzSubsidyList(rzSubsidy); + ExcelUtil util = new ExcelUtil(RzSubsidy.class); + util.exportExcel(response, list, "补助管理数据"); + } + + /** + * 获取补助管理详细信息 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:subsidy:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(rzSubsidyService.selectRzSubsidyById(id)); + } + + /** + * 新增补助管理 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:subsidy:add')") + @Log(title = "补助管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody RzSubsidy rzSubsidy) + { + return rzSubsidyService.insertRzSubsidy(rzSubsidy); + } + + /** + * 修改补助管理 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:subsidy:edit')") + @Log(title = "补助管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody RzSubsidy rzSubsidy) + { + return toAjax(rzSubsidyService.updateRzSubsidy(rzSubsidy)); + } + + /** + * 删除补助管理 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:subsidy:remove')") + @Log(title = "补助管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return toAjax(rzSubsidyService.deleteRzSubsidyById(id)); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/controller/SpecialOverTimeController.java b/evo-admin/src/main/java/com/evo/personnelMatters/controller/SpecialOverTimeController.java new file mode 100644 index 0000000..1be0d80 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/controller/SpecialOverTimeController.java @@ -0,0 +1,163 @@ +package com.evo.personnelMatters.controller; + +import com.alibaba.fastjson2.JSONObject; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.equipment.constant.Constants; +import com.evo.equipment.domain.vo.StaffData; +import com.evo.equipment.domain.vo.StaffDto; +import com.evo.framework.websocket.WebSocketUsers; +import com.evo.personnelMatters.domain.EqOverStaff; +import com.evo.personnelMatters.domain.SpecialOverTime; +import com.evo.personnelMatters.service.SpecialOverTimeService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import javax.annotation.Resource; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.util.List; + + +@RestController +@RequestMapping("/personnelMatters/specialOverTime") +public class SpecialOverTimeController extends BaseController { + + @Resource + private SpecialOverTimeService specialOverTimeService; + + @PreAuthorize("@ss.hasPermi('personnelMatters:specialOverTime:query')") + @GetMapping(value = "/getOverTimeById") + public SpecialOverTime getInfo() + { + return specialOverTimeService.selectSpecialOverTimeById(); + } + /** + * 保存时间管理 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:specialOverTime:add')") + @PostMapping + public AjaxResult addSpecialOverTime(@RequestBody SpecialOverTime specialOverTime) + { + return specialOverTimeService.addSpecialOverTime(specialOverTime); + } + + @PreAuthorize("@ss.hasPermi('personnelMatters:specialOverTime:list')") + @GetMapping("/list") + public TableDataInfo list(EqOverStaff eqOverStaff) + { + startPage(); + List list = specialOverTimeService.selectEqOverStaffList(eqOverStaff); + return getDataTable(list); + } + + + /** + * 获取照片管理详细信息 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:specialOverTime:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(specialOverTimeService.selectEqOverStaffById(id)); + } + + /** + * 新增照片管理 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:specialOverTime:add')") + @RequestMapping("/addOverStaff") + public AjaxResult add(@RequestBody EqOverStaff eqOverStaff) + { + return toAjax(specialOverTimeService.insertEqOverStaff(eqOverStaff)); + } + + /** + * 修改照片管理 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:specialOverTime:edit')") + @PutMapping + public AjaxResult edit(@RequestBody EqOverStaff eqOverStaff) + { + return toAjax(specialOverTimeService.updateEqOverStaff(eqOverStaff)); + } + + /** + * 删除照片管理 + */ + @PreAuthorize("@ss.hasPermi('personnelMatters:specialOverTime:remove')") + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return toAjax(specialOverTimeService.deleteEqOverStaffById(id)); + } + + @RequestMapping("/uploadDispatchings") + @ResponseBody + public AjaxResult uploadPDF(@RequestParam("id") Long id,@RequestParam("file") MultipartFile filePath){ + String originalFilename = filePath.getOriginalFilename(); + //校验文件后缀 + String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1); // 输出 "txt" + //判断是否是图片文件 + if(!"jpg".equals(suffix)&&!"jpeg".equals(suffix)&&!"png".equals(suffix)){ + return AjaxResult.error("非法文件不允许上传"); + }else{ + //根据ID查询员工信息 + EqOverStaff eqOverStaff = specialOverTimeService.selectEqOverStaffById(id); + try { + InputStream is = filePath.getInputStream(); + byte[] bytes = new byte[is.available()]; + is.read(bytes); + File file = new File(Constants.STAFF_IMAGE_ADDRESS+originalFilename); + FileOutputStream fos = new FileOutputStream(file); + BufferedOutputStream bos = new BufferedOutputStream(fos); + bos.write(bytes); + bos.flush(); + is.close(); + fos.close(); + bos.close(); + eqOverStaff.setImageUrl(Constants.STAFF_IMAGE_URL_OVER_TIME+originalFilename); + specialOverTimeService.updateEqOverStaff(eqOverStaff); + + //需要推送的数据 + String message = ""; + //需要返回的对象 + StaffDto cau = new StaffDto(); + //发送的数据 + StaffData caud = new StaffData(); + + //该接口固定为to_device,发送给设备用于识别对应哪个指令 + cau.setCmd("to_device"); + //无用值,空串 + cau.setForm(""); + //设备号 + cau.setTo(Constants.EQ_DEVICE_OVER_TIME_CODE); + //给服务端预留的补充字段,设备端不处理这个字段内容。设备在响应这条指令时原样返回 + cau.setExtra(""); + //发送的数据 + caud.setCmd("addUser"); + caud.setUser_id(eqOverStaff.getUserId().toString()); + caud.setName(eqOverStaff.getStaffName()); + caud.setTts_name(""); + caud.setFace_template(eqOverStaff.getImageUrl()); + caud.setEffect_time(""); + caud.setId_valid(""); + caud.setIc(""); + caud.setPhone(""); + caud.setMode(0); + cau.setData(caud); + //Java对象转换成JSON字符串 + message = JSONObject.toJSONString(cau); + //调用websocket,推送给设备 + WebSocketUsers.sendMessageToUsersByText(message); + } catch (Exception e) { + e.printStackTrace(); + } + return AjaxResult.success("文件上传成功"); + } + } + +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/domain/EqOverStaff.java b/evo-admin/src/main/java/com/evo/personnelMatters/domain/EqOverStaff.java new file mode 100644 index 0000000..af3f24f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/domain/EqOverStaff.java @@ -0,0 +1,96 @@ +package com.evo.personnelMatters.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; + +/** + * 照片管理对象 eq_over_staff + * + * @author evo + * @date 2025-04-17 + */ +public class EqOverStaff extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Long id; + + /** 人员ID */ + @Excel(name = "人员ID") + private Long userId; + + /** 员工姓名 */ + @Excel(name = "员工姓名") + private String staffName; + + /** 照片地址 */ + @Excel(name = "照片地址") + private String imageUrl; + + /** 删除标识 */ + private String delFlag; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getUserId() + { + return userId; + } + public void setStaffName(String staffName) + { + this.staffName = staffName; + } + + public String getStaffName() + { + return staffName; + } + public void setImageUrl(String imageUrl) + { + this.imageUrl = imageUrl; + } + + public String getImageUrl() + { + return imageUrl; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("userId", getUserId()) + .append("staffName", getStaffName()) + .append("imageUrl", getImageUrl()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzBusinessTrip.java b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzBusinessTrip.java new file mode 100644 index 0000000..9a7037f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzBusinessTrip.java @@ -0,0 +1,138 @@ +package com.evo.personnelMatters.domain; + +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; + +/** + * 出差管理对象 rz_business_trip + * + * @author chenyj + * @date 2024-08-30 + */ +public class RzBusinessTrip extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Long id; + + /** 部门 */ + @Excel(name = "部门") + private Long deptId; + + private String deptName; + + private Long userId; + + /** 员工姓名 */ + @Excel(name = "员工姓名") + private String name; + + /** 出差月份(到月) */ + @JsonFormat(pattern = "yyyy-MM") + @Excel(name = "出差月份", width = 30, dateFormat = "yyyy-MM") + private Date tripDate; + + /** 出差总时长(小时) */ + @Excel(name = "出差总时长", readConverterExp = "天") + private Long tripDays; + private Long overDays; //加班时长 + + /** 删除标识 */ + private String delFlag; + + public Long getOverDays() { + return overDays; + } + + public void setOverDays(Long overDays) { + this.overDays = overDays; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + + public Long getDeptId() { + return deptId; + } + + public void setDeptId(Long deptId) { + this.deptId = deptId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + public Date getTripDate() { + return tripDate; + } + + public void setTripDate(Date tripDate) { + this.tripDate = tripDate; + } + + public Long getTripDays() { + return tripDays; + } + + public void setTripDays(Long tripDays) { + this.tripDays = tripDays; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("leaveDate", getTripDate()) + .append("leaveHours", getTripDays()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzBusinessTripDetail.java b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzBusinessTripDetail.java new file mode 100644 index 0000000..2fa73cc --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzBusinessTripDetail.java @@ -0,0 +1,138 @@ +package com.evo.personnelMatters.domain; + +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import java.util.Date; + +/** + * 出差详情对象 rz_trip_detail + * + * @author chenyj + * @date 2024-09-04 + */ +public class RzBusinessTripDetail extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Long id; + + /** 出差ID */ + @Excel(name = "出差ID") + private Long tripId; + + /** 员工姓名 */ + @Excel(name = "员工姓名") + private String name; + + /** 出差开始时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "出差开始时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date tripStartTime; + + /** 出差结束时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "出差结束时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date tripEndTime; + + /** 出差时长(天) */ + @Excel(name = "出差时长(天)") + private Long tripDay; + + private Long overDays; //加班时长 + + /** 删除标识 */ + private String delFlag; + + public Long getOverDays() { + return overDays; + } + + public void setOverDays(Long overDays) { + this.overDays = overDays; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setTripId(Long tripId) + { + this.tripId = tripId; + } + + public Long getTripId() + { + return tripId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setTripStartTime(Date tripStartTime) + { + this.tripStartTime = tripStartTime; + } + + public Date getTripStartTime() + { + return tripStartTime; + } + public void setTripEndTime(Date tripEndTime) + { + this.tripEndTime = tripEndTime; + } + + public Date getTripEndTime() + { + return tripEndTime; + } + public void setTripDay(Long tripDay) + { + this.tripDay = tripDay; + } + + public Long getTripDay() + { + return tripDay; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("tripId", getTripId()) + .append("tripStartTime", getTripStartTime()) + .append("tripEndTime", getTripEndTime()) + .append("tripDay", getTripDay()) + .append("remark", getRemark()) + .append("delFlag", getDelFlag()) + .append("createTime", getCreateTime()) + .append("createBy", getCreateBy()) + .append("updateTime", getUpdateTime()) + .append("updateBy", getUpdateBy()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzHoliday.java b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzHoliday.java new file mode 100644 index 0000000..3e07d28 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzHoliday.java @@ -0,0 +1,94 @@ +package com.evo.personnelMatters.domain; + +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; + +/** + * 假期管理对象 rz_holiday + * + * @author chenyj + * @date 2024-08-03 + */ +public class RzHoliday extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 假期时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "假期时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date holiday; + + /** 假期说明 */ + @Excel(name = "假期说明") + private String remarks; + + @Excel(name = "特殊标识") + private String specialFlag; + //删除标识 + private String delFlag; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setHoliday(Date holiday) + { + this.holiday = holiday; + } + + public Date getHoliday() + { + return holiday; + } + public void setRemarks(String remarks) + { + this.remarks = remarks; + } + + public String getRemarks() + { + return remarks; + } + + public String getDelFlag() { + return delFlag; + } + + public void setDelFlag(String delFlag) { + this.delFlag = delFlag; + } + + public String getSpecialFlag() { + return specialFlag; + } + + public void setSpecialFlag(String specialFlag) { + this.specialFlag = specialFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("holiday", getHoliday()) + .append("remarks", getRemarks()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzInterviewer.java b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzInterviewer.java new file mode 100644 index 0000000..fef116b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzInterviewer.java @@ -0,0 +1,170 @@ +package com.evo.personnelMatters.domain; + +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; + +/** + * 面试信息对象 rz_interviewer + * + * @author chenyj + * @date 2024-09-07 + */ +public class RzInterviewer extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 姓名 */ + @Excel(name = "姓名") + private String name; + + /** 联系方式 */ + @Excel(name = "联系方式") + private String phone; + + /** 面试岗位 */ + @Excel(name = "面试岗位") + private String post; + + /** 具备技能 */ + @Excel(name = "具备技能") + private String content; + + /** 家庭住址 */ + @Excel(name = "家庭住址") + private String address; + + /** 面试时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "面试时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date interviewDate; + + /** 是否录用 */ + @Excel(name = "是否录用") + private String ytFlag; + + /** 备注 */ + @Excel(name = "备注") + private String remarks; + + /** 删除标记 */ + private String delFlag; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setPhone(String phone) + { + this.phone = phone; + } + + public String getPhone() + { + return phone; + } + public void setPost(String post) + { + this.post = post; + } + + public String getPost() + { + return post; + } + public void setContent(String content) + { + this.content = content; + } + + public String getContent() + { + return content; + } + public void setAddress(String address) + { + this.address = address; + } + + public String getAddress() + { + return address; + } + public void setInterviewDate(Date interviewDate) + { + this.interviewDate = interviewDate; + } + + public Date getInterviewDate() + { + return interviewDate; + } + public void setYtFlag(String ytFlag) + { + this.ytFlag = ytFlag; + } + + public String getYtFlag() + { + return ytFlag; + } + public void setRemarks(String remarks) + { + this.remarks = remarks; + } + + public String getRemarks() + { + return remarks; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("phone", getPhone()) + .append("post", getPost()) + .append("content", getContent()) + .append("address", getAddress()) + .append("interviewDate", getInterviewDate()) + .append("ytFlag", getYtFlag()) + .append("remarks", getRemarks()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzLeave.java b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzLeave.java new file mode 100644 index 0000000..4f23f1e --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzLeave.java @@ -0,0 +1,250 @@ +package com.evo.personnelMatters.domain; + +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; + +/** + * 请假管理对象 rz_leave + * + * @author evo + * @date 2025-03-15 + */ +public class RzLeave extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Long id; + + /** 员工ID */ + @Excel(name = "员工ID") + private Long userId; + + /** 部门 */ + private Long deptId; + @Excel(name = "部门") + private String deptName; + + /** 员工姓名 */ + @Excel(name = "员工姓名") + private String name; + + /** 请假月份(到月) */ + @Excel(name = "请假月份", readConverterExp = "到=月", dateFormat = "yyyy-MM") + @JsonFormat(pattern = "yyyy-MM") + private Date leaveDate; + + /** 病假时长(小时) */ + @Excel(name = "病假时长", readConverterExp = "小=时") + private Integer sickHours; + + /** 事假时长(小时) */ + @Excel(name = "事假时长", readConverterExp = "小=时") + private Integer absenceHours; + + /** 调休假时长(小时) */ + @Excel(name = "调休假时长", readConverterExp = "小=时") + private Integer compensatoryHours; + + /** 婚假时长(小时) */ + @Excel(name = "婚假时长", readConverterExp = "小=时") + private Integer marriageHours; + + /** 年休假时长(小时) */ + @Excel(name = "年休假时长", readConverterExp = "小=时") + private Integer annualHours; + + /** 产假时长(小时) */ + @Excel(name = "产假时长", readConverterExp = "小=时") + private Integer maternityHours; + + /** 陪产假时长(小时) */ + @Excel(name = "陪产假时长", readConverterExp = "小=时") + private Integer paternityHours; + + /** 丧假时长(小时) */ + @Excel(name = "丧假时长", readConverterExp = "小=时") + private Integer funeralHours; + + /** 工伤假时长(小时) */ + @Excel(name = "工伤假时长", readConverterExp = "小=时") + private Integer workHours; + + /** 删除标识 */ + private String delFlag; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getUserId() + { + return userId; + } + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + public Long getDeptId() + { + return deptId; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setLeaveDate(Date leaveDate) + { + this.leaveDate = leaveDate; + } + + public Date getLeaveDate() + { + return leaveDate; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public void setSickHours(Integer sickHours) + { + this.sickHours = sickHours; + } + + public Integer getSickHours() + { + return sickHours; + } + public void setAbsenceHours(Integer absenceHours) + { + this.absenceHours = absenceHours; + } + + public Integer getAbsenceHours() + { + return absenceHours; + } + public void setCompensatoryHours(Integer compensatoryHours) + { + this.compensatoryHours = compensatoryHours; + } + + public Integer getCompensatoryHours() + { + return compensatoryHours; + } + public void setMarriageHours(Integer marriageHours) + { + this.marriageHours = marriageHours; + } + + public Integer getMarriageHours() + { + return marriageHours; + } + public void setAnnualHours(Integer annualHours) + { + this.annualHours = annualHours; + } + + public Integer getAnnualHours() + { + return annualHours; + } + public void setMaternityHours(Integer maternityHours) + { + this.maternityHours = maternityHours; + } + + public Integer getMaternityHours() + { + return maternityHours; + } + public void setPaternityHours(Integer paternityHours) + { + this.paternityHours = paternityHours; + } + + public Integer getPaternityHours() + { + return paternityHours; + } + public void setFuneralHours(Integer funeralHours) + { + this.funeralHours = funeralHours; + } + + public Integer getFuneralHours() + { + return funeralHours; + } + public void setWorkHours(Integer workHours) + { + this.workHours = workHours; + } + + public Integer getWorkHours() + { + return workHours; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("userId", getUserId()) + .append("deptId", getDeptId()) + .append("name", getName()) + .append("leaveDate", getLeaveDate()) + .append("sickHours", getSickHours()) + .append("absenceHours", getAbsenceHours()) + .append("compensatoryHours", getCompensatoryHours()) + .append("marriageHours", getMarriageHours()) + .append("annualHours", getAnnualHours()) + .append("maternityHours", getMaternityHours()) + .append("paternityHours", getPaternityHours()) + .append("funeralHours", getFuneralHours()) + .append("workHours", getWorkHours()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzLeaveDetail.java b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzLeaveDetail.java new file mode 100644 index 0000000..ad34f5b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzLeaveDetail.java @@ -0,0 +1,146 @@ +package com.evo.personnelMatters.domain; + +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 请假管理详情对象 rz_leave_detail + * + * @author chenyj + * @date 2024-08-03 + */ +public class RzLeaveDetail extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Long id; + + /** 员工姓名 */ + @Excel(name = "员工姓名") + private String name; + + /** 请假开始时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "请假开始时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date leaveStartTime; + + /** 请假结束时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "请假结束时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date leaveEndTime; + + /** 请假时长 */ + @Excel(name = "请假时长") + private Integer leaveHour; + //请假汇总ID + private Long leaveId; + @Excel(name = "请假类型") + private String type; //请假类型 + + private String remarks; + + private String delFlag; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setLeaveStartTime(Date leaveStartTime) + { + this.leaveStartTime = leaveStartTime; + } + + public Date getLeaveStartTime() + { + return leaveStartTime; + } + public void setLeaveEndTime(Date leaveEndTime) + { + this.leaveEndTime = leaveEndTime; + } + + public Date getLeaveEndTime() + { + return leaveEndTime; + } + public void setLeaveHour(Integer leaveHour) + { + this.leaveHour = leaveHour; + } + + public Integer getLeaveHour() + { + return leaveHour; + } + public void setLeaveId(Long leaveId) + { + this.leaveId = leaveId; + } + + public String getRemarks() { + return remarks; + } + + public void setRemarks(String remarks) { + this.remarks = remarks; + } + + public Long getLeaveId() + { + return leaveId; + } + + public String getDelFlag() { + return delFlag; + } + + public void setDelFlag(String delFlag) { + this.delFlag = delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("leaveStartTime", getLeaveStartTime()) + .append("leaveEndTime", getLeaveEndTime()) + .append("leaveHours", getLeaveHour()) + .append("remark", getRemark()) + .append("createTime", getCreateTime()) + .append("createBy", getCreateBy()) + .append("updateTime", getUpdateTime()) + .append("updateBy", getUpdateBy()) + .append("leaveId", getLeaveId()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzOverTime.java b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzOverTime.java new file mode 100644 index 0000000..da32a35 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzOverTime.java @@ -0,0 +1,131 @@ +package com.evo.personnelMatters.domain; + +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 加班管理对象 rz_over_time + * + * @author chenyj + * @date 2024-09-03 + */ +public class RzOverTime extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Long id; + + /** 部门ID */ + private Long deptId; + @Excel(name = "部门") + private String deptName; + + private Long userId; + + /** 员工姓名 */ + @Excel(name = "员工姓名") + private String name; + + /** 加班月份(到月) */ + @JsonFormat(pattern = "yyyy-MM") + @Excel(name = "加班月份", readConverterExp = "到=月", dateFormat = "yyyy-MM") + private Date overTimeMonth; + + /** 加班总时长(月) */ + @Excel(name = "加班总时长") + private BigDecimal overHours; + + /** 删除标识 */ + private String delFlag; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + + public Long getDeptId() { + return deptId; + } + + public void setDeptId(Long deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + public void setOverTimeMonth(Date overTimeMonth) + { + this.overTimeMonth = overTimeMonth; + } + + public Date getOverTimeMonth() + { + return overTimeMonth; + } + public void setOverHours(BigDecimal overHours) + { + this.overHours = overHours; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public BigDecimal getOverHours() + { + return overHours; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("dept", getDeptId()) + .append("overTimeMonth", getOverTimeMonth()) + .append("overHours", getOverHours()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzOverTimeDetail.java b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzOverTimeDetail.java new file mode 100644 index 0000000..ec09fb1 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzOverTimeDetail.java @@ -0,0 +1,129 @@ +package com.evo.personnelMatters.domain; + +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 加班详情对象 rz_over_time_detail + * + * @author chenyj + * @date 2024-09-09 + */ +public class RzOverTimeDetail extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Long id; + + /** 加班ID */ + @Excel(name = "加班ID") + private Long overTimeId; + + /** 员工姓名 */ + @Excel(name = "员工姓名") + private String name; + + /** 加班开始时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "加班开始时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date overTimeStart; + + /** 请假结束时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "请假结束时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date overTimeEnd; + + /** 加班时长 */ + @Excel(name = "加班时长") + private BigDecimal overTimeHours; + + /** 删除标识 */ + private String delFlag; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setOverTimeId(Long overTimeId) + { + this.overTimeId = overTimeId; + } + + public Long getOverTimeId() + { + return overTimeId; + } + public void setOverTimeStart(Date overTimeStart) + { + this.overTimeStart = overTimeStart; + } + + public Date getOverTimeStart() + { + return overTimeStart; + } + public void setOverTimeEnd(Date overTimeEnd) + { + this.overTimeEnd = overTimeEnd; + } + + public Date getOverTimeEnd() + { + return overTimeEnd; + } + public void setOverTimeHours(BigDecimal overTimeHours) + { + this.overTimeHours = overTimeHours; + } + + public BigDecimal getOverTimeHours() + { + return overTimeHours; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("overTimeId", getOverTimeId()) + .append("overTimeStart", getOverTimeStart()) + .append("overTimeEnd", getOverTimeEnd()) + .append("overTimeHours", getOverTimeHours()) + .append("remark", getRemark()) + .append("delFlag", getDelFlag()) + .append("createTime", getCreateTime()) + .append("createBy", getCreateBy()) + .append("updateTime", getUpdateTime()) + .append("updateBy", getUpdateBy()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzSubsidy.java b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzSubsidy.java new file mode 100644 index 0000000..6824ea8 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzSubsidy.java @@ -0,0 +1,97 @@ +package com.evo.personnelMatters.domain; + +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import java.math.BigDecimal; + +/** + * 补助管理对象 rz_subsidy + * + * @author chenyj + * @date 2024-08-27 + */ +public class RzSubsidy extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 补助名称 */ + @Excel(name = "补助名称") + private String name; + + /** 补助金额 */ + @Excel(name = "补助金额") + private BigDecimal value; + + /** 备注 */ + @Excel(name = "备注") + private String remarks; + + /** 删除标识 */ + private String delFlag; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setValue(BigDecimal value) + { + this.value = value; + } + + public BigDecimal getValue() + { + return value; + } + public void setRemarks(String remarks) + { + this.remarks = remarks; + } + + public String getRemarks() + { + return remarks; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("value", getValue()) + .append("remarks", getRemarks()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/domain/SpecialOverTime.java b/evo-admin/src/main/java/com/evo/personnelMatters/domain/SpecialOverTime.java new file mode 100644 index 0000000..b4ecd87 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/domain/SpecialOverTime.java @@ -0,0 +1,59 @@ +package com.evo.personnelMatters.domain; + +import com.evo.common.core.domain.BaseEntity; + +public class SpecialOverTime extends BaseEntity { + + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Long id; + /** 开始时间 */ + private String workStart; + /** 结束时间 */ + private String workEnd; + + private String remarks; + + private String delFlag; + + public String getDelFlag() { + return delFlag; + } + + public void setDelFlag(String delFlag) { + this.delFlag = delFlag; + } + + public String getRemarks() { + return remarks; + } + + public void setRemarks(String remarks) { + this.remarks = remarks; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getWorkStart() { + return workStart; + } + + public void setWorkStart(String workStart) { + this.workStart = workStart; + } + + public String getWorkEnd() { + return workEnd; + } + + public void setWorkEnd(String workEnd) { + this.workEnd = workEnd; + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/mapper/BsOverTimeMapper.java b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/BsOverTimeMapper.java new file mode 100644 index 0000000..e335a8b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/BsOverTimeMapper.java @@ -0,0 +1,11 @@ +package com.evo.personnelMatters.mapper; + +import com.evo.personnelMatters.domain.SpecialOverTime; + +public interface BsOverTimeMapper { + + public int updateSpecialOverTime(SpecialOverTime specialOverTime); + + public SpecialOverTime selectSpecialOverTimeById(); + +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/mapper/EqOverStaffMapper.java b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/EqOverStaffMapper.java new file mode 100644 index 0000000..520c347 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/EqOverStaffMapper.java @@ -0,0 +1,48 @@ +package com.evo.personnelMatters.mapper; + +import com.evo.personnelMatters.domain.EqOverStaff; +import java.util.List; + +/** + * 照片管理Mapper接口 + * + * @author evo + * @date 2025-04-17 + */ +public interface EqOverStaffMapper +{ + /** + * 查询照片管理 + * + * @param id 照片管理主键 + * @return 照片管理 + */ + public EqOverStaff selectEqOverStaffById(Long id); + + /** + * 查询照片管理列表 + * + * @param eqOverStaff 照片管理 + * @return 照片管理集合 + */ + public List selectEqOverStaffList(EqOverStaff eqOverStaff); + + /** + * 新增照片管理 + * + * @param eqOverStaff 照片管理 + * @return 结果 + */ + public int insertEqOverStaff(EqOverStaff eqOverStaff); + + /** + * 修改照片管理 + * + * @param eqOverStaff 照片管理 + * @return 结果 + */ + public int updateEqOverStaff(EqOverStaff eqOverStaff); + + public EqOverStaff selectEqOverStaffByUserId(Long userId); + +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzBusinessTripDetailMapper.java b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzBusinessTripDetailMapper.java new file mode 100644 index 0000000..03b6f4f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzBusinessTripDetailMapper.java @@ -0,0 +1,63 @@ +package com.evo.personnelMatters.mapper; + +import com.evo.personnelMatters.domain.RzBusinessTripDetail; +import org.apache.ibatis.annotations.Param; +import java.util.List; + +/** + * 出差详情Mapper接口 + * + * @author chenyj + * @date 2024-09-04 + */ +public interface RzBusinessTripDetailMapper +{ + /** + * 查询出差详情 + * + * @param id 出差详情主键 + * @return 出差详情 + */ + public RzBusinessTripDetail selectRzTripDetailById(Long id); + + /** + * 查询出差详情列表 + * + * @param rzTripDetail 出差详情 + * @return 出差详情集合 + */ + public List selectRzTripDetailList(RzBusinessTripDetail rzTripDetail); + + /** + * 新增出差详情 + * + * @param rzTripDetail 出差详情 + * @return 结果 + */ + public int insertRzTripDetail(RzBusinessTripDetail rzTripDetail); + + /** + * 修改出差详情 + * + * @param rzTripDetail 出差详情 + * @return 结果 + */ + public int updateRzTripDetail(RzBusinessTripDetail rzTripDetail); + + /** + * 查询出差详情 + * + * @param tripId 出差详情主键 + * @return 出差详情 + */ + public RzBusinessTripDetail selectRzLeaveDetailByTripId(Long tripId); + + /** + * 根据姓名查询最后一次的出差时间 + * @param deptId + * @param name + * @return + */ + public RzBusinessTripDetail selectRzLeaveDetailByName(@Param("deptId") Long deptId, @Param("name") String name); + +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzBusinessTripMapper.java b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzBusinessTripMapper.java new file mode 100644 index 0000000..ca7d917 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzBusinessTripMapper.java @@ -0,0 +1,57 @@ +package com.evo.personnelMatters.mapper; + +import com.evo.personnelMatters.domain.RzBusinessTrip; +import org.apache.ibatis.annotations.Param; + +import java.util.Date; +import java.util.List; + +/** + * 出差管理Mapper接口 + * + * @author chenyj + * @date 2024-08-30 + */ +public interface RzBusinessTripMapper +{ + /** + * 查询出差管理 + * + * @param id 出差管理主键 + * @return 出差管理 + */ + public RzBusinessTrip selectRzBusinessTripById(Long id); + + /** + * 查询出差管理列表 + * + * @param rzBusinessTrip 出差管理 + * @return 出差管理集合 + */ + public List selectRzBusinessTripList(RzBusinessTrip rzBusinessTrip); + + /** + * 新增出差管理 + * + * @param rzBusinessTrip 出差管理 + * @return 结果 + */ + public int insertRzBusinessTrip(RzBusinessTrip rzBusinessTrip); + + /** + * 修改出差管理 + * + * @param rzBusinessTrip 出差管理 + * @return 结果 + */ + public int updateRzBusinessTrip(RzBusinessTrip rzBusinessTrip); + + /** + * 查询员工出差情况 + * + * @param rzBusinessTrip 出差管理 + * @return 出差管理集合 + */ + public RzBusinessTrip selectRzBusinessTripListByMonth(@Param("userId")Long userId,@Param("tripDate") Date tripDate); + +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzHolidayMapper.java b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzHolidayMapper.java new file mode 100644 index 0000000..3f5d45f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzHolidayMapper.java @@ -0,0 +1,46 @@ +package com.evo.personnelMatters.mapper; + +import com.evo.personnelMatters.domain.RzHoliday; +import java.util.List; + +/** + * 假期管理Mapper接口 + * + * @author chenyj + * @date 2024-08-03 + */ +public interface RzHolidayMapper +{ + /** + * 查询假期管理 + * + * @param id 假期管理主键 + * @return 假期管理 + */ + public RzHoliday selectRzHolidayById(Long id); + + /** + * 查询假期管理列表 + * + * @param rzHoliday 假期管理 + * @return 假期管理集合 + */ + public List selectRzHolidayList(RzHoliday rzHoliday); + + /** + * 新增假期管理 + * + * @param rzHoliday 假期管理 + * @return 结果 + */ + public int insertRzHoliday(RzHoliday rzHoliday); + + /** + * 修改假期管理 + * + * @param rzHoliday 假期管理 + * @return 结果 + */ + public int updateRzHoliday(RzHoliday rzHoliday); + +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzInterviewerMapper.java b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzInterviewerMapper.java new file mode 100644 index 0000000..2bfcfc2 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzInterviewerMapper.java @@ -0,0 +1,47 @@ +package com.evo.personnelMatters.mapper; + +import com.evo.personnelMatters.domain.RzInterviewer; + +import java.util.List; + +/** + * 面试信息Mapper接口 + * + * @author chenyj + * @date 2024-09-07 + */ +public interface RzInterviewerMapper +{ + /** + * 查询面试信息 + * + * @param id 面试信息主键 + * @return 面试信息 + */ + public RzInterviewer selectRzInterviewerById(Long id); + + /** + * 查询面试信息列表 + * + * @param rzInterviewer 面试信息 + * @return 面试信息集合 + */ + public List selectRzInterviewerList(RzInterviewer rzInterviewer); + + /** + * 新增面试信息 + * + * @param rzInterviewer 面试信息 + * @return 结果 + */ + public int insertRzInterviewer(RzInterviewer rzInterviewer); + + /** + * 修改面试信息 + * + * @param rzInterviewer 面试信息 + * @return 结果 + */ + public int updateRzInterviewer(RzInterviewer rzInterviewer); + +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzLeaveDetailMapper.java b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzLeaveDetailMapper.java new file mode 100644 index 0000000..1bd238a --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzLeaveDetailMapper.java @@ -0,0 +1,64 @@ +package com.evo.personnelMatters.mapper; + +import com.evo.personnelMatters.domain.RzLeaveDetail; +import org.apache.ibatis.annotations.Param; +import java.util.List; + +/** + * 请假管理详情Mapper接口 + * + * @author chenyj + * @date 2024-08-03 + */ +public interface RzLeaveDetailMapper +{ + /** + * 查询请假管理详情 + * + * @param id 请假管理详情主键 + * @return 请假管理详情 + */ + public RzLeaveDetail selectRzLeaveDetailById(Long id); + + /** + * 查询请假管理详情列表 + * + * @param rzLeaveDetail 请假管理详情 + * @return 请假管理详情集合 + */ + public List selectRzLeaveDetailList(RzLeaveDetail rzLeaveDetail); + + /** + * 新增请假管理详情 + * + * @param rzLeaveDetail 请假管理详情 + * @return 结果 + */ + public int insertRzLeaveDetail(RzLeaveDetail rzLeaveDetail); + + /** + * 修改请假管理详情 + * + * @param rzLeaveDetail 请假管理详情 + * @return 结果 + */ + public int updateRzLeaveDetail(RzLeaveDetail rzLeaveDetail); + + /** + * 根据请假ID查询详情 + * + * @param leaveId 请假管理主键 + * @return 请假管理详情 + */ + public List selectRzLeaveDetailByLeaveId(Long leaveId); + + /** + * 根据姓名和部门查询当月的请假记录 + * @param deptId + * @param name + * @return + */ + public List selectRzLeaveDetailByName(@Param("deptId") Long deptId,@Param("name") String name); + + +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzLeaveMapper.java b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzLeaveMapper.java new file mode 100644 index 0000000..6cee627 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzLeaveMapper.java @@ -0,0 +1,53 @@ +package com.evo.personnelMatters.mapper; + +import com.evo.personnelMatters.domain.RzLeave; +import org.apache.ibatis.annotations.Param; +import java.util.Date; +import java.util.List; + +/** + * 请假管理Mapper接口 + * + * @author chenyj + * @date 2024-08-03 + */ +public interface RzLeaveMapper +{ + /** + * 查询请假管理 + * + * @param id 请假管理主键 + * @return 请假管理 + */ + public RzLeave selectRzLeaveById(Long id); + + /** + * 查询请假管理列表 + * + * @param rzLeave 请假管理 + * @return 请假管理集合 + */ + public List selectRzLeaveList(RzLeave rzLeave); + + /** + * 新增请假管理 + * + * @param rzLeave 请假管理 + * @return 结果 + */ + public int insertRzLeave(RzLeave rzLeave); + + /** + * 修改请假管理 + * + * @param rzLeave 请假管理 + * @return 结果 + */ + public int updateRzLeave(RzLeave rzLeave); + + /** + * 根据员工ID和时间查询请假统计 + * @return + */ + public RzLeave queryRzLeaveByDateAndUserId(@Param("userId") Long userId, @Param("date") Date date); +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzOverTimeDetailMapper.java b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzOverTimeDetailMapper.java new file mode 100644 index 0000000..199b9bf --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzOverTimeDetailMapper.java @@ -0,0 +1,63 @@ +package com.evo.personnelMatters.mapper; + +import com.evo.personnelMatters.domain.RzOverTimeDetail; +import org.apache.ibatis.annotations.Param; +import java.util.Date; +import java.util.List; + +/** + * 加班详情Mapper接口 + * + * @author chenyj + * @date 2024-09-09 + */ +public interface RzOverTimeDetailMapper +{ + /** + * 查询加班详情 + * + * @param id 加班详情主键 + * @return 加班详情 + */ + public RzOverTimeDetail selectRzOverTimeDetailById(Long id); + + /** + * 查询加班详情列表 + * + * @param rzOverTimeDetail 加班详情 + * @return 加班详情集合 + */ + public List selectRzOverTimeDetailList(RzOverTimeDetail rzOverTimeDetail); + + /** + * 新增加班详情 + * + * @param rzOverTimeDetail 加班详情 + * @return 结果 + */ + public int insertRzOverTimeDetail(RzOverTimeDetail rzOverTimeDetail); + + /** + * 修改加班详情 + * + * @param rzOverTimeDetail 加班详情 + * @return 结果 + */ + public int updateRzOverTimeDetail(RzOverTimeDetail rzOverTimeDetail); + + /** + * 根据加班统计ID和加班开始时间查询加班情况 + * @return + */ + public RzOverTimeDetail queryRzOverTimeDetailByDateAndOverId(@Param("overId") Long overId,@Param("date") Date date); + + /** + * 查询加班详情 + * + * @param overId 加班统计ID + * @return 加班详情集合 + */ + public List queryRzOverTimeDetailByOverId(Long overId); + + +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzOverTimeMapper.java b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzOverTimeMapper.java new file mode 100644 index 0000000..878967c --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzOverTimeMapper.java @@ -0,0 +1,56 @@ +package com.evo.personnelMatters.mapper; + +import com.evo.personnelMatters.domain.RzOverTime; +import org.apache.ibatis.annotations.Param; +import java.util.Date; +import java.util.List; + +/** + * 加班管理Mapper接口 + * + * @author chenyj + * @date 2024-09-03 + */ +public interface RzOverTimeMapper +{ + /** + * 查询加班管理 + * + * @param id 加班管理主键 + * @return 加班管理 + */ + public RzOverTime selectRzOverTimeById(Long id); + + /** + * 查询加班管理列表 + * + * @param rzOverTime 加班管理 + * @return 加班管理集合 + */ + public List selectRzOverTimeList(RzOverTime rzOverTime); + + /** + * 新增加班管理 + * + * @param rzOverTime 加班管理 + * @return 结果 + */ + public int insertRzOverTime(RzOverTime rzOverTime); + + /** + * 修改加班管理 + * + * @param rzOverTime 加班管理 + * @return 结果 + */ + public int updateRzOverTime(RzOverTime rzOverTime); + + /** + * 根据员工姓名和时间查询数据 + * @param userId + * @param overTimeMonth + * @return + */ + public RzOverTime selectRzOverTimeByNameAndMonth(@Param("userId") Long userId,@Param("overTimeMonth") Date overTimeMonth); + +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzSubsidyMapper.java b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzSubsidyMapper.java new file mode 100644 index 0000000..a8ebb44 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/mapper/RzSubsidyMapper.java @@ -0,0 +1,54 @@ +package com.evo.personnelMatters.mapper; + +import com.evo.personnelMatters.domain.RzSubsidy; +import java.util.List; + +/** + * 补助管理Mapper接口 + * + * @author chenyj + * @date 2024-08-27 + */ +public interface RzSubsidyMapper +{ + /** + * 查询补助管理 + * + * @param id 补助管理主键 + * @return 补助管理 + */ + public RzSubsidy selectRzSubsidyById(Long id); + + /** + * 查询补助管理列表 + * + * @param rzSubsidy 补助管理 + * @return 补助管理集合 + */ + public List selectRzSubsidyList(RzSubsidy rzSubsidy); + + /** + * 新增补助管理 + * + * @param rzSubsidy 补助管理 + * @return 结果 + */ + public int insertRzSubsidy(RzSubsidy rzSubsidy); + + /** + * 修改补助管理 + * + * @param rzSubsidy 补助管理 + * @return 结果 + */ + public int updateRzSubsidy(RzSubsidy rzSubsidy); + + /** + * 查询补助管理 + * + * @param name 补助管理名称 + * @return 补助管理 + */ + public RzSubsidy selectRzSubsidyByName(String name); + +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzBusinessTripDetailService.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzBusinessTripDetailService.java new file mode 100644 index 0000000..c6325fb --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzBusinessTripDetailService.java @@ -0,0 +1,54 @@ +package com.evo.personnelMatters.service; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.personnelMatters.domain.RzBusinessTripDetail; +import java.util.List; + +/** + * 出差详情Service接口 + * + * @author chenyj + * @date 2024-09-04 + */ +public interface IRzBusinessTripDetailService +{ + /** + * 查询出差详情 + * + * @param id 出差详情主键 + * @return 出差详情 + */ + public RzBusinessTripDetail selectRzTripDetailById(Long id); + + /** + * 查询出差详情列表 + * + * @param rzTripDetail 出差详情 + * @return 出差详情集合 + */ + public List selectRzTripDetailList(RzBusinessTripDetail rzTripDetail); + + /** + * 新增出差详情 + * + * @param rzTripDetail 出差详情 + * @return 结果 + */ + public AjaxResult insertRzTripDetail(RzBusinessTripDetail rzTripDetail); + + /** + * 修改出差详情 + * + * @param rzTripDetail 出差详情 + * @return 结果 + */ + public AjaxResult updateRzTripDetail(RzBusinessTripDetail rzTripDetail); + + /** + * 删除出差详情信息 + * + * @param id 出差详情主键 + * @return 结果 + */ + public AjaxResult deleteRzTripDetailById(Long id); +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzBusinessTripService.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzBusinessTripService.java new file mode 100644 index 0000000..71fd2ae --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzBusinessTripService.java @@ -0,0 +1,55 @@ +package com.evo.personnelMatters.service; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.personnelMatters.domain.RzBusinessTrip; + +import java.util.List; + +/** + * 出差管理Service接口 + * + * @author chenyj + * @date 2024-08-30 + */ +public interface IRzBusinessTripService +{ + /** + * 查询出差管理 + * + * @param id 出差管理主键 + * @return 出差管理 + */ + public RzBusinessTrip selectRzBusinessTripById(Long id); + + /** + * 查询出差管理列表 + * + * @param rzBusinessTrip 出差管理 + * @return 出差管理集合 + */ + public List selectRzBusinessTripList(RzBusinessTrip rzBusinessTrip); + + /** + * 新增出差管理 + * + * @param rzBusinessTrip 出差管理 + * @return 结果 + */ + public AjaxResult insertRzBusinessTrip(RzBusinessTrip rzBusinessTrip); + + /** + * 修改出差管理 + * + * @param rzBusinessTrip 出差管理 + * @return 结果 + */ + public int updateRzBusinessTrip(RzBusinessTrip rzBusinessTrip); + + /** + * 删除出差管理信息 + * + * @param id 出差管理主键 + * @return 结果 + */ + public AjaxResult deleteRzBusinessTripById(Long id); +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzHolidayService.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzHolidayService.java new file mode 100644 index 0000000..314bc63 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzHolidayService.java @@ -0,0 +1,55 @@ +package com.evo.personnelMatters.service; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.personnelMatters.domain.RzHoliday; +import java.util.List; + +/** + * 假期管理Service接口 + * + * @author chenyj + * @date 2024-08-03 + */ +public interface IRzHolidayService +{ + /** + * 查询假期管理 + * + * @param id 假期管理主键 + * @return 假期管理 + */ + public RzHoliday selectRzHolidayById(Long id); + + /** + * 查询假期管理列表 + * + * @param rzHoliday 假期管理 + * @return 假期管理集合 + */ + public List selectRzHolidayList(RzHoliday rzHoliday); + + /** + * 新增假期管理 + * + * @param rzHoliday 假期管理 + * @return 结果 + */ + public AjaxResult insertRzHoliday(RzHoliday rzHoliday); + + /** + * 修改假期管理 + * + * @param rzHoliday 假期管理 + * @return 结果 + */ + public int updateRzHoliday(RzHoliday rzHoliday); + + /** + * 删除数据 + * @param id + * @param oprName + * @return + */ + public int deleteRzHoliday(Long id,String oprName); + +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzInterviewerService.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzInterviewerService.java new file mode 100644 index 0000000..5e91340 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzInterviewerService.java @@ -0,0 +1,54 @@ +package com.evo.personnelMatters.service; + +import com.evo.personnelMatters.domain.RzInterviewer; + +import java.util.List; + +/** + * 面试信息Service接口 + * + * @author chenyj + * @date 2024-09-07 + */ +public interface IRzInterviewerService +{ + /** + * 查询面试信息 + * + * @param id 面试信息主键 + * @return 面试信息 + */ + public RzInterviewer selectRzInterviewerById(Long id); + + /** + * 查询面试信息列表 + * + * @param rzInterviewer 面试信息 + * @return 面试信息集合 + */ + public List selectRzInterviewerList(RzInterviewer rzInterviewer); + + /** + * 新增面试信息 + * + * @param rzInterviewer 面试信息 + * @return 结果 + */ + public int insertRzInterviewer(RzInterviewer rzInterviewer); + + /** + * 修改面试信息 + * + * @param rzInterviewer 面试信息 + * @return 结果 + */ + public int updateRzInterviewer(RzInterviewer rzInterviewer); + + /** + * 删除面试信息信息 + * + * @param id 面试信息主键 + * @return 结果 + */ + public int deleteRzInterviewerById(Long id); +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzLeaveDetailService.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzLeaveDetailService.java new file mode 100644 index 0000000..236cf14 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzLeaveDetailService.java @@ -0,0 +1,53 @@ +package com.evo.personnelMatters.service; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.personnelMatters.domain.RzLeaveDetail; +import java.util.List; + +/** + * 请假管理详情Service接口 + * + * @author chenyj + * @date 2024-08-03 + */ +public interface IRzLeaveDetailService +{ + /** + * 查询请假管理详情 + * + * @param id 请假管理详情主键 + * @return 请假管理详情 + */ + public RzLeaveDetail selectRzLeaveDetailById(Long id); + + /** + * 查询请假管理详情列表 + * + * @param rzLeaveDetail 请假管理详情 + * @return 请假管理详情集合 + */ + public List selectRzLeaveDetailList(RzLeaveDetail rzLeaveDetail); + + /** + * 新增请假管理详情 + * + * @param rzLeaveDetail 请假管理详情 + * @return 结果 + */ + public AjaxResult insertRzLeaveDetail(RzLeaveDetail rzLeaveDetail); + + /** + * 修改请假管理详情 + * + * @param rzLeaveDetail 请假管理详情 + * @return 结果 + */ + public AjaxResult updateRzLeaveDetail(RzLeaveDetail rzLeaveDetail); + + /** + * 根据ID删除数据 + * @param id + * @return + */ + public AjaxResult deleteRzLeaveDetailById(Long id); +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzLeaveService.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzLeaveService.java new file mode 100644 index 0000000..8a68ac7 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzLeaveService.java @@ -0,0 +1,61 @@ +package com.evo.personnelMatters.service; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.personnelMatters.domain.RzLeave; +import com.evo.personnelMatters.domain.RzLeaveDetail; +import java.util.List; + +/** + * 请假管理Service接口 + * + * @author chenyj + * @date 2024-08-03 + */ +public interface IRzLeaveService +{ + /** + * 查询请假管理 + * + * @param id 请假管理主键 + * @return 请假管理 + */ + public RzLeave selectRzLeaveById(Long id); + + /** + * 查询请假管理列表 + * + * @param rzLeave 请假管理 + * @return 请假管理集合 + */ + public List selectRzLeaveList(RzLeave rzLeave); + + /** + * 新增请假管理 + * + * @param rzLeave 请假管理 + * @return 结果 + */ + public AjaxResult insertRzLeave(RzLeave rzLeave); + + /** + * 修改请假管理 + * + * @param rzLeave 请假管理 + * @return 结果 + */ + public AjaxResult updateRzLeave(RzLeave rzLeave); + /** + * 删除请假管理 + * + * @return 结果 + */ + public AjaxResult deleteRzLeave(Long id,String name); + + /** + * 查询员工请假详情 + * @param rzLeave + * @return + */ + public List listLeaveDetails(RzLeave rzLeave); + +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzOverTimeDetailService.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzOverTimeDetailService.java new file mode 100644 index 0000000..f28c8e3 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzOverTimeDetailService.java @@ -0,0 +1,55 @@ +package com.evo.personnelMatters.service; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.personnelMatters.domain.RzOverTimeDetail; + +import java.util.List; + +/** + * 加班详情Service接口 + * + * @author chenyj + * @date 2024-09-09 + */ +public interface IRzOverTimeDetailService +{ + /** + * 查询加班详情 + * + * @param id 加班详情主键 + * @return 加班详情 + */ + public RzOverTimeDetail selectRzOverTimeDetailById(Long id); + + /** + * 查询加班详情列表 + * + * @param rzOverTimeDetail 加班详情 + * @return 加班详情集合 + */ + public List selectRzOverTimeDetailList(RzOverTimeDetail rzOverTimeDetail); + + /** + * 新增加班详情 + * + * @param rzOverTimeDetail 加班详情 + * @return 结果 + */ + public AjaxResult insertRzOverTimeDetail(RzOverTimeDetail rzOverTimeDetail); + + /** + * 修改加班详情 + * + * @param rzOverTimeDetail 加班详情 + * @return 结果 + */ + public AjaxResult updateRzOverTimeDetail(RzOverTimeDetail rzOverTimeDetail); + + /** + * 删除加班详情信息 + * + * @param id 加班详情主键 + * @return 结果 + */ + public AjaxResult deleteRzOverTimeDetailById(Long id); +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzOverTimeService.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzOverTimeService.java new file mode 100644 index 0000000..fee067e --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzOverTimeService.java @@ -0,0 +1,63 @@ +package com.evo.personnelMatters.service; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.personnelMatters.domain.RzOverTime; +import com.evo.personnelMatters.domain.RzOverTimeDetail; + +import java.util.List; + +/** + * 加班管理Service接口 + * + * @author chenyj + * @date 2024-09-03 + */ +public interface IRzOverTimeService +{ + /** + * 查询加班管理 + * + * @param id 加班管理主键 + * @return 加班管理 + */ + public RzOverTime selectRzOverTimeById(Long id); + + /** + * 查询加班管理列表 + * + * @param rzOverTime 加班管理 + * @return 加班管理集合 + */ + public List selectRzOverTimeList(RzOverTime rzOverTime); + + /** + * 新增加班管理 + * + * @param rzOverTime 加班管理 + * @return 结果 + */ + public AjaxResult insertRzOverTime(RzOverTime rzOverTime); + + /** + * 修改加班管理 + * + * @param rzOverTime 加班管理 + * @return 结果 + */ + public int updateRzOverTime(RzOverTime rzOverTime); + + /** + * 删除加班管理信息 + * + * @param id 加班管理主键 + * @return 结果 + */ + public AjaxResult deleteRzOverTimeById(Long id); + + /** + * 查询员工的加班详情 + * @param rzOverTime + * @return + */ + public List selectRzOverTimeDetailListByUserIdAndMonth(RzOverTime rzOverTime); +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzSubsidyService.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzSubsidyService.java new file mode 100644 index 0000000..fd2331c --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/IRzSubsidyService.java @@ -0,0 +1,54 @@ +package com.evo.personnelMatters.service; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.personnelMatters.domain.RzSubsidy; +import java.util.List; + +/** + * 补助管理Service接口 + * + * @author chenyj + * @date 2024-08-27 + */ +public interface IRzSubsidyService +{ + /** + * 查询补助管理 + * + * @param id 补助管理主键 + * @return 补助管理 + */ + public RzSubsidy selectRzSubsidyById(Long id); + + /** + * 查询补助管理列表 + * + * @param rzSubsidy 补助管理 + * @return 补助管理集合 + */ + public List selectRzSubsidyList(RzSubsidy rzSubsidy); + + /** + * 新增补助管理 + * + * @param rzSubsidy 补助管理 + * @return 结果 + */ + public AjaxResult insertRzSubsidy(RzSubsidy rzSubsidy); + + /** + * 修改补助管理 + * + * @param rzSubsidy 补助管理 + * @return 结果 + */ + public int updateRzSubsidy(RzSubsidy rzSubsidy); + + /** + * 删除补助管理信息 + * + * @param id 补助管理主键 + * @return 结果 + */ + public int deleteRzSubsidyById(Long id); +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/SpecialOverTimeService.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/SpecialOverTimeService.java new file mode 100644 index 0000000..72febd4 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/SpecialOverTimeService.java @@ -0,0 +1,48 @@ +package com.evo.personnelMatters.service; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.personnelMatters.domain.EqOverStaff; +import com.evo.personnelMatters.domain.SpecialOverTime; +import java.util.List; + +public interface SpecialOverTimeService { + + public SpecialOverTime selectSpecialOverTimeById(); + + public AjaxResult addSpecialOverTime(SpecialOverTime specialOverTime); + + public List selectEqOverStaffList(EqOverStaff eqOverStaff); + + /** + * 查询照片管理 + * + * @param id 照片管理主键 + * @return 照片管理 + */ + public EqOverStaff selectEqOverStaffById(Long id); + + /** + * 新增照片管理 + * + * @param eqOverStaff 照片管理 + * @return 结果 + */ + public int insertEqOverStaff(EqOverStaff eqOverStaff); + + /** + * 修改照片管理 + * + * @param eqOverStaff 照片管理 + * @return 结果 + */ + public int updateEqOverStaff(EqOverStaff eqOverStaff); + + /** + * 删除照片管理信息 + * + * @param id 照片管理主键 + * @return 结果 + */ + public int deleteEqOverStaffById(Long id); + +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzBusinessTripDetailServiceImpl.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzBusinessTripDetailServiceImpl.java new file mode 100644 index 0000000..e1ef1d9 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzBusinessTripDetailServiceImpl.java @@ -0,0 +1,189 @@ +package com.evo.personnelMatters.service.impl; + +import com.evo.attendance.mapper.RzAttendanceStatisticalMapper; +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.personnelMatters.domain.RzBusinessTrip; +import com.evo.personnelMatters.domain.RzHoliday; +import com.evo.personnelMatters.domain.RzBusinessTripDetail; +import com.evo.personnelMatters.mapper.RzBusinessTripMapper; +import com.evo.personnelMatters.mapper.RzHolidayMapper; +import com.evo.personnelMatters.mapper.RzBusinessTripDetailMapper; +import com.evo.personnelMatters.service.IRzBusinessTripDetailService; +import com.evo.utils.DateUtil; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.annotation.Resource; +import java.text.SimpleDateFormat; +import java.util.List; + +/** + * 出差详情Service业务层处理 + * + * @author chenyj + * @date 2024-09-04 + */ +@Service +public class RzBusinessTripDetailServiceImpl implements IRzBusinessTripDetailService +{ + @Resource + private RzBusinessTripDetailMapper rzTripDetailMapper; + @Resource + private RzBusinessTripMapper rzBusinessTripMapper; //出差汇总 + @Resource + private RzHolidayMapper rzHolidayMapper; //假期管理 + @Resource + private RzAttendanceStatisticalMapper rzAttendanceStatisticalMapper; //打卡统计 + /** + * 查询出差详情 + * + * @param id 出差详情主键 + * @return 出差详情 + */ + @Override + public RzBusinessTripDetail selectRzTripDetailById(Long id) + { + return rzTripDetailMapper.selectRzTripDetailById(id); + } + + /** + * 查询出差详情列表 + * + * @param rzTripDetail 出差详情 + * @return 出差详情 + */ + @Override + public List selectRzTripDetailList(RzBusinessTripDetail rzTripDetail) + { + return rzTripDetailMapper.selectRzTripDetailList(rzTripDetail); + } + + /** + * 新增出差详情 + * + * @param rzTripDetail 出差详情 + * @return 结果 + */ + @Override + @Transactional + public AjaxResult insertRzTripDetail(RzBusinessTripDetail rzTripDetail) + { + //判断请假时间 + if(rzTripDetail.getTripStartTime().getTime() > rzTripDetail.getTripEndTime().getTime()){ + return AjaxResult.error(); + } + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); + //判断请假开始,结束时间是否在同一个月,不同月提示 + if(!sdf.format(rzTripDetail.getTripStartTime()).equals(sdf.format(rzTripDetail.getTripEndTime()))){ + return AjaxResult.error(); + } + //判断出差时间差包含几个周日 + int zr = DateUtil.isWeeked(rzTripDetail.getTripStartTime(),rzTripDetail.getTripEndTime(),1); + //判断是否包含节假日 + List h_list = rzHolidayMapper.selectRzHolidayList(null); + for (RzHoliday rzHoliday : h_list) { + if(rzHoliday.getHoliday().after(rzTripDetail.getTripStartTime()) && rzHoliday.getHoliday().before(rzTripDetail.getTripEndTime())){ + if(rzHoliday.getSpecialFlag().equals(Constants.DELETE_FLAG_1)){ + zr -= 1; + }else{ + zr += 1; + } + } + } + // 出差天数的计算 + Long ts = (rzTripDetail.getTripEndTime().getTime() - rzTripDetail.getTripStartTime().getTime())/1000/60/60/24 + 1; + rzTripDetail.setTripDay(ts); + rzTripDetail.setCreateTime(DateUtils.getNowDate()); + rzTripDetail.setCreateBy(SecurityUtils.getUsername()); + rzTripDetail.setOverDays(Long.parseLong(zr+"")); + rzTripDetail.setDelFlag(Constants.DELETE_FLAG_0); + int i = rzTripDetailMapper.insertRzTripDetail(rzTripDetail); + if(i < 1){ + return AjaxResult.error(); + } + //反写出差总时长 TODO + RzBusinessTrip rzBusinessTrip = rzBusinessTripMapper.selectRzBusinessTripById(rzTripDetail.getTripId()); + rzBusinessTrip.setTripDays(rzBusinessTrip.getTripDays() + ts); + rzBusinessTrip.setOverDays(rzBusinessTrip.getOverDays() + zr); + i = rzBusinessTripMapper.updateRzBusinessTrip(rzBusinessTrip); + if(i < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } + + /** + * 修改出差详情 + * + * @param rzTripDetail 出差详情 + * @return 结果 + */ + @Override + @Transactional + public AjaxResult updateRzTripDetail(RzBusinessTripDetail rzTripDetail) + { + //判断出差时间差包含几个周日 + int zr = DateUtil.isWeeked(rzTripDetail.getTripStartTime(),rzTripDetail.getTripEndTime(),1); + //判断是否包含节假日 + List h_list = rzHolidayMapper.selectRzHolidayList(null); + for (RzHoliday rzHoliday : h_list) { + if(rzHoliday.getHoliday().after(rzTripDetail.getTripStartTime()) && rzHoliday.getHoliday().before(rzTripDetail.getTripEndTime())){ + if(rzHoliday.getSpecialFlag().equals(Constants.DELETE_FLAG_1)){ + zr -= 1; + }else{ + zr += 1; + } + } + } + // 出差天数的计算 + Long ts = (rzTripDetail.getTripEndTime().getTime() - rzTripDetail.getTripStartTime().getTime())/1000/60/60/24 + 1; + //反写出差总时长 TODO + RzBusinessTrip rzBusinessTrip = rzBusinessTripMapper.selectRzBusinessTripById(rzTripDetail.getTripId()); + rzBusinessTrip.setTripDays(rzBusinessTrip.getTripDays() + ts - rzTripDetail.getTripDay()); + rzBusinessTrip.setOverDays(rzBusinessTrip.getOverDays() + Long.parseLong(zr+"") - rzTripDetail.getOverDays()); + int i = rzBusinessTripMapper.updateRzBusinessTrip(rzBusinessTrip); + if(i < 1){ + return AjaxResult.error(); + } + rzTripDetail.setOverDays(Long.parseLong(zr+"")); + rzTripDetail.setTripDay(ts); + rzTripDetail.setUpdateTime(DateUtils.getNowDate()); + rzTripDetail.setUpdateBy(SecurityUtils.getUsername()); + i= rzTripDetailMapper.updateRzTripDetail(rzTripDetail); + if(i < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } + + /** + * 删除出差详情信息 + * + * @param id 出差详情主键 + * @return 结果 + */ + @Override + @Transactional + public AjaxResult deleteRzTripDetailById(Long id) + { + RzBusinessTripDetail rzTripDetail = rzTripDetailMapper.selectRzTripDetailById(id); + //查询总时长,修改出差总时长 + RzBusinessTrip rzBusinessTrip = rzBusinessTripMapper.selectRzBusinessTripById(rzTripDetail.getTripId()); + rzBusinessTrip.setTripDays(rzBusinessTrip.getTripDays() - rzTripDetail.getTripDay()); + rzBusinessTrip.setOverDays(rzBusinessTrip.getOverDays() - rzTripDetail.getOverDays()); + int i = rzBusinessTripMapper.updateRzBusinessTrip(rzBusinessTrip); + if(i < 1){ + return AjaxResult.error(); + } + rzTripDetail.setDelFlag(Constants.DELETE_FLAG_1); + rzTripDetail.setUpdateTime(DateUtils.getNowDate()); + rzTripDetail.setUpdateBy(SecurityUtils.getUsername()); + i= rzTripDetailMapper.updateRzTripDetail(rzTripDetail); + if(i < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzBusinessTripServiceImpl.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzBusinessTripServiceImpl.java new file mode 100644 index 0000000..6410b1f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzBusinessTripServiceImpl.java @@ -0,0 +1,127 @@ +package com.evo.personnelMatters.service.impl; + +import com.evo.common.annotation.DataScope; +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.personnelMatters.domain.RzBusinessTrip; +import com.evo.personnelMatters.mapper.RzBusinessTripMapper; +import com.evo.personnelMatters.service.IRzBusinessTripService; +import com.evo.system.domain.SysStaff; +import com.evo.system.mapper.SysDeptMapper; +import com.evo.system.mapper.SysStaffMapper; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import java.util.List; + +/** + * 出差管理Service业务层处理 + * + * @author chenyj + * @date 2024-08-30 + */ +@Service +public class RzBusinessTripServiceImpl implements IRzBusinessTripService +{ + @Resource + private RzBusinessTripMapper rzBusinessTripMapper; + @Resource + private SysStaffMapper sysStaffMapper; //员工信息 + @Resource + private SysDeptMapper deptMapper; //部门 + + /** + * 查询出差管理 + * + * @param id 出差管理主键 + * @return 出差管理 + */ + @Override + public RzBusinessTrip selectRzBusinessTripById(Long id) + { + return rzBusinessTripMapper.selectRzBusinessTripById(id); + } + + /** + * 查询出差管理列表 + * + * @param rzBusinessTrip 出差管理 + * @return 出差管理 + */ + @Override + @DataScope(deptAlias = "d") + public List selectRzBusinessTripList(RzBusinessTrip rzBusinessTrip) + { + List res_list = rzBusinessTripMapper.selectRzBusinessTripList(rzBusinessTrip); + for (RzBusinessTrip businessTrip : res_list) { + businessTrip.setDeptName(deptMapper.selectDeptById(businessTrip.getDeptId()).getDeptName()); + } + return res_list; + } + + /** + * 新增出差管理 + * + * @param rzBusinessTrip 出差管理 + * @return 结果 + */ + @Override + public AjaxResult insertRzBusinessTrip(RzBusinessTrip rzBusinessTrip) + { + List judgeList = rzBusinessTripMapper.selectRzBusinessTripList(rzBusinessTrip); + if(StringUtils.isNotNull(judgeList) && judgeList.size() > 0){ + return AjaxResult.error(); + } + //根据员工id查询员工名称 + SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(rzBusinessTrip.getUserId()); + rzBusinessTrip.setName(sysStaff.getName()); + rzBusinessTrip.setUserId(sysStaff.getUserId()); + rzBusinessTrip.setCreateTime(DateUtils.getNowDate()); + rzBusinessTrip.setCreateBy(SecurityUtils.getUsername()); + rzBusinessTrip.setDelFlag(Constants.DELETE_FLAG_0); + int i = rzBusinessTripMapper.insertRzBusinessTrip(rzBusinessTrip); + if(i < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } + + /** + * 修改出差管理 + * + * @param rzBusinessTrip 出差管理 + * @return 结果 + */ + @Override + public int updateRzBusinessTrip(RzBusinessTrip rzBusinessTrip) + { + rzBusinessTrip.setUpdateBy(SecurityUtils.getUsername()); + rzBusinessTrip.setUpdateTime(DateUtils.getNowDate()); + return rzBusinessTripMapper.updateRzBusinessTrip(rzBusinessTrip); + } + + /** + * 删除出差管理信息 + * + * @param id 出差管理主键 + * @return 结果 + */ + @Override + public AjaxResult deleteRzBusinessTripById(Long id) + { + RzBusinessTrip rzBusinessTrip = rzBusinessTripMapper.selectRzBusinessTripById(id); + if(rzBusinessTrip.getTripDays().longValue() > 0){ + return AjaxResult.error("有出差详情,不能删除!"); + } + rzBusinessTrip.setUpdateBy(SecurityUtils.getUsername()); + rzBusinessTrip.setUpdateTime(DateUtils.getNowDate()); + rzBusinessTrip.setDelFlag(Constants.DELETE_FLAG_1); + int i = rzBusinessTripMapper.updateRzBusinessTrip(rzBusinessTrip); + if(i < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzHolidayServiceImpl.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzHolidayServiceImpl.java new file mode 100644 index 0000000..ee1a2d1 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzHolidayServiceImpl.java @@ -0,0 +1,102 @@ +package com.evo.personnelMatters.service.impl; + +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.personnelMatters.domain.RzHoliday; +import com.evo.personnelMatters.mapper.RzHolidayMapper; +import com.evo.personnelMatters.service.IRzHolidayService; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import java.util.List; + +/** + * 假期管理Service业务层处理 + * + * @author chenyj + * @date 2024-08-03 + */ +@Service +public class RzHolidayServiceImpl implements IRzHolidayService +{ + @Resource + private RzHolidayMapper rzHolidayMapper; + + /** + * 查询假期管理 + * + * @param id 假期管理主键 + * @return 假期管理 + */ + @Override + public RzHoliday selectRzHolidayById(Long id) + { + return rzHolidayMapper.selectRzHolidayById(id); + } + + /** + * 查询假期管理列表 + * + * @param rzHoliday 假期管理 + * @return 假期管理 + */ + @Override + public List selectRzHolidayList(RzHoliday rzHoliday) + { + return rzHolidayMapper.selectRzHolidayList(rzHoliday); + } + + /** + * 新增假期管理 + * + * @param rzHoliday 假期管理 + * @return 结果 + */ + @Override + public AjaxResult insertRzHoliday(RzHoliday rzHoliday) + { + List list = rzHolidayMapper.selectRzHolidayList(rzHoliday); + if(StringUtils.isNotNull(list) && list.size() > 0){ + return AjaxResult.error(); + } + rzHoliday.setCreateTime(DateUtils.getNowDate()); + rzHoliday.setCreateBy(SecurityUtils.getUsername()); + rzHoliday.setDelFlag(Constants.DELETE_FLAG_0); + int i = rzHolidayMapper.insertRzHoliday(rzHoliday); + if(i < 1){ + AjaxResult.error(); + } + return AjaxResult.success(); + } + + /** + * 修改假期管理 + * + * @param rzHoliday 假期管理 + * @return 结果 + */ + @Override + public int updateRzHoliday(RzHoliday rzHoliday) + { + rzHoliday.setUpdateTime(DateUtils.getNowDate()); + rzHoliday.setUpdateBy(SecurityUtils.getUsername()); + return rzHolidayMapper.updateRzHoliday(rzHoliday); + } + + /** + * 删除数据 + * @param id + * @param oprName + * @return + */ + @Override + public int deleteRzHoliday(Long id,String oprName){ + RzHoliday rzHoliday = rzHolidayMapper.selectRzHolidayById(id); + rzHoliday.setDelFlag(Constants.DELETE_FLAG_1); + rzHoliday.setUpdateBy(SecurityUtils.getUsername()); + rzHoliday.setUpdateTime(DateUtils.getNowDate()); + return updateRzHoliday(rzHoliday); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzInterviewerServiceImpl.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzInterviewerServiceImpl.java new file mode 100644 index 0000000..f7cfb3f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzInterviewerServiceImpl.java @@ -0,0 +1,92 @@ +package com.evo.personnelMatters.service.impl; + +import com.evo.common.constant.Constants; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.personnelMatters.domain.RzInterviewer; +import com.evo.personnelMatters.mapper.RzInterviewerMapper; +import com.evo.personnelMatters.service.IRzInterviewerService; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import java.util.List; + +/** + * 面试信息Service业务层处理 + * + * @author chenyj + * @date 2024-09-07 + */ +@Service +public class RzInterviewerServiceImpl implements IRzInterviewerService +{ + @Resource + private RzInterviewerMapper rzInterviewerMapper; + + /** + * 查询面试信息 + * + * @param id 面试信息主键 + * @return 面试信息 + */ + @Override + public RzInterviewer selectRzInterviewerById(Long id) + { + return rzInterviewerMapper.selectRzInterviewerById(id); + } + + /** + * 查询面试信息列表 + * + * @param rzInterviewer 面试信息 + * @return 面试信息 + */ + @Override + public List selectRzInterviewerList(RzInterviewer rzInterviewer) + { + return rzInterviewerMapper.selectRzInterviewerList(rzInterviewer); + } + + /** + * 新增面试信息 + * + * @param rzInterviewer 面试信息 + * @return 结果 + */ + @Override + public int insertRzInterviewer(RzInterviewer rzInterviewer) + { + rzInterviewer.setYtFlag("否"); + rzInterviewer.setCreateBy(SecurityUtils.getUsername()); + rzInterviewer.setCreateTime(DateUtils.getNowDate()); + rzInterviewer.setDelFlag(Constants.DELETE_FLAG_0); + return rzInterviewerMapper.insertRzInterviewer(rzInterviewer); + } + + /** + * 修改面试信息 + * + * @param rzInterviewer 面试信息 + * @return 结果 + */ + @Override + public int updateRzInterviewer(RzInterviewer rzInterviewer) + { + rzInterviewer.setUpdateBy(SecurityUtils.getUsername()); + rzInterviewer.setUpdateTime(DateUtils.getNowDate()); + return rzInterviewerMapper.updateRzInterviewer(rzInterviewer); + } + + /** + * 删除面试信息信息 + * + * @param id 面试信息主键 + * @return 结果 + */ + @Override + public int deleteRzInterviewerById(Long id) + { + RzInterviewer rzInterviewer = rzInterviewerMapper.selectRzInterviewerById(id); + rzInterviewer.setDelFlag(Constants.DELETE_FLAG_1); + return updateRzInterviewer(rzInterviewer); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzLeaveDetailServiceImpl.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzLeaveDetailServiceImpl.java new file mode 100644 index 0000000..e6f6db6 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzLeaveDetailServiceImpl.java @@ -0,0 +1,293 @@ +package com.evo.personnelMatters.service.impl; + +import com.evo.attendance.domain.RzAttendanceStatistical; +import com.evo.attendance.mapper.RzAttendanceStatisticalMapper; +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.personnelMatters.domain.*; +import com.evo.personnelMatters.mapper.*; +import com.evo.personnelMatters.service.IRzLeaveDetailService; +import com.evo.utils.DateUtil; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +/** + * 请假管理详情Service业务层处理 + * + * @author chenyj + * @date 2024-08-03 + */ +@Service +public class RzLeaveDetailServiceImpl implements IRzLeaveDetailService +{ + @Resource + private RzLeaveDetailMapper rzLeaveDetailMapper; + @Resource + private RzLeaveMapper rzLeaveMapper; //请假汇总 + @Resource + private RzBusinessTripMapper rzBusinessTripMapper; //出差 + @Resource + private RzAttendanceStatisticalMapper rzAttendanceStatisticalMapper; //打卡统计 + /** + * 查询请假管理详情 + * + * @param id 请假管理详情主键 + * @return 请假管理详情 + */ + @Override + public RzLeaveDetail selectRzLeaveDetailById(Long id) + { + return rzLeaveDetailMapper.selectRzLeaveDetailById(id); + } + + /** + * 查询请假管理详情列表 + * + * @param rzLeaveDetail 请假管理详情 + * @return 请假管理详情 + */ + @Override + public List selectRzLeaveDetailList(RzLeaveDetail rzLeaveDetail) + { + return rzLeaveDetailMapper.selectRzLeaveDetailList(rzLeaveDetail); + } + + /** + * 新增请假管理详情 + * + * @param rzLeaveDetail 请假管理详情 + * @return 结果 + */ + @Override + @Transactional + public AjaxResult insertRzLeaveDetail(RzLeaveDetail rzLeaveDetail) + { + //判断请假时间 + if(rzLeaveDetail.getLeaveStartTime().getTime() > rzLeaveDetail.getLeaveEndTime().getTime()){ + return AjaxResult.error("请假开始时间不能早于结束时间!!"); + } + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); + //判断请假开始,结束时间是否在同一个月,不同月提示 + if(!sdf.format(rzLeaveDetail.getLeaveStartTime()).equals(sdf.format(rzLeaveDetail.getLeaveEndTime()))){ + return AjaxResult.error("请假时间不能跨月!!"); + } + //根据员工姓名查询 + RzLeave rzLeave = rzLeaveMapper.selectRzLeaveById(rzLeaveDetail.getLeaveId()); + //计算请假时长 + Long i = DateUtil.dateUtil.autoLeavehoursForCount(rzLeaveDetail.getLeaveStartTime(),rzLeaveDetail.getLeaveEndTime(),rzLeaveDetail.getType()); + rzLeaveDetail.setLeaveHour(i.intValue()); + rzLeaveDetail.setCreateTime(DateUtils.getNowDate()); + rzLeaveDetail.setCreateBy(SecurityUtils.getUsername()); + rzLeaveDetail.setDelFlag(Constants.DELETE_FLAG_0); + int r = rzLeaveDetailMapper.insertRzLeaveDetail(rzLeaveDetail); + if(r < 1){ + return AjaxResult.error(); + } + switch (rzLeaveDetail.getType()){ + case "2": + rzLeave.setSickHours(rzLeave.getSickHours() + i.intValue()); + break; + case "3": + rzLeave.setAbsenceHours(rzLeave.getAbsenceHours() + i.intValue()); + break; + case "4": + rzLeave.setAnnualHours(rzLeave.getAnnualHours() + i.intValue()); + break; + case "5": + boolean flag = autoLeavedNumber(rzLeave.getUserId(),rzLeaveDetail.getLeaveStartTime(),i); + if(flag){ + rzLeave.setCompensatoryHours(rzLeave.getCompensatoryHours() + i.intValue()); + }else{ + return AjaxResult.error("没有调休时间!!"); + } + break; + case "6": + rzLeave.setMarriageHours(rzLeave.getMarriageHours() + i.intValue()); + break; + case "7": + rzLeave.setMaternityHours(rzLeave.getMaternityHours() + i.intValue()); + break; + case "8": + rzLeave.setPaternityHours(rzLeave.getPaternityHours() + i.intValue()); + break; + case "9": + rzLeave.setFuneralHours(rzLeave.getFuneralHours() + i.intValue()); + break; + case "10": + rzLeave.setWorkHours(rzLeave.getWorkHours() + i.intValue()); + break; + } + r = rzLeaveMapper.updateRzLeave(rzLeave); + if(r < 1){ + return AjaxResult.error(); + } + //反写考勤汇总 + RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(rzLeave.getUserId(),rzLeave.getLeaveDate()); + rzAttendanceStatistical.setAbsenteeism(new BigDecimal(rzLeave.getWorkHours() + rzLeave.getFuneralHours() + rzLeave.getPaternityHours() + rzLeave.getMaternityHours() + + rzLeave.getMarriageHours() + rzLeave.getCompensatoryHours() + rzLeave.getAnnualHours() + rzLeave.getAbsenceHours() + rzLeave.getSickHours())); + r = rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical); + if(r < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } + + /** + * 根据用户ID及时间,调休时间判断员工是否可以调休 + * @param staffId 员工ID + * @param date 请假月份 + * @param hours 请假时长 + * @return + */ + private boolean autoLeavedNumber(Long staffId, Date date,Long hours){ + //先查询出差是否有加班 + RzBusinessTrip RzBusinessTrip = rzBusinessTripMapper.selectRzBusinessTripListByMonth(staffId,date); + //出差有加班且调休时间够,则可以调休 + if(StringUtils.isNotNull(RzBusinessTrip) && RzBusinessTrip.getOverDays() * 8 >= hours){ + RzBusinessTrip.setOverDays((RzBusinessTrip.getOverDays() * 8 - hours)/8); + rzBusinessTripMapper.updateRzBusinessTrip(RzBusinessTrip); + return true; + } + return false; + } + + /** + * 修改请假管理详情 + * + * @param rzLeaveDetail 请假管理详情 + * @return 结果 + */ + @Override + public AjaxResult updateRzLeaveDetail(RzLeaveDetail rzLeaveDetail) + { + //根据ID查询原始请假小时数 + RzLeaveDetail leaveDetail = rzLeaveDetailMapper.selectRzLeaveDetailById(rzLeaveDetail.getId()); + Long i = DateUtil.dateUtil.autoLeavehoursForCount(rzLeaveDetail.getLeaveStartTime(),rzLeaveDetail.getLeaveEndTime(),rzLeaveDetail.getType()); + rzLeaveDetail.setLeaveHour(i.intValue()); + rzLeaveDetail.setUpdateBy(SecurityUtils.getUsername()); + rzLeaveDetail.setUpdateTime(DateUtils.getNowDate()); + int r = rzLeaveDetailMapper.updateRzLeaveDetail(rzLeaveDetail); + if(r < 1){ + return AjaxResult.error(); + } + //修改请假总时长 + RzLeave rzLeave = rzLeaveMapper.selectRzLeaveById(rzLeaveDetail.getLeaveId()); + //判断请假类型没有变化 + if(leaveDetail.getType().equals(rzLeaveDetail.getType())){ + switch (rzLeaveDetail.getType()){ + case "2": + rzLeave.setSickHours(rzLeave.getSickHours() + i.intValue() - leaveDetail.getLeaveHour()); + break; + case "3": + rzLeave.setAbsenceHours(rzLeave.getAbsenceHours() + i.intValue() - leaveDetail.getLeaveHour()); + break; + case "4": + rzLeave.setAnnualHours(rzLeave.getAnnualHours() + i.intValue() - leaveDetail.getLeaveHour()); + break; + case "5": + rzLeave.setCompensatoryHours(rzLeave.getCompensatoryHours() + i.intValue() - leaveDetail.getLeaveHour()); + break; + case "6": + rzLeave.setMarriageHours(rzLeave.getMarriageHours() + i.intValue() - leaveDetail.getLeaveHour()); + break; + case "7": + rzLeave.setMaternityHours(rzLeave.getMaternityHours() + i.intValue() - leaveDetail.getLeaveHour()); + break; + case "8": + rzLeave.setPaternityHours(rzLeave.getPaternityHours() + i.intValue() - leaveDetail.getLeaveHour()); + break; + case "9": + rzLeave.setFuneralHours(rzLeave.getFuneralHours() + i.intValue() - leaveDetail.getLeaveHour()); + break; + case "10": + rzLeave.setWorkHours(rzLeave.getWorkHours() + i.intValue() - leaveDetail.getLeaveHour()); + break; + } + }else{ + + } + r = rzLeaveMapper.updateRzLeave(rzLeave); + if(r < 1){ + return AjaxResult.error(); + } + //反写考勤汇总 + RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(rzLeave.getUserId(),rzLeave.getLeaveDate()); + rzAttendanceStatistical.setAbsenteeism(new BigDecimal(rzLeave.getWorkHours() + rzLeave.getFuneralHours() + rzLeave.getPaternityHours() + rzLeave.getMaternityHours() + + rzLeave.getMarriageHours() + rzLeave.getCompensatoryHours() + rzLeave.getAnnualHours() + rzLeave.getAbsenceHours() + rzLeave.getSickHours())); + r = rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical); + if(r < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } + + /** + * 根据ID删除数据 + * @param id + * @return + */ + public AjaxResult deleteRzLeaveDetailById(Long id){ + RzLeaveDetail rzLeaveDetail = rzLeaveDetailMapper.selectRzLeaveDetailById(id); + rzLeaveDetail.setUpdateBy(SecurityUtils.getUsername()); + rzLeaveDetail.setUpdateTime(DateUtils.getNowDate()); + rzLeaveDetail.setDelFlag(Constants.DELETE_FLAG_1); + int r = rzLeaveDetailMapper.updateRzLeaveDetail(rzLeaveDetail); + if(r < 1){ + return AjaxResult.error(); + } + //减少总时长 + RzLeave rzLeave = rzLeaveMapper.selectRzLeaveById(rzLeaveDetail.getLeaveId()); + switch (rzLeaveDetail.getType()){ + case "2": + rzLeave.setSickHours(rzLeave.getSickHours() - rzLeaveDetail.getLeaveHour()); + break; + case "3": + rzLeave.setAbsenceHours(rzLeave.getAbsenceHours() - rzLeaveDetail.getLeaveHour()); + break; + case "4": + rzLeave.setAnnualHours(rzLeave.getAnnualHours() - rzLeaveDetail.getLeaveHour()); + break; + case "5": + rzLeave.setCompensatoryHours(rzLeave.getCompensatoryHours() - rzLeaveDetail.getLeaveHour()); + break; + case "6": + rzLeave.setMarriageHours(rzLeave.getMarriageHours() - rzLeaveDetail.getLeaveHour()); + break; + case "7": + rzLeave.setMaternityHours(rzLeave.getMaternityHours() - rzLeaveDetail.getLeaveHour()); + break; + case "8": + rzLeave.setPaternityHours(rzLeave.getPaternityHours() - rzLeaveDetail.getLeaveHour()); + break; + case "9": + rzLeave.setFuneralHours(rzLeave.getFuneralHours() - rzLeaveDetail.getLeaveHour()); + break; + case "10": + rzLeave.setWorkHours(rzLeave.getWorkHours() - rzLeaveDetail.getLeaveHour()); + break; + } + r = rzLeaveMapper.updateRzLeave(rzLeave); + if(r < 1){ + return AjaxResult.error(); + } + //反写考勤汇总 + RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(rzLeave.getUserId(),rzLeave.getLeaveDate()); + rzAttendanceStatistical.setAbsenteeism(new BigDecimal(rzLeave.getWorkHours() + rzLeave.getFuneralHours() + rzLeave.getPaternityHours() + rzLeave.getMaternityHours() + + rzLeave.getMarriageHours() + rzLeave.getCompensatoryHours() + rzLeave.getAnnualHours() + rzLeave.getAbsenceHours() + rzLeave.getSickHours())); + r = rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical); + if(r < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } + + +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzLeaveServiceImpl.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzLeaveServiceImpl.java new file mode 100644 index 0000000..c3390b2 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzLeaveServiceImpl.java @@ -0,0 +1,153 @@ +package com.evo.personnelMatters.service.impl; + +import com.evo.common.annotation.DataScope; +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.personnelMatters.domain.RzLeave; +import com.evo.personnelMatters.domain.RzLeaveDetail; +import com.evo.personnelMatters.mapper.RzLeaveDetailMapper; +import com.evo.personnelMatters.mapper.RzLeaveMapper; +import com.evo.personnelMatters.service.IRzLeaveService; +import com.evo.system.domain.SysStaff; +import com.evo.system.mapper.SysDeptMapper; +import com.evo.system.mapper.SysStaffMapper; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +/** + * 请假管理Service业务层处理 + * + * @author chenyj + * @date 2024-08-03 + */ +@Service +public class RzLeaveServiceImpl implements IRzLeaveService +{ + @Resource + private RzLeaveMapper rzLeaveMapper; + @Resource + private RzLeaveDetailMapper rzLeaveDetailMapper; //请假详情 + @Resource + private SysStaffMapper sysStaffMapper; //员工信息 + @Resource + private SysDeptMapper deptMapper; //部门 + /** + * 查询请假管理 + * + * @param id 请假管理主键 + * @return 请假管理 + */ + @Override + public RzLeave selectRzLeaveById(Long id) + { + return rzLeaveMapper.selectRzLeaveById(id); + } + + /** + * 查询请假管理列表 + * + * @param rzLeave 请假管理 + * @return 请假管理 + */ + @Override + @DataScope(deptAlias = "d") + public List selectRzLeaveList(RzLeave rzLeave) + { + List res_list = rzLeaveMapper.selectRzLeaveList(rzLeave); + //解析部门 + for (RzLeave leave : res_list) { + leave.setDeptName(deptMapper.selectDeptById(leave.getDeptId()).getDeptName()); + } + return res_list; + } + + /** + * 新增请假管理 + * + * @param rzLeave 请假管理 + * @return 结果 + */ + @Override + public AjaxResult insertRzLeave(RzLeave rzLeave) + { + List params_list = rzLeaveMapper.selectRzLeaveList(rzLeave); + if(StringUtils.isNotNull(params_list) && params_list.size() >0){ + return AjaxResult.error(); + } + //根据员工id查询员工名称 + SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(rzLeave.getUserId()); + rzLeave.setName(sysStaff.getName()); + rzLeave.setDelFlag(Constants.DELETE_FLAG_0); + rzLeave.setCreateTime(DateUtils.getNowDate()); + rzLeave.setCreateBy(SecurityUtils.getUsername()); + int i = rzLeaveMapper.insertRzLeave(rzLeave); + if(i < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } + + /** + * 修改请假管理 + * + * @param rzLeave 请假管理 + * @return 结果 + */ + @Override + public AjaxResult updateRzLeave(RzLeave rzLeave) + { + //判断是否有详情数据 + List detail_list = rzLeaveDetailMapper.selectRzLeaveDetailByLeaveId(rzLeave.getId()); + if(StringUtils.isNotNull(detail_list) && detail_list.size() > 0){ + return AjaxResult.error(); + } + rzLeave.setUpdateTime(DateUtils.getNowDate()); + rzLeave.setUpdateBy(SecurityUtils.getUsername()); + int i= rzLeaveMapper.updateRzLeave(rzLeave); + if(i < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } + + /** + * 删除请假管理 + * + * @return 结果 + */ + @Override + public AjaxResult deleteRzLeave(Long id,String name){ + RzLeave rzLeave = rzLeaveMapper.selectRzLeaveById(id); + rzLeave.setUpdateTime(DateUtils.getNowDate()); + rzLeave.setUpdateBy(SecurityUtils.getUsername()); + rzLeave.setDelFlag(Constants.DELETE_FLAG_1); + int i= rzLeaveMapper.updateRzLeave(rzLeave); + if(i < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } + + /** + * 查询员工请假详情 + * @param rzLeave + * @return + */ + public List listLeaveDetails(RzLeave rzLeave){ + List res_list = null; + //查询指定月份的请假统计 + RzLeave leave = rzLeaveMapper.queryRzLeaveByDateAndUserId(rzLeave.getUserId(),rzLeave.getLeaveDate()); + if(leave == null){ + return new ArrayList(); + } + //查询请假详情 + res_list = rzLeaveDetailMapper.selectRzLeaveDetailByLeaveId(leave.getId()); + return res_list; + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzOverTimeDetailServiceImpl.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzOverTimeDetailServiceImpl.java new file mode 100644 index 0000000..3e92d65 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzOverTimeDetailServiceImpl.java @@ -0,0 +1,168 @@ +package com.evo.personnelMatters.service.impl; + +import com.evo.attendance.domain.RzAttendanceStatistical; +import com.evo.attendance.mapper.RzAttendanceStatisticalMapper; +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.personnelMatters.domain.RzOverTime; +import com.evo.personnelMatters.domain.RzOverTimeDetail; +import com.evo.personnelMatters.mapper.RzOverTimeDetailMapper; +import com.evo.personnelMatters.mapper.RzOverTimeMapper; +import com.evo.personnelMatters.service.IRzOverTimeDetailService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.List; + +/** + * 加班详情Service业务层处理 + * + * @author chenyj + * @date 2024-09-09 + */ +@Service +public class RzOverTimeDetailServiceImpl implements IRzOverTimeDetailService +{ + @Resource + private RzOverTimeDetailMapper rzOverTimeDetailMapper; + @Resource + private RzOverTimeMapper rzOverTimeMapper; + @Resource + private RzAttendanceStatisticalMapper rzAttendanceStatisticalMapper; //打卡统计 + /** + * 查询加班详情 + * + * @param id 加班详情主键 + * @return 加班详情 + */ + @Override + public RzOverTimeDetail selectRzOverTimeDetailById(Long id) + { + return rzOverTimeDetailMapper.selectRzOverTimeDetailById(id); + } + + /** + * 查询加班详情列表 + * + * @param rzOverTimeDetail 加班详情 + * @return 加班详情 + */ + @Override + public List selectRzOverTimeDetailList(RzOverTimeDetail rzOverTimeDetail) + { + return rzOverTimeDetailMapper.selectRzOverTimeDetailList(rzOverTimeDetail); + } + + /** + * 新增加班详情 + * + * @param rzOverTimeDetail 加班详情 + * @return 结果 + */ + @Override + @Transactional + public AjaxResult insertRzOverTimeDetail(RzOverTimeDetail rzOverTimeDetail) + { + //判断请假时间 + if(rzOverTimeDetail.getOverTimeStart().getTime() > rzOverTimeDetail.getOverTimeEnd().getTime()){ + return AjaxResult.error(); + } + Long hours = (rzOverTimeDetail.getOverTimeEnd().getTime() - rzOverTimeDetail.getOverTimeStart().getTime())/1000/60/60; + rzOverTimeDetail.setOverTimeHours(BigDecimal.valueOf(hours)); + rzOverTimeDetail.setCreateTime(DateUtils.getNowDate()); + rzOverTimeDetail.setCreateBy(SecurityUtils.getUsername()); + rzOverTimeDetail.setDelFlag(Constants.DELETE_FLAG_0); + int i = rzOverTimeDetailMapper.insertRzOverTimeDetail(rzOverTimeDetail); + if(i < 1){ + return AjaxResult.error(); + } + //反写加班总时长 + RzOverTime rzOverTime = rzOverTimeMapper.selectRzOverTimeById(rzOverTimeDetail.getOverTimeId()); + rzOverTime.setOverHours(rzOverTime.getOverHours().add(BigDecimal.valueOf(hours))); + i = rzOverTimeMapper.updateRzOverTime(rzOverTime); + if(i < 1){ + return AjaxResult.error(); + } + //反写考勤汇总 + RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(rzOverTime.getUserId(),rzOverTime.getOverTimeMonth()); + rzAttendanceStatistical.setWorkOvertimeNumber(rzOverTime.getOverHours()); + i = rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical); + if(i < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } + + /** + * 修改加班详情 + * + * @param rzOverTimeDetail 加班详情 + * @return 结果 + */ + @Override + @Transactional + public AjaxResult updateRzOverTimeDetail(RzOverTimeDetail rzOverTimeDetail) + { + //根据ID查询旧数据 + RzOverTimeDetail older = rzOverTimeDetailMapper.selectRzOverTimeDetailById(rzOverTimeDetail.getId()); + Long hours = (rzOverTimeDetail.getOverTimeEnd().getTime() - rzOverTimeDetail.getOverTimeStart().getTime())/1000/60/60; + rzOverTimeDetail.setOverTimeHours(BigDecimal.valueOf(hours)); + rzOverTimeDetail.setUpdateTime(DateUtils.getNowDate()); + rzOverTimeDetail.setUpdateBy(SecurityUtils.getUsername()); + int i = rzOverTimeDetailMapper.updateRzOverTimeDetail(rzOverTimeDetail); + if(i < 1){ + return AjaxResult.error(); + } + //反写加班总时长 + RzOverTime rzOverTime = rzOverTimeMapper.selectRzOverTimeById(rzOverTimeDetail.getOverTimeId()); + rzOverTime.setOverHours(rzOverTime.getOverHours().add(BigDecimal.valueOf(hours)).subtract(older.getOverTimeHours())); + i = rzOverTimeMapper.updateRzOverTime(rzOverTime); + if(i < 1){ + return AjaxResult.error(); + } + //反写考勤汇总 + RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(rzOverTime.getUserId(),rzOverTime.getOverTimeMonth()); + rzAttendanceStatistical.setWorkOvertimeNumber(rzOverTime.getOverHours()); + i = rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical); + if(i < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } + + /** + * 删除加班详情信息 + * + * @param id 加班详情主键 + * @return 结果 + */ + @Override + @Transactional + public AjaxResult deleteRzOverTimeDetailById(Long id) + { + RzOverTimeDetail rzOverTimeDetail = rzOverTimeDetailMapper.selectRzOverTimeDetailById(id); + rzOverTimeDetail.setDelFlag(Constants.DELETE_FLAG_1); + int i = rzOverTimeDetailMapper.updateRzOverTimeDetail(rzOverTimeDetail); + if(i < 1){ + return AjaxResult.error(); + } + //反写加班总时长 + RzOverTime rzOverTime = rzOverTimeMapper.selectRzOverTimeById(rzOverTimeDetail.getOverTimeId()); + rzOverTime.setOverHours(rzOverTime.getOverHours().subtract(rzOverTimeDetail.getOverTimeHours())); + i = rzOverTimeMapper.updateRzOverTime(rzOverTime); + if(i < 1){ + return AjaxResult.error(); + } + //反写考勤汇总 + RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(rzOverTime.getUserId(),rzOverTime.getOverTimeMonth()); + rzAttendanceStatistical.setWorkOvertimeNumber(rzOverTime.getOverHours()); + i = rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical); + if(i < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzOverTimeServiceImpl.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzOverTimeServiceImpl.java new file mode 100644 index 0000000..858dce5 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzOverTimeServiceImpl.java @@ -0,0 +1,155 @@ +package com.evo.personnelMatters.service.impl; + +import com.evo.common.annotation.DataScope; +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.personnelMatters.domain.RzOverTime; +import com.evo.personnelMatters.domain.RzOverTimeDetail; +import com.evo.personnelMatters.mapper.RzOverTimeDetailMapper; +import com.evo.personnelMatters.mapper.RzOverTimeMapper; +import com.evo.personnelMatters.service.IRzOverTimeService; +import com.evo.system.domain.SysStaff; +import com.evo.system.mapper.SysDeptMapper; +import com.evo.system.mapper.SysStaffMapper; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +/** + * 加班管理Service业务层处理 + * + * @author chenyj + * @date 2024-09-03 + */ +@Service +public class RzOverTimeServiceImpl implements IRzOverTimeService +{ + @Resource + private RzOverTimeMapper rzOverTimeMapper; + @Resource + private SysStaffMapper sysStaffMapper; //员工信息 + @Resource + private RzOverTimeDetailMapper rzOverTimeDetailMapper; //加班详情 + @Resource + private SysDeptMapper deptMapper; //部门 + + + /** + * 查询加班管理 + * + * @param id 加班管理主键 + * @return 加班管理 + */ + @Override + public RzOverTime selectRzOverTimeById(Long id) + { + return rzOverTimeMapper.selectRzOverTimeById(id); + } + + /** + * 查询加班管理列表 + * + * @param rzOverTime 加班管理 + * @return 加班管理 + */ + @Override + @DataScope(deptAlias = "d") + public List selectRzOverTimeList(RzOverTime rzOverTime) + { + List res_list = rzOverTimeMapper.selectRzOverTimeList(rzOverTime); + for (RzOverTime overTime : res_list) { + overTime.setDeptName(deptMapper.selectDeptById(overTime.getDeptId()).getDeptName()); + } + return res_list; + } + + /** + * 新增加班管理 + * + * @param rzOverTime 加班管理 + * @return 结果 + */ + @Override + public AjaxResult insertRzOverTime(RzOverTime rzOverTime) + { + RzOverTime overTime = rzOverTimeMapper.selectRzOverTimeByNameAndMonth(Long.parseLong(rzOverTime.getName()),rzOverTime.getOverTimeMonth()); + if(StringUtils.isNotNull(overTime)){ + return AjaxResult.error(); + } + //根据员工id查询员工名称 + SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.parseLong(rzOverTime.getName())); + rzOverTime.setName(sysStaff.getName()); + rzOverTime.setUserId(sysStaff.getUserId()); + rzOverTime.setCreateBy(SecurityUtils.getUsername()); + rzOverTime.setCreateTime(DateUtils.getNowDate()); + rzOverTime.setDelFlag(Constants.DELETE_FLAG_0); + int i = rzOverTimeMapper.insertRzOverTime(rzOverTime); + if(i < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } + + /** + * 修改加班管理 + * + * @param rzOverTime 加班管理 + * @return 结果 + */ + @Override + public int updateRzOverTime(RzOverTime rzOverTime) + { + rzOverTime.setUpdateBy(SecurityUtils.getUsername()); + rzOverTime.setUpdateTime(DateUtils.getNowDate()); + return rzOverTimeMapper.updateRzOverTime(rzOverTime); + } + + /** + * 删除加班管理信息 + * + * @param id 加班管理主键 + * @return 结果 + */ + @Override + public AjaxResult deleteRzOverTimeById(Long id) + { + RzOverTime rzOverTime = rzOverTimeMapper.selectRzOverTimeById(id); + if(rzOverTime.getOverHours().compareTo(new BigDecimal("0.0")) > 0){ + return AjaxResult.error("有加班工时,不能删除!"); + } + rzOverTime.setDelFlag(Constants.DELETE_FLAG_1); + rzOverTime.setUpdateBy(SecurityUtils.getUsername()); + rzOverTime.setUpdateTime(DateUtils.getNowDate()); + int i = rzOverTimeMapper.updateRzOverTime(rzOverTime); + if(i < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } + + /** + * 查询员工的加班详情 + * @param rzOverTime + * @return + */ + @Override + public List selectRzOverTimeDetailListByUserIdAndMonth(RzOverTime rzOverTime){ + List res_list = null; + //根据月份和员工ID获取加班ID + RzOverTime overTime = rzOverTimeMapper.selectRzOverTimeByNameAndMonth(rzOverTime.getUserId(),rzOverTime.getOverTimeMonth()); + if(overTime == null){ + return new ArrayList(); + } + RzOverTimeDetail rzOverTimeDetail = new RzOverTimeDetail(); + rzOverTimeDetail.setOverTimeId(overTime.getId()); + res_list = rzOverTimeDetailMapper.selectRzOverTimeDetailList(rzOverTimeDetail); + return res_list; + } + + +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzSubsidyServiceImpl.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzSubsidyServiceImpl.java new file mode 100644 index 0000000..957d53d --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzSubsidyServiceImpl.java @@ -0,0 +1,104 @@ +package com.evo.personnelMatters.service.impl; + +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.personnelMatters.domain.RzSubsidy; +import com.evo.personnelMatters.mapper.RzSubsidyMapper; +import com.evo.personnelMatters.service.IRzSubsidyService; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import java.util.List; + +/** + * 补助管理Service业务层处理 + * + * @author chenyj + * @date 2024-08-27 + */ +@Service +public class RzSubsidyServiceImpl implements IRzSubsidyService +{ + @Resource + private RzSubsidyMapper rzSubsidyMapper; + + /** + * 查询补助管理 + * + * @param id 补助管理主键 + * @return 补助管理 + */ + @Override + public RzSubsidy selectRzSubsidyById(Long id) + { + return rzSubsidyMapper.selectRzSubsidyById(id); + } + + /** + * 查询补助管理列表 + * + * @param rzSubsidy 补助管理 + * @return 补助管理 + */ + @Override + public List selectRzSubsidyList(RzSubsidy rzSubsidy) + { + return rzSubsidyMapper.selectRzSubsidyList(rzSubsidy); + } + + /** + * 新增补助管理 + * + * @param rzSubsidy 补助管理 + * @return 结果 + */ + @Override + public AjaxResult insertRzSubsidy(RzSubsidy rzSubsidy) + { + //根据名称查询 + RzSubsidy subsidy = rzSubsidyMapper.selectRzSubsidyByName(rzSubsidy.getName()); + if(StringUtils.isNotNull(subsidy)){ + return AjaxResult.error("补助名称重复!!"); + } + rzSubsidy.setCreateBy(SecurityUtils.getUsername()); + rzSubsidy.setCreateTime(DateUtils.getNowDate()); + rzSubsidy.setDelFlag(Constants.DELETE_FLAG_0); + int i = rzSubsidyMapper.insertRzSubsidy(rzSubsidy); + if(i < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } + + /** + * 修改补助管理 + * + * @param rzSubsidy 补助管理 + * @return 结果 + */ + @Override + public int updateRzSubsidy(RzSubsidy rzSubsidy) + { + rzSubsidy.setUpdateBy(SecurityUtils.getUsername()); + rzSubsidy.setUpdateTime(DateUtils.getNowDate()); + return rzSubsidyMapper.updateRzSubsidy(rzSubsidy); + } + + /** + * 删除补助管理信息 + * + * @param id 补助管理主键 + * @return 结果 + */ + @Override + public int deleteRzSubsidyById(Long id) + { + RzSubsidy rzSubsidy = rzSubsidyMapper.selectRzSubsidyById(id); + rzSubsidy.setDelFlag(Constants.DELETE_FLAG_1); + rzSubsidy.setUpdateBy(SecurityUtils.getUsername()); + rzSubsidy.setUpdateTime(DateUtils.getNowDate()); + return updateRzSubsidy(rzSubsidy); + } +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/SpecialOverTimeServiceImpl.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/SpecialOverTimeServiceImpl.java new file mode 100644 index 0000000..ab84a25 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/SpecialOverTimeServiceImpl.java @@ -0,0 +1,99 @@ +package com.evo.personnelMatters.service.impl; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.SecurityUtils; +import com.evo.personnelMatters.domain.EqOverStaff; +import com.evo.personnelMatters.domain.SpecialOverTime; +import com.evo.personnelMatters.mapper.BsOverTimeMapper; +import com.evo.personnelMatters.mapper.EqOverStaffMapper; +import com.evo.personnelMatters.service.SpecialOverTimeService; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import java.util.Date; +import java.util.List; + +@Service +public class SpecialOverTimeServiceImpl implements SpecialOverTimeService { + + @Resource + private BsOverTimeMapper bsOverTimeMapper; + @Resource + private EqOverStaffMapper eqOverStaffMapper; + + @Override + public SpecialOverTime selectSpecialOverTimeById(){ + return bsOverTimeMapper.selectSpecialOverTimeById(); + } + + @Override + public AjaxResult addSpecialOverTime(SpecialOverTime specialOverTime){ + int i = bsOverTimeMapper.updateSpecialOverTime(specialOverTime); + if(i < 1){ + return AjaxResult.error("保存失败"); + } + return AjaxResult.success("保存成功"); + } + + @Override + public List selectEqOverStaffList(EqOverStaff eqOverStaff){ + return eqOverStaffMapper.selectEqOverStaffList(eqOverStaff); + } + + /** + * 查询照片管理 + * + * @param id 照片管理主键 + * @return 照片管理 + */ + @Override + public EqOverStaff selectEqOverStaffById(Long id) + { + return eqOverStaffMapper.selectEqOverStaffById(id); + } + + /** + * 新增照片管理 + * + * @param eqOverStaff 照片管理 + * @return 结果 + */ + @Override + public int insertEqOverStaff(EqOverStaff eqOverStaff) + { + eqOverStaff.setCreateBy(SecurityUtils.getUsername()); + eqOverStaff.setCreateTime(new Date()); + eqOverStaff.setDelFlag("0"); + return eqOverStaffMapper.insertEqOverStaff(eqOverStaff); + } + + /** + * 修改照片管理 + * + * @param eqOverStaff 照片管理 + * @return 结果 + */ + @Override + public int updateEqOverStaff(EqOverStaff eqOverStaff) + { + eqOverStaff.setUpdateBy(SecurityUtils.getUsername()); + eqOverStaff.setUpdateTime(new Date()); + return eqOverStaffMapper.updateEqOverStaff(eqOverStaff); + } + + /** + * 删除照片管理信息 + * + * @param id 照片管理主键 + * @return 结果 + */ + @Override + public int deleteEqOverStaffById(Long id) + { + EqOverStaff eqOverStaff = eqOverStaffMapper.selectEqOverStaffById(id); + eqOverStaff.setDelFlag("1"); + eqOverStaff.setUpdateTime(new Date()); + eqOverStaff.setUpdateBy(SecurityUtils.getUsername()); + return eqOverStaffMapper.updateEqOverStaff(eqOverStaff); + } + +} diff --git a/evo-admin/src/main/java/com/evo/restaurant/controller/RzRestaurantDetailController.java b/evo-admin/src/main/java/com/evo/restaurant/controller/RzRestaurantDetailController.java new file mode 100644 index 0000000..eba4712 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/restaurant/controller/RzRestaurantDetailController.java @@ -0,0 +1,89 @@ +package com.evo.restaurant.controller; + +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.restaurant.domain.RzRestaurantDetail; +import com.evo.restaurant.service.IRzRestaurantDetailService; +import com.evo.system.domain.SysStaff; +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.util.List; + +/** + * 餐饮详情Controller + * + * @author chenyj + * @date 2024-09-18 + */ +@RestController +@RequestMapping("/api/v2") +public class RzRestaurantDetailController extends BaseController +{ + @Autowired + private IRzRestaurantDetailService rzRestaurantDetailService; + + /** + * 查询餐饮详情列表 + */ + @PreAuthorize("@ss.hasPermi('api:v2:list')") + @GetMapping("/list") + public TableDataInfo list(RzRestaurantDetail rzRestaurantDetail) + { + startPage(); + List list = rzRestaurantDetailService.selectRzRestaurantDetailList(rzRestaurantDetail); + return getDataTable(list); + } + + /** + * 导出餐饮详情列表 + */ + @PreAuthorize("@ss.hasPermi('api:v2:export')") + @Log(title = "餐饮详情", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, RzRestaurantDetail rzRestaurantDetail) + { + List list = rzRestaurantDetailService.selectRzRestaurantDetailList(rzRestaurantDetail); + ExcelUtil util = new ExcelUtil(RzRestaurantDetail.class); + util.exportExcel(response, list, "餐饮详情"); + } + + /** + * 刷脸获取打卡按钮权限 + * sn 设备号 + * type 设备识别类型 + * user_id 用户id + * card 人员信息中的卡号 + * confidence 人脸算法识别到的相识度 + * temperature 测量到的温度,未开启测温的设备为空 + * + * 响应: Result 返回请求类型:0:可以打卡,其它值表示无法打卡 + * Msg 对应 Result 的状态,可为空 + * Content 识别后返回的详细信息 + * button 9位长度的字符串,0 表示不可以点击 1 表示可以点击 + * clock in count 打卡次数 + * + * String sn,String type,String userId,String card,String confidence + */ + @RequestMapping("/verify_user_yt") + public String verifyUser(@RequestBody String json){ + return rzRestaurantDetailService.insertRzRestaurantDetail(json); + } + + /** + * 手动刷新刷脸记录 + */ + @GetMapping("/flushData") + public TableDataInfo flushData(){ + //根据时间查询当前餐的统计数据 + List list = rzRestaurantDetailService.flushData(); + return getDataTable(list); + } + + +} diff --git a/evo-admin/src/main/java/com/evo/restaurant/controller/RzRestaurantImagesController.java b/evo-admin/src/main/java/com/evo/restaurant/controller/RzRestaurantImagesController.java new file mode 100644 index 0000000..0d0b1c8 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/restaurant/controller/RzRestaurantImagesController.java @@ -0,0 +1,61 @@ +package com.evo.restaurant.controller; + +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.restaurant.domain.RzRestaurantImages; +import com.evo.restaurant.service.IRzRestaurantImagesService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + * 餐饮照片管理Controller + * + * @author chenyj + * @date 2024-10-25 + */ +@RestController +@RequestMapping("/restaurant/images") +public class RzRestaurantImagesController extends BaseController +{ + @Autowired + private IRzRestaurantImagesService rzRestaurantImagesService; + + /** + * 查询餐饮照片管理列表 + */ + @PreAuthorize("@ss.hasPermi('restaurant:images:list')") + @GetMapping("/list") + public TableDataInfo list(RzRestaurantImages rzRestaurantImages) + { + startPage(); + List list = rzRestaurantImagesService.selectRzRestaurantImagesList(rzRestaurantImages); + return getDataTable(list); + } + + /** + * 删除餐饮照片管理 + */ + @PreAuthorize("@ss.hasPermi('restaurant:images:remove')") + @Log(title = "餐饮照片管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public AjaxResult remove(@PathVariable Long id) + { + return toAjax(rzRestaurantImagesService.deleteRzRestaurantImagesById(id)); + } + + /** + * 上传员工照片 + */ + @RequestMapping("/uploadDispatchings") + @ResponseBody + public AjaxResult uploadPDF(@RequestParam("name") String name,@RequestParam("file") MultipartFile filePath){ + return rzRestaurantImagesService.insertRzRestaurantImages(name,filePath); + } +} diff --git a/evo-admin/src/main/java/com/evo/restaurant/controller/RzRestaurantStatisticsController.java b/evo-admin/src/main/java/com/evo/restaurant/controller/RzRestaurantStatisticsController.java new file mode 100644 index 0000000..952e9bc --- /dev/null +++ b/evo-admin/src/main/java/com/evo/restaurant/controller/RzRestaurantStatisticsController.java @@ -0,0 +1,244 @@ +package com.evo.restaurant.controller; + +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.restaurant.domain.RzRestaurantStatistics; +import com.evo.restaurant.utils.ExcelUtilCy; +import com.evo.restaurant.service.IRzRestaurantStatisticsService; +import org.springframework.beans.BeanUtils; +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.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +/** + * 餐饮统计Controller + * + * @author chenyj + * @date 2024-09-18 + */ +@RestController +@RequestMapping("/restaurant/statistics") +public class RzRestaurantStatisticsController extends BaseController +{ + @Autowired + private IRzRestaurantStatisticsService rzRestaurantStatisticsService; + + /** + * 查询餐饮统计列表 + */ + @PreAuthorize("@ss.hasPermi('restaurant:statistics:list')") + @GetMapping("/list") + public TableDataInfo list(RzRestaurantStatistics rzRestaurantStatistics) + { + startPage(); + List list = rzRestaurantStatisticsService.selectRzRestaurantStatisticsList(rzRestaurantStatistics); + return getDataTable(list); + } + + /** + * 导出餐饮统计列表 + */ + @PreAuthorize("@ss.hasPermi('restaurant:statistics:export')") + @Log(title = "餐饮统计", businessType = BusinessType.EXPORT) + @GetMapping("/export") + public AjaxResult export(RzRestaurantStatistics rzRestaurantStatistics) + { + ExcelUtilCy util = new ExcelUtilCy(RzRestaurantStatistics.class); + //创建总表 + List list = new ArrayList(); + //创建各个部门工资数据集合的集合 + List> lists = new ArrayList<>(); + //创建各个部门sheetname集合 + List sheetNameList = new ArrayList<>(); + List res_list = rzRestaurantStatisticsService.selectRzRestaurantStatisticsList(rzRestaurantStatistics); + //先找到有多少个公司部门 + for (RzRestaurantStatistics restaurantStatistics : res_list) { + if(sheetNameList == null || sheetNameList.size() == 0){ + sheetNameList.add(restaurantStatistics.getCompanyName()); + continue; + } + if(sheetNameList.contains(restaurantStatistics.getCompanyName())){ + continue; + } + sheetNameList.add(restaurantStatistics.getCompanyName()); + } + List c_list = null; + //部门合计 + RzRestaurantStatistics vo_obj = null; + RzRestaurantStatistics res_obj = null; + for (String s : sheetNameList) { + c_list = new ArrayList(); + vo_obj = new RzRestaurantStatistics(); + res_obj = new RzRestaurantStatistics(); + for (RzRestaurantStatistics restaurantStatistics : res_list) { + if(s.equals(restaurantStatistics.getCompanyName())){ + if(null == vo_obj.getBreakfastNumber()){ + vo_obj.setBreakfastNumber(0l); + } + vo_obj.setBreakfastNumber(vo_obj.getBreakfastNumber() + restaurantStatistics.getBreakfastNumber()); + if(null == vo_obj.getBreakfastExpend()){ + vo_obj.setBreakfastExpend(new BigDecimal("0.00")); + } + vo_obj.setBreakfastExpend(vo_obj.getBreakfastExpend().add(restaurantStatistics.getBreakfastExpend())); + if(null == vo_obj.getBreakfastPreSumExpend()){ + vo_obj.setBreakfastPreSumExpend(new BigDecimal("0.00")); + } + vo_obj.setBreakfastPreSumExpend(vo_obj.getBreakfastPreSumExpend().add(restaurantStatistics.getBreakfastPreSumExpend())); + if(null == vo_obj.getBreakfastSumExpend()){ + vo_obj.setBreakfastSumExpend(new BigDecimal("0.00")); + } + vo_obj.setBreakfastSumExpend(vo_obj.getBreakfastSumExpend().add(restaurantStatistics.getBreakfastSumExpend())); + if(null == vo_obj.getLunchNumber()){ + vo_obj.setLunchNumber(0l); + } + vo_obj.setLunchNumber(vo_obj.getLunchNumber() + restaurantStatistics.getLunchNumber()); + if(null == vo_obj.getLunchExpend()){ + vo_obj.setLunchExpend(new BigDecimal("0.00")); + } + vo_obj.setLunchExpend(vo_obj.getLunchExpend().add(restaurantStatistics.getLunchExpend())); + if(null == vo_obj.getLunchPreSumExpend()){ + vo_obj.setLunchPreSumExpend(new BigDecimal("0.00")); + } + vo_obj.setLunchPreSumExpend(vo_obj.getLunchPreSumExpend().add(restaurantStatistics.getLunchPreSumExpend())); + if(null == vo_obj.getLunchSumExpend()){ + vo_obj.setLunchSumExpend(new BigDecimal("0.00")); + } + vo_obj.setLunchSumExpend(vo_obj.getLunchSumExpend().add(restaurantStatistics.getLunchSumExpend())); + if(null == vo_obj.getSupperNumber()){ + vo_obj.setSupperNumber(0l); + } + vo_obj.setSupperNumber(vo_obj.getSupperNumber() + restaurantStatistics.getSupperNumber()); + if(null == vo_obj.getSupperExpend()){ + vo_obj.setSupperExpend(new BigDecimal("0.00")); + } + vo_obj.setSupperExpend(vo_obj.getSupperExpend().add(restaurantStatistics.getSupperExpend())); + if(null == vo_obj.getSupperPreSumExpend()){ + vo_obj.setSupperPreSumExpend(new BigDecimal("0.00")); + } + vo_obj.setSupperPreSumExpend(vo_obj.getSupperPreSumExpend().add(restaurantStatistics.getSupperPreSumExpend())); + if(null == vo_obj.getSupperSumExpend()){ + vo_obj.setSupperSumExpend(new BigDecimal("0.00")); + } + vo_obj.setSupperSumExpend(vo_obj.getSupperSumExpend().add(restaurantStatistics.getSupperSumExpend())); + if(null == vo_obj.getPersonalSumConsumption()){ + vo_obj.setPersonalSumConsumption(new BigDecimal("0.00")); + } + vo_obj.setPersonalSumConsumption(vo_obj.getPersonalSumConsumption().add(restaurantStatistics.getPersonalSumConsumption())); + if(vo_obj.getSumConsumption() == null){ + vo_obj.setSumConsumption(new BigDecimal("0.00")); + } + vo_obj.setSumConsumption(vo_obj.getSumConsumption().add(restaurantStatistics.getSumConsumption())); + c_list.add(restaurantStatistics); + } + } + vo_obj.setName("合计: "); + c_list.add(vo_obj); + lists.add(c_list); + BeanUtils.copyProperties(vo_obj,res_obj); + res_obj.setMonth(rzRestaurantStatistics.getMonth()); + res_obj.setName(s); + list.add(res_obj); + } + + //计算共计 + vo_obj = new RzRestaurantStatistics(); + vo_obj.setName("共计: "); + for (RzRestaurantStatistics restaurantStatistics : list) { + if(null == vo_obj.getBreakfastNumber()){ + vo_obj.setBreakfastNumber(0l); + } + vo_obj.setBreakfastNumber(vo_obj.getBreakfastNumber() + restaurantStatistics.getBreakfastNumber()); + if(null == vo_obj.getBreakfastExpend()){ + vo_obj.setBreakfastExpend(new BigDecimal("0.00")); + } + vo_obj.setBreakfastExpend(vo_obj.getBreakfastExpend().add(restaurantStatistics.getBreakfastExpend())); + if(null == vo_obj.getBreakfastPreSumExpend()){ + vo_obj.setBreakfastPreSumExpend(new BigDecimal("0.00")); + } + vo_obj.setBreakfastPreSumExpend(vo_obj.getBreakfastPreSumExpend().add(restaurantStatistics.getBreakfastPreSumExpend())); + if(null == vo_obj.getBreakfastSumExpend()){ + vo_obj.setBreakfastSumExpend(new BigDecimal("0.00")); + } + vo_obj.setBreakfastSumExpend(vo_obj.getBreakfastSumExpend().add(restaurantStatistics.getBreakfastSumExpend())); + if(null == vo_obj.getLunchNumber()){ + vo_obj.setLunchNumber(0l); + } + vo_obj.setLunchNumber(vo_obj.getLunchNumber() + restaurantStatistics.getLunchNumber()); + if(null == vo_obj.getLunchExpend()){ + vo_obj.setLunchExpend(new BigDecimal("0.00")); + } + vo_obj.setLunchExpend(vo_obj.getLunchExpend().add(restaurantStatistics.getLunchExpend())); + if(null == vo_obj.getLunchPreSumExpend()){ + vo_obj.setLunchPreSumExpend(new BigDecimal("0.00")); + } + vo_obj.setLunchPreSumExpend(vo_obj.getLunchPreSumExpend().add(restaurantStatistics.getLunchPreSumExpend())); + if(null == vo_obj.getLunchSumExpend()){ + vo_obj.setLunchSumExpend(new BigDecimal("0.00")); + } + vo_obj.setLunchSumExpend(vo_obj.getLunchSumExpend().add(restaurantStatistics.getLunchSumExpend())); + if(null == vo_obj.getSupperNumber()){ + vo_obj.setSupperNumber(0l); + } + vo_obj.setSupperNumber(vo_obj.getSupperNumber() + restaurantStatistics.getSupperNumber()); + if(null == vo_obj.getSupperExpend()){ + vo_obj.setSupperExpend(new BigDecimal("0.00")); + } + vo_obj.setSupperExpend(vo_obj.getSupperExpend().add(restaurantStatistics.getSupperExpend())); + if(null == vo_obj.getSupperPreSumExpend()){ + vo_obj.setSupperPreSumExpend(new BigDecimal("0.00")); + } + vo_obj.setSupperPreSumExpend(vo_obj.getSupperPreSumExpend().add(restaurantStatistics.getSupperPreSumExpend())); + if(null == vo_obj.getSupperSumExpend()){ + vo_obj.setSupperSumExpend(new BigDecimal("0.00")); + } + vo_obj.setSupperSumExpend(vo_obj.getSupperSumExpend().add(restaurantStatistics.getSupperSumExpend())); + if(null == vo_obj.getPersonalSumConsumption()){ + vo_obj.setPersonalSumConsumption(new BigDecimal("0.00")); + } + vo_obj.setPersonalSumConsumption(vo_obj.getPersonalSumConsumption().add(restaurantStatistics.getPersonalSumConsumption())); + if(vo_obj.getSumConsumption() == null){ + vo_obj.setSumConsumption(new BigDecimal("0.00")); + } + vo_obj.setSumConsumption(vo_obj.getSumConsumption().add(restaurantStatistics.getSumConsumption())); + } + list.add(vo_obj); + return util.exportExcel(list,lists,"总表",sheetNameList); + } + + @GetMapping("/exportkd") + public void exportkd(HttpServletResponse response,RzRestaurantStatistics rzRestaurantStatistics){ + List list = rzRestaurantStatisticsService.selectRzRestaurantStatisticsListBySxs(rzRestaurantStatistics); + ExcelUtil util = new ExcelUtil(RzRestaurantStatistics.class); + util.exportExcel(response, list, "实习生就餐"); + } + + /** + * 获取餐饮统计详细信息 + */ + @PreAuthorize("@ss.hasPermi('restaurant:statistics:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(rzRestaurantStatisticsService.selectRzRestaurantStatisticsById(id)); + } + + /** + * 校正数据 + */ + @PreAuthorize("@ss.hasPermi('restaurant:statistics:correct')") + @RequestMapping(value = "correct") + public AjaxResult correct(@RequestBody RzRestaurantStatistics rzRestaurantStatistics) + { + return rzRestaurantStatisticsService.correct(rzRestaurantStatistics); + } + +} diff --git a/evo-admin/src/main/java/com/evo/restaurant/domain/RzRestaurantDetail.java b/evo-admin/src/main/java/com/evo/restaurant/domain/RzRestaurantDetail.java new file mode 100644 index 0000000..fed41b7 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/restaurant/domain/RzRestaurantDetail.java @@ -0,0 +1,146 @@ +package com.evo.restaurant.domain; + +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; + +/** + * 餐饮详情对象 rz_restaurant_detail + * + * @author chenyj + * @date 2024-09-18 + */ +public class RzRestaurantDetail extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + //员工ID + private Long staffId; + + /** 姓名 */ + @Excel(name = "姓名") + private String name; + + /** 日期 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date date; + //统计月份 + @JsonFormat(pattern = "yyyy-MM") + private Date month; + + /** 刷脸时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "刷脸时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date time; + + /** 标记 */ + @Excel(name = "标记") + private String sign; + //统计个数 + private int number; + + /** 删除标记 */ + private String delFlag; + + public Date getMonth() { + return month; + } + + public void setMonth(Date month) { + this.month = month; + } + + public Long getStaffId() { + return staffId; + } + + public void setStaffId(Long staffId) { + this.staffId = staffId; + } + + public int getNumber() { + return number; + } + + public void setNumber(int number) { + this.number = number; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setDate(Date date) + { + this.date = date; + } + + public Date getDate() + { + return date; + } + public void setTime(Date time) + { + this.time = time; + } + + public Date getTime() + { + return time; + } + public void setSign(String sign) + { + this.sign = sign; + } + + public String getSign() + { + return sign; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("date", getDate()) + .append("time", getTime()) + .append("sign", getSign()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/restaurant/domain/RzRestaurantImages.java b/evo-admin/src/main/java/com/evo/restaurant/domain/RzRestaurantImages.java new file mode 100644 index 0000000..9f3d59a --- /dev/null +++ b/evo-admin/src/main/java/com/evo/restaurant/domain/RzRestaurantImages.java @@ -0,0 +1,82 @@ +package com.evo.restaurant.domain; + +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 餐饮照片管理对象 rz_restaurant_images + * + * @author chenyj + * @date 2024-10-25 + */ +public class RzRestaurantImages extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Long id; + + /** 员工姓名 */ + @Excel(name = "员工姓名") + private String name; + + /** 照片地址 */ + @Excel(name = "照片地址") + private String imageUrl; + + /** 删除标识 */ + private String delFlag; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setImageUrl(String imageUrl) + { + this.imageUrl = imageUrl; + } + + public String getImageUrl() + { + return imageUrl; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("imageUrl", getImageUrl()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/restaurant/domain/RzRestaurantStatistics.java b/evo-admin/src/main/java/com/evo/restaurant/domain/RzRestaurantStatistics.java new file mode 100644 index 0000000..945ceb5 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/restaurant/domain/RzRestaurantStatistics.java @@ -0,0 +1,330 @@ +package com.evo.restaurant.domain; + +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; + +/** + * 餐饮统计对象 rz_restaurant_statistics + * + * @author evo + * @date 2024-11-21 + */ +public class RzRestaurantStatistics extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 员工ID */ + @Excel(name = "员工ID") + private Long staffId; + private Long deptId; + @Excel(name = "公司名称") + private String companyName; //公司名称 + /** 姓名 */ + @Excel(name = "姓名") + private String name; + + /** 统计月份 */ + @JsonFormat(pattern = "yyyy-MM") + @Excel(name = "统计月份", width = 30, dateFormat = "yyyy-MM") + private Date month; + + /** 早餐消费 */ + @Excel(name = "早餐消费") + private BigDecimal breakfastExpend; + + /** 早餐次数 */ + @Excel(name = "早餐次数") + private Long breakfastNumber; + + /** 早餐个人总消费 */ + @Excel(name = "早餐个人总消费") + private BigDecimal breakfastPreSumExpend; + + /** 早餐总消费 */ + @Excel(name = "早餐总消费") + private BigDecimal breakfastSumExpend; + + /** 午餐消费 */ + @Excel(name = "午餐消费") + private BigDecimal lunchExpend; + + /** 午餐次数 */ + @Excel(name = "午餐次数") + private Long lunchNumber; + + /** 午餐个人总消费 */ + @Excel(name = "午餐个人总消费") + private BigDecimal lunchPreSumExpend; + + /** 午餐总消费 */ + @Excel(name = "午餐总消费") + private BigDecimal lunchSumExpend; + + /** 晚餐消费 */ + @Excel(name = "晚餐消费") + private BigDecimal supperExpend; + + /** 晚餐次数 */ + @Excel(name = "晚餐次数") + private Long supperNumber; + + /** 晚餐个人总消费 */ + @Excel(name = "晚餐个人总消费") + private BigDecimal supperPreSumExpend; + + /** 晚餐总消费 */ + @Excel(name = "晚餐总消费") + private BigDecimal supperSumExpend; + + /** 个人总消费 */ + @Excel(name = "个人总消费") + private BigDecimal personalSumConsumption; + + /** 总消费 */ + @Excel(name = "总消费") + private BigDecimal sumConsumption; + + /** 备注 */ + @Excel(name = "备注") + private String remarks; + + /** 删除标记 */ + private String delFlag; + + public String getCompanyName() { + return companyName; + } + + public void setCompanyName(String companyName) { + this.companyName = companyName; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setStaffId(Long staffId) + { + this.staffId = staffId; + } + + public Long getStaffId() + { + return staffId; + } + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + public Long getDeptId() + { + return deptId; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setMonth(Date month) + { + this.month = month; + } + + public Date getMonth() + { + return month; + } + public void setBreakfastExpend(BigDecimal breakfastExpend) + { + this.breakfastExpend = breakfastExpend; + } + + public BigDecimal getBreakfastExpend() + { + return breakfastExpend; + } + public void setBreakfastNumber(Long breakfastNumber) + { + this.breakfastNumber = breakfastNumber; + } + + public Long getBreakfastNumber() + { + return breakfastNumber; + } + public void setBreakfastPreSumExpend(BigDecimal breakfastPreSumExpend) + { + this.breakfastPreSumExpend = breakfastPreSumExpend; + } + + public BigDecimal getBreakfastPreSumExpend() + { + return breakfastPreSumExpend; + } + public void setBreakfastSumExpend(BigDecimal breakfastSumExpend) + { + this.breakfastSumExpend = breakfastSumExpend; + } + + public BigDecimal getBreakfastSumExpend() + { + return breakfastSumExpend; + } + public void setLunchExpend(BigDecimal lunchExpend) + { + this.lunchExpend = lunchExpend; + } + + public BigDecimal getLunchExpend() + { + return lunchExpend; + } + public void setLunchNumber(Long lunchNumber) + { + this.lunchNumber = lunchNumber; + } + + public Long getLunchNumber() + { + return lunchNumber; + } + public void setLunchPreSumExpend(BigDecimal lunchPreSumExpend) + { + this.lunchPreSumExpend = lunchPreSumExpend; + } + + public BigDecimal getLunchPreSumExpend() + { + return lunchPreSumExpend; + } + public void setLunchSumExpend(BigDecimal lunchSumExpend) + { + this.lunchSumExpend = lunchSumExpend; + } + + public BigDecimal getLunchSumExpend() + { + return lunchSumExpend; + } + public void setSupperExpend(BigDecimal supperExpend) + { + this.supperExpend = supperExpend; + } + + public BigDecimal getSupperExpend() + { + return supperExpend; + } + public void setSupperNumber(Long supperNumber) + { + this.supperNumber = supperNumber; + } + + public Long getSupperNumber() + { + return supperNumber; + } + public void setSupperPreSumExpend(BigDecimal supperPreSumExpend) + { + this.supperPreSumExpend = supperPreSumExpend; + } + + public BigDecimal getSupperPreSumExpend() + { + return supperPreSumExpend; + } + public void setSupperSumExpend(BigDecimal supperSumExpend) + { + this.supperSumExpend = supperSumExpend; + } + + public BigDecimal getSupperSumExpend() + { + return supperSumExpend; + } + public void setPersonalSumConsumption(BigDecimal personalSumConsumption) + { + this.personalSumConsumption = personalSumConsumption; + } + + public BigDecimal getPersonalSumConsumption() + { + return personalSumConsumption; + } + public void setSumConsumption(BigDecimal sumConsumption) + { + this.sumConsumption = sumConsumption; + } + + public BigDecimal getSumConsumption() + { + return sumConsumption; + } + public void setRemarks(String remarks) + { + this.remarks = remarks; + } + + public String getRemarks() + { + return remarks; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("staffId", getStaffId()) + .append("deptId", getDeptId()) + .append("name", getName()) + .append("month", getMonth()) + .append("breakfastExpend", getBreakfastExpend()) + .append("breakfastNumber", getBreakfastNumber()) + .append("breakfastPreSumExpend", getBreakfastPreSumExpend()) + .append("breakfastSumExpend", getBreakfastSumExpend()) + .append("lunchExpend", getLunchExpend()) + .append("lunchNumber", getLunchNumber()) + .append("lunchPreSumExpend", getLunchPreSumExpend()) + .append("lunchSumExpend", getLunchSumExpend()) + .append("supperExpend", getSupperExpend()) + .append("supperNumber", getSupperNumber()) + .append("supperPreSumExpend", getSupperPreSumExpend()) + .append("supperSumExpend", getSupperSumExpend()) + .append("personalSumConsumption", getPersonalSumConsumption()) + .append("sumConsumption", getSumConsumption()) + .append("remarks", getRemarks()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/restaurant/domain/vo/RestaurantData.java b/evo-admin/src/main/java/com/evo/restaurant/domain/vo/RestaurantData.java new file mode 100644 index 0000000..9a1949e --- /dev/null +++ b/evo-admin/src/main/java/com/evo/restaurant/domain/vo/RestaurantData.java @@ -0,0 +1,19 @@ +package com.evo.restaurant.domain.vo; + +public class RestaurantData { + + private int clock_in_count; + + public int getClock_in_count() { + return clock_in_count; + } + + public void setClock_in_count(int clock_in_count) { + this.clock_in_count = clock_in_count; + } + + @Override + public String toString() { + return "RestaurantData [clock_in_count=" + clock_in_count + "]"; + } +} diff --git a/evo-admin/src/main/java/com/evo/restaurant/domain/vo/RestaurantVo.java b/evo-admin/src/main/java/com/evo/restaurant/domain/vo/RestaurantVo.java new file mode 100644 index 0000000..b0f3816 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/restaurant/domain/vo/RestaurantVo.java @@ -0,0 +1,49 @@ +package com.evo.restaurant.domain.vo; + +public class RestaurantVo { + + private int Result; + private String Msg; + private int voice_code; + private String voice_text; + private RestaurantData Content; + + + public int getResult() { + return Result; + } + public void setResult(int result) { + Result = result; + } + public String getMsg() { + return Msg; + } + public void setMsg(String msg) { + Msg = msg; + } + + public int getVoice_code() { + return voice_code; + } + public void setVoice_code(int voice_code) { + this.voice_code = voice_code; + } + public String getVoice_text() { + return voice_text; + } + public void setVoice_text(String voice_text) { + this.voice_text = voice_text; + } + + public RestaurantData getContent() { + return Content; + } + public void setContent(RestaurantData content) { + Content = content; + } + @Override + public String toString() { + return "RestaurantVo [Result=" + Result + ", Msg=" + Msg + ", voice_code=" + voice_code + ", voice_text=" + + voice_text + ", Content=" + Content + "]"; + } +} diff --git a/evo-admin/src/main/java/com/evo/restaurant/mapper/RzRestaurantDetailMapper.java b/evo-admin/src/main/java/com/evo/restaurant/mapper/RzRestaurantDetailMapper.java new file mode 100644 index 0000000..51172e6 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/restaurant/mapper/RzRestaurantDetailMapper.java @@ -0,0 +1,40 @@ +package com.evo.restaurant.mapper; + +import com.evo.restaurant.domain.RzRestaurantDetail; + +import java.util.List; + +/** + * 餐饮详情Mapper接口 + * + * @author chenyj + * @date 2024-09-18 + */ +public interface RzRestaurantDetailMapper +{ + /** + * 查询餐饮详情 + * + * @param userId 餐饮详情主键 + * @return 餐饮详情 + */ + public RzRestaurantDetail selectRzRestaurantDetailByName(Long userId); + + /** + * 查询餐饮详情列表 + * + * @param rzRestaurantDetail 餐饮详情 + * @return 餐饮详情集合 + */ + public List selectRzRestaurantDetailList(RzRestaurantDetail rzRestaurantDetail); + + /** + * 新增餐饮详情 + * + * @param rzRestaurantDetail 餐饮详情 + * @return 结果 + */ + public int insertRzRestaurantDetail(RzRestaurantDetail rzRestaurantDetail); + + +} diff --git a/evo-admin/src/main/java/com/evo/restaurant/mapper/RzRestaurantImagesMapper.java b/evo-admin/src/main/java/com/evo/restaurant/mapper/RzRestaurantImagesMapper.java new file mode 100644 index 0000000..7ec13d6 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/restaurant/mapper/RzRestaurantImagesMapper.java @@ -0,0 +1,55 @@ +package com.evo.restaurant.mapper; + +import com.evo.restaurant.domain.RzRestaurantImages; + +import java.util.List; + +/** + * 餐饮照片管理Mapper接口 + * + * @author chenyj + * @date 2024-10-25 + */ +public interface RzRestaurantImagesMapper +{ + /** + * 查询餐饮照片管理 + * + * @param name 用户名称 + * @return 餐饮照片管理 + */ + public RzRestaurantImages selectRzRestaurantImagesByName(String name); + + /** + * 查询餐饮照片管理 + * + * @param id 主键ID + * @return 餐饮照片管理 + */ + public RzRestaurantImages selectRzRestaurantImagesById(Long id); + + /** + * 查询餐饮照片管理列表 + * + * @param rzRestaurantImages 餐饮照片管理 + * @return 餐饮照片管理集合 + */ + public List selectRzRestaurantImagesList(RzRestaurantImages rzRestaurantImages); + + /** + * 新增餐饮照片管理 + * + * @param rzRestaurantImages 餐饮照片管理 + * @return 结果 + */ + public int insertRzRestaurantImages(RzRestaurantImages rzRestaurantImages); + + /** + * 修改餐饮照片管理 + * + * @param rzRestaurantImages 餐饮照片管理 + * @return 结果 + */ + public int updateRzRestaurantImages(RzRestaurantImages rzRestaurantImages); + +} diff --git a/evo-admin/src/main/java/com/evo/restaurant/mapper/RzRestaurantStatisticsMapper.java b/evo-admin/src/main/java/com/evo/restaurant/mapper/RzRestaurantStatisticsMapper.java new file mode 100644 index 0000000..d3eb333 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/restaurant/mapper/RzRestaurantStatisticsMapper.java @@ -0,0 +1,58 @@ +package com.evo.restaurant.mapper; + +import com.evo.restaurant.domain.RzRestaurantStatistics; +import org.apache.ibatis.annotations.Param; +import java.util.Date; +import java.util.List; + +/** + * 餐饮统计Mapper接口 + * + * @author chenyj + * @date 2024-11-18 + */ +public interface RzRestaurantStatisticsMapper +{ + /** + * 查询餐饮统计 + * + * @param id 餐饮统计主键 + * @return 餐饮统计 + */ + public RzRestaurantStatistics selectRzRestaurantStatisticsById(Long id); + + /** + * 查询餐饮统计列表 + * + * @param rzRestaurantStatistics 餐饮统计 + * @return 餐饮统计集合 + */ + public List selectRzRestaurantStatisticsList(RzRestaurantStatistics rzRestaurantStatistics); + + /** + * 新增餐饮统计 + * + * @param rzRestaurantStatistics 餐饮统计 + * @return 结果 + */ + public int insertRzRestaurantStatistics(RzRestaurantStatistics rzRestaurantStatistics); + + /** + * 修改餐饮统计 + * + * @param rzRestaurantStatistics 餐饮统计 + * @return 结果 + */ + public int updateRzRestaurantStatistics(RzRestaurantStatistics rzRestaurantStatistics); + + /** + * 根据员工ID和时间查询统计信息 + * @param staffId + * @param date + * @return + */ + public RzRestaurantStatistics selectRzRestaurantStatisticsByUserIdAndDate(@Param("staffId") Long staffId,@Param("date") Date date); + + public List selectRzRestaurantStatisticsByDate(Date date); + +} diff --git a/evo-admin/src/main/java/com/evo/restaurant/service/IRzRestaurantDetailService.java b/evo-admin/src/main/java/com/evo/restaurant/service/IRzRestaurantDetailService.java new file mode 100644 index 0000000..067a208 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/restaurant/service/IRzRestaurantDetailService.java @@ -0,0 +1,39 @@ +package com.evo.restaurant.service; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.restaurant.domain.RzRestaurantDetail; + +import java.util.List; + +/** + * 餐饮详情Service接口 + * + * @author chenyj + * @date 2024-09-18 + */ +public interface IRzRestaurantDetailService +{ + + /** + * 查询餐饮详情列表 + * + * @param rzRestaurantDetail 餐饮详情 + * @return 餐饮详情集合 + */ + public List selectRzRestaurantDetailList(RzRestaurantDetail rzRestaurantDetail); + + /** + * 新增餐饮详情 + * + * @param json + * @return 结果 + */ + public String insertRzRestaurantDetail(String json); + + /** + * 当前时间的就餐人数 + * @return + */ + public List flushData(); + +} diff --git a/evo-admin/src/main/java/com/evo/restaurant/service/IRzRestaurantImagesService.java b/evo-admin/src/main/java/com/evo/restaurant/service/IRzRestaurantImagesService.java new file mode 100644 index 0000000..645ae61 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/restaurant/service/IRzRestaurantImagesService.java @@ -0,0 +1,40 @@ +package com.evo.restaurant.service; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.restaurant.domain.RzRestaurantImages; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + * 餐饮照片管理Service接口 + * + * @author chenyj + * @date 2024-10-25 + */ +public interface IRzRestaurantImagesService +{ + /** + * 查询餐饮照片管理列表 + * + * @param rzRestaurantImages 餐饮照片管理 + * @return 餐饮照片管理集合 + */ + public List selectRzRestaurantImagesList(RzRestaurantImages rzRestaurantImages); + + /** + * 删除餐饮照片管理信息 + * + * @param id 餐饮照片管理主键 + * @return 结果 + */ + public int deleteRzRestaurantImagesById(Long id); + + /** + * 新增照片管理 + * + * @param name 照片管理 + * @return 结果 + */ + public AjaxResult insertRzRestaurantImages(String name, MultipartFile filePath); +} diff --git a/evo-admin/src/main/java/com/evo/restaurant/service/IRzRestaurantStatisticsService.java b/evo-admin/src/main/java/com/evo/restaurant/service/IRzRestaurantStatisticsService.java new file mode 100644 index 0000000..c8fec50 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/restaurant/service/IRzRestaurantStatisticsService.java @@ -0,0 +1,49 @@ +package com.evo.restaurant.service; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.restaurant.domain.RzRestaurantStatistics; +import java.util.List; + +/** + * 餐饮统计Service接口 + * + * @author chenyj + * @date 2024-09-18 + */ +public interface IRzRestaurantStatisticsService +{ + /** + * 查询餐饮统计 + * + * @param id 餐饮统计主键 + * @return 餐饮统计 + */ + public RzRestaurantStatistics selectRzRestaurantStatisticsById(Long id); + + /** + * 查询餐饮统计列表 + * + * @param rzRestaurantStatistics 餐饮统计 + * @return 餐饮统计集合 + */ + public List selectRzRestaurantStatisticsList(RzRestaurantStatistics rzRestaurantStatistics); + + /** + * 新增餐饮统计 + * @return 结果 + */ + public void insertRzRestaurantStatistics(); + + /** + * 校正数据 + * @return + */ + public AjaxResult correct(RzRestaurantStatistics rzRestaurantStatistics); + + /** + * 实习生就餐导出 + * @return + */ + public List selectRzRestaurantStatisticsListBySxs(RzRestaurantStatistics rzRestaurantStatistics); + +} diff --git a/evo-admin/src/main/java/com/evo/restaurant/service/impl/RzRestaurantDetailServiceImpl.java b/evo-admin/src/main/java/com/evo/restaurant/service/impl/RzRestaurantDetailServiceImpl.java new file mode 100644 index 0000000..09d9f16 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/restaurant/service/impl/RzRestaurantDetailServiceImpl.java @@ -0,0 +1,167 @@ +package com.evo.restaurant.service.impl; + +import com.alibaba.fastjson2.JSONObject; +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.restaurant.domain.RzRestaurantDetail; +import com.evo.restaurant.domain.RzRestaurantImages; +import com.evo.restaurant.domain.RzRestaurantStatistics; +import com.evo.restaurant.domain.vo.RestaurantData; +import com.evo.restaurant.domain.vo.RestaurantVo; +import com.evo.restaurant.mapper.RzRestaurantDetailMapper; +import com.evo.restaurant.mapper.RzRestaurantImagesMapper; +import com.evo.restaurant.mapper.RzRestaurantStatisticsMapper; +import com.evo.restaurant.service.IRzRestaurantDetailService; +import com.evo.system.domain.SysStaff; +import com.evo.system.mapper.SysStaffMapper; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +/** + * 餐饮详情Service业务层处理 + * + * @author chenyj + * @date 2024-09-18 + */ +@Service +public class RzRestaurantDetailServiceImpl implements IRzRestaurantDetailService +{ + @Resource + private RzRestaurantDetailMapper rzRestaurantDetailMapper; + @Resource + private SysStaffMapper sysStaffMapper; //员工信息 + @Resource + private RzRestaurantStatisticsMapper rzRestaurantStatisticsMapper; //刷脸统计 + @Resource + private RzRestaurantImagesMapper rzRestaurantImagesMapper; //餐饮打卡信息 + + /** + * 查询餐饮详情列表 + * + * @param rzRestaurantDetail 餐饮详情 + * @return 餐饮详情 + */ + @Override + public List selectRzRestaurantDetailList(RzRestaurantDetail rzRestaurantDetail) + { + return rzRestaurantDetailMapper.selectRzRestaurantDetailList(rzRestaurantDetail); + } + /** + * 新增餐饮详情 + * + * @param json 餐饮详情 + * @return 结果 + */ + @Override + public String insertRzRestaurantDetail(String json) + { + //需要返回的对象 + RestaurantVo cfiv = new RestaurantVo(); + RestaurantData cfd = new RestaurantData(); + //获取当前时间,如果未在就餐时间之内,不统计打卡次数 + // 使用Calendar类获取当前时间 + Calendar calendar = Calendar.getInstance(); + // 获取小时数 + int hour = calendar.get(Calendar.HOUR_OF_DAY); + + //判断是否在就餐时间,如果在就餐时间打卡有效,否则打卡无效 + if(hour!=7&&hour!=8&&hour!=11&&hour!=12&&hour!=13&&hour!=18&&hour!=19&&hour!=20){ + cfiv.setResult(2); + cfiv.setMsg("{\"Result\":1,\"Msg\":\"不在打卡时间内\"}"); + return JSONObject.toJSONString(cfiv); + } + + //解析收到的数据 + JSONObject jsonObject = JSONObject.parseObject(json); + //获取用户id + String userId = jsonObject.get("user_id").toString(); + //根据员工ID查询 + SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.valueOf(userId));//打卡记录信息 + //查询只打饭卡的人员信息 + RzRestaurantImages img_obj = rzRestaurantImagesMapper.selectRzRestaurantImagesById(Long.valueOf(userId)); + if(StringUtils.isNull(sysStaff) && StringUtils.isNull(img_obj)){ + cfiv.setResult(2); + cfiv.setMsg("{\"Result\":1,\"Msg\":\"验证失败,未设置考勤权限\"}"); + return JSONObject.toJSONString(cfiv); + } + + //查询最近一次刷脸记录 + RzRestaurantDetail restaurantDetail = rzRestaurantDetailMapper.selectRzRestaurantDetailByName(Long.valueOf(userId)); + //判断最后一次打卡和当前打卡时间是否超过3小时,没有超过则提示重复打卡 + if(StringUtils.isNotNull(restaurantDetail) && (new Date().getTime() - restaurantDetail.getTime().getTime()) < 1000*60*60*3){ + //如果不是第一次打卡,则弹窗提示 + cfiv.setResult(1); + cfiv.setMsg("重复打卡!!"); + return JSONObject.toJSONString(cfiv); + } + //根据员工ID和打卡时间查询本月的打卡统计信息 + RzRestaurantStatistics restaurantStatistics = rzRestaurantStatisticsMapper.selectRzRestaurantStatisticsByUserIdAndDate(Long.valueOf(userId),new Date()); + //增加打卡记录 + RzRestaurantDetail cyFaceInfo = new RzRestaurantDetail(); + cyFaceInfo.setDate(new Date()); + cyFaceInfo.setStaffId(restaurantStatistics.getStaffId()); + cyFaceInfo.setName(restaurantStatistics.getName()); + cyFaceInfo.setTime(new Date()); + //判断刷脸时间是早餐还是午餐还是晚餐 + if(hour>6&&hour<9){ + //说明是早餐 + cyFaceInfo.setSign("早餐"); + restaurantStatistics.setBreakfastNumber(restaurantStatistics.getBreakfastNumber() + 1); + }else if(hour>=11&&hour<=14){ + //说明是午餐 + cyFaceInfo.setSign("午餐"); + restaurantStatistics.setLunchNumber(restaurantStatistics.getLunchNumber() + 1); + }else if(hour>=18&&hour<=20){ + //说明是晚餐 + cyFaceInfo.setSign("晚餐"); + restaurantStatistics.setSupperNumber(restaurantStatistics.getSupperNumber() + 1); + } + cyFaceInfo.setDelFlag(Constants.DELETE_FLAG_0); + cyFaceInfo.setCreateTime(new Date()); + int i = rzRestaurantDetailMapper.insertRzRestaurantDetail(cyFaceInfo); + if(i<1){ + cfiv.setResult(2); + cfiv.setMsg("{\"Result\":1,\"Msg\":\"打卡失败\"}"); + return JSONObject.toJSONString(cfiv); + } + //反写统计次数 + i = rzRestaurantStatisticsMapper.updateRzRestaurantStatistics(restaurantStatistics); + if(i<1){ + cfiv.setResult(2); + cfiv.setMsg("{\"Result\":1,\"Msg\":\"打卡失败\"}"); + return JSONObject.toJSONString(cfiv); + } + cfiv.setMsg("{\"Result\":1,\"Msg\":\"打卡成功!\"}"); + cfd.setClock_in_count(1); + cfiv.setContent(cfd); + cfiv.setResult(0); + return JSONObject.toJSONString(cfiv); + } + /** + * 统计当餐刷卡人数 + * @return + */ + public List flushData(){ + // 使用Calendar类获取当前时间 + Calendar calendar = Calendar.getInstance(); + // 获取小时数 + int hour = calendar.get(Calendar.HOUR_OF_DAY); + RzRestaurantDetail rzRestaurantDetail = new RzRestaurantDetail(); + if(hour == 7 || hour == 8){ + rzRestaurantDetail.setSign("早餐"); + }else if(hour == 11 || hour == 12 || hour == 13){ + rzRestaurantDetail.setSign("午餐"); + }else { + rzRestaurantDetail.setSign("晚餐"); + } + rzRestaurantDetail.setDate(new Date()); + return rzRestaurantDetailMapper.selectRzRestaurantDetailList(rzRestaurantDetail); + } + +} diff --git a/evo-admin/src/main/java/com/evo/restaurant/service/impl/RzRestaurantImagesServiceImpl.java b/evo-admin/src/main/java/com/evo/restaurant/service/impl/RzRestaurantImagesServiceImpl.java new file mode 100644 index 0000000..896c4ff --- /dev/null +++ b/evo-admin/src/main/java/com/evo/restaurant/service/impl/RzRestaurantImagesServiceImpl.java @@ -0,0 +1,199 @@ +package com.evo.restaurant.service.impl; + +import com.alibaba.fastjson2.JSONObject; +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.equipment.domain.vo.StaffData; +import com.evo.equipment.domain.vo.StaffDto; +import com.evo.framework.websocket.WebSocketUsers; +import com.evo.restaurant.domain.RzRestaurantImages; +import com.evo.restaurant.domain.RzRestaurantStatistics; +import com.evo.restaurant.mapper.RzRestaurantImagesMapper; +import com.evo.restaurant.mapper.RzRestaurantStatisticsMapper; +import com.evo.restaurant.service.IRzRestaurantImagesService; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import javax.annotation.Resource; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.util.Date; +import java.util.List; + +/** + * 餐饮照片管理Service业务层处理 + * + * @author chenyj + * @date 2024-10-25 + */ +@Service +public class RzRestaurantImagesServiceImpl implements IRzRestaurantImagesService +{ + @Resource + private RzRestaurantImagesMapper rzRestaurantImagesMapper; + @Resource + private RzRestaurantStatisticsMapper rzRestaurantStatisticsMapper; //餐饮统计 + + + /** + * 查询餐饮照片管理列表 + * + * @param rzRestaurantImages 餐饮照片管理 + * @return 餐饮照片管理 + */ + @Override + public List selectRzRestaurantImagesList(RzRestaurantImages rzRestaurantImages) + { + return rzRestaurantImagesMapper.selectRzRestaurantImagesList(rzRestaurantImages); + } + + /** + * 删除餐饮照片管理信息 + * + * @param id 餐饮照片管理主键 + * @return 结果 + */ + @Override + public int deleteRzRestaurantImagesById(Long id) + { + //根据id查询信息 + RzRestaurantImages rzRestaurantImages = rzRestaurantImagesMapper.selectRzRestaurantImagesById(id); + //删除打卡机照片 + String message = ""; + //需要返回的对象 + StaffDto cau = new StaffDto(); + //发送的数据 + StaffData caud = new StaffData(); + //该接口固定为to_device,发送给设备用于识别对应哪个指令 + cau.setCmd("to_device"); + //无用值,空串 + cau.setForm(""); + //设备号 + cau.setTo(com.evo.equipment.constant.Constants.EQ_DEVICE_CODE); + //给服务端预留的补充字段,设备端不处理这个字段内容。设备在响应这条指令时原样返回 + cau.setExtra(""); + //发送的数据 + caud.setCmd("delUser"); + caud.setUser_type(0); + caud.setUser_id(id+""); + cau.setData(caud); + //调用websocket,推送给设备 + WebSocketUsers.sendMessageToUsersByText(JSONObject.toJSONString(cau)); + //删除照片 + String img_name = rzRestaurantImages.getImageUrl().substring(rzRestaurantImages.getImageUrl().lastIndexOf("/")+1); + File file = new File(com.evo.equipment.constant.Constants.STAFF_IMAGE_ADDRESS + img_name); + if(file.exists()){ + file.delete(); + } + rzRestaurantImages.setDelFlag(Constants.DELETE_FLAG_1); + rzRestaurantImages.setUpdateTime(new Date()); + rzRestaurantImages.setUpdateBy(SecurityUtils.getUsername()); + return rzRestaurantImagesMapper.updateRzRestaurantImages(rzRestaurantImages); + } + + /** + * 新增照片管理 + * + * @param name 照片管理 + * @return 结果 + */ + @Override + public AjaxResult insertRzRestaurantImages(String name, MultipartFile filePath) + { + String originalFilename = filePath.getOriginalFilename(); + //校验文件后缀 + String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1); // 输出 "txt" + //判断是否是图片文件 + if(!"jpg".equals(suffix)&&!"jpeg".equals(suffix)&&!"png".equals(suffix)){ + return AjaxResult.error("禁止非法文件上传!"); + }else{ + //保存图片 + InputStream is = null; + FileOutputStream fos = null; + BufferedOutputStream bos = null; + try { + is = filePath.getInputStream(); + byte[] bytes = new byte[is.available()]; + is.read(bytes); + File file = new File(com.evo.equipment.constant.Constants.STAFF_IMAGE_ADDRESS+originalFilename); + fos = new FileOutputStream(file); + bos = new BufferedOutputStream(fos); + bos.write(bytes); + } catch (Exception e) { + e.printStackTrace(); + return AjaxResult.error(); + }finally { + try{ + if(StringUtils.isNotNull(bos)){ + bos.flush(); + bos.close(); + } + if(StringUtils.isNotNull(fos)){ + fos.close(); + } + if(StringUtils.isNotNull(is)){ + is.close(); + } + }catch (Exception e){ + e.printStackTrace(); + } + } + } + //写入数据库 + RzRestaurantImages rzRestaurantImages = new RzRestaurantImages(); + rzRestaurantImages.setName(name); + rzRestaurantImages.setImageUrl(com.evo.equipment.constant.Constants.STAFF_IMAGE_URL+originalFilename); + rzRestaurantImages.setCreateBy(SecurityUtils.getUsername()); + rzRestaurantImages.setCreateTime(DateUtils.getNowDate()); + rzRestaurantImages.setDelFlag(Constants.DELETE_FLAG_0); + int i = rzRestaurantImagesMapper.insertRzRestaurantImages(rzRestaurantImages); + if(i < 1){ + return AjaxResult.error(); + } + //餐饮统计 + RzRestaurantStatistics rzRestaurantStatistics = new RzRestaurantStatistics(); + rzRestaurantStatistics.setStaffId(rzRestaurantImages.getId()); + rzRestaurantStatistics.setName(rzRestaurantImages.getName()); + rzRestaurantStatistics.setMonth(DateUtils.getNowDate()); + rzRestaurantStatistics.setCreateTime(DateUtils.getNowDate()); + rzRestaurantStatistics.setDelFlag(Constants.DELETE_FLAG_0); + rzRestaurantStatistics.setCreateBy(SecurityUtils.getUsername()); + i = rzRestaurantStatisticsMapper.insertRzRestaurantStatistics(rzRestaurantStatistics); + if(i < 1){ + return AjaxResult.error(); + } + /** 上传打卡机 */ + //需要返回的对象 + StaffDto cau = new StaffDto(); + //发送的数据 + StaffData caud = new StaffData(); + //指定打卡机传输照片 + //该接口固定为to_device,发送给设备用于识别对应哪个指令 + cau.setCmd("to_device"); + //无用值,空串 + cau.setForm(""); + //设备号 + cau.setTo(com.evo.equipment.constant.Constants.EQ_DEVICE_CODE); + //给服务端预留的补充字段,设备端不处理这个字段内容。设备在响应这条指令时原样返回 + cau.setExtra(""); + //发送的数据 + caud.setCmd("addUser"); + caud.setUser_id(rzRestaurantImages.getId().toString()); + caud.setName(name); + caud.setTts_name(""); + caud.setFace_template(com.evo.equipment.constant.Constants.STAFF_IMAGE_URL+originalFilename); + caud.setEffect_time(""); + caud.setId_valid(""); + caud.setIc(""); + caud.setPhone(""); + caud.setMode(0); + cau.setData(caud); + //调用websocket,推送给设备 + WebSocketUsers.sendMessageToUsersByText(JSONObject.toJSONString(cau)); + return AjaxResult.success(); + } +} diff --git a/evo-admin/src/main/java/com/evo/restaurant/service/impl/RzRestaurantStatisticsServiceImpl.java b/evo-admin/src/main/java/com/evo/restaurant/service/impl/RzRestaurantStatisticsServiceImpl.java new file mode 100644 index 0000000..2e0441e --- /dev/null +++ b/evo-admin/src/main/java/com/evo/restaurant/service/impl/RzRestaurantStatisticsServiceImpl.java @@ -0,0 +1,187 @@ +package com.evo.restaurant.service.impl; + +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.domain.entity.SysDictData; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.StringUtils; +import com.evo.restaurant.domain.RzRestaurantDetail; +import com.evo.restaurant.domain.RzRestaurantImages; +import com.evo.restaurant.domain.RzRestaurantStatistics; +import com.evo.restaurant.mapper.RzRestaurantDetailMapper; +import com.evo.restaurant.mapper.RzRestaurantImagesMapper; +import com.evo.restaurant.mapper.RzRestaurantStatisticsMapper; +import com.evo.restaurant.service.IRzRestaurantStatisticsService; +import com.evo.system.domain.SysStaff; +import com.evo.system.domain.SysStaffDetail; +import com.evo.system.mapper.*; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.List; + +/** + * 餐饮统计Service业务层处理 + * + * @author chenyj + * @date 2024-09-18 + */ +@Service +public class RzRestaurantStatisticsServiceImpl implements IRzRestaurantStatisticsService +{ + @Resource + private RzRestaurantStatisticsMapper rzRestaurantStatisticsMapper; + @Resource + private SysDeptMapper deptMapper; //部门信息 + @Resource + private SysStaffMapper sysStaffMapper; //员工信息 + @Resource + private SysStaffDetailMapper sysStaffDetailMapper; //员工详情 + @Resource + private RzRestaurantImagesMapper rzRestaurantImagesMapper; //研究生人员 + @Resource + private SysDictDataMapper sysDictDataMapper; //数据字典 + @Resource + private RzRestaurantDetailMapper rzRestaurantDetailMapper; //餐饮详情 + /** + * 查询餐饮统计 + * + * @param id 餐饮统计主键 + * @return 餐饮统计 + */ + @Override + public RzRestaurantStatistics selectRzRestaurantStatisticsById(Long id) + { + return rzRestaurantStatisticsMapper.selectRzRestaurantStatisticsById(id); + } + /** + * 查询餐饮统计列表 + * + * @param rzRestaurantStatistics 餐饮统计 + * @return 餐饮统计 + */ + @Override + public List selectRzRestaurantStatisticsList(RzRestaurantStatistics rzRestaurantStatistics) + { + List res_list = rzRestaurantStatisticsMapper.selectRzRestaurantStatisticsList(rzRestaurantStatistics); + for (RzRestaurantStatistics restaurantStatistics : res_list) { + restaurantStatistics.setCompanyName(deptMapper.selectDeptById(restaurantStatistics.getDeptId()).getDeptName()); + } + return res_list; + } + /** + * 新增餐饮统计 + * @return 结果 + */ + @Override + public void insertRzRestaurantStatistics() + { + //获取在职员工 + List st_list = sysStaffMapper.selectSysStaffListAll(); + //查询员工的详细信息 + List dt_list = sysStaffDetailMapper.selectSysStaffDetailList(null); + RzRestaurantStatistics rzRestaurantStatistics = null; + for (SysStaff sysStaff : st_list) { + rzRestaurantStatistics = new RzRestaurantStatistics(); + rzRestaurantStatistics.setStaffId(sysStaff.getUserId()); + rzRestaurantStatistics.setDeptId(sysStaff.getDeptId()); + rzRestaurantStatistics.setName(sysStaff.getName()); + rzRestaurantStatistics.setMonth(DateUtils.getNowDate()); + //查询早午晚三餐消费 + for (SysStaffDetail sysStaffDetail : dt_list) { + if(sysStaff.getUserId() == sysStaffDetail.getStaffId()){ + rzRestaurantStatistics.setBreakfastExpend(sysStaffDetail.getBreakfastExpend()); + rzRestaurantStatistics.setLunchExpend(sysStaffDetail.getLunchExpend()); + rzRestaurantStatistics.setSupperExpend(sysStaffDetail.getSupperExpend()); + } + } + rzRestaurantStatistics.setCreateTime(DateUtils.getNowDate()); + rzRestaurantStatistics.setDelFlag(Constants.DELETE_FLAG_0); + rzRestaurantStatistics.setCreateBy("admin"); + rzRestaurantStatisticsMapper.insertRzRestaurantStatistics(rzRestaurantStatistics); + } + //获取只吃饭不打卡的职员工 + List img_list = rzRestaurantImagesMapper.selectRzRestaurantImagesList(null); + for (RzRestaurantImages rzRestaurantImages : img_list) { + rzRestaurantStatistics = new RzRestaurantStatistics(); + rzRestaurantStatistics.setStaffId(rzRestaurantImages.getId()); + rzRestaurantStatistics.setName(rzRestaurantImages.getName()); + rzRestaurantStatistics.setMonth(DateUtils.getNowDate()); + rzRestaurantStatistics.setCreateTime(DateUtils.getNowDate()); + rzRestaurantStatistics.setDelFlag(Constants.DELETE_FLAG_0); + rzRestaurantStatistics.setCreateBy("admin"); + rzRestaurantStatisticsMapper.insertRzRestaurantStatistics(rzRestaurantStatistics); + } + } + + /** + * 校正数据 + * @return + */ + @Override + public AjaxResult correct(RzRestaurantStatistics rzRestaurantStatistics){ + if(StringUtils.isNull(rzRestaurantStatistics) || StringUtils.isNull(rzRestaurantStatistics.getMonth())){ + return AjaxResult.error("请输入校正日期!!"); + } + //根据日期查询统计日期内的统计信息 + List rt_list = rzRestaurantStatisticsMapper.selectRzRestaurantStatisticsList(rzRestaurantStatistics); + //根据月份统计打卡信息 + RzRestaurantDetail rzRestaurantDetail = new RzRestaurantDetail(); + rzRestaurantDetail.setMonth(rzRestaurantStatistics.getMonth()); + List rd_list = rzRestaurantDetailMapper.selectRzRestaurantDetailList(rzRestaurantDetail); + //查询消费情况 + List dic_list = sysDictDataMapper.selectDictDataByType(Constants.SYS_RESTAUTANT); + //循环统计信息 + for (RzRestaurantStatistics restaurantStatistics : rt_list) { + //记录早午晚三餐次数 + Long breakfast = 0l; + Long lunch = 0l; + Long supper = 0l; + //循环打卡详情 + for (RzRestaurantDetail restaurantDetail : rd_list) { + if(restaurantStatistics.getStaffId() == restaurantDetail.getStaffId()){ + if("早餐".equals(restaurantDetail.getSign())){ + breakfast += 1; + continue; + } + if("午餐".equals(restaurantDetail.getSign())){ + lunch += 1; + continue; + } + if("晚餐".equals(restaurantDetail.getSign())){ + supper += 1; + } + } + } + restaurantStatistics.setBreakfastNumber(breakfast); + restaurantStatistics.setLunchNumber(lunch); + restaurantStatistics.setSupperNumber(supper); + //计算费用 + restaurantStatistics.setBreakfastPreSumExpend(restaurantStatistics.getBreakfastExpend().multiply(new BigDecimal(restaurantStatistics.getBreakfastNumber()))); + restaurantStatistics.setLunchPreSumExpend(restaurantStatistics.getLunchExpend().multiply(new BigDecimal(restaurantStatistics.getLunchNumber()))); + restaurantStatistics.setSupperPreSumExpend(restaurantStatistics.getSupperExpend().multiply(new BigDecimal(restaurantStatistics.getSupperNumber()))); + for (SysDictData sysDictData : dic_list) { + if(sysDictData.getDictLabel().indexOf("早餐") != -1){ + restaurantStatistics.setBreakfastSumExpend(new BigDecimal(sysDictData.getDictValue()).multiply(new BigDecimal(restaurantStatistics.getBreakfastNumber()))); + } + if(sysDictData.getDictLabel().indexOf("午餐") != -1){ + restaurantStatistics.setLunchSumExpend(new BigDecimal(sysDictData.getDictValue()).multiply(new BigDecimal(restaurantStatistics.getLunchNumber()))); + } + if(sysDictData.getDictLabel().indexOf("晚餐") != -1){ + restaurantStatistics.setSupperSumExpend(new BigDecimal(sysDictData.getDictValue()).multiply(new BigDecimal(restaurantStatistics.getSupperNumber()))); + } + } + restaurantStatistics.setPersonalSumConsumption(restaurantStatistics.getBreakfastPreSumExpend().add(restaurantStatistics.getLunchPreSumExpend()) + .add(restaurantStatistics.getSupperPreSumExpend())); + restaurantStatistics.setSumConsumption(restaurantStatistics.getBreakfastSumExpend().add(restaurantStatistics.getLunchSumExpend()) + .add(restaurantStatistics.getSupperSumExpend())); + rzRestaurantStatisticsMapper.updateRzRestaurantStatistics(restaurantStatistics); + } + return AjaxResult.success(); + } + @Override + public List selectRzRestaurantStatisticsListBySxs(RzRestaurantStatistics rzRestaurantStatistics){ + return rzRestaurantStatisticsMapper.selectRzRestaurantStatisticsByDate(rzRestaurantStatistics.getMonth()); + } + +} diff --git a/evo-admin/src/main/java/com/evo/restaurant/utils/ExcelUtilCy.java b/evo-admin/src/main/java/com/evo/restaurant/utils/ExcelUtilCy.java new file mode 100644 index 0000000..67135ac --- /dev/null +++ b/evo-admin/src/main/java/com/evo/restaurant/utils/ExcelUtilCy.java @@ -0,0 +1,1008 @@ +package com.evo.restaurant.utils; + +import com.evo.common.annotation.Excel; +import com.evo.common.annotation.Excel.ColumnType; +import com.evo.common.annotation.Excel.Type; +import com.evo.common.annotation.Excels; +import com.evo.common.config.EvoConfig; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.text.Convert; +import com.evo.common.exception.CustomException; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.common.utils.reflect.ReflectUtils; +import org.apache.poi.hssf.usermodel.HSSFDateUtil; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddressList; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFDataValidation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * Excel相关处理 + * + * @author ruoyi + */ +public class ExcelUtilCy{ + private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class); + + /** + * Excel sheet最大行数,默认65536 + */ + public static final int sheetSize = 65536; + + /** + * 工作表名称 + */ + private String sheetName; + + /** + * 各个部门工作表名称 + */ + private List sheetNameList; + + /** + * 导出类型(EXPORT:导出数据;IMPORT:导入模板) + */ + private Type type; + + /** + * 工作薄对象 + */ + private Workbook wb; + + /** + * 工作表对象 + */ + private Sheet sheet; + + /** + * 样式列表 + */ + private Map styles; + + /** + * 导入导出数据列表 + */ + private List list; + + /** + * 导入导出各个部门数据列表 + */ + private List> lists; + + /** + * 注解列表 + */ + private List fields; + + /** + * 实体对象 + */ + public Class clazz; + + public ExcelUtilCy(Class clazz) + { + this.clazz = clazz; + } + + // 默认单元格内容为数字时格式 + private static DecimalFormat df = new DecimalFormat("0"); + // 默认单元格格式化日期字符串 + private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + // 格式化数字 + private static DecimalFormat nf = new DecimalFormat("0.00"); + + public void init(List list,List> lists, String sheetName,List sheetNameList,Type type){ + if (list == null){ + list = new ArrayList(); + } + if(sheetNameList == null){ + sheetNameList = new ArrayList(); + } + this.list = list; + this.lists = lists; + this.sheetName = sheetName; + this.sheetNameList = sheetNameList; + this.type = type; + createExcelField(); + createWorkbook(); + } + + /** + * 对excel表单默认第一个索引名转换成list + * + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(InputStream is) throws Exception + { + return importExcel(StringUtils.EMPTY, is); + } + + /** + * 对excel表单指定表格索引名转换成list + * + * @param sheetName 表格索引名 + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(String sheetName, InputStream is) throws Exception + { + this.type = Type.IMPORT; + this.wb = WorkbookFactory.create(is); + List list = new ArrayList(); + Sheet sheet = null; + if (StringUtils.isNotEmpty(sheetName)) + { + // 如果指定sheet名,则取指定sheet中的内容. + sheet = wb.getSheet(sheetName); + } + else + { + // 如果传入的sheet名不存在则默认指向第1个sheet. + sheet = wb.getSheetAt(0); + } + + if (sheet == null) + { + throw new IOException("文件sheet不存在"); + } + + int rows = sheet.getPhysicalNumberOfRows(); + + if (rows > 0) + { + // 定义一个map用于存放excel列的序号和field. + Map cellMap = new HashMap(); + // 获取表头 + Row heard = sheet.getRow(0); + 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. + Field[] allFields = clazz.getDeclaredFields(); + // 定义一个map用于存放列的序号和field. + Map fieldsMap = new HashMap(); + for (int col = 0; col < allFields.length; col++) + { + Field field = allFields[col]; + Excel attr = field.getAnnotation(Excel.class); + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + // 设置类的私有字段属性可访问. + field.setAccessible(true); + Integer column = cellMap.get(attr.name()); + fieldsMap.put(column, field); + } + } + for (int i = 1; i < rows; i++) + { + // 从第2行开始取数据,默认第一行是表头. + Row row = sheet.getRow(i); + T entity = null; + for (Map.Entry entry : fieldsMap.entrySet()) + { + Object val = this.getCellValue(row, entry.getKey()); + + // 如果不存在实例则新建. + entity = (entity == null ? clazz.newInstance() : entity); + // 从map中得到对应列的field. + Field field = fieldsMap.get(entry.getKey()); + // 取得类型,并根据对象类型设置值. + Class fieldType = field.getType(); + if (String.class == fieldType) + { + String s = Convert.toStr(val); + if (StringUtils.endsWith(s, ".0")) + { + val = StringUtils.substringBefore(s, ".0"); + } + else + { + val = Convert.toStr(val); + } + } + else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) + { + val = Convert.toInt(val); + } + else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) + { + val = Convert.toLong(val); + } + else if ((Double.TYPE == fieldType) || (Double.class == fieldType)) + { + val = Convert.toDouble(val); + } + else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) + { + val = Convert.toFloat(val); + } + else if (BigDecimal.class == fieldType) + { + val = Convert.toBigDecimal(val); + } + else if (Date.class == fieldType) + { + if (val instanceof String) + { + val = DateUtils.parseDate(val); + } + else if (val instanceof Double) + { + val = DateUtil.getJavaDate((Double) val); + } + } + if (StringUtils.isNotNull(fieldType)) + { + Excel attr = field.getAnnotation(Excel.class); + String propertyName = field.getName(); + if (StringUtils.isNotEmpty(attr.targetAttr())) + { + propertyName = field.getName() + "." + attr.targetAttr(); + } + else if (StringUtils.isNotEmpty(attr.readConverterExp())) + { + val = reverseByExp(String.valueOf(val), attr.readConverterExp()); + } + ReflectUtils.invokeSetter(entity, propertyName, val); + } + } + list.add(entity); + } + } + return list; + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + */ + public AjaxResult exportExcel(List list, List> lists, String sheetName, List sheetNameList){ + this.init(list,lists,sheetName,sheetNameList,Type.EXPORT); + return exportExcel(); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @return 结果 + */ + public AjaxResult exportExcel(){ + OutputStream out = null; + try{ + // 取出一共有多少个sheet. + double sheetNo = 0; + sheetNo = sheetNameList.size(); + for (int index = 0; index <= sheetNo; index++){ + createSheet(sheetNo, index); + //sheet1和后边的sheet表头不一致,所以需要分开处理 + // 产生一行 + Row row = sheet.createRow(0); + int column = 0; + // 写入各个字段的列头名称 + //当index为0时,默认是第一个sheet,需要把list[1]姓名列删掉 + List fields2 = new ArrayList<>(); + fields2.addAll(fields); + for (int i = 0; i < fields2.size();i++){ + Object[] os = fields2.get(i); + Excel excel = (Excel) os[1]; + this.createCell(excel, row, column++,index); + } + if (Type.EXPORT.equals(type)){ + fillExcelData(index, row); + } + } + String filename = encodingFilename(sheetName); + out = new FileOutputStream(getAbsoluteFile(filename)); + wb.write(out); + return AjaxResult.success(filename); + }catch (Exception e){ + log.error("导出Excel异常{}", e.getMessage()); + throw new CustomException("导出Excel失败,请联系网站管理员!"); + } + finally{ + if (wb != null) + { + try + { + wb.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + } + if (out != null) + { + try + { + out.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + } + } + } + + /** + * 填充excel数据 + * + * @param index 序号 + * @param row 单元格行 + */ + public void fillExcelData(int index, Row row){ + int startNo = 0; + int endNo = 0; + if(index == 0){ + endNo = Math.min(startNo + sheetSize, list.size()); + }else{ + endNo = Math.min(startNo + sheetSize, lists.get(index-1).size()); + } + for (int i = startNo; i < endNo; i++){ + row = sheet.createRow(i + 1 - startNo); + // 得到导出对象. + T vo = null; + if(index == 0){ + vo = (T) list.get(i); + }else{ + vo = (T) lists.get(index-1).get(i); + } + int column = 0; + //当index为0时,默认是第一个sheet,需要把list[1]姓名列删掉 + List fields2 = new ArrayList<>(); + fields2.addAll(fields); + for (Object[] os : fields2){ + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + // 设置实体类私有属性可访问 + field.setAccessible(true); + this.addCell(excel, row, vo, field, column++,index); + } + } + + } + + /** + * 创建表格样式 + * + * @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); + 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("宋体"); + dataFont.setFontHeightInPoints((short) 10); + style.setFont(dataFont); +// style.setWrapText(true);//自动换行 + styles.put("data", style); + + style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font dataFonts = wb.createFont(); + dataFont.setFontName("宋体"); + dataFont.setFontHeightInPoints((short) 9); + style.setFont(dataFonts); + styles.put("datas", style); + + style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); +// style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex()); +// style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + Font headerFont = wb.createFont(); + headerFont.setFontName("宋体"); + headerFont.setFontHeightInPoints((short) 11); +// headerFont.setBold(true); +// headerFont.setColor(IndexedColors.WHITE.getIndex()); + style.setFont(headerFont); + style.setWrapText(true);//自动换行 + styles.put("header", style); + + style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("datas")); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font footerFont = wb.createFont(); + footerFont.setFontName("宋体"); + footerFont.setFontHeightInPoints((short) 12); + style.setFont(footerFont); + styles.put("footer", style); + + style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font titleFont = wb.createFont(); + titleFont.setFontName("宋体"); + titleFont.setFontHeightInPoints((short) 18); + style.setFont(titleFont); + styles.put("title", style); + + return styles; + } + + /** + * 创建单元格 + */ + public Cell createCell(Excel attr, Row row, int column,int index){ + // 创建列 + Cell cell = row.createCell(column); + // 写入列信息 + cell.setCellValue(attr.name()); + setDataValidation(attr, row, column,index); + cell.setCellStyle(styles.get("header")); + return cell; + } + + /** + * 设置单元格信息 + * + * @param value 单元格值 + * @param attr 注解相关 + * @param cell 单元格信息 + */ + public void setCellVo(Object value, Excel attr, Cell cell) + { + if (ColumnType.STRING == attr.cellType()) + { + cell.setCellType(CellType.NUMERIC); + cell.setCellValue(StringUtils.isNull(value) ? attr.defaultValue() : value + attr.suffix()); + } + else if (ColumnType.NUMERIC == attr.cellType()) + { + cell.setCellType(CellType.NUMERIC); + cell.setCellValue(Integer.parseInt(value + "")); + } + } + + /** + * 创建表格样式 + */ + public void setDataValidation(Excel attr, Row row, int column,int index){ + if(index == 0){ + if (attr.name().indexOf("注:") >= 0){ + sheet.setColumnWidth(column, 6000); + }else{ + if(column==0){ + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width()) * 120)); + }else if(column==2||column==3||column==4||column==6||column==7||column==9||column==11){ + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width()) * 115)); + }else{ + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width()) * 130)); + } + row.setHeight((short) (attr.height() * 50)); + } + // 如果设置了提示信息则鼠标放上去提示. + if (StringUtils.isNotEmpty(attr.prompt())){ + // 这里默认设了2-101列提示. + setXSSFPrompt(sheet, "", attr.prompt(), 1, 100, column, column); + } + // 如果设置了combo属性则本列只能选择不能输入 + if (attr.combo().length > 0){ + // 这里默认设了2-101列只能选择不能输入. + setXSSFValidation(sheet, attr.combo(), 1, 100, column, column); + } + }else{ + if (attr.name().indexOf("注:") >= 0){ + sheet.setColumnWidth(column, 6000); + }else{ + if(column==0){ + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width()) * 120)); + }else if(column==2||column==3||column==4||column==6||column==7||column==9||column==11){ + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width()) * 100)); + }else{ + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width()) * 110)); + } + row.setHeight((short) (attr.height() * 50)); + } + // 如果设置了提示信息则鼠标放上去提示. + if (StringUtils.isNotEmpty(attr.prompt())){ + // 这里默认设了2-101列提示. + setXSSFPrompt(sheet, "", attr.prompt(), 1, 100, column, column); + } + // 如果设置了combo属性则本列只能选择不能输入 + if (attr.combo().length > 0){ + // 这里默认设了2-101列只能选择不能输入. + setXSSFValidation(sheet, attr.combo(), 1, 100, column, column); + } + } + } + + /** + * 添加单元格 + */ + public Cell addCell(Excel attr, Row row, T vo, Field field, int column,int index){ + Cell cell = null; + try{ + // 设置行高 + row.setHeight((short) (attr.height() * 30)); + // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列. + if (attr.isExport()){ + // 创建cell + cell = row.createCell(column); + cell.setCellStyle(styles.get("data")); + + // 用于读取对象中的属性 + Object value = getTargetValue(vo, field, attr); + String dateFormat = attr.dateFormat(); + String readConverterExp = attr.readConverterExp(); + if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)){ + cell.setCellValue(DateUtils.parseDateToStr(dateFormat, (Date) value)); + }else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)){ + cell.setCellValue(convertByExp(String.valueOf(value), readConverterExp)); + }else{ + // 设置列类型 + setCellVo(value, attr, cell); + } + } + } + catch (Exception e) + { + log.error("导出Excel失败{}", e); + } + return cell; + } + + /** + * 设置 POI XSSFSheet 单元格提示 + * + * @param sheet 表单 + * @param promptTitle 提示标题 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setXSSFPrompt(Sheet sheet, String promptTitle, String promptContent, int firstRow, int endRow, + int firstCol, int endCol) + { + DataValidationHelper helper = sheet.getDataValidationHelper(); + DataValidationConstraint constraint = helper.createCustomConstraint("DD1"); + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + DataValidation dataValidation = helper.createValidation(constraint, regions); + dataValidation.createPromptBox(promptTitle, promptContent); + dataValidation.setShowPromptBox(true); + sheet.addValidationData(dataValidation); + } + + /** + * 设置某些列的值只能输入预制的数据,显示下拉框. + * + * @param sheet 要设置的sheet. + * @param textlist 下拉框显示的内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + * @return 设置好的sheet. + */ + public void setXSSFValidation(Sheet sheet, String[] textlist, int firstRow, int endRow, int firstCol, int endCol) + { + DataValidationHelper helper = sheet.getDataValidationHelper(); + // 加载下拉列表内容 + DataValidationConstraint constraint = helper.createExplicitListConstraint(textlist); + // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列 + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + // 数据有效性对象 + DataValidation dataValidation = helper.createValidation(constraint, regions); + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) + { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } + else + { + dataValidation.setSuppressDropDownArrow(false); + } + + sheet.addValidationData(dataValidation); + } + + /** + * 解析导出值 0=男,1=女,2=未知 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @return 解析后值 + * @throws Exception + */ + public static String convertByExp(String propertyValue, String converterExp) throws Exception + { + try + { + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (itemArray[0].equals(propertyValue)) + { + return itemArray[1]; + } + } + } + catch (Exception e) + { + throw e; + } + return propertyValue; + } + + /** + * 反向解析值 男=0,女=1,未知=2 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @return 解析后值 + * @throws Exception + */ + public static String reverseByExp(String propertyValue, String converterExp) throws Exception + { + try + { + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (itemArray[1].equals(propertyValue)) + { + return itemArray[0]; + } + } + } + catch (Exception e) + { + throw e; + } + return propertyValue; + } + + /** + * 编码文件名 + */ + public String encodingFilename(String filename) + { +// filename = UUID.randomUUID().toString() + "_" + filename + ".xlsx"; + filename = filename + ".xlsx"; + return filename; + } + + /** + * 获取下载路径 + * + * @param filename 文件名称 + */ + public String getAbsoluteFile(String filename) + { + String downloadPath = EvoConfig.getDownloadPath() + filename; + File desc = new File(downloadPath); + if (!desc.getParentFile().exists()) + { + desc.getParentFile().mkdirs(); + } + return downloadPath; + } + + /** + * 获取bean中的属性值 + * + * @param vo 实体对象 + * @param field 字段 + * @param excel 注解 + * @return 最终的属性值 + * @throws Exception + */ + private Object getTargetValue(T vo, Field field, Excel excel) throws Exception{ + Object o = field.get(vo); + if (StringUtils.isNotEmpty(excel.targetAttr())){ + String target = excel.targetAttr(); + if (target.indexOf(".") > -1){ + String[] targets = target.split("[.]"); + for (String name : targets){ + o = getValue(o, name); + } + }else{ + o = getValue(o, target); + } + } + return o; + } + + /** + * 以类的属性的get方法方法形式获取值 + * + * @param o + * @param name + * @return value + * @throws Exception + */ + private Object getValue(Object o, String name) throws Exception + { + if (StringUtils.isNotEmpty(name)) + { + Class clazz = o.getClass(); + String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1); + Method method = clazz.getMethod(methodName); + o = method.invoke(o); + } + return o; + } + + /** + * 得到所有定义字段 + */ + private void createExcelField() + { + this.fields = new ArrayList(); + List tempFields = new ArrayList<>(); + tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); + tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); + for (Field field : tempFields) + { + // 单注解 + if (field.isAnnotationPresent(Excel.class)) + { + putToField(field, field.getAnnotation(Excel.class)); + } + + // 多注解 + if (field.isAnnotationPresent(Excels.class)) + { + Excels attrs = field.getAnnotation(Excels.class); + Excel[] excels = attrs.value(); + for (Excel excel : excels) + { + putToField(field, excel); + } + } + } + } + + /** + * 放到字段集合中 + */ + private void putToField(Field field, Excel attr) + { + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + this.fields.add(new Object[] { field, attr }); + } + } + + /** + * 创建一个工作簿 + */ + public void createWorkbook() + { + this.wb = new SXSSFWorkbook(500); + } + + /** + * 创建工作表 + * + * @param sheetNo sheet数量 + * @param index 序号 + */ + public void createSheet(double sheetNo, int index){ + this.sheet = wb.createSheet(); + this.styles = createStyles(wb); + // 设置工作表的名称. + if (index == 0){ + wb.setSheetName(index, sheetName); + }else{ + wb.setSheetName(index, sheetNameList.get(index-1)); + } + sheet.getPrintSetup().setPaperSize(PrintSetup.A4_PAPERSIZE); + //设置横向打印 + sheet.getPrintSetup().setLandscape(true); + } + + /** + * 获取单元格值 + * + * @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.getCellTypeEnum() == CellType.NUMERIC || cell.getCellTypeEnum() == CellType.FORMULA) + { + val = cell.getNumericCellValue(); + if (HSSFDateUtil.isCellDateFormatted(cell)) + { + val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换 + } + else + { + if ((Double) val % 1 > 0) + { + val = new DecimalFormat("0.00").format(val); + } + else + { + val = new DecimalFormat("0").format(val); + } + } + } + else if (cell.getCellTypeEnum() == CellType.STRING) + { + val = cell.getStringCellValue(); + } + else if (cell.getCellTypeEnum() == CellType.BOOLEAN) + { + val = cell.getBooleanCellValue(); + } + else if (cell.getCellTypeEnum() == CellType.ERROR) + { + val = cell.getErrorCellValue(); + } + + } + } + catch (Exception e) + { + return val; + } + return val; + } + + public static ArrayList> readExcel2007(Sheet sheet) { + if(sheet==null){ + return null; + } + try { + ArrayList> rowList = new ArrayList>(); + ArrayList colList; + Row row; + Cell cell; + Object value; + for (int i = sheet.getFirstRowNum(), rowCount = 0; rowCount < sheet.getPhysicalNumberOfRows(); i++) { + row = sheet.getRow(i); + colList = new ArrayList(); + if (row == null) { + // 当读取行为空时 + if (i != sheet.getPhysicalNumberOfRows()) {// 判断是否是最后一行 + rowList.add(colList); + } + continue; + } else { + rowCount++; + } + for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) { + cell = row.getCell(j); + if (cell == null || cell.getCellType() == CellType.BLANK) { + // 当该单元格为空 + if (j != row.getLastCellNum()) {// 判断是否是该行中最后一个单元格 + colList.add(""); + } + continue; + } + switch (cell.getCellType()) { + case STRING: + // System.out.println(i + "行" + j + " 列 is String + // type"); + value = cell.getStringCellValue(); + break; + case NUMERIC: + if ("@".equals(cell.getCellStyle().getDataFormatString())) { + value = df.format(cell.getNumericCellValue()); + } else if ("General".equals(cell.getCellStyle().getDataFormatString())) { + value = nf.format(cell.getNumericCellValue()); + } else { + value = sdf.format(HSSFDateUtil.getJavaDate(cell.getNumericCellValue())); + } + // System.out.println(i + "行" + j + // + " 列 is Number type ; DateFormt:" + // + value.toString()); + break; + case BOOLEAN: + // System.out.println(i + "行" + j + " 列 is Boolean + // type"); + value = Boolean.valueOf(cell.getBooleanCellValue()); + break; + case BLANK: + // System.out.println(i + "行" + j + " 列 is Blank type"); + value = ""; + break; + default: + // System.out.println(i + "行" + j + " 列 is default + // type"); + value = cell.toString(); + }// end switch + colList.add(value); + } // end for j + rowList.add(colList); + } // end for i + + return rowList; + } catch (Exception e) { + System.out.println("exception"); + return null; + } + } + + public static DecimalFormat getDf() { + return df; + } + + public static void setDf(DecimalFormat df) { + ExcelUtilCy.df = df; + } + + public static SimpleDateFormat getSdf() { + return sdf; + } + + public static void setSdf(SimpleDateFormat sdf) { + ExcelUtilCy.sdf = sdf; + } + + public static DecimalFormat getNf() { + return nf; + } + + public static void setNf(DecimalFormat nf) { + ExcelUtilCy.nf = nf; + } +} diff --git a/evo-admin/src/main/java/com/evo/system/controller/CacheController.java b/evo-admin/src/main/java/com/evo/system/controller/CacheController.java new file mode 100644 index 0000000..d68ee6b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/controller/CacheController.java @@ -0,0 +1,121 @@ +package com.evo.system.controller; + +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.evo.common.constant.CacheConstants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.StringUtils; +import com.evo.system.domain.SysCache; + +/** + * 缓存监控 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/system/controller/CommonController.java b/evo-admin/src/main/java/com/evo/system/controller/CommonController.java new file mode 100644 index 0000000..917e9ad --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/controller/CommonController.java @@ -0,0 +1,163 @@ +package com.evo.system.controller; + +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.evo.common.config.EvoConfig; +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.file.FileUploadUtils; +import com.evo.common.utils.file.FileUtils; +import com.evo.framework.config.ServerConfig; + +/** + * 通用请求处理 + * + * @author evo + */ +@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 = EvoConfig.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 = EvoConfig.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 = EvoConfig.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 = EvoConfig.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/evo-admin/src/main/java/com/evo/system/controller/SysDeptController.java b/evo-admin/src/main/java/com/evo/system/controller/SysDeptController.java new file mode 100644 index 0000000..5e1da46 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/controller/SysDeptController.java @@ -0,0 +1,144 @@ +package com.evo.system.controller; + +import java.util.List; + +import com.evo.common.core.domain.TreeSelect; +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.evo.common.annotation.Log; +import com.evo.common.constant.UserConstants; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.domain.entity.SysDept; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.StringUtils; +import com.evo.system.service.ISysDeptService; + +/** + * 部门信息 + * + * @author evo + */ +@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)); + } + + /** + * 查询部门树 + * @return + */ + @GetMapping("/listAllDepts") + public List listAllDepts() + { + return deptService.selectAllDeptList(); + } +} diff --git a/evo-admin/src/main/java/com/evo/system/controller/SysDictDataController.java b/evo-admin/src/main/java/com/evo/system/controller/SysDictDataController.java new file mode 100644 index 0000000..b2fe6ec --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/controller/SysDictDataController.java @@ -0,0 +1,121 @@ +package com.evo.system.controller; + +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.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.domain.entity.SysDictData; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.system.service.ISysDictDataService; +import com.evo.system.service.ISysDictTypeService; + +/** + * 数据字典信息 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/system/controller/SysDictTypeController.java b/evo-admin/src/main/java/com/evo/system/controller/SysDictTypeController.java new file mode 100644 index 0000000..0b18dee --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/controller/SysDictTypeController.java @@ -0,0 +1,131 @@ +package com.evo.system.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.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.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.domain.entity.SysDictType; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.system.service.ISysDictTypeService; + +/** + * 数据字典信息 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/system/controller/SysIndexController.java b/evo-admin/src/main/java/com/evo/system/controller/SysIndexController.java new file mode 100644 index 0000000..787fee0 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/controller/SysIndexController.java @@ -0,0 +1,29 @@ +package com.evo.system.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.evo.common.config.EvoConfig; +import com.evo.common.utils.StringUtils; + +/** + * 首页 + * + * @author evo + */ +@RestController +public class SysIndexController +{ + /** 系统基础配置 */ + @Autowired + private EvoConfig EvoConfig; + + /** + * 访问首页,提示语 + */ + @RequestMapping("/") + public String index() + { + return StringUtils.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。", EvoConfig.getName(), EvoConfig.getVersion()); + } +} diff --git a/evo-admin/src/main/java/com/evo/system/controller/SysLoginController.java b/evo-admin/src/main/java/com/evo/system/controller/SysLoginController.java new file mode 100644 index 0000000..f28cb6a --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/controller/SysLoginController.java @@ -0,0 +1,85 @@ +package com.evo.system.controller; + +import java.util.List; +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.domain.entity.SysMenu; +import com.evo.common.core.domain.entity.SysUser; +import com.evo.common.core.domain.model.LoginBody; +import com.evo.common.utils.SecurityUtils; +import com.evo.framework.web.service.SysLoginService; +import com.evo.framework.web.service.SysPermissionService; +import com.evo.system.service.ISysMenuService; + +/** + * 登录验证 + * + * @author evo + */ +@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()); + 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/evo-admin/src/main/java/com/evo/system/controller/SysLogininforController.java b/evo-admin/src/main/java/com/evo/system/controller/SysLogininforController.java new file mode 100644 index 0000000..57aa078 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/controller/SysLogininforController.java @@ -0,0 +1,82 @@ +package com.evo.system.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.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.framework.web.service.SysPasswordService; +import com.evo.system.domain.SysLogininfor; +import com.evo.system.service.ISysLogininforService; + +/** + * 系统访问记录 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/system/controller/SysMenuController.java b/evo-admin/src/main/java/com/evo/system/controller/SysMenuController.java new file mode 100644 index 0000000..fcccb07 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/controller/SysMenuController.java @@ -0,0 +1,142 @@ +package com.evo.system.controller; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.evo.common.annotation.Log; +import com.evo.common.constant.UserConstants; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.domain.entity.SysMenu; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.StringUtils; +import com.evo.system.service.ISysMenuService; + +/** + * 菜单信息 + * + * @author evo + */ +@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)); + } +} diff --git a/evo-admin/src/main/java/com/evo/system/controller/SysOperlogController.java b/evo-admin/src/main/java/com/evo/system/controller/SysOperlogController.java new file mode 100644 index 0000000..3b5a9c1 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/controller/SysOperlogController.java @@ -0,0 +1,69 @@ +package com.evo.system.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.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.system.domain.SysOperLog; +import com.evo.system.service.ISysOperLogService; + +/** + * 操作日志记录 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/system/controller/SysProfileController.java b/evo-admin/src/main/java/com/evo/system/controller/SysProfileController.java new file mode 100644 index 0000000..5ad6230 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/controller/SysProfileController.java @@ -0,0 +1,136 @@ +package com.evo.system.controller; + +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.evo.common.annotation.Log; +import com.evo.common.config.EvoConfig; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.domain.entity.SysUser; +import com.evo.common.core.domain.model.LoginUser; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.file.FileUploadUtils; +import com.evo.common.utils.file.MimeTypeUtils; +import com.evo.framework.web.service.TokenService; +import com.evo.system.service.ISysUserService; + +/** + * 个人信息 业务处理 + * + * @author evo + */ +@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())); + 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(EvoConfig.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/evo-admin/src/main/java/com/evo/system/controller/SysRoleController.java b/evo-admin/src/main/java/com/evo/system/controller/SysRoleController.java new file mode 100644 index 0000000..593c7ab --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/controller/SysRoleController.java @@ -0,0 +1,262 @@ +package com.evo.system.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.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.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.domain.entity.SysDept; +import com.evo.common.core.domain.entity.SysRole; +import com.evo.common.core.domain.entity.SysUser; +import com.evo.common.core.domain.model.LoginUser; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.framework.web.service.SysPermissionService; +import com.evo.framework.web.service.TokenService; +import com.evo.system.domain.SysUserRole; +import com.evo.system.service.ISysDeptService; +import com.evo.system.service.ISysRoleService; +import com.evo.system.service.ISysUserService; + +/** + * 角色信息 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/system/controller/SysStaffController.java b/evo-admin/src/main/java/com/evo/system/controller/SysStaffController.java new file mode 100644 index 0000000..3068058 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/controller/SysStaffController.java @@ -0,0 +1,164 @@ +package com.evo.system.controller; + +import java.util.List; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import com.evo.system.domain.SysStaff; +import com.evo.system.domain.vo.SysStaffVo; +import com.evo.system.service.ISysStaffService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.common.core.page.TableDataInfo; +import org.springframework.web.multipart.MultipartFile; + +/** + * 员工管理Controller + * + * @author evo + * @date 2024-11-21 + */ +@RestController +@RequestMapping("/system/staff") +public class SysStaffController extends BaseController +{ + @Resource + private ISysStaffService sysStaffService; + + /** + * 查询员工管理列表 + */ + @PreAuthorize("@ss.hasPermi('system:staff:list')") + @GetMapping("/list") + public TableDataInfo list(SysStaff sysStaff) + { + + startPage(); + List list = sysStaffService.selectSysStaffList(sysStaff); + return getDataTable(list); + } + /** + * 导出员工管理列表 + */ + @PreAuthorize("@ss.hasPermi('system:staff:export')") + @Log(title = "员工管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysStaff sysStaff) + { + List list = sysStaffService.selectSysStaffList(sysStaff); + ExcelUtil util = new ExcelUtil(SysStaff.class); + util.exportExcel(response, list, "员工管理数据"); + } + /** + * 导出员工详情 + */ + @PreAuthorize("@ss.hasPermi('system:staff:exportDetail')") + @PostMapping("/exportDetail") + public void exportDetail(HttpServletResponse response, SysStaff sysStaff) + { + List list = sysStaffService.selectSysStaffDetailList(sysStaff); + ExcelUtil util = new ExcelUtil(SysStaffVo.class); + util.exportExcel(response, list, "员工详情数据"); + } + /** + * 获取员工管理详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:staff:query')") + @GetMapping(value = "/{userId}") + public AjaxResult getInfo(@PathVariable("userId") Long userId) + { + return success(sysStaffService.selectSysStaffByUserId(userId)); + } + /** + * 新增员工管理 + */ + @PreAuthorize("@ss.hasPermi('system:staff:add')") + @Log(title = "员工管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysStaff sysStaff) + { + return sysStaffService.insertSysStaff(sysStaff); + } + /** + * 修改员工管理 + */ + @PreAuthorize("@ss.hasPermi('system:staff:edit')") + @Log(title = "员工管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysStaff sysStaff) + { + return sysStaffService.updateSysStaff(sysStaff); + } + /** + * 删除员工管理 + */ + @PreAuthorize("@ss.hasPermi('system:staff:remove')") + @Log(title = "员工管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{userId}") + public AjaxResult remove(@PathVariable Long userId) + { + SysStaff sysStaff = sysStaffService.selectSysStaffByUserId(userId); + if(!"-1".equals(sysStaff.getStatus())){ + return AjaxResult.error("没有离职的员工不能删除!!"); + } + return toAjax(sysStaffService.deleteSysStaffByUserId(userId)); + } + /** + * 查询所有在职员工 + * @return + */ + @GetMapping("/listStaffAll") + public List listStaffAll() + { + List list = sysStaffService.selectSysStaffListAll(); + return list; + } + /** + * 上传五险一金信息文件 + */ + @PreAuthorize("@ss.hasPermi('system:staff:importFund')") + @PostMapping("/uploadAccumulationFund") + public AjaxResult uploadAccumulationFund(@RequestParam("file") MultipartFile filePath) { + return sysStaffService.uploadAccumulationFund(filePath); + } + /** + * 模板导出 + * @param response + */ + @PostMapping("/importTemplate") + public void importTemplate(HttpServletResponse response) + { + ExcelUtil util = new ExcelUtil(SysStaffVo.class); + util.importTemplateExcel(response, "员工信息"); + } + /** + * 数据导入 + * @param file + * @return + * @throws Exception + */ + @PreAuthorize("@ss.hasPermi('system:staff:import')") + @PostMapping("/importData") + public AjaxResult importData(MultipartFile file) throws Exception + { + ExcelUtil util = new ExcelUtil(SysStaffVo.class); + List staffList = util.importExcel(file.getInputStream()); + return sysStaffService.importStaff(staffList); + } + + /** + * 根据部门查询在职员工 + * @return + */ + @GetMapping("/listStaffByDept/{dept}") + public List listStaffByDept(@PathVariable("dept") Long dept) + { + List list = sysStaffService.queryysStaffByDeptId(dept); + return list; + } + +} diff --git a/evo-admin/src/main/java/com/evo/system/controller/SysStaffDetailController.java b/evo-admin/src/main/java/com/evo/system/controller/SysStaffDetailController.java new file mode 100644 index 0000000..060acb5 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/controller/SysStaffDetailController.java @@ -0,0 +1,69 @@ +package com.evo.system.controller; + +import java.util.List; +import javax.annotation.Resource; + +import com.evo.system.domain.SysStaff; +import com.evo.system.domain.SysStaffDetail; +import com.evo.system.service.ISysStaffDetailService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import com.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.enums.BusinessType; +import com.evo.common.core.page.TableDataInfo; + +/** + * 员工详情Controller + * + * @author evo + * @date 2024-11-22 + */ +@RestController +@RequestMapping("/system/staffDetail") +public class SysStaffDetailController extends BaseController +{ + @Resource + private ISysStaffDetailService sysStaffDetailService; + + /** + * 查询员工详情列表 + */ + @PreAuthorize("@ss.hasPermi('system:staffDetail:list')") + @GetMapping("/list") + public TableDataInfo list(SysStaffDetail sysStaffDetail) + { + startPage(); + List list = sysStaffDetailService.selectSysStaffDetailList(sysStaffDetail); + return getDataTable(list); + } + + /** + * 获取员工详情详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:staffDetail:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(sysStaffDetailService.selectSysStaffDetailById(id)); + } + + /** + * 修改员工详情 + */ + @PreAuthorize("@ss.hasPermi('system:staffDetail:edit')") + @Log(title = "员工详情", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysStaffDetail sysStaffDetail) + { + return toAjax(sysStaffDetailService.updateSysStaffDetail(sysStaffDetail)); + } + + @DeleteMapping("/clearAllSubsidy") + public AjaxResult clearAllSubsidy() + { + return sysStaffDetailService.clearAllSubsidy(); + } + +} diff --git a/evo-admin/src/main/java/com/evo/system/controller/SysUserController.java b/evo-admin/src/main/java/com/evo/system/controller/SysUserController.java new file mode 100644 index 0000000..33177b0 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/controller/SysUserController.java @@ -0,0 +1,250 @@ +package com.evo.system.controller; + +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.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.domain.entity.SysDept; +import com.evo.common.core.domain.entity.SysRole; +import com.evo.common.core.domain.entity.SysUser; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.system.service.ISysDeptService; +import com.evo.system.service.ISysRoleService; +import com.evo.system.service.ISysUserService; + +/** + * 用户信息 + * + * @author evo + */ +@RestController +@RequestMapping("/system/user") +public class SysUserController extends BaseController +{ + @Autowired + private ISysUserService userService; + + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysDeptService deptService; + + /** + * 获取用户列表 + */ + @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())); + if (StringUtils.isNotNull(userId)) + { + SysUser sysUser = userService.selectUserById(userId); + ajax.put(AjaxResult.DATA_TAG, sysUser); + 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/evo-admin/src/main/java/com/evo/system/controller/SysUserOnlineController.java b/evo-admin/src/main/java/com/evo/system/controller/SysUserOnlineController.java new file mode 100644 index 0000000..2ebcfe9 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/controller/SysUserOnlineController.java @@ -0,0 +1,83 @@ +package com.evo.system.controller; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.evo.common.annotation.Log; +import com.evo.common.constant.CacheConstants; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.domain.model.LoginUser; +import com.evo.common.core.page.TableDataInfo; +import com.evo.common.core.redis.RedisCache; +import com.evo.common.enums.BusinessType; +import com.evo.common.utils.StringUtils; +import com.evo.system.domain.SysUserOnline; +import com.evo.system.service.ISysUserOnlineService; + +/** + * 在线用户监控 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/system/domain/SysCache.java b/evo-admin/src/main/java/com/evo/system/domain/SysCache.java new file mode 100644 index 0000000..c2269a9 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/domain/SysCache.java @@ -0,0 +1,81 @@ +package com.evo.system.domain; + +import com.evo.common.utils.StringUtils; + +/** + * 缓存信息 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/domain/SysLogininfor.java b/evo-admin/src/main/java/com/evo/system/domain/SysLogininfor.java new file mode 100644 index 0000000..4f4ba11 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/domain/SysLogininfor.java @@ -0,0 +1,144 @@ +package com.evo.system.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.evo.common.annotation.Excel; +import com.evo.common.annotation.Excel.ColumnType; +import com.evo.common.core.domain.BaseEntity; + +/** + * 系统访问记录表 sys_logininfor + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/domain/SysOperLog.java b/evo-admin/src/main/java/com/evo/system/domain/SysOperLog.java new file mode 100644 index 0000000..70964b4 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/domain/SysOperLog.java @@ -0,0 +1,269 @@ +package com.evo.system.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.evo.common.annotation.Excel; +import com.evo.common.annotation.Excel.ColumnType; +import com.evo.common.core.domain.BaseEntity; + +/** + * 操作日志记录表 oper_log + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/domain/SysRoleDept.java b/evo-admin/src/main/java/com/evo/system/domain/SysRoleDept.java new file mode 100644 index 0000000..e4cac07 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/domain/SysRoleDept.java @@ -0,0 +1,46 @@ +package com.evo.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 角色和部门关联 sys_role_dept + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/domain/SysRoleMenu.java b/evo-admin/src/main/java/com/evo/system/domain/SysRoleMenu.java new file mode 100644 index 0000000..b59eca4 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/domain/SysRoleMenu.java @@ -0,0 +1,46 @@ +package com.evo.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 角色和菜单关联 sys_role_menu + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/domain/SysStaff.java b/evo-admin/src/main/java/com/evo/system/domain/SysStaff.java new file mode 100644 index 0000000..427c70f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/domain/SysStaff.java @@ -0,0 +1,563 @@ +package com.evo.system.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; + +/** + * 员工管理对象 sys_staff + * + * @author evo + * @date 2024-11-21 + */ +public class SysStaff extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Long userId; + /** 部门ID */ + private Long deptId; + @Excel(name = "部门") + private String deptName; + /** 编号 */ + @Excel(name = "编号") + private String code; + + /** 姓名 */ + @Excel(name = "姓名") + private String name; + + /** 身份证号 */ + @Excel(name = "身份证号") + private String idCard; + + /** 性别 */ + @Excel(name = "性别") + private String sex; + + /** 年龄 */ + @Excel(name = "年龄") + private Long age; + + /** 电话 */ + @Excel(name = "电话") + private String phone; + + /** 住址 */ + @Excel(name = "住址") + private String address; + + /** 学历 */ + @Excel(name = "学历") + private String level; + + /** 专业 */ + @Excel(name = "专业") + private String major; + + /** 毕业学校 */ + @Excel(name = "毕业学校") + private String school; + + /** 银行卡号 */ + @Excel(name = "银行卡号") + private String bankNumber; + + /** 开户行 */ + @Excel(name = "开户行") + private String bank; + + /** 入职时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "入职时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date employmentDate; + + /** 履历 */ + @Excel(name = "履历") + private String experience; + + /** 试用期限 */ + @Excel(name = "试用期限") + private Long workerTerm; + + /** 转正日期 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "转正日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date regularDate; + + /** 离职时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "离职时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date quitDate; + + /** 合同-起 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "合同-起", width = 30, dateFormat = "yyyy-MM-dd") + private Date contractStart; + + /** 合同-止 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "合同-止", width = 30, dateFormat = "yyyy-MM-dd") + private Date contractEnd; + + /** 合同类型 */ + @Excel(name = "合同类型") + private String contractType; + + /** 社保 */ + @Excel(name = "社保") + private String socialType; + @Excel(name = "是否新农合") + private String socialSubsidy; + + /** 工龄 */ + @Excel(name = "工龄") + private Long seniority; + + /** 是否有加班费 */ + @Excel(name = "是否有加班费") + private String isOvertimePay; + + /** 住宿标识 */ + @Excel(name = "住宿标识") + private String zsFlag; + + /** 保密合同 */ + @Excel(name = "保密合同") + private String secrecy; + + /** 工伤 */ + @Excel(name = "工伤") + private String injury; + + /** 雇主险 */ + @Excel(name = "雇主险") + private String insurance; + + /** 介绍人 */ + @Excel(name = "介绍人") + private String introducer; + + /** 是否打卡 */ + @Excel(name = "是否打卡") + private String clockIn; + + /** 在职状态 */ + @Excel(name = "在职状态") + private String status; + + /** 全额工资时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "全额工资时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date wagesRatioDate; + + /** 公司 */ + @Excel(name = "公司") + private String companyName; + + /** 备注 */ + @Excel(name = "备注") + private String remarks; + + /** 删除标识 */ + private String delFlag; + + private String isLeader; //是领导 + + public String getSocialSubsidy() { + return socialSubsidy; + } + + public void setSocialSubsidy(String socialSubsidy) { + this.socialSubsidy = socialSubsidy; + } + + public String getIsLeader() { + return isLeader; + } + + public void setIsLeader(String isLeader) { + this.isLeader = isLeader; + } + + public String getCompanyName() { + return companyName; + } + + public void setCompanyName(String companyName) { + this.companyName = companyName; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getUserId() + { + return userId; + } + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + public Long getDeptId() + { + return deptId; + } + public void setCode(String code) + { + this.code = code; + } + + public String getCode() + { + return code; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setIdCard(String idCard) + { + this.idCard = idCard; + } + + public String getIdCard() + { + return idCard; + } + public void setSex(String sex) + { + this.sex = sex; + } + + public String getSex() + { + return sex; + } + public void setAge(Long age) + { + this.age = age; + } + + public Long getAge() + { + return age; + } + public void setPhone(String phone) + { + this.phone = phone; + } + + public String getPhone() + { + return phone; + } + public void setAddress(String address) + { + this.address = address; + } + + public String getAddress() + { + return address; + } + public void setLevel(String level) + { + this.level = level; + } + + public String getLevel() + { + return level; + } + public void setMajor(String major) + { + this.major = major; + } + + public String getMajor() + { + return major; + } + public void setSchool(String school) + { + this.school = school; + } + + public String getSchool() + { + return school; + } + public void setBankNumber(String bankNumber) + { + this.bankNumber = bankNumber; + } + + public String getBankNumber() + { + return bankNumber; + } + public void setBank(String bank) + { + this.bank = bank; + } + + public String getBank() + { + return bank; + } + public void setEmploymentDate(Date employmentDate) + { + this.employmentDate = employmentDate; + } + + public Date getEmploymentDate() + { + return employmentDate; + } + public void setExperience(String experience) + { + this.experience = experience; + } + + public String getExperience() + { + return experience; + } + public void setWorkerTerm(Long workerTerm) + { + this.workerTerm = workerTerm; + } + + public Long getWorkerTerm() + { + return workerTerm; + } + public void setRegularDate(Date regularDate) + { + this.regularDate = regularDate; + } + + public Date getRegularDate() + { + return regularDate; + } + public void setQuitDate(Date quitDate) + { + this.quitDate = quitDate; + } + + public Date getQuitDate() + { + return quitDate; + } + public void setContractStart(Date contractStart) + { + this.contractStart = contractStart; + } + + public Date getContractStart() + { + return contractStart; + } + public void setContractEnd(Date contractEnd) + { + this.contractEnd = contractEnd; + } + + public Date getContractEnd() + { + return contractEnd; + } + public void setContractType(String contractType) + { + this.contractType = contractType; + } + + public String getContractType() + { + return contractType; + } + public void setSocialType(String socialType) + { + this.socialType = socialType; + } + + public String getSocialType() + { + return socialType; + } + public void setSeniority(Long seniority) + { + this.seniority = seniority; + } + + public Long getSeniority() + { + return seniority; + } + public void setIsOvertimePay(String isOvertimePay) + { + this.isOvertimePay = isOvertimePay; + } + + public String getIsOvertimePay() + { + return isOvertimePay; + } + public void setZsFlag(String zsFlag) + { + this.zsFlag = zsFlag; + } + + public String getZsFlag() + { + return zsFlag; + } + public void setSecrecy(String secrecy) + { + this.secrecy = secrecy; + } + + public String getSecrecy() + { + return secrecy; + } + public void setInjury(String injury) + { + this.injury = injury; + } + + public String getInjury() + { + return injury; + } + public void setInsurance(String insurance) + { + this.insurance = insurance; + } + + public String getInsurance() + { + return insurance; + } + public void setIntroducer(String introducer) + { + this.introducer = introducer; + } + + public String getIntroducer() + { + return introducer; + } + public void setClockIn(String clockIn) + { + this.clockIn = clockIn; + } + + public String getClockIn() + { + return clockIn; + } + public void setStatus(String status) + { + this.status = status; + } + + public String getStatus() + { + return status; + } + + public Date getWagesRatioDate() { + return wagesRatioDate; + } + + public void setWagesRatioDate(Date wagesRatioDate) { + this.wagesRatioDate = wagesRatioDate; + } + + public void setRemarks(String remarks) + { + this.remarks = remarks; + } + + public String getRemarks() + { + return remarks; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("deptId", getDeptId()) + .append("code", getCode()) + .append("name", getName()) + .append("idCard", getIdCard()) + .append("sex", getSex()) + .append("age", getAge()) + .append("phone", getPhone()) + .append("address", getAddress()) + .append("level", getLevel()) + .append("major", getMajor()) + .append("school", getSchool()) + .append("bankNumber", getBankNumber()) + .append("bank", getBank()) + .append("employmentDate", getEmploymentDate()) + .append("experience", getExperience()) + .append("workerTerm", getWorkerTerm()) + .append("regularDate", getRegularDate()) + .append("quitDate", getQuitDate()) + .append("contractStart", getContractStart()) + .append("contractEnd", getContractEnd()) + .append("contractType", getContractType()) + .append("socialType", getSocialType()) + .append("seniority", getSeniority()) + .append("isOvertimePay", getIsOvertimePay()) + .append("zsFlag", getZsFlag()) + .append("secrecy", getSecrecy()) + .append("injury", getInjury()) + .append("insurance", getInsurance()) + .append("introducer", getIntroducer()) + .append("clockIn", getClockIn()) + .append("status", getStatus()) + .append("wagesRatioDate", getWagesRatioDate()) + .append("remarks", getRemarks()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/system/domain/SysStaffDetail.java b/evo-admin/src/main/java/com/evo/system/domain/SysStaffDetail.java new file mode 100644 index 0000000..c7f2763 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/domain/SysStaffDetail.java @@ -0,0 +1,592 @@ +package com.evo.system.domain; + +import java.math.BigDecimal; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; + +/** + * 员工详情对象 sys_staff_detail + * + * @author evo + * @date 2024-11-22 + */ +public class SysStaffDetail extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Long id; + + /** 员工ID */ + @Excel(name = "员工ID") + private Long staffId; + + /** 基本工资 */ + @Excel(name = "基本工资") + private BigDecimal basicSalary; + + /** 岗位工资 */ + @Excel(name = "岗位工资") + private BigDecimal jobsSalary; + + /** 日薪 */ + @Excel(name = "日薪") + private BigDecimal dailyWage; + + /** 时薪 */ + @Excel(name = "时薪") + private BigDecimal hoursSalary; + + /** 全勤奖 */ + @Excel(name = "全勤奖") + private BigDecimal fullFrequentlySubsidies; + + /** 学历补助 */ + @Excel(name = "学历补助") + private BigDecimal levelOfEducationSubsidies; + + /** 合同补助 */ + @Excel(name = "合同补助") + private BigDecimal contractSubsidies; + + /** 工龄补助 */ + @Excel(name = "工龄补助") + private BigDecimal senioritySubsidies; + + /** 社保补助 */ + @Excel(name = "社保补助") + private BigDecimal socialSecuritySubsidies; + @Excel(name = "中班补助") + private BigDecimal middleSubsidies; + + /** 夜班补助 */ + @Excel(name = "夜班补助") + private BigDecimal nightShiftSubsidies; + + /** 夜餐补助 */ + @Excel(name = "夜餐补助") + private BigDecimal dinnerSubsidies; + + /** 固定补助 */ + @Excel(name = "固定补助") + private BigDecimal fixedAllowance; + + /** 其他补助 */ + @Excel(name = "其他补助") + private BigDecimal otherSubsidies; + + /** 早餐消费 */ + @Excel(name = "早餐消费") + private BigDecimal breakfastExpend; + + /** 午餐消费 */ + @Excel(name = "午餐消费") + private BigDecimal lunchExpend; + + /** 晚餐消费 */ + @Excel(name = "晚餐消费") + private BigDecimal supperExpend; + + /** 离职扣款 */ + @Excel(name = "离职扣款") + private BigDecimal subsidyDeductMoney; + + /** 其他扣款 */ + @Excel(name = "其他扣款") + private BigDecimal deductions; + + /** 养老保险 */ + @Excel(name = "养老保险") + private BigDecimal endowmentInsurance; + + /** 医疗保险 */ + @Excel(name = "医疗保险") + private BigDecimal medicalInsurance; + + /** 工伤保险 */ + @Excel(name = "工伤保险") + private BigDecimal employmentInjuryInsurance; + + /** 生育保险 */ + @Excel(name = "生育保险") + private BigDecimal maternityInsurance; + + /** 失业保险 */ + @Excel(name = "失业保险") + private BigDecimal unemploymentInsurance; + + /** 公积金 */ + @Excel(name = "公积金") + private BigDecimal accumulationFund; + /** 五险一金公司缴纳 */ + private BigDecimal countInsurance; + + /** 子女教育 */ + @Excel(name = "子女教育") + private BigDecimal childrenEducation; + + /** 赡养老人 */ + @Excel(name = "赡养老人") + private BigDecimal supportTheOld; + + /** 住房贷款 */ + @Excel(name = "住房贷款") + private BigDecimal housingLoans; + + /** 住房租金 */ + @Excel(name = "住房租金") + private BigDecimal housingRents; + + /** 继续教育 */ + @Excel(name = "继续教育") + private BigDecimal adultEducation; + + /** 大病医疗 */ + @Excel(name = "大病医疗") + private BigDecimal treatmentForSeriousDisease; + + /** 本年累计专项附加扣除 */ + @Excel(name = "本年累计专项附加扣除") + private BigDecimal specialDeduction; + + /** 本年累计已发工资 */ + @Excel(name = "本年累计已发工资") + private BigDecimal totalWages; + + /** 本年累计已缴个税 */ + @Excel(name = "本年累计已缴个税") + private BigDecimal aggregatePersonalIncomeTax; + + /** 备注 */ + @Excel(name = "备注") + private String remarks; + private BigDecimal OverWages; //加班工资 + private BigDecimal absenteeismSalary; //请假扣款 + private BigDecimal absenteeismSubsidies; //补助扣除 + + /** 删除标识 */ + private String delFlag; + + public BigDecimal getMiddleSubsidies() { + return middleSubsidies; + } + + public void setMiddleSubsidies(BigDecimal middleSubsidies) { + this.middleSubsidies = middleSubsidies; + } + + public BigDecimal getCountInsurance() { + return countInsurance; + } + + public void setCountInsurance(BigDecimal countInsurance) { + this.countInsurance = countInsurance; + } + + public BigDecimal getAbsenteeismSubsidies() { + return absenteeismSubsidies; + } + + public void setAbsenteeismSubsidies(BigDecimal absenteeismSubsidies) { + this.absenteeismSubsidies = absenteeismSubsidies; + } + + public BigDecimal getAbsenteeismSalary() { + return absenteeismSalary; + } + + public void setAbsenteeismSalary(BigDecimal absenteeismSalary) { + this.absenteeismSalary = absenteeismSalary; + } + + public BigDecimal getOverWages() { + return OverWages; + } + + public void setOverWages(BigDecimal overWages) { + OverWages = overWages; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setStaffId(Long staffId) + { + this.staffId = staffId; + } + + public Long getStaffId() + { + return staffId; + } + public void setBasicSalary(BigDecimal basicSalary) + { + this.basicSalary = basicSalary; + } + + public BigDecimal getBasicSalary() + { + return basicSalary; + } + public void setJobsSalary(BigDecimal jobsSalary) + { + this.jobsSalary = jobsSalary; + } + + public BigDecimal getJobsSalary() + { + return jobsSalary; + } + public void setDailyWage(BigDecimal dailyWage) + { + this.dailyWage = dailyWage; + } + + public BigDecimal getDailyWage() + { + return dailyWage; + } + public void setHoursSalary(BigDecimal hoursSalary) + { + this.hoursSalary = hoursSalary; + } + + public BigDecimal getHoursSalary() + { + return hoursSalary; + } + public void setFullFrequentlySubsidies(BigDecimal fullFrequentlySubsidies) + { + this.fullFrequentlySubsidies = fullFrequentlySubsidies; + } + + public BigDecimal getFullFrequentlySubsidies() + { + return fullFrequentlySubsidies; + } + public void setLevelOfEducationSubsidies(BigDecimal levelOfEducationSubsidies) + { + this.levelOfEducationSubsidies = levelOfEducationSubsidies; + } + + public BigDecimal getLevelOfEducationSubsidies() + { + return levelOfEducationSubsidies; + } + public void setContractSubsidies(BigDecimal contractSubsidies) + { + this.contractSubsidies = contractSubsidies; + } + + public BigDecimal getContractSubsidies() + { + return contractSubsidies; + } + public void setSenioritySubsidies(BigDecimal senioritySubsidies) + { + this.senioritySubsidies = senioritySubsidies; + } + + public BigDecimal getSenioritySubsidies() + { + return senioritySubsidies; + } + public void setSocialSecuritySubsidies(BigDecimal socialSecuritySubsidies) + { + this.socialSecuritySubsidies = socialSecuritySubsidies; + } + + public BigDecimal getSocialSecuritySubsidies() + { + return socialSecuritySubsidies; + } + public void setNightShiftSubsidies(BigDecimal nightShiftSubsidies) + { + this.nightShiftSubsidies = nightShiftSubsidies; + } + + public BigDecimal getNightShiftSubsidies() + { + return nightShiftSubsidies; + } + public void setDinnerSubsidies(BigDecimal dinnerSubsidies) + { + this.dinnerSubsidies = dinnerSubsidies; + } + + public BigDecimal getDinnerSubsidies() + { + return dinnerSubsidies; + } + public void setFixedAllowance(BigDecimal fixedAllowance) + { + this.fixedAllowance = fixedAllowance; + } + + public BigDecimal getFixedAllowance() + { + return fixedAllowance; + } + public void setOtherSubsidies(BigDecimal otherSubsidies) + { + this.otherSubsidies = otherSubsidies; + } + + public BigDecimal getOtherSubsidies() + { + return otherSubsidies; + } + public void setBreakfastExpend(BigDecimal breakfastExpend) + { + this.breakfastExpend = breakfastExpend; + } + + public BigDecimal getBreakfastExpend() + { + return breakfastExpend; + } + public void setLunchExpend(BigDecimal lunchExpend) + { + this.lunchExpend = lunchExpend; + } + + public BigDecimal getLunchExpend() + { + return lunchExpend; + } + public void setSupperExpend(BigDecimal supperExpend) + { + this.supperExpend = supperExpend; + } + + public BigDecimal getSupperExpend() + { + return supperExpend; + } + public void setSubsidyDeductMoney(BigDecimal subsidyDeductMoney) + { + this.subsidyDeductMoney = subsidyDeductMoney; + } + + public BigDecimal getSubsidyDeductMoney() + { + return subsidyDeductMoney; + } + public void setDeductions(BigDecimal deductions) + { + this.deductions = deductions; + } + + public BigDecimal getDeductions() + { + return deductions; + } + public void setEndowmentInsurance(BigDecimal endowmentInsurance) + { + this.endowmentInsurance = endowmentInsurance; + } + + public BigDecimal getEndowmentInsurance() + { + return endowmentInsurance; + } + public void setMedicalInsurance(BigDecimal medicalInsurance) + { + this.medicalInsurance = medicalInsurance; + } + + public BigDecimal getMedicalInsurance() + { + return medicalInsurance; + } + public void setEmploymentInjuryInsurance(BigDecimal employmentInjuryInsurance) + { + this.employmentInjuryInsurance = employmentInjuryInsurance; + } + + public BigDecimal getEmploymentInjuryInsurance() + { + return employmentInjuryInsurance; + } + public void setMaternityInsurance(BigDecimal maternityInsurance) + { + this.maternityInsurance = maternityInsurance; + } + + public BigDecimal getMaternityInsurance() + { + return maternityInsurance; + } + public void setUnemploymentInsurance(BigDecimal unemploymentInsurance) + { + this.unemploymentInsurance = unemploymentInsurance; + } + + public BigDecimal getUnemploymentInsurance() + { + return unemploymentInsurance; + } + public void setAccumulationFund(BigDecimal accumulationFund) + { + this.accumulationFund = accumulationFund; + } + + public BigDecimal getAccumulationFund() + { + return accumulationFund; + } + public void setChildrenEducation(BigDecimal childrenEducation) + { + this.childrenEducation = childrenEducation; + } + + public BigDecimal getChildrenEducation() + { + return childrenEducation; + } + public void setSupportTheOld(BigDecimal supportTheOld) + { + this.supportTheOld = supportTheOld; + } + + public BigDecimal getSupportTheOld() + { + return supportTheOld; + } + public void setHousingLoans(BigDecimal housingLoans) + { + this.housingLoans = housingLoans; + } + + public BigDecimal getHousingLoans() + { + return housingLoans; + } + public void setHousingRents(BigDecimal housingRents) + { + this.housingRents = housingRents; + } + + public BigDecimal getHousingRents() + { + return housingRents; + } + public void setAdultEducation(BigDecimal adultEducation) + { + this.adultEducation = adultEducation; + } + + public BigDecimal getAdultEducation() + { + return adultEducation; + } + public void setTreatmentForSeriousDisease(BigDecimal treatmentForSeriousDisease) + { + this.treatmentForSeriousDisease = treatmentForSeriousDisease; + } + + public BigDecimal getTreatmentForSeriousDisease() + { + return treatmentForSeriousDisease; + } + public void setSpecialDeduction(BigDecimal specialDeduction) + { + this.specialDeduction = specialDeduction; + } + + public BigDecimal getSpecialDeduction() + { + return specialDeduction; + } + public void setTotalWages(BigDecimal totalWages) + { + this.totalWages = totalWages; + } + + public BigDecimal getTotalWages() + { + return totalWages; + } + public void setAggregatePersonalIncomeTax(BigDecimal aggregatePersonalIncomeTax) + { + this.aggregatePersonalIncomeTax = aggregatePersonalIncomeTax; + } + + public BigDecimal getAggregatePersonalIncomeTax() + { + return aggregatePersonalIncomeTax; + } + public void setRemarks(String remarks) + { + this.remarks = remarks; + } + + public String getRemarks() + { + return remarks; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("staffId", getStaffId()) + .append("basicSalary", getBasicSalary()) + .append("jobsSalary", getJobsSalary()) + .append("dailyWage", getDailyWage()) + .append("hoursSalary", getHoursSalary()) + .append("fullFrequentlySubsidies", getFullFrequentlySubsidies()) + .append("levelOfEducationSubsidies", getLevelOfEducationSubsidies()) + .append("contractSubsidies", getContractSubsidies()) + .append("senioritySubsidies", getSenioritySubsidies()) + .append("socialSecuritySubsidies", getSocialSecuritySubsidies()) + .append("nightShiftSubsidies", getNightShiftSubsidies()) + .append("dinnerSubsidies", getDinnerSubsidies()) + .append("fixedAllowance", getFixedAllowance()) + .append("otherSubsidies", getOtherSubsidies()) + .append("breakfastExpend", getBreakfastExpend()) + .append("lunchExpend", getLunchExpend()) + .append("supperExpend", getSupperExpend()) + .append("subsidyDeductMoney", getSubsidyDeductMoney()) + .append("deductions", getDeductions()) + .append("endowmentInsurance", getEndowmentInsurance()) + .append("medicalInsurance", getMedicalInsurance()) + .append("employmentInjuryInsurance", getEmploymentInjuryInsurance()) + .append("maternityInsurance", getMaternityInsurance()) + .append("unemploymentInsurance", getUnemploymentInsurance()) + .append("accumulationFund", getAccumulationFund()) + .append("childrenEducation", getChildrenEducation()) + .append("supportTheOld", getSupportTheOld()) + .append("housingLoans", getHousingLoans()) + .append("housingRents", getHousingRents()) + .append("adultEducation", getAdultEducation()) + .append("treatmentForSeriousDisease", getTreatmentForSeriousDisease()) + .append("specialDeduction", getSpecialDeduction()) + .append("totalWages", getTotalWages()) + .append("aggregatePersonalIncomeTax", getAggregatePersonalIncomeTax()) + .append("remarks", getRemarks()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/evo-admin/src/main/java/com/evo/system/domain/SysUserOnline.java b/evo-admin/src/main/java/com/evo/system/domain/SysUserOnline.java new file mode 100644 index 0000000..38a019b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/domain/SysUserOnline.java @@ -0,0 +1,113 @@ +package com.evo.system.domain; + +/** + * 当前在线会话 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/domain/SysUserRole.java b/evo-admin/src/main/java/com/evo/system/domain/SysUserRole.java new file mode 100644 index 0000000..0dfd62c --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/domain/SysUserRole.java @@ -0,0 +1,46 @@ +package com.evo.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 用户和角色关联 sys_user_role + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/domain/vo/MetaVo.java b/evo-admin/src/main/java/com/evo/system/domain/vo/MetaVo.java new file mode 100644 index 0000000..45bb0d1 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/domain/vo/MetaVo.java @@ -0,0 +1,106 @@ +package com.evo.system.domain.vo; + +import com.evo.common.utils.StringUtils; + +/** + * 路由显示信息 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/domain/vo/RouterVo.java b/evo-admin/src/main/java/com/evo/system/domain/vo/RouterVo.java new file mode 100644 index 0000000..dafec1c --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/domain/vo/RouterVo.java @@ -0,0 +1,148 @@ +package com.evo.system.domain.vo; + +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.List; + +/** + * 路由配置信息 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/system/domain/vo/SysStaffVo.java b/evo-admin/src/main/java/com/evo/system/domain/vo/SysStaffVo.java new file mode 100644 index 0000000..2568290 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/domain/vo/SysStaffVo.java @@ -0,0 +1,769 @@ +package com.evo.system.domain.vo; + +import com.evo.common.annotation.Excel; +import com.fasterxml.jackson.annotation.JsonFormat; +import java.math.BigDecimal; +import java.util.Date; + +public class SysStaffVo { + @Excel(name = "* 部门") + private String deptName; + /** 编号 */ + @Excel(name = "编号") + private String code; + /** 姓名 */ + @Excel(name = "* 姓名") + private String name; + /** 身份证号 */ + @Excel(name = "* 身份证号") + private String idCard; + /** 性别 */ + @Excel(name = "性别") + private String sex; + /** 年龄 */ + @Excel(name = "年龄") + private Long age; + /** 电话 */ + @Excel(name = "电话") + private String phone; + /** 住址 */ + @Excel(name = "住址") + private String address; + /** 学历 */ + @Excel(name = "* 学历") + private String level; + /** 专业 */ + @Excel(name = "专业") + private String major; + /** 毕业学校 */ + @Excel(name = "毕业学校") + private String school; + /** 银行卡号 */ + @Excel(name = "银行卡号") + private String bankNumber; + /** 开户行 */ + @Excel(name = "开户行") + private String bank; + /** 入职时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = " * 入职时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date employmentDate; + /** 全额工资时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "全额工资时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date wagesRatioDate; + /** 履历 */ + @Excel(name = "履历") + private String experience; + /** 试用期限 */ + @Excel(name = "试用期限") + private Long workerTerm; + /** 转正日期 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "转正日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date regularDate; + /** 离职时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "离职时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date quitDate; + /** 合同-起 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "合同-起", width = 30, dateFormat = "yyyy-MM-dd") + private Date contractStart; + /** 合同-止 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "合同-止", width = 30, dateFormat = "yyyy-MM-dd") + private Date contractEnd; + /** 合同类型 */ + @Excel(name = "* 合同期限") + private String contractType; + @Excel(name = "* 是否新农合") + private String socialSubsidy; + /** 社保 */ + @Excel(name = "* 社保") + private String socialType; + /** 工龄 */ + @Excel(name = "工龄") + private Long seniority; + + /** 是否有加班费 */ + @Excel(name = "* 加班费") + private String isOvertimePay; + /** 住宿标识 */ + @Excel(name = "* 住宿") + private String zsFlag; + /** 保密合同 */ + @Excel(name = "保密合同") + private String secrecy; + /** 工伤 */ + @Excel(name = "工伤") + private String injury; + /** 雇主险 */ + @Excel(name = "雇主险") + private String insurance; + /** 介绍人 */ + @Excel(name = "介绍人") + private String introducer; + /** 是否打卡 */ + @Excel(name = "* 打卡") + private String clockIn; + /** 在职状态 */ + @Excel(name = "在职状态") + private String status; + @Excel(name = "* 公司") + private String companyName; + @Excel(name = "基本工资") + private BigDecimal basicSalary; + /** 岗位工资 */ + @Excel(name = "岗位工资") + private BigDecimal jobsSalary; + /** 日薪 */ + @Excel(name = "日薪") + private BigDecimal dailyWage; + /** 时薪 */ + @Excel(name = "时薪") + private BigDecimal hoursSalary; + /** 全勤奖 */ + @Excel(name = "全勤奖") + private BigDecimal fullFrequentlySubsidies; + /** 学历补助 */ + @Excel(name = "学历补助") + private BigDecimal levelOfEducationSubsidies; + /** 合同补助 */ + @Excel(name = "合同补助") + private BigDecimal contractSubsidies; + /** 工龄补助 */ + @Excel(name = "工龄补助") + private BigDecimal senioritySubsidies; + /** 社保补助 */ + @Excel(name = "社保补助") + private BigDecimal socialSecuritySubsidies; + + @Excel(name = "中班补助") + private BigDecimal middleSubsidies; + /** 夜班补助 */ + @Excel(name = "夜班补助") + private BigDecimal nightShiftSubsidies; + /** 夜餐补助 */ + @Excel(name = "夜餐补助") + private BigDecimal dinnerSubsidies; + /** 固定补助 */ + @Excel(name = "固定补助") + private BigDecimal fixedAllowance; + /** 其他补助 */ + @Excel(name = "其他补助") + private BigDecimal otherSubsidies; + /** 早餐消费 */ + @Excel(name = "早餐消费") + private BigDecimal breakfastExpend; + /** 午餐消费 */ + @Excel(name = "午餐消费") + private BigDecimal lunchExpend; + /** 晚餐消费 */ + @Excel(name = "晚餐消费") + private BigDecimal supperExpend; + /** 离职扣款 */ + @Excel(name = "离职扣款") + private BigDecimal subsidyDeductMoney; + /** 其他扣款 */ + @Excel(name = "其他扣款") + private BigDecimal deductions; + /** 养老保险 */ + @Excel(name = "养老保险") + private BigDecimal endowmentInsurance; + /** 医疗保险 */ + @Excel(name = "医疗保险") + private BigDecimal medicalInsurance; + /** 工伤保险 */ + @Excel(name = "工伤保险") + private BigDecimal employmentInjuryInsurance; + /** 生育保险 */ + @Excel(name = "生育保险") + private BigDecimal maternityInsurance; + /** 失业保险 */ + @Excel(name = "失业保险") + private BigDecimal unemploymentInsurance; + /** 公积金 */ + @Excel(name = "公积金") + private BigDecimal accumulationFund; + /** 子女教育 */ + @Excel(name = "子女教育") + private BigDecimal childrenEducation; + /** 赡养老人 */ + @Excel(name = "赡养老人") + private BigDecimal supportTheOld; + /** 住房贷款 */ + @Excel(name = "住房贷款") + private BigDecimal housingLoans; + /** 住房租金 */ + @Excel(name = "住房租金") + private BigDecimal housingRents; + /** 继续教育 */ + @Excel(name = "继续教育") + private BigDecimal adultEducation; + /** 大病医疗 */ + @Excel(name = "大病医疗") + private BigDecimal treatmentForSeriousDisease; + /** 本年累计专项附加扣除 */ + @Excel(name = "本年累计专项附加扣除") + private BigDecimal specialDeduction; + /** 本年累计已发工资 */ + @Excel(name = "本年累计已发工资") + private BigDecimal totalWages; + /** 本年累计已缴个税 */ + @Excel(name = "本年累计已缴个税") + private BigDecimal aggregatePersonalIncomeTax; + /** 备注 */ + @Excel(name = "备注") + private String remarks; + + public String getSocialSubsidy() { + return socialSubsidy; + } + + public void setSocialSubsidy(String socialSubsidy) { + this.socialSubsidy = socialSubsidy; + } + + public BigDecimal getMiddleSubsidies() { + return middleSubsidies; + } + + public void setMiddleSubsidies(BigDecimal middleSubsidies) { + this.middleSubsidies = middleSubsidies; + } + + public String getCompanyName() { + return companyName; + } + + public void setCompanyName(String companyName) { + this.companyName = companyName; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getIdCard() { + return idCard; + } + + public void setIdCard(String idCard) { + this.idCard = idCard; + } + + public String getSex() { + return sex; + } + + public void setSex(String sex) { + this.sex = sex; + } + + public Long getAge() { + return age; + } + + public void setAge(Long age) { + this.age = age; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getLevel() { + return level; + } + + public void setLevel(String level) { + this.level = level; + } + + public String getMajor() { + return major; + } + + public void setMajor(String major) { + this.major = major; + } + + public String getSchool() { + return school; + } + + public void setSchool(String school) { + this.school = school; + } + + public String getBankNumber() { + return bankNumber; + } + + public void setBankNumber(String bankNumber) { + this.bankNumber = bankNumber; + } + + public String getBank() { + return bank; + } + + public void setBank(String bank) { + this.bank = bank; + } + + public Date getEmploymentDate() { + return employmentDate; + } + + public void setEmploymentDate(Date employmentDate) { + this.employmentDate = employmentDate; + } + + public Date getWagesRatioDate() { + return wagesRatioDate; + } + + public void setWagesRatioDate(Date wagesRatioDate) { + this.wagesRatioDate = wagesRatioDate; + } + + public String getExperience() { + return experience; + } + + public void setExperience(String experience) { + this.experience = experience; + } + + public Long getWorkerTerm() { + return workerTerm; + } + + public void setWorkerTerm(Long workerTerm) { + this.workerTerm = workerTerm; + } + + public Date getRegularDate() { + return regularDate; + } + + public void setRegularDate(Date regularDate) { + this.regularDate = regularDate; + } + + public Date getQuitDate() { + return quitDate; + } + + public void setQuitDate(Date quitDate) { + this.quitDate = quitDate; + } + + public Date getContractStart() { + return contractStart; + } + + public void setContractStart(Date contractStart) { + this.contractStart = contractStart; + } + + public Date getContractEnd() { + return contractEnd; + } + + public void setContractEnd(Date contractEnd) { + this.contractEnd = contractEnd; + } + + public String getContractType() { + return contractType; + } + + public void setContractType(String contractType) { + this.contractType = contractType; + } + + public String getSocialType() { + return socialType; + } + + public void setSocialType(String socialType) { + this.socialType = socialType; + } + + public Long getSeniority() { + return seniority; + } + + public void setSeniority(Long seniority) { + this.seniority = seniority; + } + + public String getIsOvertimePay() { + return isOvertimePay; + } + + public void setIsOvertimePay(String isOvertimePay) { + this.isOvertimePay = isOvertimePay; + } + + public String getZsFlag() { + return zsFlag; + } + + public void setZsFlag(String zsFlag) { + this.zsFlag = zsFlag; + } + + public String getSecrecy() { + return secrecy; + } + + public void setSecrecy(String secrecy) { + this.secrecy = secrecy; + } + + public String getInjury() { + return injury; + } + + public void setInjury(String injury) { + this.injury = injury; + } + + public String getInsurance() { + return insurance; + } + + public void setInsurance(String insurance) { + this.insurance = insurance; + } + + public String getIntroducer() { + return introducer; + } + + public void setIntroducer(String introducer) { + this.introducer = introducer; + } + + public String getClockIn() { + return clockIn; + } + + public void setClockIn(String clockIn) { + this.clockIn = clockIn; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public BigDecimal getBasicSalary() { + return basicSalary; + } + + public void setBasicSalary(BigDecimal basicSalary) { + this.basicSalary = basicSalary; + } + + public BigDecimal getJobsSalary() { + return jobsSalary; + } + + public void setJobsSalary(BigDecimal jobsSalary) { + this.jobsSalary = jobsSalary; + } + + public BigDecimal getDailyWage() { + return dailyWage; + } + + public void setDailyWage(BigDecimal dailyWage) { + this.dailyWage = dailyWage; + } + + public BigDecimal getHoursSalary() { + return hoursSalary; + } + + public void setHoursSalary(BigDecimal hoursSalary) { + this.hoursSalary = hoursSalary; + } + + public BigDecimal getFullFrequentlySubsidies() { + return fullFrequentlySubsidies; + } + + public void setFullFrequentlySubsidies(BigDecimal fullFrequentlySubsidies) { + this.fullFrequentlySubsidies = fullFrequentlySubsidies; + } + + public BigDecimal getLevelOfEducationSubsidies() { + return levelOfEducationSubsidies; + } + + public void setLevelOfEducationSubsidies(BigDecimal levelOfEducationSubsidies) { + this.levelOfEducationSubsidies = levelOfEducationSubsidies; + } + + public BigDecimal getContractSubsidies() { + return contractSubsidies; + } + + public void setContractSubsidies(BigDecimal contractSubsidies) { + this.contractSubsidies = contractSubsidies; + } + + public BigDecimal getSenioritySubsidies() { + return senioritySubsidies; + } + + public void setSenioritySubsidies(BigDecimal senioritySubsidies) { + this.senioritySubsidies = senioritySubsidies; + } + + public BigDecimal getSocialSecuritySubsidies() { + return socialSecuritySubsidies; + } + + public void setSocialSecuritySubsidies(BigDecimal socialSecuritySubsidies) { + this.socialSecuritySubsidies = socialSecuritySubsidies; + } + + public BigDecimal getNightShiftSubsidies() { + return nightShiftSubsidies; + } + + public void setNightShiftSubsidies(BigDecimal nightShiftSubsidies) { + this.nightShiftSubsidies = nightShiftSubsidies; + } + + public BigDecimal getDinnerSubsidies() { + return dinnerSubsidies; + } + + public void setDinnerSubsidies(BigDecimal dinnerSubsidies) { + this.dinnerSubsidies = dinnerSubsidies; + } + + public BigDecimal getFixedAllowance() { + return fixedAllowance; + } + + public void setFixedAllowance(BigDecimal fixedAllowance) { + this.fixedAllowance = fixedAllowance; + } + + public BigDecimal getOtherSubsidies() { + return otherSubsidies; + } + + public void setOtherSubsidies(BigDecimal otherSubsidies) { + this.otherSubsidies = otherSubsidies; + } + + public BigDecimal getBreakfastExpend() { + return breakfastExpend; + } + + public void setBreakfastExpend(BigDecimal breakfastExpend) { + this.breakfastExpend = breakfastExpend; + } + + public BigDecimal getLunchExpend() { + return lunchExpend; + } + + public void setLunchExpend(BigDecimal lunchExpend) { + this.lunchExpend = lunchExpend; + } + + public BigDecimal getSupperExpend() { + return supperExpend; + } + + public void setSupperExpend(BigDecimal supperExpend) { + this.supperExpend = supperExpend; + } + + public BigDecimal getSubsidyDeductMoney() { + return subsidyDeductMoney; + } + + public void setSubsidyDeductMoney(BigDecimal subsidyDeductMoney) { + this.subsidyDeductMoney = subsidyDeductMoney; + } + + public BigDecimal getDeductions() { + return deductions; + } + + public void setDeductions(BigDecimal deductions) { + this.deductions = deductions; + } + + public BigDecimal getEndowmentInsurance() { + return endowmentInsurance; + } + + public void setEndowmentInsurance(BigDecimal endowmentInsurance) { + this.endowmentInsurance = endowmentInsurance; + } + + public BigDecimal getMedicalInsurance() { + return medicalInsurance; + } + + public void setMedicalInsurance(BigDecimal medicalInsurance) { + this.medicalInsurance = medicalInsurance; + } + + public BigDecimal getEmploymentInjuryInsurance() { + return employmentInjuryInsurance; + } + + public void setEmploymentInjuryInsurance(BigDecimal employmentInjuryInsurance) { + this.employmentInjuryInsurance = employmentInjuryInsurance; + } + + public BigDecimal getMaternityInsurance() { + return maternityInsurance; + } + + public void setMaternityInsurance(BigDecimal maternityInsurance) { + this.maternityInsurance = maternityInsurance; + } + + public BigDecimal getUnemploymentInsurance() { + return unemploymentInsurance; + } + + public void setUnemploymentInsurance(BigDecimal unemploymentInsurance) { + this.unemploymentInsurance = unemploymentInsurance; + } + + public BigDecimal getAccumulationFund() { + return accumulationFund; + } + + public void setAccumulationFund(BigDecimal accumulationFund) { + this.accumulationFund = accumulationFund; + } + + public BigDecimal getChildrenEducation() { + return childrenEducation; + } + + public void setChildrenEducation(BigDecimal childrenEducation) { + this.childrenEducation = childrenEducation; + } + + public BigDecimal getSupportTheOld() { + return supportTheOld; + } + + public void setSupportTheOld(BigDecimal supportTheOld) { + this.supportTheOld = supportTheOld; + } + + public BigDecimal getHousingLoans() { + return housingLoans; + } + + public void setHousingLoans(BigDecimal housingLoans) { + this.housingLoans = housingLoans; + } + + public BigDecimal getHousingRents() { + return housingRents; + } + + public void setHousingRents(BigDecimal housingRents) { + this.housingRents = housingRents; + } + + public BigDecimal getAdultEducation() { + return adultEducation; + } + + public void setAdultEducation(BigDecimal adultEducation) { + this.adultEducation = adultEducation; + } + + public BigDecimal getTreatmentForSeriousDisease() { + return treatmentForSeriousDisease; + } + + public void setTreatmentForSeriousDisease(BigDecimal treatmentForSeriousDisease) { + this.treatmentForSeriousDisease = treatmentForSeriousDisease; + } + + public BigDecimal getSpecialDeduction() { + return specialDeduction; + } + + public void setSpecialDeduction(BigDecimal specialDeduction) { + this.specialDeduction = specialDeduction; + } + + public BigDecimal getTotalWages() { + return totalWages; + } + + public void setTotalWages(BigDecimal totalWages) { + this.totalWages = totalWages; + } + public BigDecimal getAggregatePersonalIncomeTax() { + return aggregatePersonalIncomeTax; + } + + public void setAggregatePersonalIncomeTax(BigDecimal aggregatePersonalIncomeTax) { + this.aggregatePersonalIncomeTax = aggregatePersonalIncomeTax; + } + public String getRemarks() { + return remarks; + } + + public void setRemarks(String remarks) { + this.remarks = remarks; + } +} diff --git a/evo-admin/src/main/java/com/evo/system/mapper/SysDeptMapper.java b/evo-admin/src/main/java/com/evo/system/mapper/SysDeptMapper.java new file mode 100644 index 0000000..cc8194b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/mapper/SysDeptMapper.java @@ -0,0 +1,130 @@ +package com.evo.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.evo.common.core.domain.entity.SysDept; + +/** + * 部门管理 数据层 + * + * @author evo + */ +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); + /** + * 查询部门树 + * @return + */ + public List queryDeptTreeList(); + + /** + * 查询所有的公司 + * @return + */ + public List queryAllDeptForMin(); + /** + * 递归查询所有子集 + * @param deptId + * @return + */ + public List queryDeptsByDeptId(Long deptId); + /** + * 修改部门领导信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int updateDeptForLeader(SysDept dept); +} diff --git a/evo-admin/src/main/java/com/evo/system/mapper/SysDictDataMapper.java b/evo-admin/src/main/java/com/evo/system/mapper/SysDictDataMapper.java new file mode 100644 index 0000000..23023ee --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/mapper/SysDictDataMapper.java @@ -0,0 +1,95 @@ +package com.evo.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.evo.common.core.domain.entity.SysDictData; + +/** + * 字典表 数据层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/mapper/SysDictTypeMapper.java b/evo-admin/src/main/java/com/evo/system/mapper/SysDictTypeMapper.java new file mode 100644 index 0000000..ecf6601 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/mapper/SysDictTypeMapper.java @@ -0,0 +1,83 @@ +package com.evo.system.mapper; + +import java.util.List; +import com.evo.common.core.domain.entity.SysDictType; + +/** + * 字典表 数据层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/mapper/SysLogininforMapper.java b/evo-admin/src/main/java/com/evo/system/mapper/SysLogininforMapper.java new file mode 100644 index 0000000..9b23326 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/mapper/SysLogininforMapper.java @@ -0,0 +1,42 @@ +package com.evo.system.mapper; + +import java.util.List; +import com.evo.system.domain.SysLogininfor; + +/** + * 系统访问日志情况信息 数据层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/mapper/SysMenuMapper.java b/evo-admin/src/main/java/com/evo/system/mapper/SysMenuMapper.java new file mode 100644 index 0000000..7bf6381 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/mapper/SysMenuMapper.java @@ -0,0 +1,125 @@ +package com.evo.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.evo.common.core.domain.entity.SysMenu; + +/** + * 菜单表 数据层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/mapper/SysOperLogMapper.java b/evo-admin/src/main/java/com/evo/system/mapper/SysOperLogMapper.java new file mode 100644 index 0000000..61a333f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/mapper/SysOperLogMapper.java @@ -0,0 +1,48 @@ +package com.evo.system.mapper; + +import java.util.List; +import com.evo.system.domain.SysOperLog; + +/** + * 操作日志 数据层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/mapper/SysRoleDeptMapper.java b/evo-admin/src/main/java/com/evo/system/mapper/SysRoleDeptMapper.java new file mode 100644 index 0000000..6bf52cb --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/mapper/SysRoleDeptMapper.java @@ -0,0 +1,44 @@ +package com.evo.system.mapper; + +import java.util.List; +import com.evo.system.domain.SysRoleDept; + +/** + * 角色与部门关联表 数据层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/mapper/SysRoleMapper.java b/evo-admin/src/main/java/com/evo/system/mapper/SysRoleMapper.java new file mode 100644 index 0000000..fe4e17b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/mapper/SysRoleMapper.java @@ -0,0 +1,107 @@ +package com.evo.system.mapper; + +import java.util.List; +import com.evo.common.core.domain.entity.SysRole; + +/** + * 角色表 数据层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/mapper/SysRoleMenuMapper.java b/evo-admin/src/main/java/com/evo/system/mapper/SysRoleMenuMapper.java new file mode 100644 index 0000000..8fe202d --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/mapper/SysRoleMenuMapper.java @@ -0,0 +1,44 @@ +package com.evo.system.mapper; + +import java.util.List; +import com.evo.system.domain.SysRoleMenu; + +/** + * 角色与菜单关联表 数据层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/mapper/SysStaffDetailMapper.java b/evo-admin/src/main/java/com/evo/system/mapper/SysStaffDetailMapper.java new file mode 100644 index 0000000..8e2e3ef --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/mapper/SysStaffDetailMapper.java @@ -0,0 +1,56 @@ +package com.evo.system.mapper; + +import com.evo.system.domain.SysStaffDetail; + +import java.util.List; + +/** + * 员工详情Mapper接口 + * + * @author evo + * @date 2024-11-22 + */ +public interface SysStaffDetailMapper +{ + /** + * 查询员工详情 + * + * @param id 员工详情主键 + * @return 员工详情 + */ + public SysStaffDetail selectSysStaffDetailById(Long id); + + /** + * 查询员工详情列表 + * + * @param sysStaffDetail 员工详情 + * @return 员工详情集合 + */ + public List selectSysStaffDetailList(SysStaffDetail sysStaffDetail); + + /** + * 新增员工详情 + * + * @param sysStaffDetail 员工详情 + * @return 结果 + */ + public int insertSysStaffDetail(SysStaffDetail sysStaffDetail); + + /** + * 修改员工详情 + * + * @param sysStaffDetail 员工详情 + * @return 结果 + */ + public int updateSysStaffDetail(SysStaffDetail sysStaffDetail); + /** + * 根据员工ID查询员工详情 + * + * @param staffId 员工ID + * @return 员工详情 + */ + public SysStaffDetail selectSysStaffDetailByStaffId(Long staffId); + + public int clearAllSubsidy(); + +} diff --git a/evo-admin/src/main/java/com/evo/system/mapper/SysStaffMapper.java b/evo-admin/src/main/java/com/evo/system/mapper/SysStaffMapper.java new file mode 100644 index 0000000..96b0af1 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/mapper/SysStaffMapper.java @@ -0,0 +1,84 @@ +package com.evo.system.mapper; + +import com.evo.system.domain.SysStaff; +import org.apache.ibatis.annotations.Param; + +import java.util.Date; +import java.util.List; + +/** + * 员工管理Mapper接口 + * + * @author evo + * @date 2024-11-21 + */ +public interface SysStaffMapper +{ + /** + * 查询员工管理 + * + * @param userId 员工管理主键 + * @return 员工管理 + */ + public SysStaff selectSysStaffByUserId(Long userId); + + /** + * 查询员工管理列表 + * + * @param sysStaff 员工管理 + * @return 员工管理集合 + */ + public List selectSysStaffList(SysStaff sysStaff); + + /** + * 新增员工管理 + * + * @param sysStaff 员工管理 + * @return 结果 + */ + public int insertSysStaff(SysStaff sysStaff); + /** + * 修改员工管理 + * + * @param sysStaff 员工管理 + * @return 结果 + */ + public int updateSysStaff(SysStaff sysStaff); + /** + * 查询所有的在职员工信息 + * @return + */ + public List selectSysStaffListAll(); + /** + * 根据身份证号查询员工信息 + * @param idCard + * @return + */ + public SysStaff queryysStaffByIdCard(String idCard); + /** + * 根据身份证号和部门查询员工信息 + * @param idCard + * @return + */ + public SysStaff queryysStaffByIdCardAndDeptId(@Param("idCard") String idCard,@Param("deptId") Long deptId); + /** + * 根据公司查询编号 + * @param compayName + * @return + */ + public SysStaff querySysStaffOfMaxByCompany(String compayName); + /** + * 根据月份查询需要统计工资的人员信息 + * @param emplDate 入职时间 + * @param quitDate 离职时间 + * @return + */ + public List querySysStaffListOfMonth(@Param("emplDate") Date emplDate, @Param("quitDate")Date quitDate); + /** + * 根据部门查询员工信息 + * @param list + * @return + */ + public List queryysStaffByDeptId(List list); + +} diff --git a/evo-admin/src/main/java/com/evo/system/mapper/SysUserMapper.java b/evo-admin/src/main/java/com/evo/system/mapper/SysUserMapper.java new file mode 100644 index 0000000..1fd0195 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/mapper/SysUserMapper.java @@ -0,0 +1,127 @@ +package com.evo.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.evo.common.core.domain.entity.SysUser; + +/** + * 用户表 数据层 + * + * @author evo + */ +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); + + /** + * 通过用户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/evo-admin/src/main/java/com/evo/system/mapper/SysUserRoleMapper.java b/evo-admin/src/main/java/com/evo/system/mapper/SysUserRoleMapper.java new file mode 100644 index 0000000..95bf561 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/mapper/SysUserRoleMapper.java @@ -0,0 +1,62 @@ +package com.evo.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.evo.system.domain.SysUserRole; + +/** + * 用户与角色关联表 数据层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/service/ISysDeptService.java b/evo-admin/src/main/java/com/evo/system/service/ISysDeptService.java new file mode 100644 index 0000000..d35cb84 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/ISysDeptService.java @@ -0,0 +1,135 @@ +package com.evo.system.service; + +import java.util.List; +import com.evo.common.core.domain.TreeSelect; +import com.evo.common.core.domain.entity.SysDept; + +/** + * 部门管理 服务层 + * + * @author evo + */ +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); + + /** + * 查询所有的有效部门 + * @return + */ + public List selectAllDeptList(); + /** + * 查询所有的公司 + * @return + */ + public List queryAllDeptForMin(); +} diff --git a/evo-admin/src/main/java/com/evo/system/service/ISysDictDataService.java b/evo-admin/src/main/java/com/evo/system/service/ISysDictDataService.java new file mode 100644 index 0000000..ec15b10 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/ISysDictDataService.java @@ -0,0 +1,60 @@ +package com.evo.system.service; + +import java.util.List; +import com.evo.common.core.domain.entity.SysDictData; + +/** + * 字典 业务层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/service/ISysDictTypeService.java b/evo-admin/src/main/java/com/evo/system/service/ISysDictTypeService.java new file mode 100644 index 0000000..2a3a90e --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/ISysDictTypeService.java @@ -0,0 +1,98 @@ +package com.evo.system.service; + +import java.util.List; +import com.evo.common.core.domain.entity.SysDictData; +import com.evo.common.core.domain.entity.SysDictType; + +/** + * 字典 业务层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/service/ISysLogininforService.java b/evo-admin/src/main/java/com/evo/system/service/ISysLogininforService.java new file mode 100644 index 0000000..1648a6f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/ISysLogininforService.java @@ -0,0 +1,40 @@ +package com.evo.system.service; + +import java.util.List; +import com.evo.system.domain.SysLogininfor; + +/** + * 系统访问日志情况信息 服务层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/service/ISysMenuService.java b/evo-admin/src/main/java/com/evo/system/service/ISysMenuService.java new file mode 100644 index 0000000..73f9118 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/ISysMenuService.java @@ -0,0 +1,144 @@ +package com.evo.system.service; + +import java.util.List; +import java.util.Set; +import com.evo.common.core.domain.TreeSelect; +import com.evo.common.core.domain.entity.SysMenu; +import com.evo.system.domain.vo.RouterVo; + +/** + * 菜单 业务层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/service/ISysOperLogService.java b/evo-admin/src/main/java/com/evo/system/service/ISysOperLogService.java new file mode 100644 index 0000000..5632f8f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/ISysOperLogService.java @@ -0,0 +1,48 @@ +package com.evo.system.service; + +import java.util.List; +import com.evo.system.domain.SysOperLog; + +/** + * 操作日志 服务层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/service/ISysRoleService.java b/evo-admin/src/main/java/com/evo/system/service/ISysRoleService.java new file mode 100644 index 0000000..0522e26 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/ISysRoleService.java @@ -0,0 +1,173 @@ +package com.evo.system.service; + +import java.util.List; +import java.util.Set; +import com.evo.common.core.domain.entity.SysRole; +import com.evo.system.domain.SysUserRole; + +/** + * 角色业务层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/service/ISysStaffDetailService.java b/evo-admin/src/main/java/com/evo/system/service/ISysStaffDetailService.java new file mode 100644 index 0000000..e644749 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/ISysStaffDetailService.java @@ -0,0 +1,45 @@ +package com.evo.system.service; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.system.domain.SysStaffDetail; +import java.util.List; + +/** + * 员工详情Service接口 + * + * @author evo + * @date 2024-11-22 + */ +public interface ISysStaffDetailService +{ + /** + * 查询员工详情 + * + * @param id 员工详情主键 + * @return 员工详情 + */ + public SysStaffDetail selectSysStaffDetailById(Long id); + + /** + * 查询员工详情列表 + * + * @param sysStaffDetail 员工详情 + * @return 员工详情集合 + */ + public List selectSysStaffDetailList(SysStaffDetail sysStaffDetail); + + /** + * 修改员工详情 + * + * @param sysStaffDetail 员工详情 + * @return 结果 + */ + public int updateSysStaffDetail(SysStaffDetail sysStaffDetail); + + /** + * 清理补助 + * @return + */ + public AjaxResult clearAllSubsidy(); + +} diff --git a/evo-admin/src/main/java/com/evo/system/service/ISysStaffService.java b/evo-admin/src/main/java/com/evo/system/service/ISysStaffService.java new file mode 100644 index 0000000..fa503f8 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/ISysStaffService.java @@ -0,0 +1,95 @@ +package com.evo.system.service; + +import com.evo.common.core.domain.AjaxResult; +import com.evo.system.domain.SysStaff; +import com.evo.system.domain.vo.SysStaffVo; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + * 员工管理Service接口 + * + * @author evo + * @date 2024-11-21 + */ +public interface ISysStaffService +{ + /** + * 查询员工管理 + * + * @param userId 员工管理主键 + * @return 员工管理 + */ + public SysStaff selectSysStaffByUserId(Long userId); + /** + * 查询员工管理列表 + * + * @param sysStaff 员工管理 + * @return 员工管理集合 + */ + public List selectSysStaffList(SysStaff sysStaff); + /** + * 新增员工管理 + * + * @param sysStaff 员工管理 + * @return 结果 + */ + public AjaxResult insertSysStaff(SysStaff sysStaff); + /** + * 修改员工管理 + * + * @param sysStaff 员工管理 + * @return 结果 + */ + public AjaxResult updateSysStaff(SysStaff sysStaff); + /** + * 删除员工管理信息 + * + * @param userId 员工管理主键 + * @return 结果 + */ + public int deleteSysStaffByUserId(Long userId); + /** + * 查询所有的在职员工信息 + * @return + */ + public List selectSysStaffListAll(); + /** + * 上传五险一金 + * @param filePath + * @return + */ + public AjaxResult uploadAccumulationFund(MultipartFile filePath); + /** + * 查询所有的在职员工信息 + * @return + */ + public List selectSysStaffDetailList(SysStaff sysStaff); + /** + * 导入员工数据 + * + * @param staffList 用户数据列表 + * @return 结果 + */ + public AjaxResult importStaff(List staffList); + /** + * 每月1号自动生成考勤信息 + */ + public void autoCreateAttendanceData(); + /** + * 每天计算转正,离职日期 + */ + public void autoRegularWorking(); + /** + * 根据部门查询员工信息 + * @param deptId + * @return + */ + public List queryysStaffByDeptId(Long deptId); + + /** + * 自动计算工龄 + */ + public void calculationOfSeniority(); +} diff --git a/evo-admin/src/main/java/com/evo/system/service/ISysUserOnlineService.java b/evo-admin/src/main/java/com/evo/system/service/ISysUserOnlineService.java new file mode 100644 index 0000000..4357752 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/ISysUserOnlineService.java @@ -0,0 +1,48 @@ +package com.evo.system.service; + +import com.evo.common.core.domain.model.LoginUser; +import com.evo.system.domain.SysUserOnline; + +/** + * 在线用户 服务层 + * + * @author evo + */ +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/evo-admin/src/main/java/com/evo/system/service/ISysUserService.java b/evo-admin/src/main/java/com/evo/system/service/ISysUserService.java new file mode 100644 index 0000000..57cebec --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/ISysUserService.java @@ -0,0 +1,198 @@ +package com.evo.system.service; + +import java.util.List; +import com.evo.common.core.domain.entity.SysUser; + +/** + * 用户 业务层 + * + * @author evo + */ +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); + + /** + * 通过用户ID查询用户 + * + * @param userId 用户ID + * @return 用户对象信息 + */ + public SysUser selectUserById(Long userId); + + /** + * 根据用户ID查询用户所属角色组 + * + * @param userName 用户名 + * @return 结果 + */ + public String selectUserRoleGroup(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/evo-admin/src/main/java/com/evo/system/service/impl/SysDeptServiceImpl.java b/evo-admin/src/main/java/com/evo/system/service/impl/SysDeptServiceImpl.java new file mode 100644 index 0000000..a927296 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/impl/SysDeptServiceImpl.java @@ -0,0 +1,363 @@ +package com.evo.system.service.impl; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; +import org.springframework.stereotype.Service; +import com.evo.common.annotation.DataScope; +import com.evo.common.constant.UserConstants; +import com.evo.common.core.domain.TreeSelect; +import com.evo.common.core.domain.entity.SysDept; +import com.evo.common.core.domain.entity.SysRole; +import com.evo.common.core.domain.entity.SysUser; +import com.evo.common.core.text.Convert; +import com.evo.common.exception.ServiceException; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.spring.SpringUtils; +import com.evo.system.mapper.SysDeptMapper; +import com.evo.system.mapper.SysRoleMapper; +import com.evo.system.service.ISysDeptService; +import javax.annotation.Resource; + +/** + * 部门管理 服务实现 + * + * @author evo + */ +@Service +public class SysDeptServiceImpl implements ISysDeptService +{ + @Resource + private SysDeptMapper deptMapper; + + @Resource + 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(StringUtils.isNotNull(info)){ + // 如果父节点不为正常状态,则不允许新增子节点 + if (!UserConstants.DEPT_NORMAL.equals(info.getStatus())) + { + throw new ServiceException("部门停用,不允许新增"); + } + if(StringUtils.isNotEmpty(info.getAncestors())){ + dept.setAncestors(info.getAncestors() + "," + dept.getParentId()); + }else{ + dept.setAncestors(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; + } + + /** + * 查询所有的有效部门 + * @return + */ + @Override + public List selectAllDeptList(){ + List depts = deptMapper.queryDeptTreeList(); + return buildDeptTreeSelect(depts); + } + + /** + * 查询所有的公司 + * @return + */ + @Override + public List queryAllDeptForMin(){ + return deptMapper.queryAllDeptForMin(); + } +} diff --git a/evo-admin/src/main/java/com/evo/system/service/impl/SysDictDataServiceImpl.java b/evo-admin/src/main/java/com/evo/system/service/impl/SysDictDataServiceImpl.java new file mode 100644 index 0000000..d6e4372 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/impl/SysDictDataServiceImpl.java @@ -0,0 +1,111 @@ +package com.evo.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.evo.common.core.domain.entity.SysDictData; +import com.evo.common.utils.DictUtils; +import com.evo.system.mapper.SysDictDataMapper; +import com.evo.system.service.ISysDictDataService; + +/** + * 字典 业务层处理 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/system/service/impl/SysDictTypeServiceImpl.java b/evo-admin/src/main/java/com/evo/system/service/impl/SysDictTypeServiceImpl.java new file mode 100644 index 0000000..050123c --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/impl/SysDictTypeServiceImpl.java @@ -0,0 +1,223 @@ +package com.evo.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.evo.common.constant.UserConstants; +import com.evo.common.core.domain.entity.SysDictData; +import com.evo.common.core.domain.entity.SysDictType; +import com.evo.common.exception.ServiceException; +import com.evo.common.utils.DictUtils; +import com.evo.common.utils.StringUtils; +import com.evo.system.mapper.SysDictDataMapper; +import com.evo.system.mapper.SysDictTypeMapper; +import com.evo.system.service.ISysDictTypeService; + +/** + * 字典 业务层处理 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/system/service/impl/SysLogininforServiceImpl.java b/evo-admin/src/main/java/com/evo/system/service/impl/SysLogininforServiceImpl.java new file mode 100644 index 0000000..8da5c1b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/impl/SysLogininforServiceImpl.java @@ -0,0 +1,65 @@ +package com.evo.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.evo.system.domain.SysLogininfor; +import com.evo.system.mapper.SysLogininforMapper; +import com.evo.system.service.ISysLogininforService; + +/** + * 系统访问日志情况信息 服务层处理 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/system/service/impl/SysMenuServiceImpl.java b/evo-admin/src/main/java/com/evo/system/service/impl/SysMenuServiceImpl.java new file mode 100644 index 0000000..272c63e --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/impl/SysMenuServiceImpl.java @@ -0,0 +1,543 @@ +package com.evo.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.evo.common.constant.Constants; +import com.evo.common.constant.UserConstants; +import com.evo.common.core.domain.TreeSelect; +import com.evo.common.core.domain.entity.SysMenu; +import com.evo.common.core.domain.entity.SysRole; +import com.evo.common.core.domain.entity.SysUser; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.system.domain.vo.MetaVo; +import com.evo.system.domain.vo.RouterVo; +import com.evo.system.mapper.SysMenuMapper; +import com.evo.system.mapper.SysRoleMapper; +import com.evo.system.mapper.SysRoleMenuMapper; +import com.evo.system.service.ISysMenuService; + +/** + * 菜单 业务层处理 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/system/service/impl/SysOperLogServiceImpl.java b/evo-admin/src/main/java/com/evo/system/service/impl/SysOperLogServiceImpl.java new file mode 100644 index 0000000..dd58eef --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/impl/SysOperLogServiceImpl.java @@ -0,0 +1,76 @@ +package com.evo.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.evo.system.domain.SysOperLog; +import com.evo.system.mapper.SysOperLogMapper; +import com.evo.system.service.ISysOperLogService; + +/** + * 操作日志 服务层处理 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/system/service/impl/SysRoleServiceImpl.java b/evo-admin/src/main/java/com/evo/system/service/impl/SysRoleServiceImpl.java new file mode 100644 index 0000000..4d439c5 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/impl/SysRoleServiceImpl.java @@ -0,0 +1,427 @@ +package com.evo.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.evo.common.annotation.DataScope; +import com.evo.common.constant.UserConstants; +import com.evo.common.core.domain.entity.SysRole; +import com.evo.common.core.domain.entity.SysUser; +import com.evo.common.exception.ServiceException; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.spring.SpringUtils; +import com.evo.system.domain.SysRoleDept; +import com.evo.system.domain.SysRoleMenu; +import com.evo.system.domain.SysUserRole; +import com.evo.system.mapper.SysRoleDeptMapper; +import com.evo.system.mapper.SysRoleMapper; +import com.evo.system.mapper.SysRoleMenuMapper; +import com.evo.system.mapper.SysUserRoleMapper; +import com.evo.system.service.ISysRoleService; + +/** + * 角色 业务层处理 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/system/service/impl/SysStaffDetailServiceImpl.java b/evo-admin/src/main/java/com/evo/system/service/impl/SysStaffDetailServiceImpl.java new file mode 100644 index 0000000..7e5b166 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/impl/SysStaffDetailServiceImpl.java @@ -0,0 +1,140 @@ +package com.evo.system.service.impl; + +import java.math.BigDecimal; +import java.util.List; +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.domain.entity.SysDictData; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.restaurant.domain.RzRestaurantStatistics; +import com.evo.restaurant.mapper.RzRestaurantStatisticsMapper; +import com.evo.system.domain.SysStaff; +import com.evo.system.domain.SysStaffDetail; +import com.evo.system.mapper.SysDictDataMapper; +import com.evo.system.mapper.SysStaffDetailMapper; +import com.evo.system.mapper.SysStaffMapper; +import com.evo.system.service.ISysStaffDetailService; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; + +/** + * 员工详情Service业务层处理 + * + * @author evo + * @date 2024-11-22 + */ +@Service +public class SysStaffDetailServiceImpl implements ISysStaffDetailService +{ + @Resource + private SysStaffDetailMapper sysStaffDetailMapper; + @Resource + private SysStaffMapper sysStaffMapper; //员工信息 + @Resource + private SysDictDataMapper sysDictDataMapper; //数据字典 + @Resource + private RzRestaurantStatisticsMapper rzRestaurantStatisticsMapper; //餐饮统计 + + /** + * 查询员工详情 + * + * @param id 员工详情主键 + * @return 员工详情 + */ + @Override + public SysStaffDetail selectSysStaffDetailById(Long id) + { + return sysStaffDetailMapper.selectSysStaffDetailById(id); + } + + /** + * 查询员工详情列表 + * + * @param sysStaffDetail 员工详情 + * @return 员工详情 + */ + @Override + public List selectSysStaffDetailList(SysStaffDetail sysStaffDetail) + { + return sysStaffDetailMapper.selectSysStaffDetailList(sysStaffDetail); + } + + /** + * 修改员工详情 + * + * @param sysStaffDetail 员工详情 + * @return 结果 + */ + @Override + public int updateSysStaffDetail(SysStaffDetail sysStaffDetail) + { + //餐饮 + List cy_list = sysDictDataMapper.selectDictDataByType(Constants.SYS_RESTAUTANT); + //根据员工ID查询员工信息 + SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(sysStaffDetail.getStaffId()); + //判断员工的住宿和工资类型填写餐补费用,住宿,早,午,晚:2,3,3 + if("是".equals(sysStaff.getZsFlag())){ + for (SysDictData sysDictData : cy_list) { + if("个人早餐".equals(sysDictData.getDictLabel())){ + sysStaffDetail.setBreakfastExpend(new BigDecimal(sysDictData.getDictValue())); + } + if("个人午餐".equals(sysDictData.getDictLabel())){ + sysStaffDetail.setLunchExpend(new BigDecimal(sysDictData.getDictValue())); + } + if("个人晚餐".equals(sysDictData.getDictLabel())){ + sysStaffDetail.setSupperExpend(new BigDecimal(sysDictData.getDictValue())); + } + } + }else { + //非住宿,月工资 + if(StringUtils.isNotNull(sysStaffDetail.getBasicSalary())){ + for (SysDictData sysDictData : cy_list) { + if("早餐消费".equals(sysDictData.getDictLabel())){ + sysStaffDetail.setBreakfastExpend(new BigDecimal(sysDictData.getDictValue())); + } + if("个人午餐".equals(sysDictData.getDictLabel())){ + sysStaffDetail.setLunchExpend(new BigDecimal(sysDictData.getDictValue())); + } + if("个人晚餐".equals(sysDictData.getDictLabel())){ + sysStaffDetail.setSupperExpend(new BigDecimal(sysDictData.getDictValue())); + } + } + }else{ + for (SysDictData sysDictData : cy_list) { + if("早餐消费".equals(sysDictData.getDictLabel())){ + sysStaffDetail.setBreakfastExpend(new BigDecimal(sysDictData.getDictValue())); + } + if("个人午餐".equals(sysDictData.getDictLabel())){ + sysStaffDetail.setLunchExpend(new BigDecimal(sysDictData.getDictValue())); + } + if("晚餐消费".equals(sysDictData.getDictLabel())){ + sysStaffDetail.setSupperExpend(new BigDecimal(sysDictData.getDictValue())); + } + } + } + } + sysStaffDetail.setUpdateTime(DateUtils.getNowDate()); + sysStaffDetail.setUpdateBy(SecurityUtils.getUsername()); + //根据员工ID查询当前餐饮详情,反写个人消费信息 + RzRestaurantStatistics rzRestaurantStatistics = rzRestaurantStatisticsMapper.selectRzRestaurantStatisticsByUserIdAndDate(sysStaff.getUserId(),DateUtils.getNowDate()); + if(StringUtils.isNotNull(rzRestaurantStatistics)){ + rzRestaurantStatistics.setBreakfastExpend(sysStaffDetail.getBreakfastExpend()); + rzRestaurantStatistics.setLunchExpend(sysStaffDetail.getLunchExpend()); + rzRestaurantStatistics.setSupperExpend(sysStaffDetail.getSupperExpend()); + rzRestaurantStatisticsMapper.updateRzRestaurantStatistics(rzRestaurantStatistics); + } + return sysStaffDetailMapper.updateSysStaffDetail(sysStaffDetail); + } + + + public AjaxResult clearAllSubsidy(){ + int i = sysStaffDetailMapper.clearAllSubsidy(); + if(i < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } + +} diff --git a/evo-admin/src/main/java/com/evo/system/service/impl/SysStaffServiceImpl.java b/evo-admin/src/main/java/com/evo/system/service/impl/SysStaffServiceImpl.java new file mode 100644 index 0000000..d60a6ad --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/impl/SysStaffServiceImpl.java @@ -0,0 +1,952 @@ +package com.evo.system.service.impl; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import com.evo.attendance.domain.RzAttendance; +import com.evo.attendance.domain.RzAttendanceStatistical; +import com.evo.attendance.mapper.RzAttendanceMapper; +import com.evo.attendance.mapper.RzAttendanceStatisticalMapper; +import com.evo.common.annotation.DataScope; +import com.evo.common.constant.Constants; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.domain.entity.SysDept; +import com.evo.common.core.domain.entity.SysDictData; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.bean.BeanUtils; +import com.evo.personnelMatters.domain.RzHoliday; +import com.evo.personnelMatters.domain.RzSubsidy; +import com.evo.personnelMatters.mapper.RzHolidayMapper; +import com.evo.personnelMatters.mapper.RzSubsidyMapper; +import com.evo.restaurant.domain.RzRestaurantStatistics; +import com.evo.restaurant.mapper.RzRestaurantStatisticsMapper; +import com.evo.system.domain.SysStaff; +import com.evo.system.domain.SysStaffDetail; +import com.evo.system.domain.vo.SysStaffVo; +import com.evo.system.mapper.SysDeptMapper; +import com.evo.system.mapper.SysDictDataMapper; +import com.evo.system.mapper.SysStaffDetailMapper; +import com.evo.system.mapper.SysStaffMapper; +import com.evo.system.service.ISysStaffService; +import com.evo.utils.DateUtil; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.usermodel.WorkbookFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import javax.annotation.Resource; + +/** + * 员工管理Service业务层处理 + * + * @author evo + * @date 2024-11-21 + */ +@Service +public class SysStaffServiceImpl implements ISysStaffService +{ + @Resource + private SysStaffMapper sysStaffMapper; + @Resource + private SysStaffDetailMapper sysStaffDetailMapper; //员工详情 + @Resource + private SysDictDataMapper sysDictDataMapper; //数据字典 + @Resource + private SysDeptMapper deptMapper; //部门信息 + @Resource + private RzSubsidyMapper rzSubsidyMapper; //补助信息 + @Resource + private RzAttendanceStatisticalMapper rzAttendanceStatisticalMapper; //考勤统计 + @Resource + private RzAttendanceMapper rzAttendanceMapper; //打卡记录 + @Resource + private RzHolidayMapper rzHolidayMapper; //假期 + @Resource + private RzRestaurantStatisticsMapper rzRestaurantStatisticsMapper; //餐饮统计 + /** + * 查询员工管理 + * + * @param userId 员工管理主键 + * @return 员工管理 + */ + @Override + public SysStaff selectSysStaffByUserId(Long userId) + { + return sysStaffMapper.selectSysStaffByUserId(userId); + } + /** + * 查询员工管理列表 + * + * @param sysStaff 员工管理 + * @return 员工管理 + */ + @Override + @DataScope(deptAlias = "d") + public List selectSysStaffList(SysStaff sysStaff) + { + List res_list = sysStaffMapper.selectSysStaffList(sysStaff); + for (SysStaff staff : res_list) { + staff.setDeptName(deptMapper.selectDeptById(staff.getDeptId()).getDeptName()); + } + return res_list; + } + /** + * 新增员工管理 + * + * @param sysStaff 员工管理 + * @return 结果 + */ + @Override + @Transactional + public AjaxResult insertSysStaff(SysStaff sysStaff) + { + //根据省份证号查询是否已经录入 + SysStaff p_staff = sysStaffMapper.queryysStaffByIdCard(sysStaff.getIdCard()); + if(StringUtils.isNotNull(p_staff)){ + return AjaxResult.error("此人录入过!!"); + } + //判断是否是领导,是反写部门信息 + if("是".equals(sysStaff.getIsLeader())){ + //根据ID查询部门信息 + SysDept sysDept = deptMapper.selectDeptById(sysStaff.getDeptId()); + sysDept.setPhone(sysStaff.getPhone()); + sysDept.setLeader(sysStaff.getName()); + int i = deptMapper.updateDept(sysDept); + if(i < 1){ + return AjaxResult.error(); + } + } + //根据省份证确定性别和年龄 + Long year = Long.parseLong(sysStaff.getIdCard().substring(6,10)); + Long age = Long.parseLong(new SimpleDateFormat("yyyy").format(new Date())) - year; + sysStaff.setAge(age); + if(Integer.parseInt(sysStaff.getIdCard().substring(16,17)) % 2 == 0){ + sysStaff.setSex("1"); + }else{ + sysStaff.setSex("0"); + } + //员工编码 + sysStaff.setCode(getCodeByCompanyName(sysStaff.getCompanyName())); + sysStaff.setSeniority(0l); + sysStaff.setStatus(Constants.JOB_STATIS_0); + sysStaff.setCreateTime(DateUtils.getNowDate()); + sysStaff.setCreateBy(SecurityUtils.getUsername()); + sysStaff.setDelFlag(Constants.DELETE_FLAG_0); + int i = sysStaffMapper.insertSysStaff(sysStaff); + if(i < 1){ + return AjaxResult.error(); + } + //员工详情 + createStaffDetail(sysStaff); + //打卡统计,打卡详情 + createRzAttendance(sysStaff); + createRestaurantStatistics(sysStaff); + + return AjaxResult.success(); + } + /** + * 创建员工详情信息 + * @param sysStaff + */ + private void createStaffDetail(SysStaff sysStaff){ + // 根据员工ID查询员工详情是否存在 + SysStaffDetail sysStaffDetail = sysStaffDetailMapper.selectSysStaffDetailByStaffId(sysStaff.getUserId()); + if(StringUtils.isNull(sysStaffDetail)){ + sysStaffDetail = new SysStaffDetail(); + } + //查询学历 + List xl_list = sysDictDataMapper.selectDictDataByType(Constants.SYS_LEVEL); + //学历补助 + for (SysDictData sysDictData : xl_list) { + if(sysDictData.getDictValue().equals(sysStaff.getLevel())){ + RzSubsidy rzSubsidy = rzSubsidyMapper.selectRzSubsidyByName(sysDictData.getDictLabel()); + if(StringUtils.isNotNull(rzSubsidy)){ + sysStaffDetail.setLevelOfEducationSubsidies(rzSubsidy.getValue()); + } + } + } + //合同补助 1年期合同 + if("1".equals(sysStaff.getContractType())){ + sysStaffDetail.setContractSubsidies(new BigDecimal(Constants.SYS_CONTRACT_0)); + }else if("3".equals(sysStaff.getContractType())){ //3年期合同 + sysStaffDetail.setContractSubsidies(new BigDecimal(Constants.SYS_CONTRACT_1)); + }else { + sysStaffDetail.setContractSubsidies(new BigDecimal("0.00")); + } + //社保补助 判断是否是新农合 ,是社保补助400元 + if("新农合".equals(sysStaff.getSocialType()) && "是".equals(sysStaff.getSocialSubsidy())){ + sysStaffDetail.setSocialSecuritySubsidies(new BigDecimal(Constants.SYS_SOCIAL_SUBSIDIES)); + }else{ + sysStaffDetail.setSocialSecuritySubsidies(new BigDecimal("0.00")); + } + if(StringUtils.isNull(sysStaffDetail.getStaffId())){ + sysStaffDetail.setStaffId(sysStaff.getUserId()); + sysStaffDetail.setSenioritySubsidies(new BigDecimal(Constants.SYS_SENIORITY_SUBSIDIES)); + sysStaffDetail.setCreateBy(SecurityUtils.getUsername()); + sysStaffDetail.setCreateTime(DateUtils.getNowDate()); + sysStaffDetail.setDelFlag(Constants.DELETE_FLAG_0); + sysStaffDetailMapper.insertSysStaffDetail(sysStaffDetail); + }else{ + sysStaffDetail.setUpdateBy(SecurityUtils.getUsername()); + sysStaffDetail.setUpdateTime(DateUtils.getNowDate()); + sysStaffDetailMapper.updateSysStaffDetail(sysStaffDetail); + } + } + /** + * 创建打卡考勤信息 + * @param sysStaff + */ + private void createRzAttendance(SysStaff sysStaff){ + //根据员工ID查询当月的统计信息统计信息 + RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(sysStaff.getUserId(),DateUtils.getNowDate()); + if(StringUtils.isNotNull(rzAttendanceStatistical)){ + //判断名称和部门是否一样。不一样操作修改 + if(!rzAttendanceStatistical.getName().equals(sysStaff.getName()) || rzAttendanceStatistical.getDeptId() != sysStaff.getDeptId()){ + //修改部门和姓名 + rzAttendanceStatistical.setName(sysStaff.getName()); + rzAttendanceStatistical.setDeptId(sysStaff.getDeptId()); + rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical); + //查询考勤详情修改 + List kq_list = rzAttendanceMapper.queryMonthAttendanceByStaffId(sysStaff.getUserId(),new Date()); + //循环修改信息 + for (RzAttendance rzAttendance : kq_list) { + rzAttendance.setDeptId(sysStaff.getDeptId()); + rzAttendance.setName(sysStaff.getName()); + rzAttendanceMapper.updateRzAttendance(rzAttendance); + } + } + return; + } + //新增考勤统计 + rzAttendanceStatistical = new RzAttendanceStatistical(); + rzAttendanceStatistical.setStaffId(sysStaff.getUserId()); + rzAttendanceStatistical.setName(sysStaff.getName()); + rzAttendanceStatistical.setMonth(DateUtils.getNowDate()); + rzAttendanceStatistical.setShouldAttendance(new BigDecimal(currentMonthAttendance()).multiply(new BigDecimal("8.00"))); + rzAttendanceStatistical.setDeptId(sysStaff.getDeptId()); + rzAttendanceStatistical.setDelFlag(Constants.DELETE_FLAG_0); + rzAttendanceStatistical.setCreateBy(SecurityUtils.getUsername()); + rzAttendanceStatistical.setCreateTime(DateUtils.getNowDate()); + rzAttendanceStatisticalMapper.insertRzAttendanceStatistical(rzAttendanceStatistical); + //新增考勤详情 + //获取当月天数 + Calendar calendar = Calendar.getInstance(); + int days = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); + SimpleDateFormat sdfm = new SimpleDateFormat("yyyy-MM"); + SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd"); + RzAttendance rzAttendance = null; + List pa_list = new ArrayList(); + for(int p=1;p<=days;p++){ + rzAttendance = new RzAttendance(); + rzAttendance.setDeptId(sysStaff.getDeptId()); + rzAttendance.setName(sysStaff.getName()); + rzAttendance.setStaffId(sysStaff.getUserId()); + try{ + String rq = sdfm.format(DateUtils.getNowDate()); + if(p < 10){ + rq += "-" + Constants.SEIZE_A_SEAT_0 + p; + }else { + rq += "-" + p; + } + rzAttendance.setAttendanceDate(sdfd.parse(rq)); + }catch (Exception e){ + e.printStackTrace(); + } + rzAttendance.setDelFlag(Constants.DELETE_FLAG_0); + rzAttendance.setCreateTime(DateUtils.getNowDate()); + rzAttendance.setCreateBy(SecurityUtils.getUsername()); + pa_list.add(rzAttendance); + } + rzAttendanceMapper.insertBatchRzAttendance(pa_list); + } + /** + * 创建餐饮统计 + * @param sysStaff + */ + private void createRestaurantStatistics(SysStaff sysStaff){ + RzRestaurantStatistics rzRestaurantStatistics = rzRestaurantStatisticsMapper.selectRzRestaurantStatisticsByUserIdAndDate(sysStaff.getUserId(),DateUtils.getNowDate()); + if(StringUtils.isNotNull(rzRestaurantStatistics)){ + rzRestaurantStatistics.setCompanyName(sysStaff.getCompanyName()); + rzRestaurantStatistics.setDeptId(sysStaff.getDeptId()); + rzRestaurantStatistics.setName(sysStaff.getName()); + rzRestaurantStatisticsMapper.updateRzRestaurantStatistics(rzRestaurantStatistics); + return; + } + rzRestaurantStatistics = new RzRestaurantStatistics(); + rzRestaurantStatistics.setName(sysStaff.getName()); + rzRestaurantStatistics.setCompanyName(sysStaff.getCompanyName()); + rzRestaurantStatistics.setDeptId(sysStaff.getDeptId()); + rzRestaurantStatistics.setStaffId(sysStaff.getUserId()); + rzRestaurantStatistics.setMonth(DateUtils.getNowDate()); + SysStaffDetail sysStaffDetail = sysStaffDetailMapper.selectSysStaffDetailByStaffId(sysStaff.getUserId()); + if(StringUtils.isNotNull(sysStaffDetail)){ + rzRestaurantStatistics.setBreakfastExpend(sysStaffDetail.getBreakfastExpend()); + rzRestaurantStatistics.setLunchExpend(sysStaffDetail.getLunchExpend()); + rzRestaurantStatistics.setSupperExpend(sysStaffDetail.getSupperExpend()); + } + rzRestaurantStatistics.setDelFlag(Constants.DELETE_FLAG_0); + rzRestaurantStatistics.setCreateBy(SecurityUtils.getUsername()); + rzRestaurantStatistics.setCreateTime(DateUtils.getNowDate()); + rzRestaurantStatisticsMapper.insertRzRestaurantStatistics(rzRestaurantStatistics); + } + /** + * 计算当月应出勤天数 + * @return + */ + private Long currentMonthAttendance(){ + //获取当月的天数 + Calendar calendar = Calendar.getInstance(); + int days = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); + SimpleDateFormat sdfm = new SimpleDateFormat("yyyy-MM"); + SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd"); + //获取当月第一天和最后一天 + Date startDate = null; + Date endDate = null; + try{ + startDate = sdfd.parse(sdfm.format(DateUtils.getNowDate()) + "-01"); + endDate = sdfd.parse(sdfm.format(DateUtils.getNowDate()) + "-" + days); + }catch (Exception e){ + e.printStackTrace(); + } + //除去周日 + days = days - DateUtil.isWeeked(startDate,endDate,1); + //查询假期,计算节假日 + List jq_list = rzHolidayMapper.selectRzHolidayList(null); + for (RzHoliday rzHoliday : jq_list) { + //判断假期在本月 + if(rzHoliday.getHoliday().getTime() > startDate.getTime() && rzHoliday.getHoliday().getTime() < endDate.getTime()){ + //判断是上班或休息 + if("0".equals(rzHoliday.getSpecialFlag())){ + days -= 1; + }else{ + days += 1; + } + } + } + return Long.valueOf(days); + } + /** + * 修改员工管理 + * + * @param sysStaff 员工管理 + * @return 结果 + */ + @Override + @Transactional + public AjaxResult updateSysStaff(SysStaff sysStaff) + { + //判断是否有离职时间,有则为离职 + if(StringUtils.isNotNull(sysStaff.getQuitDate())){ + //离职时间小于当前,说明离职了 + if(sysStaff.getQuitDate().getTime() < DateUtils.getNowDate().getTime()){ + sysStaff.setStatus("-1"); + int i = sysStaffMapper.updateSysStaff(sysStaff); + if(i < 1){ + return AjaxResult.error(); + } + return AjaxResult.success(); + } + } + //判断转正日期 + /*if(StringUtils.isNotNull(sysStaff.getRegularDate())){ + //离职时间小于当前,说明离职了 + if(sysStaff.getRegularDate().getTime() < DateUtils.getNowDate().getTime()){ + sysStaff.setStatus("1"); + int i = sysStaffMapper.updateSysStaff(sysStaff); + if(i < 1){ + return AjaxResult.error(); + } + } + }*/ + //根据省份证确定性别和年龄 + Long year = Long.parseLong(sysStaff.getIdCard().substring(6,10)); + Long age = Long.parseLong(new SimpleDateFormat("yyyy").format(new Date())) - year; + sysStaff.setAge(age); + if(Integer.parseInt(sysStaff.getIdCard().substring(16,17)) % 2 == 0){ + sysStaff.setSex("1"); + }else{ + sysStaff.setSex("0"); + } + //根据员工ID查询原来的数据信息 + SysStaff old_staff = sysStaffMapper.selectSysStaffByUserId(sysStaff.getUserId()); + //判断员工更换公司 + if(!old_staff.getCompanyName().equals(sysStaff.getCompanyName())){ + //保存旧公司数据存档 + old_staff.setDelFlag(Constants.DELETE_FLAG_1); + old_staff.setUpdateBy(SecurityUtils.getUsername()); + old_staff.setUpdateTime(DateUtils.getNowDate()); + int i = sysStaffMapper.updateSysStaff(old_staff); + if(i < 1){ + return AjaxResult.error(); + } + //处理新公司数据 + createNewStaff(sysStaff); + }else { + //根据部门ID查询部门信息 + SysDept oldDept = deptMapper.selectDeptById(old_staff.getDeptId()); + //判断原来为领导,现在不是领导则把旧职位部门负责人反写 + if("是".equals(old_staff.getIsLeader())){ + oldDept.setPhone(""); + oldDept.setLeader(""); + }else{ + oldDept.setPhone(sysStaff.getPhone()); + oldDept.setLeader(sysStaff.getName()); + } + oldDept.setUpdateTime(DateUtils.getNowDate()); + oldDept.setUpdateBy(SecurityUtils.getUsername()); + int i = deptMapper.updateDeptForLeader(oldDept); + if(i < 1){ + return AjaxResult.error(); + } + sysStaff.setUpdateTime(DateUtils.getNowDate()); + sysStaff.setUpdateBy(SecurityUtils.getUsername()); + i= sysStaffMapper.updateSysStaff(sysStaff); + if(i < 1){ + return AjaxResult.error(); + } + //修改员工详情 + createStaffDetail(sysStaff); + //修改考勤统计 + createRzAttendance(sysStaff); + //餐饮统计 + createRestaurantStatistics(sysStaff); + } + return AjaxResult.success(); + } + /** + * 更换新公司的处理,创建新员工 + */ + private void createNewStaff(SysStaff sysStaff){ + //根据身份证查询员工是否已经入职过现在的公司 + SysStaff param_staff = sysStaffMapper.queryysStaffByIdCardAndDeptId(sysStaff.getIdCard(),sysStaff.getDeptId()); + if(StringUtils.isNotNull(param_staff)){ + param_staff.setDelFlag(Constants.DELETE_FLAG_0); + param_staff.setUpdateBy(SecurityUtils.getUsername()); + param_staff.setUpdateTime(DateUtils.getNowDate()); + sysStaffMapper.updateSysStaff(param_staff); + return; + } + sysStaff.setCode(getCodeByCompanyName(sysStaff.getCompanyName())); + sysStaff.setCreateBy(SecurityUtils.getUsername()); + sysStaff.setCreateTime(DateUtils.getNowDate()); + sysStaff.setDelFlag(Constants.DELETE_FLAG_0); + //清除原来的ID + sysStaff.setUserId(null); + sysStaffMapper.insertSysStaff(sysStaff); + //添加员工详情 + createStaffDetail(sysStaff); + //修改考勤统计 + createRzAttendance(sysStaff); + //餐饮统计 + createRestaurantStatistics(sysStaff); + } + /** + * 删除员工管理信息 + * + * @param userId 员工管理主键 + * @return 结果 + */ + @Override + public int deleteSysStaffByUserId(Long userId) + { + SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(userId); + //判断员工是否为领导,是反写部门 + if("是".equals(sysStaff.getIsLeader())){ + //根据ID查询部门信息 + SysDept sysDept = deptMapper.selectDeptById(sysStaff.getDeptId()); + sysDept.setPhone(""); + sysDept.setLeader(""); + int i = deptMapper.updateDept(sysDept); + if(i < 1){ + return 0; + } + } + sysStaff.setUpdateTime(DateUtils.getNowDate()); + sysStaff.setUpdateBy(SecurityUtils.getUsername()); + sysStaff.setDelFlag(Constants.DELETE_FLAG_1); + return sysStaffMapper.updateSysStaff(sysStaff); + } + /** + * 查询所有的在职员工信息 + * @return + */ + public List selectSysStaffListAll(){ + List res_list = sysStaffMapper.selectSysStaffListAll(); + for (SysStaff sysStaff : res_list) { + sysStaff.setDeptName(deptMapper.selectDeptById(sysStaff.getDeptId()).getDeptName()); + } + return res_list; + } + /** + * 上传五险一金信息文件 + */ + @Override + public AjaxResult uploadAccumulationFund(MultipartFile filePath) { + String originalFilename = filePath.getOriginalFilename(); + //校验文件后缀 + String postfix = originalFilename.substring(originalFilename.length() - 3); + String substring = originalFilename.substring(originalFilename.length() - 4); + //判断是否是xlsx文件或xls文件 + if ("xls".equals(postfix) || "xlsx".equals(substring)) { + InputStream is = null; + FileOutputStream fos = null; + BufferedOutputStream bos = null; + try { + is = filePath.getInputStream(); + byte[] bytes = new byte[is.available()]; + is.read(bytes); + File file = new File(com.evo.equipment.constant.Constants.STAFF_FUND_ADDRESS + originalFilename); + fos = new FileOutputStream(file); + bos = new BufferedOutputStream(fos); + bos.write(bytes); + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + if (is != null) { + is.close(); + } + if (bos != null) { + bos.flush(); + bos.close(); + } + if (fos != null) { + fos.close(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + //写入数据库 + writeStaffInformation(originalFilename); + return AjaxResult.success(); + } + return AjaxResult.error(); + } + /** + * 把公积金写入系统 + * @param originalFilename + * @return + */ + private AjaxResult writeStaffInformation(String originalFilename){ + //在指定位置读取文件 + Workbook wb = null; + Sheet sheet = null; + try { + File files = new File(com.evo.equipment.constant.Constants.STAFF_FUND_ADDRESS + originalFilename); + if(null == files){ + return AjaxResult.error(); + } + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); + wb = WorkbookFactory.create(files); + sheet = wb.getSheetAt(0); + //得到行数 + int rowNumbers = sheet.getLastRowNum(); + SysStaff sysStaff = null; + SysStaffDetail staffDetail = null; + //存储缴纳公积金人员信息 + List de_list = new ArrayList(); + for(int p=4;p< rowNumbers;p++){ + Row row = sheet.getRow(p); + //身份证号为空,处理下一条数据 + if(StringUtils.isEmpty(row.getCell(2).getStringCellValue())){ + continue; + } + //根据身份证号查询员工 + sysStaff = sysStaffMapper.queryysStaffByIdCard(row.getCell(2).getStringCellValue()); + //没有此员工继续下一条 + if(StringUtils.isNull(sysStaff)){ + continue; + } + staffDetail = sysStaffDetailMapper.selectSysStaffDetailByStaffId(sysStaff.getUserId()); + if(StringUtils.isNotNull(row.getCell(5).getNumericCellValue())){ + BigDecimal big = BigDecimal.valueOf(row.getCell(5).getNumericCellValue()); + if(StringUtils.isNotNull(row.getCell(7).getNumericCellValue())){ + big = big.add(BigDecimal.valueOf(row.getCell(7).getNumericCellValue())); + } + staffDetail.setEndowmentInsurance(big); //养老 + } + if(StringUtils.isNotNull(row.getCell(10).getNumericCellValue())){ + BigDecimal big = BigDecimal.valueOf(row.getCell(10).getNumericCellValue()); + if(StringUtils.isNotNull(row.getCell(12).getNumericCellValue())){ + big = big.add(BigDecimal.valueOf(row.getCell(12).getNumericCellValue())); + } + staffDetail.setUnemploymentInsurance(big); //失业 + } + if(StringUtils.isNotNull(row.getCell(15).getNumericCellValue())){ + BigDecimal big = BigDecimal.valueOf(row.getCell(15).getNumericCellValue()); + if(StringUtils.isNotNull(row.getCell(18).getNumericCellValue())){ + big = big.add(BigDecimal.valueOf(row.getCell(18).getNumericCellValue())); + } + staffDetail.setMedicalInsurance(big); //医疗 + } + if(StringUtils.isNotNull(row.getCell(25).getNumericCellValue())){ + BigDecimal big = BigDecimal.valueOf(row.getCell(25).getNumericCellValue()); + if(StringUtils.isNotNull(row.getCell(27).getNumericCellValue())){ + big = big.add(BigDecimal.valueOf(row.getCell(27).getNumericCellValue())); + } + staffDetail.setAccumulationFund(big); //公积金 + } + //公司缴纳保险总和 + if(StringUtils.isNotNull(row.getCell(31).getNumericCellValue())){ + staffDetail.setCountInsurance(BigDecimal.valueOf(row.getCell(31).getNumericCellValue())); + } + sysStaffDetailMapper.updateSysStaffDetail(staffDetail); + de_list.add(staffDetail); + } + //查询公司员工 + List s_list = sysStaffDetailMapper.selectSysStaffDetailList(null); + //修改没有公积金的员工 + for(SysStaffDetail sysStaffDetail : s_list){ + int flag = 0; //标识五险一金的员工 0,不存在 + for (SysStaffDetail detail : de_list) { + if(sysStaffDetail.getStaffId() == detail.getStaffId()){ + flag = 1; + break; + } + } + if(flag == 0){ + sysStaffDetail.setEndowmentInsurance(new BigDecimal("0.00")); //养老 + sysStaffDetail.setMedicalInsurance(new BigDecimal("0.00")); //医疗 + sysStaffDetail.setUnemploymentInsurance(new BigDecimal("0.00")); //失业 + sysStaffDetail.setEmploymentInjuryInsurance(new BigDecimal("0.00")); //工伤 + sysStaffDetail.setMaternityInsurance(new BigDecimal("0.00")); //生育 + sysStaffDetail.setAccumulationFund(new BigDecimal("0.00")); //公积金 + sysStaffDetail.setDeductions(new BigDecimal("0.00")); + sysStaffDetail.setCountInsurance(new BigDecimal("0.00")); + sysStaffDetailMapper.updateSysStaffDetail(sysStaffDetail); + } + } + } catch (Exception e) { + e.printStackTrace(); + }finally { + try{ + if(wb != null){ + wb.close(); + } + }catch (Exception e){ + e.printStackTrace(); + } + } + return AjaxResult.success(); + } + /** + * 查询所有的在职员工信息 + * @return + */ + @Override + public List selectSysStaffDetailList(SysStaff sysStaff){ + List res_list = new ArrayList(); + //查询员工信息 + List yg_list = sysStaffMapper.selectSysStaffList(sysStaff); + List sub_list = sysDictDataMapper.selectDictDataByType("sys_level"); + List zz_list = sysDictDataMapper.selectDictDataByType("sys_worker_status"); + SysStaffVo sysStaffVo = null; + for (SysStaff staff : yg_list) { + sysStaffVo = new SysStaffVo(); + BeanUtils.copyProperties(staff,sysStaffVo); + //根据员工信息查询详情信息 + SysStaffDetail sysStaffDetail = sysStaffDetailMapper.selectSysStaffDetailByStaffId(staff.getUserId()); + BeanUtils.copyProperties(sysStaffDetail,sysStaffVo); + sysStaffVo.setDeptName(deptMapper.selectDeptById(staff.getDeptId()).getDeptName()); + for (SysDictData dictData : sub_list) { + if(dictData.getDictValue().equals(staff.getLevel())){ + sysStaffVo.setLevel(dictData.getDictLabel()); + } + } + for (SysDictData dictData : zz_list) { + if(dictData.getDictValue().equals(staff.getStatus())){ + sysStaffVo.setStatus(dictData.getDictLabel()); + } + } + res_list.add(sysStaffVo); + } + return res_list; + } + /** + * 导入员工信息 + * @param staffList 用户数据列表 + * @return + */ + @Override + @Transactional + public AjaxResult importStaff(List staffList){ + if (StringUtils.isNull(staffList) || staffList.size() == 0){ + return AjaxResult.success(); + } + try{ + //把学历,性别,部门转化为相对应ID + List xl_list = sysDictDataMapper.selectDictDataByType(Constants.SYS_LEVEL); + //在职状态 + List zz_list = sysDictDataMapper.selectDictDataByType(Constants.SYS_WORK_STATUS); + //餐饮 + List cy_list = sysDictDataMapper.selectDictDataByType(Constants.SYS_RESTAUTANT); + //合同年限 + List ht_list = sysDictDataMapper.selectDictDataByType(Constants.SYS_CONTRACT); + //所属公司 + List gs_list = sysDictDataMapper.selectDictDataByType(Constants.SYS_COMPANY); + List dept_list = deptMapper.queryDeptTreeList(); + SysStaff sysStaff = null; + SysStaffDetail sysStaffDetail = null; + for (SysStaffVo Staffvo : staffList){ + //判断必填项是否为空,为空执行下一条数据: 身份证号,姓名,部门,是否有加班费,入职日期,学历,打卡,合同,社保 + if(StringUtils.isEmpty(Staffvo.getIdCard()) || StringUtils.isEmpty(Staffvo.getName()) || StringUtils.isEmpty(Staffvo.getDeptName()) + || StringUtils.isEmpty(Staffvo.getIsOvertimePay()) || Staffvo.getEmploymentDate() == null || StringUtils.isEmpty(Staffvo.getLevel()) + || StringUtils.isEmpty(Staffvo.getClockIn()) || StringUtils.isEmpty(Staffvo.getContractType()) || StringUtils.isEmpty(Staffvo.getSocialType()) + || StringUtils.isEmpty(Staffvo.getSocialSubsidy())){ + continue; + } + sysStaff = new SysStaff(); + sysStaffDetail = new SysStaffDetail(); + BeanUtils.copyProperties(Staffvo,sysStaff); + BeanUtils.copyProperties(Staffvo,sysStaffDetail); + // 验证是否存在这个员工 + SysStaff staff = sysStaffMapper.queryysStaffByIdCard(sysStaff.getIdCard()); + //员工存在 + if(StringUtils.isNotNull(staff)){ + continue; + } + for (SysDictData sysDictData : gs_list) { + if(sysDictData.getDictLabel().equals(Staffvo.getCompanyName())){ + sysStaff.setCompanyName(sysDictData.getDictValue()); + break; + } + } + //学历解析 + for (SysDictData sysDictData : xl_list) { + if(sysDictData.getDictLabel().equals(Staffvo.getLevel())){ + sysStaff.setLevel(sysDictData.getDictValue()); + break; + } + } + // 判断员工编码是否存在,不存在,自动生成 + if(StringUtils.isEmpty(sysStaff.getCode())){ + sysStaff.setCode(getCodeByCompanyName(sysStaff.getCompanyName())); + } + for (SysDept sysDept : dept_list) { + if(sysDept.getDeptName().equals(sysStaff.getDeptName())){ + sysStaff.setDeptId(sysDept.getDeptId()); + break; + } + } + //处理在职状态 + for (SysDictData sysDictData : zz_list) { + if(sysDictData.getDictLabel().equals(Staffvo.getStatus())){ + sysStaff.setStatus(sysDictData.getDictValue()); + break; + } + } + //合同年限 + for (SysDictData sysDictData : ht_list) { + if(sysDictData.getDictLabel().equals(Staffvo.getContractType())){ + sysStaff.setContractType(sysDictData.getDictValue()); + break; + } + } + //计算性别和年龄 + if(StringUtils.isNotEmpty(sysStaff.getIdCard())){ + //根据身份证解析性别和年龄 + int year = Integer.parseInt(sysStaff.getIdCard().substring(6,10)); + int age = Integer.parseInt(new SimpleDateFormat("yyyy").format(new Date())) - year; + sysStaff.setAge(Long.parseLong(age+"")); + if(Integer.parseInt(sysStaff.getIdCard().substring(16,17)) % 2 == 0){ + sysStaff.setSex("1"); + }else{ + sysStaff.setSex("0"); + } + } + sysStaff.setCreateTime(DateUtils.getNowDate()); + sysStaff.setCreateBy(SecurityUtils.getUsername()); + sysStaff.setDelFlag(Constants.DELETE_FLAG_0); + int i = sysStaffMapper.insertSysStaff(sysStaff); + if(i < 1){ + return AjaxResult.error(); + } + //获取三餐数据 + //判断员工的住宿和工资类型填写餐补费用,住宿,早,午,晚:2,3,3 + if("是".equals(sysStaff.getZsFlag())){ + for (SysDictData sysDictData : cy_list) { + if("个人早餐".equals(sysDictData.getDictLabel())){ + sysStaffDetail.setBreakfastExpend(new BigDecimal(sysDictData.getDictValue())); + } + if("个人午餐".equals(sysDictData.getDictLabel())){ + sysStaffDetail.setLunchExpend(new BigDecimal(sysDictData.getDictValue())); + } + if("个人晚餐".equals(sysDictData.getDictLabel())){ + sysStaffDetail.setSupperExpend(new BigDecimal(sysDictData.getDictValue())); + } + } + }else { + //非住宿,月工资 + if(StringUtils.isNotNull(sysStaffDetail.getBasicSalary())){ + for (SysDictData sysDictData : cy_list) { + if("早餐消费".equals(sysDictData.getDictLabel())){ + sysStaffDetail.setBreakfastExpend(new BigDecimal(sysDictData.getDictValue())); + } + if("个人午餐".equals(sysDictData.getDictLabel())){ + sysStaffDetail.setLunchExpend(new BigDecimal(sysDictData.getDictValue())); + } + if("个人晚餐".equals(sysDictData.getDictLabel())){ + sysStaffDetail.setSupperExpend(new BigDecimal(sysDictData.getDictValue())); + } + } + }else{ + for (SysDictData sysDictData : cy_list) { + if("早餐消费".equals(sysDictData.getDictLabel())){ + sysStaffDetail.setBreakfastExpend(new BigDecimal(sysDictData.getDictValue())); + } + if("个人午餐".equals(sysDictData.getDictLabel())){ + sysStaffDetail.setLunchExpend(new BigDecimal(sysDictData.getDictValue())); + } + if("晚餐消费".equals(sysDictData.getDictLabel())){ + sysStaffDetail.setSupperExpend(new BigDecimal(sysDictData.getDictValue())); + } + } + } + } + sysStaffDetail.setStaffId(sysStaff.getUserId()); + sysStaffDetail.setDelFlag(Constants.DELETE_FLAG_0); + sysStaffDetail.setCreateTime(DateUtils.getNowDate()); + sysStaffDetail.setCreateBy(SecurityUtils.getUsername()); + i = sysStaffDetailMapper.insertSysStaffDetail(sysStaffDetail); + if(i < 1){ + return AjaxResult.error(); + } + createRzAttendance(sysStaff); + //餐饮统计 + createRestaurantStatistics(sysStaff); + } + } catch (Exception e){ + e.printStackTrace(); + return AjaxResult.error(); + } + return AjaxResult.success(); + } + /** + * 根据公司名称得到员工编号 + * @param companyName + * @return + */ + private String getCodeByCompanyName(String companyName){ + //根据公司名称查询当前公司下的最大编号 + SysStaff macCode = sysStaffMapper.querySysStaffOfMaxByCompany(companyName); + if(macCode == null){ + return companyName + "0001"; + } + int code = Integer.parseInt(macCode.getCode().replace(companyName,"")) + 1; + if(code < 10){ + return companyName + Constants.SEIZE_A_SEAT_2 + code; + }else if(code < 100){ + return companyName + Constants.SEIZE_A_SEAT_1 + code; + }else if(code < 1000){ + return companyName + Constants.SEIZE_A_SEAT_0 + code; + }else{ + return companyName + code; + } + } + /** + * 每月1号自动生成考勤信息 + */ + @Override + public void autoCreateAttendanceData(){ + //获取在职员工数据 + List params_list = sysStaffMapper.selectSysStaffListAll(); + //循环在职员工生成考勤统计 + for (SysStaff sysStaff : params_list) { + createRzAttendance(sysStaff); + } + } + + /** + * 每天计算转正,离职日期 + */ + @Override + public void autoRegularWorking(){ + //获取在职员工数据 + List params_list = sysStaffMapper.selectSysStaffListAll(); + for (SysStaff sysStaff : params_list) { + //判断员工是否离职 + if(StringUtils.isNotNull(sysStaff.getQuitDate()) && sysStaff.getQuitDate().getTime() < DateUtils.getNowDate().getTime()){ + sysStaff.setStatus("-1"); + sysStaffMapper.updateSysStaff(sysStaff); + return; + } + //判断转正时间,无转正日期自动计算转正日期(入职日期后一个月) + if(StringUtils.isNull(sysStaff.getRegularDate())){ + //获取入职一个月后的日期 + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sysStaff.getEmploymentDate()); + calendar.add(Calendar.MONTH,1); + sysStaff.setRegularDate(calendar.getTime()); + } + //判断转正日期和今天时间比较 + if(sysStaff.getRegularDate().getTime() < DateUtils.getNowDate().getTime()){ + sysStaff.setStatus("1"); + } + sysStaffMapper.updateSysStaff(sysStaff); + } + } + + /** + * 根据部门查询员工信息 + * @param deptId + * @return + */ + @Override + public List queryysStaffByDeptId(Long deptId){ + //根据ID查询所有子集 + List d_list = deptMapper.queryDeptsByDeptId(deptId); + List list = new ArrayList(); + for (SysDept sysDept : d_list) { + list.add(sysDept.getDeptId()); + } + return sysStaffMapper.queryysStaffByDeptId(list); + } + + /** + * 自动计算工龄 + */ + @Override + public void calculationOfSeniority(){ + //获取在职员工数据 + List params_list = sysStaffMapper.selectSysStaffListAll(); + //当前日期减去一个月计算工龄,计算工资比实际工龄延后一个月 + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.MONTH, -1); + SimpleDateFormat sdfm = new SimpleDateFormat("yyyy-MM"); + SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd"); + try{ + String str = sdfm.format(calendar.getTime()); + Date date = sdfd.parse(str + "-01"); + for (SysStaff sysStaff : params_list) { + //获取入职日期,计算入职日期到当前时间差 + int years = date.getYear() - sysStaff.getEmploymentDate().getYear(); + int months = date.getMonth() - sysStaff.getEmploymentDate().getMonth(); + int days = date.getDate() - sysStaff.getEmploymentDate().getDate(); + //判断月份和日期 + if (months < 0 || (months == 0 && days < 0)) { + years -= 1; + } + if(years > 0){ + sysStaff.setSeniority(Long.valueOf(years)); + }else{ + sysStaff.setSeniority(0l); + } + sysStaffMapper.updateSysStaff(sysStaff); + } + }catch(Exception e){ + e.printStackTrace(); + } + } +} diff --git a/evo-admin/src/main/java/com/evo/system/service/impl/SysUserOnlineServiceImpl.java b/evo-admin/src/main/java/com/evo/system/service/impl/SysUserOnlineServiceImpl.java new file mode 100644 index 0000000..d51612a --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/impl/SysUserOnlineServiceImpl.java @@ -0,0 +1,96 @@ +package com.evo.system.service.impl; + +import org.springframework.stereotype.Service; +import com.evo.common.core.domain.model.LoginUser; +import com.evo.common.utils.StringUtils; +import com.evo.system.domain.SysUserOnline; +import com.evo.system.service.ISysUserOnlineService; + +/** + * 在线用户 服务层处理 + * + * @author evo + */ +@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/evo-admin/src/main/java/com/evo/system/service/impl/SysUserServiceImpl.java b/evo-admin/src/main/java/com/evo/system/service/impl/SysUserServiceImpl.java new file mode 100644 index 0000000..180524f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/system/service/impl/SysUserServiceImpl.java @@ -0,0 +1,484 @@ +package com.evo.system.service.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import javax.annotation.Resource; +import javax.validation.Validator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import com.evo.common.annotation.DataScope; +import com.evo.common.constant.UserConstants; +import com.evo.common.core.domain.entity.SysRole; +import com.evo.common.core.domain.entity.SysUser; +import com.evo.common.exception.ServiceException; +import com.evo.common.utils.SecurityUtils; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.bean.BeanValidators; +import com.evo.common.utils.spring.SpringUtils; +import com.evo.system.domain.SysUserRole; +import com.evo.system.mapper.SysRoleMapper; +import com.evo.system.mapper.SysUserMapper; +import com.evo.system.mapper.SysUserRoleMapper; +import com.evo.system.service.ISysDeptService; +import com.evo.system.service.ISysUserService; + +/** + * 用户 业务层处理 + * + * @author evo + */ +@Service +public class SysUserServiceImpl implements ISysUserService +{ + private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class); + + @Resource + private SysUserMapper userMapper; + + @Resource + private SysRoleMapper roleMapper; + + @Resource + private SysUserRoleMapper userRoleMapper; + + @Resource + private ISysDeptService deptService; + + @Resource + 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); + } + + /** + * 通过用户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 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); + // 新增用户与角色管理 + 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); + 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 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); + 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); + 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()); + 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/evo-admin/src/main/java/com/evo/task/TaskController.java b/evo-admin/src/main/java/com/evo/task/TaskController.java new file mode 100644 index 0000000..318debe --- /dev/null +++ b/evo-admin/src/main/java/com/evo/task/TaskController.java @@ -0,0 +1,59 @@ +package com.evo.task; + +import com.evo.attendance.service.IRzAbnormalDetailService; +import com.evo.restaurant.service.IRzRestaurantStatisticsService; +import com.evo.system.service.ISysStaffService; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +@Component +public class TaskController { + + @Resource + private ISysStaffService sysStaffService; //员工信息 + @Resource + private IRzRestaurantStatisticsService rzRestaurantStatisticsService; //餐饮统计 + @Resource + private IRzAbnormalDetailService abnormalDetailService; //异常卡 + + /** + * 每月1号 0:20 自动生成考勤数据 + */ + @Scheduled(cron = "0 20 0 1 * ?") + public void autoCreateAttendanceData(){ + sysStaffService.autoCreateAttendanceData(); + }; + /** + * 每月1号 1:00 自动生成餐饮统计信息 + */ + @Scheduled(cron = "0 0 1 1 * ?") + public void insertRzRestaurantStatistics(){ + rzRestaurantStatisticsService.insertRzRestaurantStatistics(); + } + /** + * 每天 1:10 计算转正,离职日期 + */ + @Scheduled(cron = "0 30 1 * * ?") + public void autoRegularWorking(){ + sysStaffService.autoRegularWorking(); + }; + + /** + * 每天23:00 计算当天的异常 + */ + //@Scheduled(cron = "0 0/30 * * * ?") + @Scheduled(cron = "0 0 23 * * ?") + public void autoCalculaLateness(){ + abnormalDetailService.insertRzAbnormalDetail(); + } + + /** + * 每月10号2点自动计算工龄 + */ + @Scheduled(cron = "0 0 2 10 * ?") + public void calculationOfSeniority(){ + sysStaffService.calculationOfSeniority(); + } +} diff --git a/evo-admin/src/main/java/com/evo/utils/DateUtil.java b/evo-admin/src/main/java/com/evo/utils/DateUtil.java new file mode 100644 index 0000000..757cf08 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/utils/DateUtil.java @@ -0,0 +1,134 @@ +package com.evo.utils; + +import com.evo.personnelMatters.domain.RzHoliday; +import com.evo.personnelMatters.mapper.RzHolidayMapper; +import org.springframework.stereotype.Component; +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +@Component +public class DateUtil { + + @Resource + private RzHolidayMapper rzHolidayMapper; //假期管理 + + public static DateUtil dateUtil; + + @PostConstruct + public void init(){ + dateUtil = this; + dateUtil.rzHolidayMapper = this.rzHolidayMapper; + } + + /** + * 计算俩个时间之间的小时数 + * @param beginTime 请假开始时间 + * @param endTime 请假结束时间 + * @param flag 假期类型 + * @return + */ + public Long autoLeavehoursForCount(Date beginTime, Date endTime,String flag){ + SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat sdfh = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + //根据时间计算时间差 ,小时 + Long xsc = 0l; + try{ + Date b_time = sdfh.parse(sdfd.format(beginTime) +" 08:30:00"); + Date e_time = sdfh.parse(sdfd.format(endTime) +" 17:30:00"); + if(beginTime.before(b_time) && endTime.after(e_time)){ + xsc = (e_time.getTime() - b_time.getTime())/1000/60/60; + }else{ + if(endTime.after(e_time)){ + xsc = (e_time.getTime() - beginTime.getTime())/1000/60/60; + } + if(beginTime.before(b_time)){ + xsc = (endTime.getTime() - b_time.getTime())/1000/60/60; + } + } + }catch (Exception e){ + e.printStackTrace(); + } + //计算天数 + Long ts = xsc/24; + //假期类型为婚嫁,产假,陪产假计算周日和节假日,其他的假期都不算周日和节假日 + if(!"6".equals(flag) && !"7".equals(flag) && !"8".equals(flag)){ + //判断是否有周日 ,有周日减去 + int zr = isWeeked(beginTime,endTime,1); + ts = ts - zr; + //查询节假日, 判断是否节假日 + List h_list = rzHolidayMapper.selectRzHolidayList(null); + for (RzHoliday rzHoliday : h_list) { + if(rzHoliday.getHoliday().before(endTime) && rzHoliday.getHoliday().after(beginTime)){ + //判断周日上班时间 + if("1".equals(rzHoliday.getSpecialFlag())){ + ts = ts + 1; + }else{ + ts = ts - 1; + } + } + } + } + //请假结果小时数 + Long res = ts * 8; + //小时余数 + Long xsys = xsc%24; + //判断剩余小时数大于4小时,则请假为一天 + if(xsys > 4){ + res = res + 8; + }else if(xsys > 0){ + res = res + 4; + } + return res; + } + + /** + * 判断日期是否包含周日 + * @param beginTime 开始时间 + * @param endTime 结束时间 + * @param flag flag:1是周日,flag:7是周六 + * @return + */ + public static int isWeeked(Date beginTime,Date endTime,int flag){ + int result = 0; + try { + Calendar cal = Calendar.getInstance(); + cal.setTime(beginTime); + while(cal.getTime().before(endTime)){ + int week_index = cal.get(Calendar.DAY_OF_WEEK); + if(week_index==flag){ + result += 1; + } + cal.add(Calendar.DAY_OF_MONTH,1); + } + } catch (Exception e){ + result = -1; + e.printStackTrace(); + } + return result; + } + + /** + * 判断日期是周日 + * @param date + * @param flag flag:1是周日,flag:7是周六 + * @return + */ + public static boolean isSaturday(Date date,int flag){ + try { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + int week_index = cal.get(Calendar.DAY_OF_WEEK); + if(week_index==flag){ + return true; + } + } catch (Exception e){ + e.printStackTrace(); + } + return false; + } + +} diff --git a/evo-admin/src/main/resources/META-INF/spring-devtools.properties b/evo-admin/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 0000000..37e7b58 --- /dev/null +++ b/evo-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/evo-admin/src/main/resources/application-druid.yml b/evo-admin/src/main/resources/application-druid.yml new file mode 100644 index 0000000..1bdd017 --- /dev/null +++ b/evo-admin/src/main/resources/application-druid.yml @@ -0,0 +1,63 @@ +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 主库数据源 + master: + url: jdbc:mysql://192.168.5.12:3306/evo_cw_new?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: yite + password: hbyt2024 + #username: root + #password: yj.chen@001 + # 从库数据源 + 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: evo + 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 diff --git a/evo-admin/src/main/resources/application.yml b/evo-admin/src/main/resources/application.yml new file mode 100644 index 0000000..81364e4 --- /dev/null +++ b/evo-admin/src/main/resources/application.yml @@ -0,0 +1,127 @@ +# 项目相关配置 +evo: + # 名称 + name: evo + # 版本 + version: 3.8.8 + # 版权年份 + copyrightYear: 2024 + # 文件路径 示例( Windows配置D:/evo/uploadPath,Linux配置 /home/evo/uploadPath) + profile: D:/evo/uploadPath + # 获取ip地址开关 + addressEnabled: false + +# 开发环境配置 +server: + # 服务器的HTTP端口,默认为8080 + port: 8081 + 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.evo: 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: 20MB + # 设置总上传的文件大小 + max-request-size: 300MB + # 服务模块 + devtools: + restart: + # 热部署开关 + enabled: true + # redis 配置 + redis: + # 地址 + host: localhost + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 0 + # 密码 + password: + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + +# token配置 +token: + # 令牌自定义标识 + header: Authorization + # 令牌密钥 + secret: abcdefghijklmnopqrstuvwxyz + # 令牌有效期(默认30分钟) + expireTime: 480 + +# MyBatis配置 +mybatis: + # 搜索指定包别名 + typeAliasesPackage: com.evo.**.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/* diff --git a/evo-admin/src/main/resources/banner.txt b/evo-admin/src/main/resources/banner.txt new file mode 100644 index 0000000..2c9caf8 --- /dev/null +++ b/evo-admin/src/main/resources/banner.txt @@ -0,0 +1,24 @@ +Application Version: ${evo.version} +Spring Boot Version: ${spring-boot.version} +//////////////////////////////////////////////////////////////////// +// _ooOoo_ // +// o8888888o // +// 88" . "88 // +// (| ^_^ |) // +// O\ = /O // +// ____/`---'\____ // +// .' \\| |// `. // +// / \\||| : |||// \ // +// / _||||| -:- |||||- \ // +// | | \\\ - /// | | // +// | \_| ''\---/'' | | // +// \ .-\__ `-` ___/-. / // +// ___`. .' /--.--\ `. . ___ // +// ."" '< `.___\_<|>_/___.' >'"". // +// | | : `- \`.;`\ _ /`;.`/ - ` : | | // +// \ \ `-. \_ __\ /__ _/ .-` / / // +// ========`-.____`-.___\_____/___.-`____.-'======== // +// `=---=' // +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // +// 佛祖保佑 永不宕机 永无BUG // +//////////////////////////////////////////////////////////////////// diff --git a/evo-admin/src/main/resources/generator.yml b/evo-admin/src/main/resources/generator.yml new file mode 100644 index 0000000..65c1584 --- /dev/null +++ b/evo-admin/src/main/resources/generator.yml @@ -0,0 +1,10 @@ +# 代码生成 +gen: + # 作者 + author: evo + # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool + packageName: com.evo.product + # 自动去除表前缀,默认是false + autoRemovePre: false + # 表前缀(生成类名不会包含表前缀,多个用逗号分隔) + tablePrefix: product_ diff --git a/evo-admin/src/main/resources/i18n/messages.properties b/evo-admin/src/main/resources/i18n/messages.properties new file mode 100644 index 0000000..93de005 --- /dev/null +++ b/evo-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/evo-admin/src/main/resources/logback.xml b/evo-admin/src/main/resources/logback.xml new file mode 100644 index 0000000..8cb8cc1 --- /dev/null +++ b/evo-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} + + + + + + + + + + + + + + + + + + + + + + + diff --git a/evo-admin/src/main/resources/mapper/attendance/RzAbnormalDetailMapper.xml b/evo-admin/src/main/resources/mapper/attendance/RzAbnormalDetailMapper.xml new file mode 100644 index 0000000..7031be5 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/attendance/RzAbnormalDetailMapper.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + select id, abnormal_id, name,clock_date,clock_type, abnormal_time, money, remarks, del_flag, create_by, create_time, update_time, update_by from rz_abnormal_detail + + + + + + + + insert into rz_abnormal_detail + + abnormal_id, + name, + clock_date, + clock_type, + abnormal_time, + money, + remarks, + del_flag, + create_by, + create_time, + update_time, + update_by, + + + #{abnormalId}, + #{name}, + #{clockDate}, + #{clockType}, + #{abnormalTime}, + #{money}, + #{remarks}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateTime}, + #{updateBy}, + + + + + update rz_abnormal_detail + + abnormal_id = #{abnormalId}, + name = #{name}, + clock_date = #{clockDate}, + abnormal_time = #{abnormalTime}, + money = #{money}, + remarks = #{remarks}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_time = #{updateTime}, + update_by = #{updateBy}, + + where id = #{id} + + + + + diff --git a/evo-admin/src/main/resources/mapper/attendance/RzAbnormalMapper.xml b/evo-admin/src/main/resources/mapper/attendance/RzAbnormalMapper.xml new file mode 100644 index 0000000..e745787 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/attendance/RzAbnormalMapper.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + select id, dept_id, user_id, name, month, number, money, del_flag, create_by, create_time, update_by, update_time from rz_abnormal + + + + + + + + insert into rz_abnormal + + dept_id, + user_id, + name, + month, + number, + money, + del_flag, + create_by, + create_time, + update_by, + update_time, + + + #{deptId}, + #{userId}, + #{name}, + #{month}, + #{number}, + #{money}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update rz_abnormal + + dept_id = #{deptId}, + user_id = #{userId}, + name = #{name}, + month = #{month}, + number = #{number}, + money = #{money}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + + diff --git a/evo-admin/src/main/resources/mapper/attendance/RzAttendanceDetailMapper.xml b/evo-admin/src/main/resources/mapper/attendance/RzAttendanceDetailMapper.xml new file mode 100644 index 0000000..50f7cf8 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/attendance/RzAttendanceDetailMapper.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + select id, staff_id, name, equipment_code, button_type, date_time, remark, del_flag, create_by, create_time, update_by, update_time from rz_attendance_detail + + + + + + insert into rz_attendance_detail + + staff_id, + name, + equipment_code, + button_type, + date_time, + remark, + del_flag, + create_by, + create_time, + update_by, + update_time, + + + #{staffId}, + #{name}, + #{equipmentCode}, + #{buttonType}, + #{dateTime}, + #{remark}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update rz_attendance_detail + + staff_id = #{staffId}, + name = #{name}, + equipment_code = #{equipmentCode}, + button_type = #{buttonType}, + date_time = #{dateTime}, + remark = #{remark}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + + + + diff --git a/evo-admin/src/main/resources/mapper/attendance/RzAttendanceMapper.xml b/evo-admin/src/main/resources/mapper/attendance/RzAttendanceMapper.xml new file mode 100644 index 0000000..9112eba --- /dev/null +++ b/evo-admin/src/main/resources/mapper/attendance/RzAttendanceMapper.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, staff_id, name, dept_id, attendance_date, rules, work_start_time,ycs_flag,ycx_flag, work_end_time, work_sum,work_hours,night_number,middle_shift_number,remarks, del_flag, create_by, create_time, update_by, update_time from rz_attendance + + + + + + + + update rz_attendance + + staff_id = #{staffId}, + name = #{name}, + dept_id = #{deptId}, + attendance_date = #{attendanceDate}, + rules = #{rules}, + work_start_time = #{workStartTime}, + work_end_time = #{workEndTime}, + work_sum = #{workSum}, + night_number = #{nightNumber}, + middle_shift_number = #{middleShiftNumber}, + remarks = #{remarks}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + ycs_flag = #{ycsFlag}, + ycx_flag = #{ycxFlag}, + + where id = #{id} + + + + + + + + + + + + + + insert into rz_attendance(staff_id, name, dept_id, attendance_date,del_flag, create_by, create_time,ycs_flag,ycx_flag) + VALUES + + (#{item.staffId}, #{item.name}, #{item.deptId}, #{item.attendanceDate}, #{item.delFlag}, #{item.createBy}, #{item.createTime}, #{item.ycsFlag}, #{item.ycxFlag}) + + + + + diff --git a/evo-admin/src/main/resources/mapper/attendance/RzAttendanceStatisticalMapper.xml b/evo-admin/src/main/resources/mapper/attendance/RzAttendanceStatisticalMapper.xml new file mode 100644 index 0000000..074dae8 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/attendance/RzAttendanceStatisticalMapper.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, staff_id, month, dept_id, name, should_attendance, real_attendance,over_time_hours, essential_attendance, work_overtime_number, absenteeism, late_number, leave_early, less_number, night_number, middle_shift_number, del_flag, create_by, create_time, update_by, update_time from rz_attendance_statistical + + + + + + + + insert into rz_attendance_statistical + + staff_id, + month, + dept_id, + name, + should_attendance, + real_attendance, + essential_attendance, + work_overtime_number, + absenteeism, + late_number, + leave_early, + less_number, + night_number, + middle_shift_number, + del_flag, + create_by, + create_time, + update_by, + update_time, + over_time_hours, + + + #{staffId}, + #{month}, + #{deptId}, + #{name}, + #{shouldAttendance}, + #{realAttendance}, + #{essentialAttendance}, + #{workOvertimeNumber}, + #{absenteeism}, + #{lateNumber}, + #{leaveEarly}, + #{lessNumber}, + #{nightNumber}, + #{middleShiftNumber}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{overTimeHours}, + + + + + update rz_attendance_statistical + + staff_id = #{staffId}, + month = #{month}, + dept_id = #{deptId}, + name = #{name}, + should_attendance = #{shouldAttendance}, + real_attendance = #{realAttendance}, + essential_attendance = #{essentialAttendance}, + work_overtime_number = #{workOvertimeNumber}, + absenteeism = #{absenteeism}, + late_number = #{lateNumber}, + leave_early = #{leaveEarly}, + less_number = #{lessNumber}, + night_number = #{nightNumber}, + middle_shift_number = #{middleShiftNumber}, + del_flag = #{delFlag}, + create_by = #{createBy}, + update_time = #{updateTime}, + over_time_hours = #{overTimeHours}, + + where id = #{id} + + + + + + diff --git a/evo-admin/src/main/resources/mapper/attendance/RzSpecialAttendanceMapper.xml b/evo-admin/src/main/resources/mapper/attendance/RzSpecialAttendanceMapper.xml new file mode 100644 index 0000000..42308a4 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/attendance/RzSpecialAttendanceMapper.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + select id, staff_id, name, dept_id, attendance_date, work_start_time, work_end_time, work_hours, remarks, del_flag, create_by, create_time, update_by, update_time from rz_special_attendance + + + + + + + + insert into rz_special_attendance + + staff_id, + name, + dept_id, + attendance_date, + work_start_time, + work_end_time, + work_hours, + remarks, + del_flag, + create_by, + create_time, + update_by, + update_time, + + + #{staffId}, + #{name}, + #{deptId}, + #{attendanceDate}, + #{workStartTime}, + #{workEndTime}, + #{workHours}, + #{remarks}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update rz_special_attendance + + staff_id = #{staffId}, + name = #{name}, + dept_id = #{deptId}, + attendance_date = #{attendanceDate}, + work_start_time = #{workStartTime}, + work_end_time = #{workEndTime}, + work_hours = #{workHours}, + remarks = #{remarks}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + + diff --git a/evo-admin/src/main/resources/mapper/attendance/RzSpecialOverTimeMapper.xml b/evo-admin/src/main/resources/mapper/attendance/RzSpecialOverTimeMapper.xml new file mode 100644 index 0000000..9e3d086 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/attendance/RzSpecialOverTimeMapper.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + select id, user_id, dept_id, name, over_date, sick_hours, del_flag, create_by, create_time, update_by, update_time from rz_special_over_time + + + + + + + + insert into rz_special_over_time + + user_id, + dept_id, + name, + over_date, + sick_hours, + del_flag, + create_by, + create_time, + update_by, + update_time, + + + #{userId}, + #{deptId}, + #{name}, + #{overDate}, + #{sickHours}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update rz_special_over_time + + user_id = #{userId}, + dept_id = #{deptId}, + name = #{name}, + over_date = #{overDate}, + sick_hours = #{sickHours}, + del_flag = #{delFlag}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + + diff --git a/evo-admin/src/main/resources/mapper/equipment/EqButtonMapper.xml b/evo-admin/src/main/resources/mapper/equipment/EqButtonMapper.xml new file mode 100644 index 0000000..5f8fa00 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/equipment/EqButtonMapper.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + select id, num, name, image, del_flag, remarks, create_by, create_time, update_by, update_time from eq_button + + + + + + + + insert into eq_button + + num, + name, + image, + del_flag, + remarks, + create_by, + create_time, + update_by, + update_time, + + + #{num}, + #{name}, + #{image}, + #{delFlag}, + #{remarks}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update eq_button + + num = #{num}, + name = #{name}, + image = #{image}, + del_flag = #{delFlag}, + remarks = #{remarks}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + diff --git a/evo-admin/src/main/resources/mapper/equipment/EqImagesMapper.xml b/evo-admin/src/main/resources/mapper/equipment/EqImagesMapper.xml new file mode 100644 index 0000000..527b7c2 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/equipment/EqImagesMapper.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + select id, user_id, staff_name, image_url,hours,time_clock, del_flag, create_by, create_time, update_by, update_time from eq_images + + + + + + + + insert into eq_images + + user_id, + staff_name, + image_url, + hours, + time_clock, + del_flag, + create_by, + create_time, + update_by, + update_time, + + + #{userId}, + #{staffName}, + #{imageUrl}, + #{hours}, + #{timeClock}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update eq_images + + user_id = #{userId}, + staff_name = #{staffName}, + image_url = #{imageUrl}, + hours = #{hours}, + time_clock = #{timeClock}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + diff --git a/evo-admin/src/main/resources/mapper/equipment/EqSnDetailMapper.xml b/evo-admin/src/main/resources/mapper/equipment/EqSnDetailMapper.xml new file mode 100644 index 0000000..95ef949 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/equipment/EqSnDetailMapper.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + select id, sn, version_code, version_name, ip, sn_time, type, del_flag, create_time, create_by, update_time, update_by from eq_sn_detail + + + + + + insert into eq_sn_detail + + sn, + version_code, + version_name, + ip, + sn_time, + type, + del_flag, + create_time, + create_by, + + + #{sn}, + #{versionCode}, + #{versionName}, + #{ip}, + #{snTime}, + #{type}, + #{delFlag}, + #{createTime}, + #{createBy}, + + + + + update eq_sn_detail + + sn = #{sn}, + version_code = #{versionCode}, + version_name = #{versionName}, + ip = #{ip}, + sn_time = #{snTime}, + type = #{type}, + del_flag = #{delFlag}, + update_time = #{updateTime}, + update_by = #{updateBy}, + + where id = #{id} + + + + + diff --git a/evo-admin/src/main/resources/mapper/equipment/EqStatusTimeMapper.xml b/evo-admin/src/main/resources/mapper/equipment/EqStatusTimeMapper.xml new file mode 100644 index 0000000..e3946bf --- /dev/null +++ b/evo-admin/src/main/resources/mapper/equipment/EqStatusTimeMapper.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + select id, status, time, remark, del_flag, create_time, create_by, update_time, update_by from eq_status_time + + + + + + + + insert into eq_status_time + + status, + time, + remark, + del_flag, + create_time, + create_by, + update_time, + update_by, + + + #{status}, + #{time}, + #{remark}, + #{delFlag}, + #{createTime}, + #{createBy}, + #{updateTime}, + #{updateBy}, + + + + + update eq_status_time + + status = #{status}, + time = #{time}, + remark = #{remark}, + del_flag = #{delFlag}, + update_time = #{updateTime}, + update_by = #{updateBy}, + + where id = #{id} + + + + diff --git a/evo-admin/src/main/resources/mapper/finance/RzSalaryDetailMapper.xml b/evo-admin/src/main/resources/mapper/finance/RzSalaryDetailMapper.xml new file mode 100644 index 0000000..0174ae7 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/finance/RzSalaryDetailMapper.xml @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, staff_id, name, month, wb_flag, dept_id,month_salary, basic_salary, job_salary, daily_wage, hours_salary, overtime_salary, level_subsidies, contract_subsidies, seniority_salary, social_subsidies, full_subsidies, night_subsidies, dinner_subsidies, subsidy_or_bonus, absenteeism_salary, absenteeism_subsidies, meal_fee, deductions, salary, pay_insurance, endowment_insurance, medical_insurance, employment_injury_insurance, maternity_insurance, unemployment_insurance, accumulation_fund, salary_before_tax, total_wages, annual_exemption_amount, special_deduction, taxable_income, tax_rate, slow_down_the_deduction, aggregate_personal_income_tax, aggregate_tax, tax_payable, net_payroll, remarks, del_flag, create_by, create_time, update_by, update_time from rz_salary_detail + + + + + + + + insert into rz_salary_detail + + staff_id, + name, + month, + wb_flag, + dept_id, + month_salary, + basic_salary, + job_salary, + daily_wage, + hours_salary, + overtime_salary, + level_subsidies, + contract_subsidies, + seniority_salary, + social_subsidies, + full_subsidies, + night_subsidies, + dinner_subsidies, + subsidy_or_bonus, + absenteeism_salary, + absenteeism_subsidies, + meal_fee, + deductions, + salary, + pay_insurance, + endowment_insurance, + medical_insurance, + employment_injury_insurance, + maternity_insurance, + unemployment_insurance, + accumulation_fund, + salary_before_tax, + total_wages, + annual_exemption_amount, + special_deduction, + taxable_income, + tax_rate, + slow_down_the_deduction, + aggregate_personal_income_tax, + tax_payable, + net_payroll, + remarks, + del_flag, + create_by, + create_time, + update_by, + update_time, + + + #{staffId}, + #{name}, + #{month}, + #{wbFlag}, + #{deptId}, + #{monthSalary}, + #{basicSalary}, + #{jobSalary}, + #{dailyWage}, + #{hoursSalary}, + #{overtimeSalary}, + #{levelSubsidies}, + #{contractSubsidies}, + #{senioritySalary}, + #{socialSubsidies}, + #{fullSubsidies}, + #{nightSubsidies}, + #{dinnerSubsidies}, + #{subsidyOrBonus}, + #{absenteeismSalary}, + #{absenteeismSubsidies}, + #{mealFee}, + #{deductions}, + #{salary}, + #{payInsurance}, + #{endowmentInsurance}, + #{medicalInsurance}, + #{employmentInjuryInsurance}, + #{maternityInsurance}, + #{unemploymentInsurance}, + #{accumulationFund}, + #{salaryBeforeTax}, + #{totalWages}, + #{annualExemptionAmount}, + #{specialDeduction}, + #{taxableIncome}, + #{taxRate}, + #{slowDownTheDeduction}, + #{aggregatePersonalIncomeTax}, + #{taxPayable}, + #{netPayroll}, + #{remarks}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update rz_salary_detail + + staff_id = #{staffId}, + name = #{name}, + month = #{month}, + wb_flag = #{wbFlag}, + dept_id = #{deptId}, + month_salary = #{monthSalary}, + basic_salary = #{basicSalary}, + job_salary = #{jobSalary}, + daily_wage = #{dailyWage}, + hours_salary = #{hoursSalary}, + overtime_salary = #{overtimeSalary}, + level_subsidies = #{levelSubsidies}, + contract_subsidies = #{contractSubsidies}, + seniority_salary = #{senioritySalary}, + social_subsidies = #{socialSubsidies}, + full_subsidies = #{fullSubsidies}, + night_subsidies = #{nightSubsidies}, + dinner_subsidies = #{dinnerSubsidies}, + subsidy_or_bonus = #{subsidyOrBonus}, + absenteeism_salary = #{absenteeismSalary}, + absenteeism_subsidies = #{absenteeismSubsidies}, + meal_fee = #{mealFee}, + deductions = #{deductions}, + salary = #{salary}, + pay_insurance = #{payInsurance}, + endowment_insurance = #{endowmentInsurance}, + medical_insurance = #{medicalInsurance}, + employment_injury_insurance = #{employmentInjuryInsurance}, + maternity_insurance = #{maternityInsurance}, + unemployment_insurance = #{unemploymentInsurance}, + accumulation_fund = #{accumulationFund}, + salary_before_tax = #{salaryBeforeTax}, + total_wages = #{totalWages}, + annual_exemption_amount = #{annualExemptionAmount}, + special_deduction = #{specialDeduction}, + taxable_income = #{taxableIncome}, + tax_rate = #{taxRate}, + slow_down_the_deduction = #{slowDownTheDeduction}, + aggregate_personal_income_tax = #{aggregatePersonalIncomeTax}, + tax_payable = #{taxPayable}, + net_payroll = #{netPayroll}, + remarks = #{remarks}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + + + + + + + diff --git a/evo-admin/src/main/resources/mapper/finance/RzSalaryStatisticsMapper.xml b/evo-admin/src/main/resources/mapper/finance/RzSalaryStatisticsMapper.xml new file mode 100644 index 0000000..b2808f1 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/finance/RzSalaryStatisticsMapper.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + select id, month, number, status, remarks, del_flag, create_by, create_time, update_by, update_time from rz_salary_statistics + + + + + + + + insert into rz_salary_statistics + + month, + number, + status, + remarks, + del_flag, + create_by, + create_time, + update_by, + update_time, + + + #{month}, + #{number}, + #{status}, + #{remarks}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update rz_salary_statistics + + month = #{month}, + number = #{number}, + status = #{status}, + remarks = #{remarks}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + diff --git a/evo-admin/src/main/resources/mapper/generator/GenTableColumnMapper.xml b/evo-admin/src/main/resources/mapper/generator/GenTableColumnMapper.xml new file mode 100644 index 0000000..280f9d3 --- /dev/null +++ b/evo-admin/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} + + + + diff --git a/evo-admin/src/main/resources/mapper/generator/GenTableMapper.xml b/evo-admin/src/main/resources/mapper/generator/GenTableMapper.xml new file mode 100644 index 0000000..e33b69c --- /dev/null +++ b/evo-admin/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} + + + + diff --git a/evo-admin/src/main/resources/mapper/personnelMatters/BsOverTimeMapper.xml b/evo-admin/src/main/resources/mapper/personnelMatters/BsOverTimeMapper.xml new file mode 100644 index 0000000..307f453 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/personnelMatters/BsOverTimeMapper.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + update bs_over_time + + work_start = #{workStart}, + work_end = #{workEnd}, + remarks = #{remarks}, + del_flag = #{delFlag}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + diff --git a/evo-admin/src/main/resources/mapper/personnelMatters/EqOverStaffMapper.xml b/evo-admin/src/main/resources/mapper/personnelMatters/EqOverStaffMapper.xml new file mode 100644 index 0000000..5ab128a --- /dev/null +++ b/evo-admin/src/main/resources/mapper/personnelMatters/EqOverStaffMapper.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + select id, user_id, staff_name, image_url, del_flag, create_by, create_time, update_by, update_time from eq_over_staff + + + + + + + + insert into eq_over_staff + + user_id, + staff_name, + image_url, + del_flag, + create_by, + create_time, + update_by, + update_time, + + + #{userId}, + #{staffName}, + #{imageUrl}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update eq_over_staff + + user_id = #{userId}, + staff_name = #{staffName}, + image_url = #{imageUrl}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + + diff --git a/evo-admin/src/main/resources/mapper/personnelMatters/RzBusinessTripDetailMapper.xml b/evo-admin/src/main/resources/mapper/personnelMatters/RzBusinessTripDetailMapper.xml new file mode 100644 index 0000000..c5864ed --- /dev/null +++ b/evo-admin/src/main/resources/mapper/personnelMatters/RzBusinessTripDetailMapper.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + select id, trip_id, name, trip_start_time, trip_end_time, trip_day,over_days, remark, del_flag, create_time, create_by, update_time, update_by from rz_business_trip_detail + + + + + + + + insert into rz_business_trip_detail + + trip_id, + name, + trip_start_time, + trip_end_time, + trip_day, + over_days, + remark, + del_flag, + create_time, + create_by, + update_time, + update_by, + + + #{tripId}, + #{name}, + #{tripStartTime}, + #{tripEndTime}, + #{tripDay}, + #{overDays}, + #{remark}, + #{delFlag}, + #{createTime}, + #{createBy}, + #{updateTime}, + #{updateBy}, + + + + + update rz_business_trip_detail + + trip_id = #{tripId}, + name = #{name}, + trip_start_time = #{tripStartTime}, + trip_end_time = #{tripEndTime}, + trip_day = #{tripDay}, + over_days = #{overDays}, + remark = #{remark}, + del_flag = #{delFlag}, + create_time = #{createTime}, + create_by = #{createBy}, + update_time = #{updateTime}, + update_by = #{updateBy}, + + where id = #{id} + + + + + + + + + diff --git a/evo-admin/src/main/resources/mapper/personnelMatters/RzBusinessTripMapper.xml b/evo-admin/src/main/resources/mapper/personnelMatters/RzBusinessTripMapper.xml new file mode 100644 index 0000000..e6d1877 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/personnelMatters/RzBusinessTripMapper.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + select id, dept_id,user_id, name, trip_date, trip_days,over_days, del_flag, create_by, create_time, update_by, update_time from rz_business_trip + + + + + + + + insert into rz_business_trip + + dept_id, + user_id, + name, + trip_date, + trip_days, + over_days, + del_flag, + create_by, + create_time, + update_by, + update_time, + + + #{deptId}, + #{userId}, + #{name}, + #{tripDate}, + #{tripDays}, + #{overDays}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update rz_business_trip + + dept_id = #{deptId}, + user_id = #{userId}, + name = #{name}, + trip_date = #{tripDate}, + trip_days = #{tripDays}, + over_days = #{overDays}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + + + diff --git a/evo-admin/src/main/resources/mapper/personnelMatters/RzHolidayMapper.xml b/evo-admin/src/main/resources/mapper/personnelMatters/RzHolidayMapper.xml new file mode 100644 index 0000000..d7b8961 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/personnelMatters/RzHolidayMapper.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + select id, holiday, remarks,special_flag,del_flag, create_by, create_time, update_by, update_time from bs_holidays + + + + + + + + insert into bs_holidays + + holiday, + remarks, + special_flag, + del_flag, + create_by, + create_time, + update_by, + update_time, + + + #{holiday}, + #{remarks}, + #{specialFlag}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update bs_holidays + + holiday = #{holiday}, + remarks = #{remarks}, + special_flag = #{specialFlag}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + diff --git a/evo-admin/src/main/resources/mapper/personnelMatters/RzInterviewerMapper.xml b/evo-admin/src/main/resources/mapper/personnelMatters/RzInterviewerMapper.xml new file mode 100644 index 0000000..6b9decf --- /dev/null +++ b/evo-admin/src/main/resources/mapper/personnelMatters/RzInterviewerMapper.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + select id, name, phone, post, content, address, interview_date, yt_flag, remarks, del_flag, create_by, create_time, update_by, update_time from rz_interviewer + + + + + + + + insert into rz_interviewer + + name, + phone, + post, + content, + address, + interview_date, + yt_flag, + remarks, + del_flag, + create_by, + create_time, + update_by, + update_time, + + + #{name}, + #{phone}, + #{post}, + #{content}, + #{address}, + #{interviewDate}, + #{ytFlag}, + #{remarks}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update rz_interviewer + + name = #{name}, + phone = #{phone}, + post = #{post}, + content = #{content}, + address = #{address}, + interview_date = #{interviewDate}, + yt_flag = #{ytFlag}, + remarks = #{remarks}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + diff --git a/evo-admin/src/main/resources/mapper/personnelMatters/RzLeaveDetailMapper.xml b/evo-admin/src/main/resources/mapper/personnelMatters/RzLeaveDetailMapper.xml new file mode 100644 index 0000000..1ef9808 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/personnelMatters/RzLeaveDetailMapper.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + select id, leave_id,name,type, leave_start_time, leave_end_time, leave_hour, remarks, create_time, create_by, update_time, update_by, del_flag from rz_leave_detail + + + + + + + + insert into rz_leave_detail + + leave_id, + name, + type, + leave_start_time, + leave_end_time, + leave_hour, + remarks, + create_time, + create_by, + update_time, + update_by, + del_flag, + + + #{leaveId}, + #{name}, + #{type}, + #{leaveStartTime}, + #{leaveEndTime}, + #{leaveHour}, + #{remarks}, + #{createTime}, + #{createBy}, + #{updateTime}, + #{updateBy}, + #{delFlag}, + + + + + update rz_leave_detail + + name = #{name}, + type = #{type}, + leave_start_time = #{leaveStartTime}, + leave_end_time = #{leaveEndTime}, + leave_hour = #{leaveHour}, + remarks = #{remarks}, + create_time = #{createTime}, + create_by = #{createBy}, + update_time = #{updateTime}, + update_by = #{updateBy}, + leave_id = #{leaveId}, + del_flag = #{delFlag}, + + where id = #{id} + + + + + + + diff --git a/evo-admin/src/main/resources/mapper/personnelMatters/RzLeaveMapper.xml b/evo-admin/src/main/resources/mapper/personnelMatters/RzLeaveMapper.xml new file mode 100644 index 0000000..570c77f --- /dev/null +++ b/evo-admin/src/main/resources/mapper/personnelMatters/RzLeaveMapper.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, user_id, dept_id, name, leave_date, sick_hours, absence_hours, compensatory_hours, marriage_hours, annual_hours, maternity_hours, paternity_hours, funeral_hours, work_hours, del_flag, create_by, create_time, update_by, update_time from rz_leave d + + + + + + + + insert into rz_leave + + user_id, + dept_id, + name, + leave_date, + sick_hours, + absence_hours, + compensatory_hours, + marriage_hours, + annual_hours, + maternity_hours, + paternity_hours, + funeral_hours, + work_hours, + del_flag, + create_by, + create_time, + update_by, + update_time, + + + #{userId}, + #{deptId}, + #{name}, + #{leaveDate}, + #{sickHours}, + #{absenceHours}, + #{compensatoryHours}, + #{marriageHours}, + #{annualHours}, + #{maternityHours}, + #{paternityHours}, + #{funeralHours}, + #{workHours}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update rz_leave + + user_id = #{userId}, + dept_id = #{deptId}, + name = #{name}, + leave_date = #{leaveDate}, + sick_hours = #{sickHours}, + absence_hours = #{absenceHours}, + compensatory_hours = #{compensatoryHours}, + marriage_hours = #{marriageHours}, + annual_hours = #{annualHours}, + maternity_hours = #{maternityHours}, + paternity_hours = #{paternityHours}, + funeral_hours = #{funeralHours}, + work_hours = #{workHours}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + + diff --git a/evo-admin/src/main/resources/mapper/personnelMatters/RzOverTimeDetailMapper.xml b/evo-admin/src/main/resources/mapper/personnelMatters/RzOverTimeDetailMapper.xml new file mode 100644 index 0000000..30e3308 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/personnelMatters/RzOverTimeDetailMapper.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + select id, over_time_id, name, over_time_start, over_time_end, over_time_hours, remark, del_flag, create_time, create_by, update_time, update_by from rz_over_time_detail + + + + + + + + insert into rz_over_time_detail + + over_time_id, + name, + over_time_start, + over_time_end, + over_time_hours, + remark, + del_flag, + create_time, + create_by, + update_time, + update_by, + + + #{overTimeId}, + #{name}, + #{overTimeStart}, + #{overTimeEnd}, + #{overTimeHours}, + #{remark}, + #{delFlag}, + #{createTime}, + #{createBy}, + #{updateTime}, + #{updateBy}, + + + + + update rz_over_time_detail + + over_time_id = #{overTimeId}, + name = #{name}, + over_time_start = #{overTimeStart}, + over_time_end = #{overTimeEnd}, + over_time_hours = #{overTimeHours}, + remark = #{remark}, + del_flag = #{delFlag}, + create_time = #{createTime}, + create_by = #{createBy}, + update_time = #{updateTime}, + update_by = #{updateBy}, + + where id = #{id} + + + + + + + diff --git a/evo-admin/src/main/resources/mapper/personnelMatters/RzOverTimeMapper.xml b/evo-admin/src/main/resources/mapper/personnelMatters/RzOverTimeMapper.xml new file mode 100644 index 0000000..ce0dcc4 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/personnelMatters/RzOverTimeMapper.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + select id, dept_id,user_id, name, over_time_month, over_hours, del_flag, create_by, create_time, update_by, update_time from rz_over_time + + + + + + + + insert into rz_over_time + + dept_id, + user_id, + name, + over_time_month, + over_hours, + del_flag, + create_by, + create_time, + update_by, + update_time, + + + #{deptId}, + #{userId}, + #{name}, + #{overTimeMonth}, + #{overHours}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update rz_over_time + + dept_id = #{deptId}, + user_id = #{userId}, + name = #{name}, + over_time_month = #{overTimeMonth}, + over_hours = #{overHours}, + del_flag = #{delFlag}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + + diff --git a/evo-admin/src/main/resources/mapper/personnelMatters/RzSubsidyMapper.xml b/evo-admin/src/main/resources/mapper/personnelMatters/RzSubsidyMapper.xml new file mode 100644 index 0000000..9f7b73b --- /dev/null +++ b/evo-admin/src/main/resources/mapper/personnelMatters/RzSubsidyMapper.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + select id, name, value, remarks, del_flag, create_by, create_time, update_by, update_time from bs_level_subsidy + + + + + + + + insert into bs_level_subsidy + + name, + value, + remarks, + del_flag, + create_by, + create_time, + update_by, + update_time, + + + #{name}, + #{value}, + #{remarks}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update bs_level_subsidy + + name = #{name}, + value = #{value}, + remarks = #{remarks}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + diff --git a/evo-admin/src/main/resources/mapper/restaurant/RzRestaurantDetailMapper.xml b/evo-admin/src/main/resources/mapper/restaurant/RzRestaurantDetailMapper.xml new file mode 100644 index 0000000..0539f7d --- /dev/null +++ b/evo-admin/src/main/resources/mapper/restaurant/RzRestaurantDetailMapper.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + select id, staff_id,name, date, time, sign, del_flag, create_by, create_time, update_by, update_time from rz_restaurant_detail + + + + + + + + insert into rz_restaurant_detail + + staff_id, + name, + date, + time, + sign, + del_flag, + create_by, + create_time, + update_by, + update_time, + + + #{staffId}, + #{name}, + #{date}, + #{time}, + #{sign}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + diff --git a/evo-admin/src/main/resources/mapper/restaurant/RzRestaurantImagesMapper.xml b/evo-admin/src/main/resources/mapper/restaurant/RzRestaurantImagesMapper.xml new file mode 100644 index 0000000..501df14 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/restaurant/RzRestaurantImagesMapper.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + select id, name, image_url, del_flag, create_by, create_time, update_by, update_time from rz_restaurant_images + + + + + + + + + + insert into rz_restaurant_images + + name, + image_url, + del_flag, + create_by, + create_time, + update_by, + update_time, + + + #{name}, + #{imageUrl}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update rz_restaurant_images + + name = #{name}, + image_url = #{imageUrl}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + diff --git a/evo-admin/src/main/resources/mapper/restaurant/RzRestaurantStatisticsMapper.xml b/evo-admin/src/main/resources/mapper/restaurant/RzRestaurantStatisticsMapper.xml new file mode 100644 index 0000000..7297e31 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/restaurant/RzRestaurantStatisticsMapper.xml @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, staff_id, dept_id, name, month, breakfast_expend, breakfast_number, breakfast_pre_sum_expend, breakfast_sum_expend, lunch_expend, lunch_number, lunch_pre_sum_expend, lunch_sum_expend, supper_expend, supper_number, supper_pre_sum_expend, supper_sum_expend, personal_sum_consumption, sum_consumption, remarks, del_flag, create_by, create_time, update_by, update_time from rz_restaurant_statistics + + + + + + + + insert into rz_restaurant_statistics + + staff_id, + dept_id, + name, + month, + breakfast_expend, + breakfast_number, + breakfast_pre_sum_expend, + breakfast_sum_expend, + lunch_expend, + lunch_number, + lunch_pre_sum_expend, + lunch_sum_expend, + supper_expend, + supper_number, + supper_pre_sum_expend, + supper_sum_expend, + personal_sum_consumption, + sum_consumption, + remarks, + del_flag, + create_by, + create_time, + update_by, + update_time, + + + #{staffId}, + #{deptId}, + #{name}, + #{month}, + #{breakfastExpend}, + #{breakfastNumber}, + #{breakfastPreSumExpend}, + #{breakfastSumExpend}, + #{lunchExpend}, + #{lunchNumber}, + #{lunchPreSumExpend}, + #{lunchSumExpend}, + #{supperExpend}, + #{supperNumber}, + #{supperPreSumExpend}, + #{supperSumExpend}, + #{personalSumConsumption}, + #{sumConsumption}, + #{remarks}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update rz_restaurant_statistics + + staff_id = #{staffId}, + dept_id = #{deptId}, + name = #{name}, + month = #{month}, + breakfast_expend = #{breakfastExpend}, + breakfast_number = #{breakfastNumber}, + breakfast_pre_sum_expend = #{breakfastPreSumExpend}, + breakfast_sum_expend = #{breakfastSumExpend}, + lunch_expend = #{lunchExpend}, + lunch_number = #{lunchNumber}, + lunch_pre_sum_expend = #{lunchPreSumExpend}, + lunch_sum_expend = #{lunchSumExpend}, + supper_expend = #{supperExpend}, + supper_number = #{supperNumber}, + supper_pre_sum_expend = #{supperPreSumExpend}, + supper_sum_expend = #{supperSumExpend}, + personal_sum_consumption = #{personalSumConsumption}, + sum_consumption = #{sumConsumption}, + remarks = #{remarks}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + + + + diff --git a/evo-admin/src/main/resources/mapper/system/SysDeptMapper.xml b/evo-admin/src/main/resources/mapper/system/SysDeptMapper.xml new file mode 100644 index 0000000..d2c5c6a --- /dev/null +++ b/evo-admin/src/main/resources/mapper/system/SysDeptMapper.xml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.leader, d.phone,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, + leader, + phone, + status, + create_by, + create_time + )values( + #{deptId}, + #{parentId}, + #{deptName}, + #{ancestors}, + #{leader}, + #{phone}, + #{status}, + #{createBy}, + sysdate() + ) + + + + update sys_dept + + parent_id = #{parentId}, + dept_name = #{deptName}, + ancestors = #{ancestors}, + leader = #{leader}, + phone = #{phone}, + 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 = '1' where dept_id = #{deptId} + + + + + + + + + + update sys_dept set leader = #{leader},phone = #{phone},update_by = #{updateBy},update_time = sysdate() + where dept_id = #{deptId} + + diff --git a/evo-admin/src/main/resources/mapper/system/SysDictDataMapper.xml b/evo-admin/src/main/resources/mapper/system/SysDictDataMapper.xml new file mode 100644 index 0000000..2c365d0 --- /dev/null +++ b/evo-admin/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() + ) + + + diff --git a/evo-admin/src/main/resources/mapper/system/SysDictTypeMapper.xml b/evo-admin/src/main/resources/mapper/system/SysDictTypeMapper.xml new file mode 100644 index 0000000..e9efaf9 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/system/SysDictTypeMapper.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + 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() + ) + + + diff --git a/evo-admin/src/main/resources/mapper/system/SysLogininforMapper.xml b/evo-admin/src/main/resources/mapper/system/SysLogininforMapper.xml new file mode 100644 index 0000000..def7f6b --- /dev/null +++ b/evo-admin/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 + + + diff --git a/evo-admin/src/main/resources/mapper/system/SysMenuMapper.xml b/evo-admin/src/main/resources/mapper/system/SysMenuMapper.xml new file mode 100644 index 0000000..2a5e7ca --- /dev/null +++ b/evo-admin/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} + + + diff --git a/evo-admin/src/main/resources/mapper/system/SysOperLogMapper.xml b/evo-admin/src/main/resources/mapper/system/SysOperLogMapper.xml new file mode 100644 index 0000000..d9f348b --- /dev/null +++ b/evo-admin/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 + + + diff --git a/evo-admin/src/main/resources/mapper/system/SysRoleDeptMapper.xml b/evo-admin/src/main/resources/mapper/system/SysRoleDeptMapper.xml new file mode 100644 index 0000000..7d95070 --- /dev/null +++ b/evo-admin/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}) + + + + diff --git a/evo-admin/src/main/resources/mapper/system/SysRoleMapper.xml b/evo-admin/src/main/resources/mapper/system/SysRoleMapper.xml new file mode 100644 index 0000000..47d5af8 --- /dev/null +++ b/evo-admin/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 = '1' where role_id = #{roleId} + + + + update sys_role set del_flag = '1' where role_id in + + #{roleId} + + + + diff --git a/evo-admin/src/main/resources/mapper/system/SysRoleMenuMapper.xml b/evo-admin/src/main/resources/mapper/system/SysRoleMenuMapper.xml new file mode 100644 index 0000000..b67b59c --- /dev/null +++ b/evo-admin/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}) + + + + diff --git a/evo-admin/src/main/resources/mapper/system/SysStaffDetailMapper.xml b/evo-admin/src/main/resources/mapper/system/SysStaffDetailMapper.xml new file mode 100644 index 0000000..d68630f --- /dev/null +++ b/evo-admin/src/main/resources/mapper/system/SysStaffDetailMapper.xml @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, staff_id, basic_salary, jobs_salary,count_insurance, daily_wage, hours_salary, full_frequently_subsidies, middle_subsidies,level_of_education_subsidies, contract_subsidies, seniority_subsidies, social_security_subsidies, night_shift_subsidies, dinner_subsidies, fixed_allowance, other_subsidies, breakfast_expend, lunch_expend, supper_expend, subsidy_deduct_money, deductions, endowment_insurance, medical_insurance, employment_injury_insurance, maternity_insurance, unemployment_insurance, accumulation_fund, children_education, support_the_old, housing_loans, housing_rents, adult_education, treatment_for_serious_disease, special_deduction, total_wages, aggregate_personal_income_tax, remarks, del_flag, create_by, create_time, update_by, update_time from sys_staff_detail + + + + + + + + insert into sys_staff_detail + + staff_id, + basic_salary, + jobs_salary, + daily_wage, + hours_salary, + full_frequently_subsidies, + level_of_education_subsidies, + contract_subsidies, + seniority_subsidies, + social_security_subsidies, + night_shift_subsidies, + dinner_subsidies, + fixed_allowance, + other_subsidies, + breakfast_expend, + lunch_expend, + supper_expend, + subsidy_deduct_money, + deductions, + endowment_insurance, + medical_insurance, + employment_injury_insurance, + maternity_insurance, + unemployment_insurance, + accumulation_fund, + children_education, + support_the_old, + housing_loans, + housing_rents, + adult_education, + treatment_for_serious_disease, + special_deduction, + total_wages, + aggregate_personal_income_tax, + remarks, + del_flag, + create_by, + create_time, + update_by, + update_time, + count_insurance, + middle_subsidies, + + + #{staffId}, + #{basicSalary}, + #{jobsSalary}, + #{dailyWage}, + #{hoursSalary}, + #{fullFrequentlySubsidies}, + #{levelOfEducationSubsidies}, + #{contractSubsidies}, + #{senioritySubsidies}, + #{socialSecuritySubsidies}, + #{nightShiftSubsidies}, + #{dinnerSubsidies}, + #{fixedAllowance}, + #{otherSubsidies}, + #{breakfastExpend}, + #{lunchExpend}, + #{supperExpend}, + #{subsidyDeductMoney}, + #{deductions}, + #{endowmentInsurance}, + #{medicalInsurance}, + #{employmentInjuryInsurance}, + #{maternityInsurance}, + #{unemploymentInsurance}, + #{accumulationFund}, + #{childrenEducation}, + #{supportTheOld}, + #{housingLoans}, + #{housingRents}, + #{adultEducation}, + #{treatmentForSeriousDisease}, + #{specialDeduction}, + #{totalWages}, + #{aggregatePersonalIncomeTax}, + #{remarks}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{countInsurance}, + #{middleSubsidies}, + + + + + update sys_staff_detail + + staff_id = #{staffId}, + basic_salary = #{basicSalary}, + jobs_salary = #{jobsSalary}, + daily_wage = #{dailyWage}, + hours_salary = #{hoursSalary}, + full_frequently_subsidies = #{fullFrequentlySubsidies}, + level_of_education_subsidies = #{levelOfEducationSubsidies}, + contract_subsidies = #{contractSubsidies}, + seniority_subsidies = #{senioritySubsidies}, + social_security_subsidies = #{socialSecuritySubsidies}, + night_shift_subsidies = #{nightShiftSubsidies}, + dinner_subsidies = #{dinnerSubsidies}, + fixed_allowance = #{fixedAllowance}, + other_subsidies = #{otherSubsidies}, + breakfast_expend = #{breakfastExpend}, + lunch_expend = #{lunchExpend}, + supper_expend = #{supperExpend}, + subsidy_deduct_money = #{subsidyDeductMoney}, + deductions = #{deductions}, + endowment_insurance = #{endowmentInsurance}, + medical_insurance = #{medicalInsurance}, + employment_injury_insurance = #{employmentInjuryInsurance}, + maternity_insurance = #{maternityInsurance}, + unemployment_insurance = #{unemploymentInsurance}, + accumulation_fund = #{accumulationFund}, + children_education = #{childrenEducation}, + support_the_old = #{supportTheOld}, + housing_loans = #{housingLoans}, + housing_rents = #{housingRents}, + adult_education = #{adultEducation}, + treatment_for_serious_disease = #{treatmentForSeriousDisease}, + special_deduction = #{specialDeduction}, + total_wages = #{totalWages}, + aggregate_personal_income_tax = #{aggregatePersonalIncomeTax}, + remarks = #{remarks}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + count_insurance = #{countInsurance}, + middle_subsidies = #{middleSubsidies}, + + where id = #{id} + + + + + + update sys_staff_detail set other_subsidies = 0.00,deductions = 0.00 + + diff --git a/evo-admin/src/main/resources/mapper/system/SysStaffMapper.xml b/evo-admin/src/main/resources/mapper/system/SysStaffMapper.xml new file mode 100644 index 0000000..2a083a4 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/system/SysStaffMapper.xml @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select user_id,company_name, dept_id, code, name, id_card,is_leader, sex, age, phone, address, level, major, school, bank_number,social_subsidy, bank, employment_date, experience, worker_term, regular_date, quit_date, contract_start, contract_end, contract_type, social_type, seniority, is_overtime_pay, zs_flag, secrecy, injury, insurance, introducer, clock_in, status, wages_ratio_date, remarks, del_flag, create_by, create_time, update_by, update_time from sys_staff + + + + + + + + insert into sys_staff + + company_name, + dept_id, + code, + name, + id_card, + is_leader, + sex, + age, + phone, + address, + level, + major, + school, + bank_number, + bank, + employment_date, + experience, + worker_term, + regular_date, + quit_date, + contract_start, + contract_end, + contract_type, + social_type, + seniority, + is_overtime_pay, + zs_flag, + secrecy, + injury, + insurance, + introducer, + clock_in, + status, + wages_ratio_date, + remarks, + del_flag, + create_by, + create_time, + update_by, + update_time, + social_subsidy, + + + #{companyName}, + #{deptId}, + #{code}, + #{name}, + #{idCard}, + #{isLeader}, + #{sex}, + #{age}, + #{phone}, + #{address}, + #{level}, + #{major}, + #{school}, + #{bankNumber}, + #{bank}, + #{employmentDate}, + #{experience}, + #{workerTerm}, + #{regularDate}, + #{quitDate}, + #{contractStart}, + #{contractEnd}, + #{contractType}, + #{socialType}, + #{seniority}, + #{isOvertimePay}, + #{zsFlag}, + #{secrecy}, + #{injury}, + #{insurance}, + #{introducer}, + #{clockIn}, + #{status}, + #{wagesRatioDate}, + #{remarks}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{socialSubsidy}, + + + + + update sys_staff + + company_name = #{companyName}, + dept_id = #{deptId}, + code = #{code}, + name = #{name}, + id_card = #{idCard}, + is_leader = #{isLeader}, + sex = #{sex}, + age = #{age}, + phone = #{phone}, + address = #{address}, + level = #{level}, + major = #{major}, + school = #{school}, + bank_number = #{bankNumber}, + bank = #{bank}, + employment_date = #{employmentDate}, + experience = #{experience}, + worker_term = #{workerTerm}, + regular_date = #{regularDate}, + quit_date = #{quitDate}, + contract_start = #{contractStart}, + contract_end = #{contractEnd}, + contract_type = #{contractType}, + social_type = #{socialType}, + seniority = #{seniority}, + is_overtime_pay = #{isOvertimePay}, + zs_flag = #{zsFlag}, + secrecy = #{secrecy}, + injury = #{injury}, + insurance = #{insurance}, + introducer = #{introducer}, + clock_in = #{clockIn}, + status = #{status}, + wages_ratio_date = #{wagesRatioDate}, + remarks = #{remarks}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + social_subsidy = #{socialSubsidy}, + + where user_id = #{userId} + + + + + + + + + + + + + + diff --git a/evo-admin/src/main/resources/mapper/system/SysUserMapper.xml b/evo-admin/src/main/resources/mapper/system/SysUserMapper.xml new file mode 100644 index 0000000..2dffc52 --- /dev/null +++ b/evo-admin/src/main/resources/mapper/system/SysUserMapper.xml @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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.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 = '1' where user_id = #{userId} + + + + update sys_user set del_flag = '1' where user_id in + + #{userId} + + + + diff --git a/evo-admin/src/main/resources/mapper/system/SysUserRoleMapper.xml b/evo-admin/src/main/resources/mapper/system/SysUserRoleMapper.xml new file mode 100644 index 0000000..9ad20da --- /dev/null +++ b/evo-admin/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} + + + diff --git a/evo-admin/src/main/resources/mybatis/mybatis-config.xml b/evo-admin/src/main/resources/mybatis/mybatis-config.xml new file mode 100644 index 0000000..ac47c03 --- /dev/null +++ b/evo-admin/src/main/resources/mybatis/mybatis-config.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/evo-admin/src/main/resources/vm/java/controller.java.vm b/evo-admin/src/main/resources/vm/java/controller.java.vm new file mode 100644 index 0000000..f9d3970 --- /dev/null +++ b/evo-admin/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.evo.common.annotation.Log; +import com.evo.common.core.controller.BaseController; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.enums.BusinessType; +import ${packageName}.domain.${ClassName}; +import ${packageName}.service.I${ClassName}Service; +import com.evo.common.utils.poi.ExcelUtil; +#if($table.crud || $table.sub) +import com.evo.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/evo-admin/src/main/resources/vm/java/domain.java.vm b/evo-admin/src/main/resources/vm/java/domain.java.vm new file mode 100644 index 0000000..b8e605c --- /dev/null +++ b/evo-admin/src/main/resources/vm/java/domain.java.vm @@ -0,0 +1,105 @@ +package ${packageName}.domain; + +#foreach ($import in $importList) +import ${import}; +#end +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.evo.common.annotation.Excel; +#if($table.crud || $table.sub) +import com.evo.common.core.domain.BaseEntity; +#elseif($table.tree) +import com.evo.common.core.domain.TreeEntity; +#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/evo-admin/src/main/resources/vm/java/mapper.java.vm b/evo-admin/src/main/resources/vm/java/mapper.java.vm new file mode 100644 index 0000000..7e7d7c2 --- /dev/null +++ b/evo-admin/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/evo-admin/src/main/resources/vm/java/service.java.vm b/evo-admin/src/main/resources/vm/java/service.java.vm new file mode 100644 index 0000000..264882b --- /dev/null +++ b/evo-admin/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/evo-admin/src/main/resources/vm/java/serviceImpl.java.vm b/evo-admin/src/main/resources/vm/java/serviceImpl.java.vm new file mode 100644 index 0000000..b925863 --- /dev/null +++ b/evo-admin/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.evo.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.evo.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/evo-admin/src/main/resources/vm/java/sub-domain.java.vm b/evo-admin/src/main/resources/vm/java/sub-domain.java.vm new file mode 100644 index 0000000..0d6fc91 --- /dev/null +++ b/evo-admin/src/main/resources/vm/java/sub-domain.java.vm @@ -0,0 +1,76 @@ +package ${packageName}.domain; + +#foreach ($import in $subImportList) +import ${import}; +#end +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; + +/** + * ${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/evo-admin/src/main/resources/vm/js/api.js.vm b/evo-admin/src/main/resources/vm/js/api.js.vm new file mode 100644 index 0000000..9295524 --- /dev/null +++ b/evo-admin/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/evo-admin/src/main/resources/vm/sql/sql.vm b/evo-admin/src/main/resources/vm/sql/sql.vm new file mode 100644 index 0000000..0575583 --- /dev/null +++ b/evo-admin/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/evo-admin/src/main/resources/vm/vue/index-tree.vue.vm b/evo-admin/src/main/resources/vm/vue/index-tree.vue.vm new file mode 100644 index 0000000..4819c2a --- /dev/null +++ b/evo-admin/src/main/resources/vm/vue/index-tree.vue.vm @@ -0,0 +1,505 @@ + + + diff --git a/evo-admin/src/main/resources/vm/vue/index.vue.vm b/evo-admin/src/main/resources/vm/vue/index.vue.vm new file mode 100644 index 0000000..6296014 --- /dev/null +++ b/evo-admin/src/main/resources/vm/vue/index.vue.vm @@ -0,0 +1,602 @@ + + + diff --git a/evo-admin/src/main/resources/vm/vue/v3/index-tree.vue.vm b/evo-admin/src/main/resources/vm/vue/v3/index-tree.vue.vm new file mode 100644 index 0000000..c54d62b --- /dev/null +++ b/evo-admin/src/main/resources/vm/vue/v3/index-tree.vue.vm @@ -0,0 +1,474 @@ + + + diff --git a/evo-admin/src/main/resources/vm/vue/v3/index.vue.vm b/evo-admin/src/main/resources/vm/vue/v3/index.vue.vm new file mode 100644 index 0000000..8b25665 --- /dev/null +++ b/evo-admin/src/main/resources/vm/vue/v3/index.vue.vm @@ -0,0 +1,590 @@ + + + diff --git a/evo-admin/src/main/resources/vm/xml/mapper.xml.vm b/evo-admin/src/main/resources/vm/xml/mapper.xml.vm new file mode 100644 index 0000000..456755b --- /dev/null +++ b/evo-admin/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/pom.xml b/pom.xml new file mode 100644 index 0000000..0c76d43 --- /dev/null +++ b/pom.xml @@ -0,0 +1,189 @@ + + + 4.0.0 + + com.evo + evo + 3.8.8 + + evo + 伊特管理系统 + + + 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.3 + 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} + + + + + + evo-admin + + 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 + + + + + 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..5288970 --- /dev/null +++ b/ry.sh @@ -0,0 +1,86 @@ +#!/bin/sh +# ./ry.sh start 启动 stop 停止 restart 重启 status 状态 +AppName=evo-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 From d3943bad8c6ba40d0ae6a3ea724bb68d3bc75e25 Mon Sep 17 00:00:00 2001 From: lhb <495598773@qq.com> Date: Mon, 5 May 2025 17:32:37 +0800 Subject: [PATCH 2/8] =?UTF-8?q?fix:=E4=BF=AE=E6=94=B9=E8=A1=A5=E5=8D=A1?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E5=90=8C=E6=AD=A5=E6=9B=B4=E6=96=B0=E8=80=83?= =?UTF-8?q?=E5=8B=A4=E7=BB=9F=E8=AE=A1=E4=BF=A1=E6=81=AF=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapper/RzAttendanceStatisticalMapper.java | 6 ++ .../service/IRzAttendanceService.java | 8 +++ .../service/impl/RzAttendanceServiceImpl.java | 60 ++++++++++++++++++- .../RzAttendanceStatisticalMapper.xml | 6 ++ 4 files changed, 79 insertions(+), 1 deletion(-) diff --git a/evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceStatisticalMapper.java b/evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceStatisticalMapper.java index 52b1372..09d5d8a 100644 --- a/evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceStatisticalMapper.java +++ b/evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceStatisticalMapper.java @@ -59,4 +59,10 @@ public interface RzAttendanceStatisticalMapper */ public List queryStatisticalByMonth(Date month); + /** + * 查询某个人考勤月的考勤统计信息 * + * @return 考勤统计集合 + */ + public List queryStatisticalByMonthAndName(@Param("attendanceDate") Date attendanceDate,@Param("name") String name); + } diff --git a/evo-admin/src/main/java/com/evo/attendance/service/IRzAttendanceService.java b/evo-admin/src/main/java/com/evo/attendance/service/IRzAttendanceService.java index 3187688..e35999d 100644 --- a/evo-admin/src/main/java/com/evo/attendance/service/IRzAttendanceService.java +++ b/evo-admin/src/main/java/com/evo/attendance/service/IRzAttendanceService.java @@ -52,4 +52,12 @@ public interface IRzAttendanceService * @return 考勤记录集合 */ public List listAttendanceByParams(RzAttendance rzAttendance); + + /** + * 手动更改考勤记录时更新考勤统计信息 + * + * @param rzAttendance 考勤记录 + * @return 考勤记录集合 + */ + public AjaxResult upateStatisticalByRzAttendance(RzAttendance rzAttendance); } diff --git a/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceServiceImpl.java b/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceServiceImpl.java index 8b9e24b..ad12e8e 100644 --- a/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceServiceImpl.java +++ b/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceServiceImpl.java @@ -1,5 +1,6 @@ package com.evo.attendance.service.impl; +import com.evo.attendance.domain.RzAttendanceStatistical; import com.evo.common.annotation.DataScope; import com.evo.common.core.domain.AjaxResult; import com.evo.common.core.domain.entity.SysDept; @@ -10,11 +11,15 @@ import com.evo.attendance.mapper.RzAttendanceMapper; import com.evo.attendance.mapper.RzAttendanceStatisticalMapper; import com.evo.attendance.service.IRzAttendanceService; import com.evo.common.utils.StringUtils; +import com.evo.personnelMatters.domain.RzOverTime; +import com.evo.personnelMatters.mapper.RzOverTimeMapper; import com.evo.system.mapper.SysDeptMapper; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.ZoneId; import java.util.Date; import java.util.List; @@ -33,6 +38,8 @@ public class RzAttendanceServiceImpl implements IRzAttendanceService private SysDeptMapper deptMapper; //部门 @Resource private RzAttendanceStatisticalMapper rzAttendanceStatisticalMapper; //考勤汇总 + @Resource + private RzOverTimeMapper rzOverTimeMapper; /** * 查询考勤记录 @@ -89,7 +96,12 @@ public class RzAttendanceServiceImpl implements IRzAttendanceService rzAttendance.setYcxFlag("0"); rzAttendance.setUpdateBy(SecurityUtils.getUsername()); rzAttendance.setUpdateTime(DateUtils.getNowDate()); - return rzAttendanceMapper.updateRzAttendance(rzAttendance); + + int count = rzAttendanceMapper.updateRzAttendance(rzAttendance); + if (count >0) { + upateStatisticalByRzAttendance(rzAttendance); + } + return count; } /** @@ -189,4 +201,50 @@ public class RzAttendanceServiceImpl implements IRzAttendanceService return rzAttendanceMapper.listAttendanceByParams(rzAttendance); } + public static int getMonthFromDate(Date date) { + if (date == null) { + return -1; // 或者抛出异常 + } + LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + return localDate.getMonthValue(); // 返回 1-12 + } + + /** + * 手动更改考勤记录时更新考勤统计信息 + * + * @param rzAttendance 考勤记录 + * @return 考勤记录集合 + */ + public AjaxResult upateStatisticalByRzAttendance(RzAttendance rzAttendance) { + + //查询条件月统计的数据 + List ms_list = rzAttendanceStatisticalMapper.queryStatisticalByMonthAndName(rzAttendance.getAttendanceDate(),rzAttendance.getName()); + if (null != ms_list && ms_list.size() > 0) { + //初始化打卡记录 + RzAttendanceStatistical attendanceStatistical = ms_list.get(0); + attendanceStatistical.setEssentialAttendance(new BigDecimal("0.0")); + attendanceStatistical.setWorkOvertimeNumber(new BigDecimal("0.0")); + attendanceStatistical.setMiddleShiftNumber(0l); + attendanceStatistical.setNightNumber(0l); + //查询打卡记录 +// RzAttendance rzAttendance = new RzAttendance(); + rzAttendance.setAttendanceDate(rzAttendance.getAttendanceDate()); + rzAttendance.setStaffId(attendanceStatistical.getStaffId()); + List at_list = rzAttendanceMapper.listAttendanceByParams(rzAttendance); + for (RzAttendance attendance : at_list) { + attendanceStatistical.setEssentialAttendance(attendanceStatistical.getEssentialAttendance().add(attendance.getWorkSum())); + attendanceStatistical.setMiddleShiftNumber(attendanceStatistical.getMiddleShiftNumber() + attendance.getMiddleShiftNumber()); + attendanceStatistical.setNightNumber(attendanceStatistical.getNightNumber() + attendance.getNightNumber()); + } + //获取加班数据 + RzOverTime rzOverTime = rzOverTimeMapper.selectRzOverTimeByNameAndMonth(attendanceStatistical.getStaffId(), rzAttendance.getAttendanceDate()); + if (StringUtils.isNotNull(rzOverTime)) { + attendanceStatistical.setWorkOvertimeNumber(rzOverTime.getOverHours()); + } + attendanceStatistical.setRealAttendance(attendanceStatistical.getEssentialAttendance().add(attendanceStatistical.getWorkOvertimeNumber())); + rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(attendanceStatistical); + } + return AjaxResult.success(); + } + } diff --git a/evo-admin/src/main/resources/mapper/attendance/RzAttendanceStatisticalMapper.xml b/evo-admin/src/main/resources/mapper/attendance/RzAttendanceStatisticalMapper.xml index 074dae8..00f05f1 100644 --- a/evo-admin/src/main/resources/mapper/attendance/RzAttendanceStatisticalMapper.xml +++ b/evo-admin/src/main/resources/mapper/attendance/RzAttendanceStatisticalMapper.xml @@ -136,4 +136,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where DATE_FORMAT( month, '%Y%m' ) = DATE_FORMAT(#{month} , '%Y%m' ) AND del_flag = '0' + + + From d6896c1783f413f1381b6c7f26a70fba7e610e55 Mon Sep 17 00:00:00 2001 From: lhb <495598773@qq.com> Date: Wed, 7 May 2025 08:41:48 +0800 Subject: [PATCH 3/8] =?UTF-8?q?fix:=E6=89=93=E5=8D=A1=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/evo/attendance/mapper/RzAttendanceDetailMapper.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceDetailMapper.java b/evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceDetailMapper.java index 9882e8f..15244da 100644 --- a/evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceDetailMapper.java +++ b/evo-admin/src/main/java/com/evo/attendance/mapper/RzAttendanceDetailMapper.java @@ -44,9 +44,7 @@ public interface RzAttendanceDetailMapper * @param staffId * @return 考勤明细集合 */ - public default RzAttendanceDetail selectRzAttendanceDetailByStaffId(@Param("staffId") Long staffId) { - return null; - } + public RzAttendanceDetail selectRzAttendanceDetailByStaffId(@Param("staffId") Long staffId); public List selectRzAttendanceDetailByMonth(Date date); From 7dd42131c05ee17b81b99dda4055b2b22c84430b Mon Sep 17 00:00:00 2001 From: lhb <495598773@qq.com> Date: Wed, 7 May 2025 14:57:37 +0800 Subject: [PATCH 4/8] =?UTF-8?q?fix:=E6=97=A7=E7=B3=BB=E7=BB=9F=E5=8E=86?= =?UTF-8?q?=E5=8F=B2=E6=95=B0=E6=8D=AE=E8=BF=81=E7=A7=BB=E5=88=B0=E6=96=B0?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/RzSalaryDetailServiceImpl.java | 8 +- .../RzRestaurantDetailController.java | 10 + .../restaurant/domain/CyConsumptionInfo.java | 384 ++++++++++++++++++ .../mapper/RzRestaurantStatisticsMapper.java | 5 + .../service/IRzRestaurantDetailService.java | 2 + .../impl/RzRestaurantDetailServiceImpl.java | 146 +++++++ .../RzRestaurantStatisticsMapper.xml | 46 +++ 7 files changed, 597 insertions(+), 4 deletions(-) create mode 100644 evo-admin/src/main/java/com/evo/restaurant/domain/CyConsumptionInfo.java diff --git a/evo-admin/src/main/java/com/evo/finance/service/impl/RzSalaryDetailServiceImpl.java b/evo-admin/src/main/java/com/evo/finance/service/impl/RzSalaryDetailServiceImpl.java index fe3a615..dffe6b0 100644 --- a/evo-admin/src/main/java/com/evo/finance/service/impl/RzSalaryDetailServiceImpl.java +++ b/evo-admin/src/main/java/com/evo/finance/service/impl/RzSalaryDetailServiceImpl.java @@ -401,18 +401,18 @@ public class RzSalaryDetailServiceImpl implements IRzSalaryDetailService if(sysStaffDetail.getDailyWage().doubleValue() > 0) { //额薪资日期在工资月下一个月 calendar.set(Calendar.MONTH,1); - //全额薪资日期在工资月以前 - if(sysStaff.getWagesRatioDate().before(month)) { + //全额薪资日期在工资月以前----null != sysStaff.getWagesRatioDate() && + if(null != sysStaff.getWagesRatioDate() && sysStaff.getWagesRatioDate().before(month)) { sysStaffDetail.setBasicSalary(sysStaffDetail.getDailyWage().divide(new BigDecimal("8.0"),2, RoundingMode.HALF_UP) .multiply(rzAttendanceStatistical.getRealAttendance().add(rzAttendanceStatistical.getWorkOvertimeNumber()))); - }else if(sysStaff.getWagesRatioDate().after(calendar.getTime())) { + }else if(null != sysStaff.getWagesRatioDate() && sysStaff.getWagesRatioDate().after(calendar.getTime())) { sysStaffDetail.setBasicSalary(sysStaffDetail.getDailyWage().divide(new BigDecimal("8.0"),2, RoundingMode.HALF_UP) .multiply(rzAttendanceStatistical.getRealAttendance().add(rzAttendanceStatistical.getWorkOvertimeNumber())).multiply(new BigDecimal(Constants.SUBSIDY_PERIOD))); }else { //根据转正日期,查询员工的打卡信息 BigDecimal att_work = new BigDecimal("0.0"); for (RzAttendance rzAttendance : att_list) { - if(rzAttendance.getAttendanceDate().before(sysStaff.getWagesRatioDate())) { + if(null != sysStaff.getWagesRatioDate() && rzAttendance.getAttendanceDate().before(sysStaff.getWagesRatioDate())) { att_work = att_work.add(rzAttendance.getWorkSum()); } } diff --git a/evo-admin/src/main/java/com/evo/restaurant/controller/RzRestaurantDetailController.java b/evo-admin/src/main/java/com/evo/restaurant/controller/RzRestaurantDetailController.java index eba4712..09e070b 100644 --- a/evo-admin/src/main/java/com/evo/restaurant/controller/RzRestaurantDetailController.java +++ b/evo-admin/src/main/java/com/evo/restaurant/controller/RzRestaurantDetailController.java @@ -85,5 +85,15 @@ public class RzRestaurantDetailController extends BaseController return getDataTable(list); } + /** + * 新旧系统切换临时处理历史数据方法 + * @param + * @return + */ + @RequestMapping("/initDaka") + public String initDaka(){ + return rzRestaurantDetailService.initRzRestaurantDetail(); + } + } diff --git a/evo-admin/src/main/java/com/evo/restaurant/domain/CyConsumptionInfo.java b/evo-admin/src/main/java/com/evo/restaurant/domain/CyConsumptionInfo.java new file mode 100644 index 0000000..e5e979e --- /dev/null +++ b/evo-admin/src/main/java/com/evo/restaurant/domain/CyConsumptionInfo.java @@ -0,0 +1,384 @@ +package com.evo.restaurant.domain; + +import java.util.Date; + +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 餐饮消费明细对象 cy_consumption_info + * + * @author zhukangchao + * @date 2023-10-05 + */ +public class CyConsumptionInfo extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 月统计id */ + private Long statisticsId; + + /** 日期 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date dateTime; + + private String dateTime1; + + public String getDateTime1() { + return dateTime1; + } + + public void setDateTime1(String dateTime1) { + this.dateTime1 = dateTime1; + } + + /** 姓名 */ + @Excel(name = "姓名") + private String name; + + /** 上班卡 */ + @Excel(name = "上班卡") + private String shangBan; + + /** 下班卡 */ + @Excel(name = "下班卡") + private String xiaBan; + + /** 工作时长 */ + @Excel(name = "工作时长") + private Double duration; + + /** 早餐次数 */ + @Excel(name = "早餐次数") + private Long breakfastNumber; + + /** 早餐补助 */ + @Excel(name = "早餐补助") + private Double breakfastSubsidy; + + /** 早餐个人消费 */ + @Excel(name = "早餐个人消费") + private Double breakfastPersonalConsumption; + + /** 早餐总消费 */ + @Excel(name = "早餐总消费") + private Double breakfastSumConsumption; + + /** 午餐次数 */ + @Excel(name = "午餐次数") + private Long lunchNumber; + + /** 午餐补助 */ + @Excel(name = "午餐补助") + private Double lunchSubsidy; + + /** 午餐个人消费 */ + @Excel(name = "午餐个人消费") + private Double lunchPresonalConsumption; + + /** 午餐总消费 */ + @Excel(name = "午餐总消费") + private Double lunchSumConsumption; + + /** 晚餐次数 */ + @Excel(name = "晚餐次数") + private Long supperNumber; + + /** 晚餐补助 */ + @Excel(name = "晚餐补助") + private Double supperSubsidy; + + /** 晚餐个人消费 */ + @Excel(name = "晚餐个人消费") + private Double supperPersonalConsumption; + + /** 晚餐总消费 */ + @Excel(name = "晚餐总消费") + private Double supperSumConsumption; + + /** 总补贴 */ + @Excel(name = "总补贴") + private Double sumSubsidy; + + /** 个人总消费 */ + @Excel(name = "个人总消费") + private Double personalSumConsumption; + + /** 总消费 */ + @Excel(name = "总消费") + private Double sumConsumption; + + /** 备用字段1 */ + @Excel(name = "备用字段1") + private String sparedOne; + + /** 备用字段2 */ + @Excel(name = "备用字段2") + private String sparedTwo; + + /** 备用字段3 */ + @Excel(name = "备用字段3") + private Long sparedThree; + + /** 备用字段4 */ + @Excel(name = "备用字段4") + private Long sparedFour; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + + public Long getStatisticsId() { + return statisticsId; + } + + public void setStatisticsId(Long statisticsId) { + this.statisticsId = statisticsId; + } + + public void setDateTime(Date dateTime) + { + this.dateTime = dateTime; + } + + public Date getDateTime() + { + return dateTime; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setShangBan(String shangBan) + { + this.shangBan = shangBan; + } + + public String getShangBan() + { + return shangBan; + } + public void setXiaBan(String xiaBan) + { + this.xiaBan = xiaBan; + } + + public String getXiaBan() + { + return xiaBan; + } + public void setDuration(Double duration) + { + this.duration = duration; + } + + public Double getDuration() + { + return duration; + } + public void setBreakfastNumber(Long breakfastNumber) + { + this.breakfastNumber = breakfastNumber; + } + + public Long getBreakfastNumber() + { + return breakfastNumber; + } + public void setBreakfastSubsidy(Double breakfastSubsidy) + { + this.breakfastSubsidy = breakfastSubsidy; + } + + public Double getBreakfastSubsidy() + { + return breakfastSubsidy; + } + public void setBreakfastPersonalConsumption(Double breakfastPersonalConsumption) + { + this.breakfastPersonalConsumption = breakfastPersonalConsumption; + } + + public Double getBreakfastPersonalConsumption() + { + return breakfastPersonalConsumption; + } + public void setBreakfastSumConsumption(Double breakfastSumConsumption) + { + this.breakfastSumConsumption = breakfastSumConsumption; + } + + public Double getBreakfastSumConsumption() + { + return breakfastSumConsumption; + } + public void setLunchNumber(Long lunchNumber) + { + this.lunchNumber = lunchNumber; + } + + public Long getLunchNumber() + { + return lunchNumber; + } + public void setLunchSubsidy(Double lunchSubsidy) + { + this.lunchSubsidy = lunchSubsidy; + } + + public Double getLunchSubsidy() + { + return lunchSubsidy; + } + public void setLunchPresonalConsumption(Double lunchPresonalConsumption) + { + this.lunchPresonalConsumption = lunchPresonalConsumption; + } + + public Double getLunchPresonalConsumption() + { + return lunchPresonalConsumption; + } + public void setLunchSumConsumption(Double lunchSumConsumption) + { + this.lunchSumConsumption = lunchSumConsumption; + } + + public Double getLunchSumConsumption() + { + return lunchSumConsumption; + } + public void setSupperNumber(Long supperNumber) + { + this.supperNumber = supperNumber; + } + + public Long getSupperNumber() + { + return supperNumber; + } + public void setSupperSubsidy(Double supperSubsidy) + { + this.supperSubsidy = supperSubsidy; + } + + public Double getSupperSubsidy() + { + return supperSubsidy; + } + public void setSupperPersonalConsumption(Double supperPersonalConsumption) + { + this.supperPersonalConsumption = supperPersonalConsumption; + } + + public Double getSupperPersonalConsumption() + { + return supperPersonalConsumption; + } + public void setSupperSumConsumption(Double supperSumConsumption) + { + this.supperSumConsumption = supperSumConsumption; + } + + public Double getSupperSumConsumption() + { + return supperSumConsumption; + } + public void setSumSubsidy(Double sumSubsidy) + { + this.sumSubsidy = sumSubsidy; + } + + public Double getSumSubsidy() + { + return sumSubsidy; + } + public void setPersonalSumConsumption(Double personalSumConsumption) + { + this.personalSumConsumption = personalSumConsumption; + } + + public Double getPersonalSumConsumption() + { + return personalSumConsumption; + } + public void setSumConsumption(Double sumConsumption) + { + this.sumConsumption = sumConsumption; + } + + public Double getSumConsumption() + { + return sumConsumption; + } + public void setSparedOne(String sparedOne) + { + this.sparedOne = sparedOne; + } + + public String getSparedOne() + { + return sparedOne; + } + public void setSparedTwo(String sparedTwo) + { + this.sparedTwo = sparedTwo; + } + + public String getSparedTwo() + { + return sparedTwo; + } + public void setSparedThree(Long sparedThree) + { + this.sparedThree = sparedThree; + } + + public Long getSparedThree() + { + return sparedThree; + } + public void setSparedFour(Long sparedFour) + { + this.sparedFour = sparedFour; + } + + public Long getSparedFour() + { + return sparedFour; + } + + @Override + public String toString() { + return "CyConsumptionInfo [id=" + id + ", statisticsId=" + statisticsId + ", dateTime=" + dateTime + ", name=" + + name + ", shangBan=" + shangBan + ", xiaBan=" + xiaBan + ", duration=" + duration + + ", breakfastNumber=" + breakfastNumber + ", breakfastSubsidy=" + breakfastSubsidy + + ", breakfastPersonalConsumption=" + breakfastPersonalConsumption + ", breakfastSumConsumption=" + + breakfastSumConsumption + ", lunchNumber=" + lunchNumber + ", lunchSubsidy=" + lunchSubsidy + + ", lunchPresonalConsumption=" + lunchPresonalConsumption + ", lunchSumConsumption=" + + lunchSumConsumption + ", supperNumber=" + supperNumber + ", supperSubsidy=" + supperSubsidy + + ", supperPersonalConsumption=" + supperPersonalConsumption + ", supperSumConsumption=" + + supperSumConsumption + ", sumSubsidy=" + sumSubsidy + ", personalSumConsumption=" + + personalSumConsumption + ", sumConsumption=" + sumConsumption + ", sparedOne=" + sparedOne + + ", sparedTwo=" + sparedTwo + ", sparedThree=" + sparedThree + ", sparedFour=" + sparedFour + "]"; + } + +} diff --git a/evo-admin/src/main/java/com/evo/restaurant/mapper/RzRestaurantStatisticsMapper.java b/evo-admin/src/main/java/com/evo/restaurant/mapper/RzRestaurantStatisticsMapper.java index d3eb333..fe7b55e 100644 --- a/evo-admin/src/main/java/com/evo/restaurant/mapper/RzRestaurantStatisticsMapper.java +++ b/evo-admin/src/main/java/com/evo/restaurant/mapper/RzRestaurantStatisticsMapper.java @@ -1,5 +1,6 @@ package com.evo.restaurant.mapper; +import com.evo.restaurant.domain.CyConsumptionInfo; import com.evo.restaurant.domain.RzRestaurantStatistics; import org.apache.ibatis.annotations.Param; import java.util.Date; @@ -21,6 +22,8 @@ public interface RzRestaurantStatisticsMapper */ public RzRestaurantStatistics selectRzRestaurantStatisticsById(Long id); + public List selectRzRestaurantStatisticsById2(String name); + /** * 查询餐饮统计列表 * @@ -55,4 +58,6 @@ public interface RzRestaurantStatisticsMapper public List selectRzRestaurantStatisticsByDate(Date date); + public List selectRzRestaurantStatisticsByDate2(Date date); + } diff --git a/evo-admin/src/main/java/com/evo/restaurant/service/IRzRestaurantDetailService.java b/evo-admin/src/main/java/com/evo/restaurant/service/IRzRestaurantDetailService.java index 067a208..3fb7dc7 100644 --- a/evo-admin/src/main/java/com/evo/restaurant/service/IRzRestaurantDetailService.java +++ b/evo-admin/src/main/java/com/evo/restaurant/service/IRzRestaurantDetailService.java @@ -30,6 +30,8 @@ public interface IRzRestaurantDetailService */ public String insertRzRestaurantDetail(String json); + public String initRzRestaurantDetail(); + /** * 当前时间的就餐人数 * @return diff --git a/evo-admin/src/main/java/com/evo/restaurant/service/impl/RzRestaurantDetailServiceImpl.java b/evo-admin/src/main/java/com/evo/restaurant/service/impl/RzRestaurantDetailServiceImpl.java index 09d9f16..871d5b7 100644 --- a/evo-admin/src/main/java/com/evo/restaurant/service/impl/RzRestaurantDetailServiceImpl.java +++ b/evo-admin/src/main/java/com/evo/restaurant/service/impl/RzRestaurantDetailServiceImpl.java @@ -6,6 +6,7 @@ import com.evo.common.core.domain.AjaxResult; import com.evo.common.utils.DateUtils; import com.evo.common.utils.SecurityUtils; import com.evo.common.utils.StringUtils; +import com.evo.restaurant.domain.CyConsumptionInfo; import com.evo.restaurant.domain.RzRestaurantDetail; import com.evo.restaurant.domain.RzRestaurantImages; import com.evo.restaurant.domain.RzRestaurantStatistics; @@ -19,6 +20,7 @@ import com.evo.system.domain.SysStaff; import com.evo.system.mapper.SysStaffMapper; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.List; @@ -143,6 +145,150 @@ public class RzRestaurantDetailServiceImpl implements IRzRestaurantDetailService cfiv.setResult(0); return JSONObject.toJSONString(cfiv); } + + @Override + public String initRzRestaurantDetail() + { + + RzRestaurantStatistics rzRestaurantStatistics = new RzRestaurantStatistics(); + String dateStr = "2025-04-01"; + SimpleDateFormat sdf0 = new SimpleDateFormat("yyyy-MM-dd"); + try { + Date date = sdf0.parse(dateStr); + System.out.println(date); + rzRestaurantStatistics.setMonth(date); + } catch (Exception e) { + e.printStackTrace(); + } + + //根据日期查询统计日期内的统计信息 + List rt_list = rzRestaurantStatisticsMapper.selectRzRestaurantStatisticsList(rzRestaurantStatistics); + //循环统计信息 + /** + * 1、查询出统计表需要循环的人员信息 + * 2、遍历统计记录,拿 name和(shang_ban、xia_ban不为空并且4-1到4-14日的记录)字段去查询cy_consumption_info表 + * 3、二层循环遍历cy_consumption_info表: + */ + for (RzRestaurantStatistics restaurantStatistics : rt_list) { + String name = restaurantStatistics.getName(); + List cyConsumptionInfoList= rzRestaurantStatisticsMapper.selectRzRestaurantStatisticsById2(name); + + for (CyConsumptionInfo cyConsumptionInfo : cyConsumptionInfoList) { + // 创建日期格式化对象 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + + // Date 转 String + Date date_time = cyConsumptionInfo.getDateTime(); + String formattedDate = sdf.format(date_time); + String formattedDate1 = formattedDate + " 08:10:00"; + String formattedDate2 = formattedDate + " 12:10:00"; + String formattedDate3 = formattedDate + " 18:10:00"; + System.out.println("Formatted Date: " + formattedDate); + SimpleDateFormat sdff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date1 =null; + Date date2 =null; + Date date3 =null; + try { + date1 = sdff.parse(formattedDate1); + date2 = sdff.parse(formattedDate2); + date3 = sdff.parse(formattedDate3); + } catch (Exception e) { + e.printStackTrace(); + } + + if(cyConsumptionInfo.getBreakfastNumber()==1){ + + RzRestaurantDetail cyFaceInfo = new RzRestaurantDetail(); + cyFaceInfo.setDate(date1); + cyFaceInfo.setStaffId(restaurantStatistics.getStaffId()); + cyFaceInfo.setName(restaurantStatistics.getName()); + cyFaceInfo.setTime(date1); + + cyFaceInfo.setSign("早餐"); +// restaurantStatistics.setBreakfastNumber(restaurantStatistics.getBreakfastNumber() + 1); + + cyFaceInfo.setDelFlag(Constants.DELETE_FLAG_0); + cyFaceInfo.setCreateTime(date1); + rzRestaurantDetailMapper.insertRzRestaurantDetail(cyFaceInfo); + } + + if(cyConsumptionInfo.getLunchNumber()==1){ + RzRestaurantDetail cyFaceInfo = new RzRestaurantDetail(); + cyFaceInfo.setDate(date2); + cyFaceInfo.setStaffId(restaurantStatistics.getStaffId()); + cyFaceInfo.setName(restaurantStatistics.getName()); + cyFaceInfo.setTime(date2); + + cyFaceInfo.setSign("午餐"); +// restaurantStatistics.setBreakfastNumber(restaurantStatistics.getBreakfastNumber() + 1); + + cyFaceInfo.setDelFlag(Constants.DELETE_FLAG_0); + cyFaceInfo.setCreateTime(date2); + rzRestaurantDetailMapper.insertRzRestaurantDetail(cyFaceInfo); + } + + if(cyConsumptionInfo.getSupperNumber()==1){ + RzRestaurantDetail cyFaceInfo = new RzRestaurantDetail(); + cyFaceInfo.setDate(date3); + cyFaceInfo.setStaffId(restaurantStatistics.getStaffId()); + cyFaceInfo.setName(restaurantStatistics.getName()); + cyFaceInfo.setTime(date3); + + cyFaceInfo.setSign("晚餐"); +// restaurantStatistics.setBreakfastNumber(restaurantStatistics.getBreakfastNumber() + 1); + + cyFaceInfo.setDelFlag(Constants.DELETE_FLAG_0); + cyFaceInfo.setCreateTime(date3); + rzRestaurantDetailMapper.insertRzRestaurantDetail(cyFaceInfo); + } + + } + + } + + //根据员工ID和打卡时间查询本月的打卡统计信息 + /*List restaurantStatistics = rzRestaurantStatisticsMapper.selectRzRestaurantStatisticsByDate2(new Date()); + //增加打卡记录 + RzRestaurantDetail cyFaceInfo = new RzRestaurantDetail(); + cyFaceInfo.setDate(new Date()); + cyFaceInfo.setStaffId(restaurantStatistics.getStaffId()); + cyFaceInfo.setName(restaurantStatistics.getName()); + cyFaceInfo.setTime(new Date()); + //判断刷脸时间是早餐还是午餐还是晚餐 + if(hour>6&&hour<9){ + //说明是早餐 + cyFaceInfo.setSign("早餐"); + restaurantStatistics.setBreakfastNumber(restaurantStatistics.getBreakfastNumber() + 1); + }else if(hour>=11&&hour<=14){ + //说明是午餐 + cyFaceInfo.setSign("午餐"); + restaurantStatistics.setLunchNumber(restaurantStatistics.getLunchNumber() + 1); + }else if(hour>=18&&hour<=20){ + //说明是晚餐 + cyFaceInfo.setSign("晚餐"); + restaurantStatistics.setSupperNumber(restaurantStatistics.getSupperNumber() + 1); + } + cyFaceInfo.setDelFlag(Constants.DELETE_FLAG_0); + cyFaceInfo.setCreateTime(new Date()); + int i = rzRestaurantDetailMapper.insertRzRestaurantDetail(cyFaceInfo); + if(i<1){ + cfiv.setResult(2); + cfiv.setMsg("{\"Result\":1,\"Msg\":\"打卡失败\"}"); + return JSONObject.toJSONString(cfiv); + } + //反写统计次数 + i = rzRestaurantStatisticsMapper.updateRzRestaurantStatistics(restaurantStatistics); + if(i<1){ + cfiv.setResult(2); + cfiv.setMsg("{\"Result\":1,\"Msg\":\"打卡失败\"}"); + return JSONObject.toJSONString(cfiv); + } + cfiv.setMsg("{\"Result\":1,\"Msg\":\"打卡成功!\"}"); + cfd.setClock_in_count(1); + cfiv.setContent(cfd); + cfiv.setResult(0);*/ + return JSONObject.toJSONString(""); + } /** * 统计当餐刷卡人数 * @return diff --git a/evo-admin/src/main/resources/mapper/restaurant/RzRestaurantStatisticsMapper.xml b/evo-admin/src/main/resources/mapper/restaurant/RzRestaurantStatisticsMapper.xml index 7297e31..9b39fe0 100644 --- a/evo-admin/src/main/resources/mapper/restaurant/RzRestaurantStatisticsMapper.xml +++ b/evo-admin/src/main/resources/mapper/restaurant/RzRestaurantStatisticsMapper.xml @@ -32,10 +32,44 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, staff_id, dept_id, name, month, breakfast_expend, breakfast_number, breakfast_pre_sum_expend, breakfast_sum_expend, lunch_expend, lunch_number, lunch_pre_sum_expend, lunch_sum_expend, supper_expend, supper_number, supper_pre_sum_expend, supper_sum_expend, personal_sum_consumption, sum_consumption, remarks, del_flag, create_by, create_time, update_by, update_time from rz_restaurant_statistics + + select id,statistics_id, create_time, date_time, name, shang_ban, xia_ban, duration, breakfast_number, breakfast_subsidy, breakfast_personal_consumption, breakfast_sum_consumption, lunch_number, lunch_subsidy, lunch_presonal_consumption, lunch_sum_consumption, supper_number, supper_subsidy, supper_personal_consumption, supper_sum_consumption, sum_subsidy, personal_sum_consumption, sum_consumption, spared_one, spared_two, spared_three, spared_four from cy_consumption_info + + + + insert into rz_restaurant_statistics @@ -147,6 +188,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where staff_id = #{staffId} and del_flag = '0' and DATE_FORMAT( month, '%Y%m' ) = DATE_FORMAT(#{date} , '%Y%m' ) + +