From 7b1878ed989949cb4a7aa16adab6fbe48b5325ea Mon Sep 17 00:00:00 2001
From: huangzhen <867217663@qq.com>
Date: 星期三, 16 八月 2023 14:35:50 +0800
Subject: [PATCH] 代码提交

---
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/RoleInfoDoaminDTO.java                       |   25 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/DeviceExceptionLog.java                                        |   25 
 src/main/resources/template/dailyReportTemplate.docx                                                                  |    0 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/SysDeparmentRepository.java             |   29 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasCategoryServiceImpl.java                              |  222 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindDailyReportPageRespDTO.java                           |   23 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/model/bo/CreateNewMenuItemBO.java                     |  177 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/WarningThresholdEnum.java                                       |   41 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateGasThresholdReqDTO.java                              |   16 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/ChangePasswdReqDto.java                |   34 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/RoleInfoConverter.java                       |   18 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/infra/cache/service/impl/UserCacheInfraServiceImpl.java               |   62 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasWarnLogSmsUser.java                                         |   32 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/UserRoleDomainService.java                     |   21 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/domain/Result.java                                            |  111 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/Role.java                                       |   67 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/schedule/HeartbeatSchedule.java                                       |   92 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/SysUserIdentityBindReposity.java        |   28 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/cache/RedisUtils.java                                          |  261 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/UserRoleBindReposity.java               |   30 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/serializa/JavaTimeAutoConfiguration.java                       |   30 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/RoleMenuBind.java                               |   65 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/RoleBindMenuItemBO.java                       |   36 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/SysUserRoleBindDomainDTO.java                |   17 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/decorator/WarningThresholdUpdateEvent.java                            |   14 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseInit.java                                       |   26 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/SysUserRoleBind.java                            |   29 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/RoleRespDTO.java                      |   24 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/RoleRepository.java                     |   34 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/SysUserIdentityBind.java                        |   26 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/MonitorDailyReportServiceImpl.java                       |   85 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/DelRegionByIdReqDTO.java                                   |   14 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/UserIdentityConverter.java                   |   30 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/converter/AttachmentAppConverter.java          |   24 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/ResultCode.java                                         |   88 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/entity/AttachmentInfo.java                          |   64 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserIdentityBindAppRespDTO.java       |   15 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasThresholdService.java                                      |   22 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/UserController.java                            |  113 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/model/dto/resp/MenuItemApiDTO.java                     |  148 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/schedule/DailyReportSchedule.java                                     |  482 +
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/service/AttachmentDomainService.java                |   20 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/HeartbeatExcWebsocketServer.java                            |  171 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasAtmosphereLineChartRespDTO.java                        |   20 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/resp/UserIdentityBindApiDTO.java           |   15 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/resp/UserRoleBindApiDTO.java               |   15 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasCategoryRepository.java                                 |   14 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/schedule/GasConcentrationAutoCreateKeySchedule.java                   |   64 
 pom.xml                                                                                                               |  203 
 src/main/resources/config/redisson-dev.yml                                                                            |   42 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/UserIdentityRepository.java             |   15 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/RegionService.java                                            |   31 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/GasFluxPageQuery.java                                    |   22 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/utils/SpringUtils.java                                        |   17 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/TokenAppService.java                      |   15 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/attachment/dto/resp/AttachmentApiRespDTO.java          |   48 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/SysDepartmentDomainService.java                |   24 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/SysUserIndentityBindConverter.java           |   44 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/req/AddRoleApiDTO.java                     |   14 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/GasLineChartReqDTO.java                                    |   21 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/SystemCacheKeyEnum.java                                 |   35 
 src/main/resources/config/application-dev.yaml                                                                        |  119 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/entity/MenuItem.java                                  |  261 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/ForeignResultCode.java                                  |   88 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/interceptor/TokenInterceptor.java                              |   33 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasWarnUserPageRespDTO.java                           |   24 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/SysDepartmentAppDTO.java              |   34 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasWarnUserController.java                                 |   49 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/utils/ThreadLocalUtil.java                                            |   28 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/MonitorDailyReport.java                                        |   29 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/AccountMenuAppService.java                |    9 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/DelGasWarnUserByIdReqDTO.java                              |   14 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/service/impl/AttachmentAppServiceImpl.java     |  245 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/RoleMenuDomainService.java                     |   18 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/file/FilePathConfig.java                                       |   32 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateRegionReqDTO.java                                    |   23 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/CreateRegionReqDTO.java                                    |   22 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/exception/ExceptionInfo.java                                  |   46 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/SysDepartmentBO.java                          |   30 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/ModifyMenuItemApiDTO.java             |  104 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/RegionRepository.java                                      |   24 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/SysDepartmentAppServiceImpl.java     |   86 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/SysUserIdentityBindDomainServiceImpl.java |  115 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/enums/FileProjectConstants.java                     |   20 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UploadGasConcentrationReqDTO.java                          |   99 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/WebSecurityConfig.java                           |   76 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasMonitorDataController.java                              |   67 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/UserIdentityDomainService.java                 |   17 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/service/impl/MenuAppServiceImpl.java             |  298 
 src/main/resources/config/application.yaml                                                                            |    6 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindRegionPageRespDTO.java                                |   24 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasWarnUserRepository.java                                 |   25 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/converter/MenuInfoApiConverter.java           |  119 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/dtos/GasConcentrationDto.java                                  |   97 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/SysDepartmentAppService.java              |   22 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/enums/MenuItemTypeEnum.java                           |   55 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/DeviceMonitorReqDTO.java                                   |   25 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasCategoryByIdRespDTO.java                           |   24 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseInfo.java                                       |   46 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/DataReceiveController.java                                 |   46 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/enums/UserStatusEnum.java                              |   57 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/exception/BusinessException.java                              |   74 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/resp/UserIdentityApiDTO.java               |   15 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasThresholdController.java                                |   36 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/domain/SearchResult.java                                      |   86 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/UserIdentityAppService.java               |   15 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/exception/DataReceiveException.java                           |   74 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/common/BaseController.java                             |   35 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/file/ReportFilePathConfig.java                                 |   22 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/enums/IdentityStatusEnum.java                          |   48 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/GasConcentrationStateEnum.java                                  |   30 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateGasWarnUserReqDTO.java                               |   23 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/WebMvcConfig.java                                |   20 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/UpdateUserAppReqDTO.java               |   32 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/RoleMenuBindRepository.java             |   30 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/model/dto/resp/MenuItemMetaApiDTO.java                 |  124 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/UserBindRoleBO.java                           |   15 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasFluxPageRespDTO.java                                   |   42 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasLineChartRespDTO.java                                  |   49 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserInfoAppRespDTO.java               |   49 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/UserTagEnum.java                                        |   37 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasThresholdServiceImpl.java                             |   93 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/AccountAppServiceImpl.java           |  407 +
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/ModifyMenuItemAppDTO.java          |  185 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/DeviceExceptionLogService.java                                |   12 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/LoginRespDto.java                     |   21 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/converter/UserIndentityAppConverter.java          |   27 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/AddAndUpdateMenuItemApiDTO.java       |  104 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/entity/SysConfig.java                                 |   49 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/exception/GlobalExceptionHandler.java                          |  163 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindGasWarnLogPageQuery.java                             |   24 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/AuthController.java                            |   33 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/service/MenuDomainService.java                        |   33 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/DataReceiveServiceImpl.java                              |  540 +
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/CreateNewUserAppReqDTO.java            |   32 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/resp/UserInfoApiDTO.java                   |   42 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/file/InitConfig.java                                           |   40 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/SysDepartmentDomainDTO.java                  |   34 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasWarnLogService.java                                        |   23 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/service/impl/AttachmentDomainServiceImpl.java       |   66 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/SysDepartmentAppAddReqDTO.java         |   32 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/AddAndUpdateMenuItemAppDTO.java    |  185 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasThresholdListRespDTO.java                              |   20 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/MonitorDailyReportController.java                          |   31 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/RegionLngLatRepository.java                                |   18 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/attachment/converter/AttachmentApiConverter.java       |   28 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasThreshold.java                                              |   33 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/SysDepartmentAppUpdateReqDTO.java      |   24 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseDataCon.java                                    |   34 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/infra/cache/service/UserCacheInfraService.java                        |   12 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindGasCategoryPageQuery.java                            |   15 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/MenuItemBindRoleApiDTO.java           |   36 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/infra/cache/domain/CacheUserInfo.java                                 |   83 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/service/dto/resp/AttachmentAppRespDTO.java     |   48 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/repository/jpa/AttachmentReposity.java              |   28 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/UserIdentity.java                               |   24 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/LoginReqAppDTO.java                    |   34 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindRegionByIdRespDTO.java                                |   22 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/RegionServiceImpl.java                                   |  234 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasCategoryPageRespDTO.java                           |   24 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/CompanyLicenseDataCache.java                           |  403 +
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/RoleMenuDomainServiceImpl.java            |  151 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/SysDeparmentConverter.java                   |   42 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasCategoryService.java                                       |   27 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/UserDomainService.java                         |  136 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasFluxService.java                                           |   30 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/CreateGasWarnUserReqDTO.java                               |   21 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/GasFluxLineChartReqDTO.java                                |   23 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/query/UserQuery.java                           |   22 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/interface/sysManage/LicenseManage.java                                |   64 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasWarnLogServiceImpl.java                               |  163 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindRegionLngLatPageRespDTO.java                          |   21 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/converter/UserInfoAppConverter.java               |   67 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasThresholdRepository.java                                |   17 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseFilter.java                                     |   61 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/UserRepository.java                     |   60 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/CreateGasCategoryReqDTO.java                               |   22 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/RegionLngLat.java                                              |   26 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasCategoryController.java                                 |   75 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/UserRoleEnum.java                                       |   43 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/GasConcentrationExcWebsocketServer.java                     |  172 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/StatusEnum.java                                         |   99 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateRegionLngLatReqDTO.java                              |   16 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/MenuItemMetaDTO.java                  |  117 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/UserIdentityAppServiceImpl.java      |   30 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindRegionPageQuery.java                                 |   15 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserRoleBindRespDTO.java              |   15 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/GasAtmospherePageQuery.java                              |   21 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/RoleController.java                            |   45 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/req/UserSearchReqDTO.java                  |   64 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/MonitorDailyReportRepository.java                          |   16 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/utils/BeanCopyUtils.java                                      |   56 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasConcentration.java                                          |  103 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/UserInfoDomainConverter.java                 |   90 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/UserDomainServiceImpl.java                |  647 +
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasWarnLog.java                                                |   60 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/converter/AttachmentDomainConverter.java            |   25 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/RoleAppServiceImpl.java              |   88 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasFluxServiceImpl.java                                  |  123 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasWarnUser.java                                               |   39 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/service/AttachmentAppService.java              |   27 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasWarnLogController.java                                  |   34 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/SysDepartment.java                              |   68 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasWarnLogSmsUserService.java                                 |   15 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/GasFluxWebsocketServer.java                                 |  171 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/GasFluxStateEnum.java                                           |   30 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateGasCategoryReqDTO.java                               |   22 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasWarnLogPageRespDTO.java                            |   57 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/TokenInfoDto.java                     |   34 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/SysDepartmentDomainServiceImpl.java       |  166 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/GasPageQuery.java                                        |   20 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/service/MenuAppService.java                      |   39 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/model/dto/MenuItemDomainDTO.java                      |  207 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/MenuManageController.java                     |   91 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/RoleDomainService.java                         |   32 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasConcentrationService.java                                  |   24 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/NewMenuItemAppDTO.java             |  175 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindGasWarnUserPageQuery.java                            |   15 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/GasConcentrationWebsocketServer.java                        |  171 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/UserMenuController.java                       |   47 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/TokenCheckWhiteListEnum.java                     |   79 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/TokenConfig.java                                 |   69 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/SysUserIdentityBindDomainService.java          |   17 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/UpdateUserBO.java                             |   31 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/cache/RedisConfig.java                                         |   36 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/CreateUserBO.java                             |   25 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/RegionController.java                                      |   53 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/GasDeviceExcWebsocketServer.java                            |  171 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseKCon.java                                       |   22 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/DeviceExceptionLogRepository.java                          |   15 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasFluxLineChartRespDTO.java                              |   43 
 src/main/resources/config/redisson-online-uat.yml                                                                     |   42 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/Region.java                                                    |   49 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/RoleBindMenuAppDTO.java            |   36 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/websocket/WebSocketConfig.java                                 |   15 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/MonitorDataServiceImpl.java                              |  377 +
 src/main/java/com/gkhy/fourierSpecialGasMonitor/utils/SendMessageUtil.java                                            |   49 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/HeartbeatExecEnum.java                                          |   37 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/SystemConfigKeyEnum.java                                |   31 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/SysDepartmentController.java                   |   42 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasWarnLogRepository.java                                  |   18 
 src/main/resources/config/application-online-uat.yaml                                                                 |   96 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/resp/MenuItemAppDTO.java               |  217 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasFluxRepository.java                                     |   20 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/converter/UserIdentityApiConverter.java        |   27 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/converter/UserInfoApiConverter.java            |   53 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/repository/jpa/SysConfigRepository.java               |    9 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/Application.java                                                      |   20 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/TokenAuthenticationFilter.java                   |  148 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/MenuItemBindRoleAppDTO.java        |   36 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/User.java                                       |   88 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/converter/RoleInfoAppConverter.java               |   18 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasConcentrationServiceImpl.java                         |  101 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/DeleteStatusEnum.java                                           |   32 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasAtmospherePageRespDTO.java                             |   19 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/MyWebMvcConfigurerAdapter.java                   |   26 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/UserIdentityDomainServiceImpl.java        |   37 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/attachment/AttachmentController.java                   |  133 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasFlux.java                                                   |   71 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasCategoryListRespDTO.java                               |   24 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasCategory.java                                               |   46 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasWarnLogSmsUserRepository.java                           |   16 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindDailyReportPageQuery.java                            |   19 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/GasAtmosphereLineChartReqDTO.java                          |   21 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/MonitorDataService.java                                       |   30 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/service/dto/req/AttachmentAppReq.java          |   48 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/MethodEnum.java                                         |   52 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/UserInfoDomainDTO.java                       |   55 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/MenuItemBindRoleBO.java                       |   36 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UploadGasFluxReqDTO.java                                   |   64 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserIndentityAppDTO.java              |   18 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/utils/PageUtils.java                                          |   30 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/serializa/JacksonConfiguration.java                            |   32 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseBizWhiteEnum.java                               |   51 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/req/ModRoleApiDTO.java                     |   24 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/service/impl/MenuDomainServiceImpl.java               |  372 +
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/threadExecutor/ExecutorConfig.java                             |   82 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/model/bo/ModifyMenuItemBO.java                        |  196 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/CreateRegionLngLatReqDTO.java                              |   16 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/HardwareStateEnum.java                                          |   32 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/UserIdentityDomainDTO.java                   |   19 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasWarnUserService.java                                       |   29 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasWarnUserServiceImpl.java                              |  184 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/AccountMenuAppServiceImpl.java       |  122 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/TokenAppServiceImpl.java             |  121 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasPageRespDTO.java                                       |   49 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/ContextUserDto.java                   |   57 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/model/PageQuery.java                                          |   47 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/domain/ForeignResult.java                                     |  106 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasConcentrationRepository.java                            |   17 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/SysUserIdentityBindDomainDTO.java            |   15 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasWarnLogSmsUserServiceImpl.java                        |   26 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/repository/jpa/MenuItemRepository.java                |   52 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/RoleBindMenuApiDTO.java               |   36 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasWarnLogSmsUserPageRespDTO.java                     |   26 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/req/LoginReqDTO.java                       |   24 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/UserRoleBindConverter.java                   |   44 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/dto/resp/AttachmentDomainDTO.java                   |   49 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/RoleAppService.java                       |   18 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/MonitorDailyReportService.java                                |   18 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/DeviceExceptionLogServiceImpl.java                       |   24 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/AccountAppService.java                    |   45 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/service/DataReceiveService.java                                       |   22 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserRoleBindAppRespDTO.java           |   15 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/UserIndentityController.java                   |   38 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/UserRoleDomainServiceImpl.java            |  126 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/converter/MenuItemConverter.java                      |   18 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/WarnHandleStatusEnum.java                                       |   32 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/convert/MenuItemAppConvert.java                  |   39 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/cors/CorsConfig.java                                           |   39 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/enums/UserIdTypeEnum.java                              |   54 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseManageService.java                              |   63 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/RoleDomainServiceImpl.java                |  148 
 src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseTypeEnum.java                                   |   47 
 314 files changed, 20,056 insertions(+), 0 deletions(-)

diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..08f110f
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.gkhy</groupId>
+    <artifactId>FourierSpecialGasMonitor</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <properties>
+        <springboot.version>2.7.5</springboot.version>
+        <druid.version>1.2.14</druid.version>
+        <redisson.version>3.17.7</redisson.version>
+    </properties>
+
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.7.5</version>
+    </parent>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-logging</artifactId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>logback-classic</artifactId>
+                    <groupId>ch.qos.logback</groupId>
+                </exclusion>
+                <!--                <exclusion>-->
+                <!--                    <groupId>org.springframework.boot</groupId>-->
+                <!--                    <artifactId>spring-boot-starter-tomcat</artifactId>-->
+                <!--                </exclusion>-->
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-log4j2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-beans</artifactId>
+            <version>5.3.23</version>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>8.0.31</version>
+        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>com.baomidou</groupId>-->
+<!--            <artifactId>mybatis-plus-boot-starter</artifactId>-->
+<!--            <version>3.5.2</version>-->
+<!--        </dependency>-->
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjweaver</artifactId>
+            <version>1.9.9.1</version>
+            <!--            <scope>runtime</scope>-->
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+            <version>${druid.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>31.1-jre</version>
+        </dependency>
+        <dependency>
+            <groupId>org.redisson</groupId>
+            <artifactId>redisson-spring-boot-starter</artifactId>
+            <version>${redisson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-websocket</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-maven-plugin</artifactId>
+            <version>${springboot.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.58</version>
+        </dependency>
+        <!--        七牛云短信-->
+        <dependency>
+            <groupId>com.qiniu</groupId>
+            <artifactId>qiniu-java-sdk</artifactId>
+            <version>[7.2.0, 7.2.99]</version>
+        </dependency>
+
+        <!--Jackson LocalDateTime支持-->
+        <dependency>
+            <groupId>com.fasterxml.jackson.datatype</groupId>
+            <artifactId>jackson-datatype-jsr310</artifactId>
+            <version>2.14.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.10</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>4.1.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml-schemas</artifactId>
+            <version>4.1.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+            <version>4.1.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-scratchpad</artifactId>
+            <version>4.1.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.xmlbeans</groupId>
+            <artifactId>xmlbeans</artifactId>
+            <version>3.1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>ooxml-schemas</artifactId>
+            <version>1.4</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.10.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <!-- 该项目的启动入口 -->
+                    <mainClass>com.gkhy.fourierSpecialGasMonitor.Application</mainClass>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <!--把依赖的所有包都打包生成的Jar包中-->
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    
+</project>
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/Application.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/Application.java
new file mode 100644
index 0000000..0756f61
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/Application.java
@@ -0,0 +1,20 @@
+package com.gkhy.fourierSpecialGasMonitor;
+
+import io.micrometer.core.instrument.util.StringUtils;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+import java.math.BigDecimal;
+
+@EnableJpaAuditing
+@EnableScheduling
+@SpringBootApplication
+public class Application {
+
+    public static void main(String[] args){
+//        SpringApplication.run(Application.class);
+        SpringApplication.run(Application.class,args);
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/AuthController.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/AuthController.java
new file mode 100644
index 0000000..88d0d8d
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/AuthController.java
@@ -0,0 +1,33 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.account;
+
+import com.gkhy.fourierSpecialGasMonitor.api.controller.account.dto.req.LoginReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.common.BaseController;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto.LoginReqAppDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.service.AccountAppService;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/account/auth")
+public class AuthController extends BaseController {
+
+    @Autowired
+    private AccountAppService accountAppService;
+
+    @PostMapping("/login")
+    public Result login(@RequestBody LoginReqDTO loginReqDTO){
+        LoginReqAppDTO loginReqAppDTO = new LoginReqAppDTO();
+        loginReqAppDTO.setName(loginReqDTO.getName());
+        loginReqAppDTO.setPwd(loginReqDTO.getPwd());
+        Result result = accountAppService.login(loginReqAppDTO);
+        return result;
+    }
+
+    @GetMapping("/logout")
+    public Result logout(){
+        Long userId = getCurrentUserId();
+        Result result = accountAppService.logout(userId);
+        return result;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/RoleController.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/RoleController.java
new file mode 100644
index 0000000..ef53e22
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/RoleController.java
@@ -0,0 +1,45 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.account;
+
+import com.gkhy.fourierSpecialGasMonitor.api.controller.account.dto.req.AddRoleApiDTO;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.account.dto.req.ModRoleApiDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.service.RoleAppService;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/account/role")
+public class RoleController {
+
+    @Autowired
+    private RoleAppService roleAppService;
+
+    @PostMapping("/new")
+    @Transactional
+    public Result createNewRole(@RequestBody AddRoleApiDTO dto){
+        Result result = roleAppService.newRole(dto.getName());
+        return result;
+    }
+
+    @PostMapping("/mod/name")
+    @Transactional
+    public Result updateRoleName(@RequestBody ModRoleApiDTO dto){
+        Result result = roleAppService.updateRoleName(dto.getRoleId(), dto.getName());
+        return result;
+    }
+
+    @PostMapping("/del")
+    @Transactional
+    public Result delNewRole(@RequestBody ModRoleApiDTO dto){
+        Result result = roleAppService.deleteRole(dto.getRoleId());
+        return result;
+    }
+
+    @GetMapping("/find/all/active")
+    public SearchResult findAllRoleList(){
+        SearchResult result = roleAppService.findAllRoleList();
+        return result;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/SysDepartmentController.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/SysDepartmentController.java
new file mode 100644
index 0000000..2d73e21
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/SysDepartmentController.java
@@ -0,0 +1,42 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.account;
+
+import cn.hutool.json.JSONObject;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.common.BaseController;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto.SysDepartmentAppAddReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto.SysDepartmentAppUpdateReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.service.SysDepartmentAppService;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/7
+ * @time: 16:34
+ */
+@RestController
+@RequestMapping("account/department")
+public class SysDepartmentController extends BaseController {
+    @Autowired
+    private SysDepartmentAppService sysDepartmentAppService;
+
+    @PostMapping("/save")
+    public Result save(@RequestBody SysDepartmentAppAddReqDTO req){
+
+        return sysDepartmentAppService.save(req,getCurrentUserId());
+    }
+    @PostMapping("/update")
+    public Result update(@RequestBody SysDepartmentAppUpdateReqDTO req){
+        return sysDepartmentAppService.update(req,getCurrentUserId());
+    }
+    @PostMapping("/delete")
+    public Result delete(@RequestBody JSONObject jsonObject){
+        return sysDepartmentAppService.delete(jsonObject.getLong("id"),getCurrentUserId());
+    }
+    @GetMapping("/list")
+    public Result list(){
+        return sysDepartmentAppService.list();
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/UserController.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/UserController.java
new file mode 100644
index 0000000..b10a650
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/UserController.java
@@ -0,0 +1,113 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.account;
+
+import com.gkhy.fourierSpecialGasMonitor.api.controller.account.converter.UserInfoApiConverter;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.account.dto.req.UserSearchReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.account.dto.resp.UserInfoApiDTO;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.account.query.UserQuery;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto.ChangePasswdReqDto;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto.CreateNewUserAppReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto.UpdateUserAppReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.UserInfoAppRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.service.AccountAppService;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.commons.utils.PageUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/account/user")
+public class UserController {
+
+    @Autowired
+    private AccountAppService accountAppService;
+
+    @Autowired
+    private UserInfoApiConverter userInfoApiConverter;
+
+    @PostMapping("/add")
+    public Result createNewUser(@RequestBody CreateNewUserAppReqDTO reqDto){
+        Result result = accountAppService.createNewUser(reqDto);
+        return result;
+    }
+
+    @GetMapping("/find/list/realName")
+    public SearchResult findUsersByName(@RequestParam String name){
+        SearchResult<List<UserInfoApiDTO>> result = new SearchResult<>();
+        result.setSuccess();
+        SearchResult sr = accountAppService.findUserByRealName(name);
+        if(sr.getData() != null && sr.getCount() > 0){
+            result.setData(userInfoApiConverter.toApiDtoList((List<UserInfoAppRespDTO>) sr.getData()));
+            result.setCount(sr.getCount());
+        }
+        return result;
+    }
+    @PostMapping("/find/user/list")
+    public SearchResult findUser(@RequestBody PageQuery<UserQuery> pageQuery){
+        SearchResult<List<UserInfoApiDTO>> result = new SearchResult<>();
+        result.setSuccess();
+        SearchResult<List<UserInfoAppRespDTO>> sr = accountAppService.findUser(pageQuery);
+        PageUtils.checkCheck(pageQuery);
+        if(sr != null){
+            BeanUtils.copyProperties(sr,result);
+            result.setData(userInfoApiConverter.toApiDtoList((List<UserInfoAppRespDTO>) sr.getData()));
+        }
+        return result;
+    }
+
+    /**
+     * 专家库
+     * @param pageQuery
+     * @return
+     */
+    @PostMapping("/find/expert/list")
+    public SearchResult findExpert(@RequestBody PageQuery<UserQuery> pageQuery){
+        SearchResult<List<UserInfoApiDTO>> result = new SearchResult<>();
+        result.setSuccess();
+        SearchResult<List<UserInfoAppRespDTO>> sr = accountAppService.findExpert(pageQuery);
+        PageUtils.checkCheck(pageQuery);
+        if(sr != null){
+            BeanUtils.copyProperties(sr,result);
+            result.setData(userInfoApiConverter.toApiDtoList((List<UserInfoAppRespDTO>) sr.getData()));
+        }
+        return result;
+    }
+
+    @PostMapping("/find/list/roleId")
+    public SearchResult findUserByRole(@RequestBody UserSearchReqDTO searchReqDTO){
+        SearchResult<List<UserInfoApiDTO>> result = new SearchResult<>();
+        result.setSuccess();
+        SearchResult<List<UserInfoAppRespDTO>> sr = accountAppService.findUserByRole(searchReqDTO.getRoleId(),
+                searchReqDTO.getUsePage(),searchReqDTO.getPageIndex(),searchReqDTO.getPageSize());
+        if(sr != null){
+            BeanUtils.copyProperties(sr,result);
+            result.setData(userInfoApiConverter.toApiDtoList((List<UserInfoAppRespDTO>) sr.getData()));
+        }
+        return result;
+    }
+
+    @GetMapping("/deleteUser")
+    public Result deleteUser(@RequestParam Long userId){
+        Result result = accountAppService.deleteUser(userId);
+        return result;
+    }
+
+    @PostMapping("/update/info")
+    public Result updateUserInfo(@RequestBody UpdateUserAppReqDTO updateDto){
+        Result result = accountAppService.updateUser(updateDto);
+        return result;
+    }
+    /**
+     * 修改用户密码
+     */
+    @PostMapping("/update/password")
+    public Result updatePassword(@RequestBody ChangePasswdReqDto changePasswdReqDto){
+        Result result = accountAppService.updateUserPassword(changePasswdReqDto);
+        return result;
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/UserIndentityController.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/UserIndentityController.java
new file mode 100644
index 0000000..a7eeb30
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/UserIndentityController.java
@@ -0,0 +1,38 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.account;
+
+import com.gkhy.fourierSpecialGasMonitor.api.controller.account.converter.UserIdentityApiConverter;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.account.dto.resp.UserIdentityApiDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.UserIndentityAppDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.service.UserIdentityAppService;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/4
+ * @time: 13:40
+ */
+@RestController
+@RequestMapping("/account/user/identity")
+public class UserIndentityController {
+
+    @Autowired
+    private UserIdentityApiConverter userIdentityApiConverter;
+    @Autowired
+    private UserIdentityAppService userIdentityAppService;
+
+    @PostMapping("/list")
+    public Result findUser(){
+        Result<List<UserIdentityApiDTO>> result = new Result<>();
+        result.setSuccess();
+        List<UserIndentityAppDTO> list = userIdentityAppService.list();
+        result.setData(userIdentityApiConverter.toApiDtoList(list));
+        return result;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/converter/UserIdentityApiConverter.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/converter/UserIdentityApiConverter.java
new file mode 100644
index 0000000..2afdec3
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/converter/UserIdentityApiConverter.java
@@ -0,0 +1,27 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.account.converter;
+
+import com.gkhy.fourierSpecialGasMonitor.api.controller.account.dto.resp.UserIdentityApiDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.UserIndentityAppDTO;
+import com.gkhy.fourierSpecialGasMonitor.commons.utils.BeanCopyUtils;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/4
+ * @time: 13:44
+ */
+@Component
+public class UserIdentityApiConverter {
+    public List<UserIdentityApiDTO> toApiDtoList(List<UserIndentityAppDTO> list) {
+        List<UserIdentityApiDTO> respList = new ArrayList<>();
+        if(!CollectionUtils.isEmpty(list)){
+            respList = BeanCopyUtils.copyBeanList(list,UserIdentityApiDTO.class);
+        }
+        return respList;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/converter/UserInfoApiConverter.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/converter/UserInfoApiConverter.java
new file mode 100644
index 0000000..5028314
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/converter/UserInfoApiConverter.java
@@ -0,0 +1,53 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.account.converter;
+
+import com.gkhy.fourierSpecialGasMonitor.api.controller.account.dto.resp.UserIdentityBindApiDTO;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.account.dto.resp.UserInfoApiDTO;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.account.dto.resp.UserRoleBindApiDTO;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.attachment.dto.resp.AttachmentApiRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.UserInfoAppRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.commons.utils.BeanCopyUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class UserInfoApiConverter {
+
+    public UserInfoApiDTO toApiDto(UserInfoAppRespDTO appDto){
+        if(appDto == null)
+            return null;
+        UserInfoApiDTO apiDTO = new UserInfoApiDTO();
+        BeanUtils.copyProperties(appDto,apiDTO);
+        //角色
+        List<UserRoleBindApiDTO> userRoleBindApiDTOS = new ArrayList<>();
+        if(appDto.getRoles() != null){
+            userRoleBindApiDTOS = BeanCopyUtils.copyBeanList(appDto.getRoles(), UserRoleBindApiDTO.class);
+        }
+        apiDTO.setRoles(userRoleBindApiDTOS);
+        //身份
+        List<UserIdentityBindApiDTO> userIdentityBindApiDTOS = new ArrayList<>();
+        if(appDto.getUserIdentities() != null){
+            userIdentityBindApiDTOS = BeanCopyUtils.copyBeanList(appDto.getUserIdentities(), UserIdentityBindApiDTO.class);
+        }
+        //资质附件
+        if(appDto.getQualificationAttaAppRespDTO() != null){
+            AttachmentApiRespDTO attachmentApiRespDTO = new AttachmentApiRespDTO();
+            BeanUtils.copyProperties(appDto.getQualificationAttaAppRespDTO(),attachmentApiRespDTO);
+            apiDTO.setQualificationAttApiRespDTO(attachmentApiRespDTO);
+        }
+        apiDTO.setUserIdentities(userIdentityBindApiDTOS);
+        return apiDTO;
+    }
+
+    public List<UserInfoApiDTO> toApiDtoList(List<UserInfoAppRespDTO> appDtoList){
+        if(appDtoList == null || appDtoList.isEmpty())
+            return null;
+        List<UserInfoApiDTO> apiDtoList = new ArrayList<>();
+        appDtoList.forEach(appDto -> {
+            apiDtoList.add(toApiDto(appDto));
+        });
+        return apiDtoList;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/req/AddRoleApiDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/req/AddRoleApiDTO.java
new file mode 100644
index 0000000..ce9a798
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/req/AddRoleApiDTO.java
@@ -0,0 +1,14 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.account.dto.req;
+
+public class AddRoleApiDTO {
+
+    private String name;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/req/LoginReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/req/LoginReqDTO.java
new file mode 100644
index 0000000..02949ff
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/req/LoginReqDTO.java
@@ -0,0 +1,24 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.account.dto.req;
+
+public class LoginReqDTO {
+
+    private String name;
+
+    private String pwd;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPwd() {
+        return pwd;
+    }
+
+    public void setPwd(String pwd) {
+        this.pwd = pwd;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/req/ModRoleApiDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/req/ModRoleApiDTO.java
new file mode 100644
index 0000000..a047eda
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/req/ModRoleApiDTO.java
@@ -0,0 +1,24 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.account.dto.req;
+
+public class ModRoleApiDTO {
+
+    private Long roleId;
+
+    private String name;
+
+    public Long getRoleId() {
+        return roleId;
+    }
+
+    public void setRoleId(Long roleId) {
+        this.roleId = roleId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/req/UserSearchReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/req/UserSearchReqDTO.java
new file mode 100644
index 0000000..839bbfc
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/req/UserSearchReqDTO.java
@@ -0,0 +1,64 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.account.dto.req;
+
+public class UserSearchReqDTO {
+
+    private String name;
+
+    private String realName;
+
+    private Long roleId;
+
+    private Boolean usePage;
+
+    private Integer pageSize;
+
+    private Integer pageIndex;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getRealName() {
+        return realName;
+    }
+
+    public void setRealName(String realName) {
+        this.realName = realName;
+    }
+
+    public Long getRoleId() {
+        return roleId;
+    }
+
+    public void setRoleId(Long roleId) {
+        this.roleId = roleId;
+    }
+
+    public Boolean getUsePage() {
+        return usePage;
+    }
+
+    public void setUsePage(Boolean usePage) {
+        this.usePage = usePage;
+    }
+
+    public Integer getPageSize() {
+        return pageSize;
+    }
+
+    public void setPageSize(Integer pageSize) {
+        this.pageSize = pageSize;
+    }
+
+    public Integer getPageIndex() {
+        return pageIndex;
+    }
+
+    public void setPageIndex(Integer pageIndex) {
+        this.pageIndex = pageIndex;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/resp/UserIdentityApiDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/resp/UserIdentityApiDTO.java
new file mode 100644
index 0000000..a027016
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/resp/UserIdentityApiDTO.java
@@ -0,0 +1,15 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.account.dto.resp;
+
+import lombok.Data;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/4
+ * @time: 13:42
+ */
+@Data
+public class UserIdentityApiDTO {
+    private Long id ;
+    private String identity;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/resp/UserIdentityBindApiDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/resp/UserIdentityBindApiDTO.java
new file mode 100644
index 0000000..8213606
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/resp/UserIdentityBindApiDTO.java
@@ -0,0 +1,15 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.account.dto.resp;
+
+import lombok.Data;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/4
+ * @time: 10:32
+ */
+@Data
+public class UserIdentityBindApiDTO {
+    private Long userIdentityId;
+    private String userIdentity;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/resp/UserInfoApiDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/resp/UserInfoApiDTO.java
new file mode 100644
index 0000000..cbc6a5b
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/resp/UserInfoApiDTO.java
@@ -0,0 +1,42 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.account.dto.resp;
+
+import com.gkhy.fourierSpecialGasMonitor.api.controller.attachment.dto.resp.AttachmentApiRespDTO;
+import lombok.Data;
+
+import java.util.List;
+@Data
+public class UserInfoApiDTO {
+
+    private Long id;
+
+    //所属角色ID
+   /* private Long roleId;*/
+
+    private String name;
+
+    //真实姓名
+    private String realName;
+
+    private String phone;
+
+    private Byte idType;
+
+    private String idSerial;
+
+    private Long depId;
+    private String depName;
+    /**
+     * 身份(0专家,1非专家)
+     */
+    private Byte identityStatus;
+    //资质证书id
+    private Long qualificationAttId;
+
+    private List<UserRoleBindApiDTO> roles;
+
+    private List<UserIdentityBindApiDTO> userIdentities;
+
+    private AttachmentApiRespDTO qualificationAttApiRespDTO;
+
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/resp/UserRoleBindApiDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/resp/UserRoleBindApiDTO.java
new file mode 100644
index 0000000..5ff9873
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/dto/resp/UserRoleBindApiDTO.java
@@ -0,0 +1,15 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.account.dto.resp;
+
+import lombok.Data;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/13
+ * @time: 10:46
+ */
+@Data
+public class UserRoleBindApiDTO {
+    private Long roleId;
+    private String roleName;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/query/UserQuery.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/query/UserQuery.java
new file mode 100644
index 0000000..61a866a
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/account/query/UserQuery.java
@@ -0,0 +1,22 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.account.query;
+
+import lombok.Data;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/4/21
+ * @time: 9:39
+ */
+@Data
+public class UserQuery {
+
+    private String name;
+
+    private String realName;
+
+    private Long roleId;
+
+    private Long userIndentityId;
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/attachment/AttachmentController.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/attachment/AttachmentController.java
new file mode 100644
index 0000000..be16226
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/attachment/AttachmentController.java
@@ -0,0 +1,133 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.attachment;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.attachment.converter.AttachmentApiConverter;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.common.BaseController;
+import com.gkhy.fourierSpecialGasMonitor.application.attachment.service.AttachmentAppService;
+import com.gkhy.fourierSpecialGasMonitor.application.attachment.service.dto.resp.AttachmentAppRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.domain.attachment.enums.FileProjectConstants;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/6
+ * @time: 14:22
+ */
+@RestController
+@RequestMapping("/attachment")
+public class AttachmentController extends BaseController {
+
+    @Autowired
+    private AttachmentAppService attachmentAppService;
+    @Autowired
+    private AttachmentApiConverter converter;
+
+    /**
+     * 根据标识查询文件具体信息
+     * @param key
+     * @return
+     */
+    @GetMapping("/get/{key}")
+    public Result get(@PathVariable String key) {
+        AttachmentAppRespDTO byKey = attachmentAppService.findByKey(key);
+        return new Result(ResultCode.OK, converter.getApiRespDTO(byKey));
+    }
+
+    /**
+     * 根据id获取文件
+     * @param id
+     * @return
+     */
+    @GetMapping("/get/{id}")
+    public Result get(@PathVariable Long id) {
+        AttachmentAppRespDTO byId = attachmentAppService.findById(id);
+        return new Result(ResultCode.OK,converter.getApiRespDTO(byId));
+    }
+
+
+    /**
+     * 删除文件数据
+     * @param id
+     * @return
+     */
+    @DeleteMapping("/delete/{id}")
+    public Result delete(@PathVariable Long id) {
+        attachmentAppService.delete(id);
+        return Result.success();
+    }
+
+
+
+    /**
+     * @Description 上传文件(返回文件标识)
+     * @Param [file, module]
+     **/
+    @PostMapping("/upload/key")
+    public Result uploadReturnKey(@RequestParam("file") MultipartFile
+                                     file, @RequestParam("module") String module) {
+        Object returnStr = attachmentAppService.saveFileToPath(file, module, FileProjectConstants.ReturnType.KEY,getCurrentUserId());
+        return new Result(ResultCode.OK,returnStr);
+    }
+
+    /**
+     * @Description 上传文件(返回文件信息)
+     * @Param [file, module]
+     **/
+    @PostMapping("/upload/detail")
+    public Result uploadReturnDetail(@RequestParam("file") MultipartFile
+                                        file, @RequestParam("module") String module) {
+        Object detail = attachmentAppService.saveFileToPath(file, module, FileProjectConstants.ReturnType.DETAIL,getCurrentUserId());
+        return new Result(ResultCode.OK,detail);
+    }
+    /**
+     * @Description 上传文件(返回访问路径)
+     * @Date 2021/4/20 19:28
+     * @Param [file, module]
+     **/
+    @PostMapping("/upload/url")
+    public Result uploadReturnUrl(@RequestParam("file") MultipartFile file, @RequestParam("module") String module) {
+        Object returnStr = attachmentAppService.saveFileToPath(file, module, FileProjectConstants.ReturnType.URL,getCurrentUserId());
+        return new Result(ResultCode.OK,returnStr);
+    }
+
+    /**
+     * @return org.springframework.http.ResponseEntity<byte [ ]>
+     * @Description 获取下载文件流
+     * @Param [key]
+     **/
+    @GetMapping("/downloadFile/{key}")
+    public void download(@PathVariable String key, HttpServletResponse response) {
+        attachmentAppService.downloadForStream(response, key);
+    }
+
+    /**
+     * @return void
+     * @Description 文件下载(改写)
+     * @Param [key, response, request]
+     **/
+    @RequestMapping(value = "/downloadFileByKey/{key}", method = {RequestMethod.POST, RequestMethod.GET})
+    public void downloadFileByKey(@PathVariable String key, HttpServletResponse response, HttpServletRequest
+            request) {
+        attachmentAppService.downloadByKey(response, request, key);
+    }
+
+
+    /**
+     * @Description 获取下载文件路径
+     * @Param [key]
+     **/
+    @GetMapping("/downloadUrl/{key}")
+    public Result downLoad( @PathVariable String key) {
+        AttachmentAppRespDTO byKey = attachmentAppService.findByKey(key);
+        return new Result(ResultCode.OK,byKey.getFileUrl());
+    }
+
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/attachment/converter/AttachmentApiConverter.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/attachment/converter/AttachmentApiConverter.java
new file mode 100644
index 0000000..4912e18
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/attachment/converter/AttachmentApiConverter.java
@@ -0,0 +1,28 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.attachment.converter;
+
+import com.gkhy.fourierSpecialGasMonitor.api.controller.attachment.dto.resp.AttachmentApiRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.attachment.service.dto.resp.AttachmentAppRespDTO;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Component;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/7
+ * @time: 16:55
+ */
+@Component
+public class AttachmentApiConverter {
+
+    public AttachmentApiRespDTO getApiRespDTO(AttachmentAppRespDTO appRespDTO){
+        if (appRespDTO == null){
+            return null;
+        }
+        AttachmentApiRespDTO attachmentApiRespDTO = new AttachmentApiRespDTO();
+        BeanUtils.copyProperties(appRespDTO,attachmentApiRespDTO);
+        return attachmentApiRespDTO;
+    }
+
+
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/attachment/dto/resp/AttachmentApiRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/attachment/dto/resp/AttachmentApiRespDTO.java
new file mode 100644
index 0000000..9bad80f
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/attachment/dto/resp/AttachmentApiRespDTO.java
@@ -0,0 +1,48 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.attachment.dto.resp;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/7
+ * @time: 16:54
+ */
+@Data
+public class AttachmentApiRespDTO {
+    private Long id;
+    //文件标识
+    private String fileKey;
+    //文件本地址
+    private String filePath;
+    //文件访问路径
+    private String fileUrl;
+    //文件名称
+    private String fileName;
+    //文件后缀
+    private String fileSuffix;
+    //文件描述
+    private String fileDesc;
+    //文件大小
+    private Long fileSize;
+    //文件类型
+    private String fileType;
+    //模块
+    private String module;
+    //删除标识 0-未删除,1-删除
+    private Integer delFlag;
+    //创建时间
+    private LocalDateTime createTime;
+    //创建人id
+    private Long createUid;
+    //创建人姓名
+    private String createUname;
+    //修改时间
+    private LocalDateTime updateTime;
+    //修改人id
+    private Long updateUid;
+    //修改人姓名
+    private String updateUname;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/common/BaseController.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/common/BaseController.java
new file mode 100644
index 0000000..af17224
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/common/BaseController.java
@@ -0,0 +1,35 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.common;
+
+import com.gkhy.fourierSpecialGasMonitor.config.authorization.TokenConfig;
+import org.springframework.web.bind.annotation.ModelAttribute;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class BaseController {
+
+    @Resource
+    protected TokenConfig tokenConfig;
+
+    protected HttpServletRequest request;
+    protected HttpServletResponse response;
+
+    @ModelAttribute
+    public void setReqAndResp(HttpServletRequest request, HttpServletResponse response){
+        this.request = request;
+        this.response = response;
+    }
+
+    protected Long getCurrentUserId(){
+        String userId = this.request.getHeader(tokenConfig.getLoginUserHeader());
+        if(userId == null || userId.isEmpty())
+            return -1L;
+        try {
+            Long uid = Long.parseLong(userId);
+            return uid;
+        } catch (NumberFormatException e) {
+            return -1L;
+        }
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/model/dto/resp/MenuItemApiDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/model/dto/resp/MenuItemApiDTO.java
new file mode 100644
index 0000000..2317e5c
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/model/dto/resp/MenuItemApiDTO.java
@@ -0,0 +1,148 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.model.dto.resp;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MenuItemApiDTO {
+
+    private Long id;
+
+    //菜单级别
+    private Integer level;
+
+    //父级菜单
+    private Long parentId;
+
+
+    //菜单项描述信息
+    private String description;
+
+    //菜单项名称
+    private String name;
+
+    //路径
+    private String path;
+
+    //重定向路径
+    private String redirect;
+
+
+    private Byte priority;
+
+    private Boolean isPublic;
+
+    private String component;
+
+    private MenuItemMetaApiDTO meta;
+
+    private List<Long> menuSuperior;
+
+    private List<MenuItemApiDTO> children;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Integer getLevel() {
+        return level;
+    }
+
+    public void setLevel(Integer level) {
+        this.level = level;
+    }
+
+    public Long getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getRedirect() {
+        return redirect;
+    }
+
+    public void setRedirect(String redirect) {
+        this.redirect = redirect;
+    }
+
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Byte getPriority() {
+        return priority;
+    }
+
+    public void setPriority(Byte priority) {
+        this.priority = priority;
+    }
+
+    public Boolean getPublic() {
+        return isPublic;
+    }
+
+    public void setPublic(Boolean aPublic) {
+        isPublic = aPublic;
+    }
+
+    public String getComponent() {
+        return component;
+    }
+
+    public void setComponent(String component) {
+        this.component = component;
+    }
+
+    public MenuItemMetaApiDTO getMeta() {
+        return meta;
+    }
+
+    public void setMeta(MenuItemMetaApiDTO meta) {
+        this.meta = meta;
+    }
+
+    public List<Long> getMenuSuperior() {
+        return menuSuperior;
+    }
+
+    public void setMenuSuperior(List<Long> menuSuperior) {
+        this.menuSuperior = menuSuperior;
+    }
+
+    public List<MenuItemApiDTO> getChildren() {
+        if(children == null)
+            children = new ArrayList<>(0);
+        return children;
+    }
+
+    public void setChildren(List<MenuItemApiDTO> children) {
+        this.children = children;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/model/dto/resp/MenuItemMetaApiDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/model/dto/resp/MenuItemMetaApiDTO.java
new file mode 100644
index 0000000..6a8814c
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/model/dto/resp/MenuItemMetaApiDTO.java
@@ -0,0 +1,124 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.model.dto.resp;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+* @Description: 菜单基本属性
+*/
+public class MenuItemMetaApiDTO implements Serializable {
+
+    private static final long serialVersionUID = 3278913464169090683L;
+
+    private String title;
+
+    private String isLink;
+
+    private Boolean isHide;
+
+    private Boolean isKeepAlive;
+
+    private Boolean isAffix;
+
+    private Boolean isIframe;
+
+    private String icon;
+
+    private List<Long> roles;
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public String getIsLink() {
+        return isLink;
+    }
+
+    public void setIsLink(String isLink) {
+        this.isLink = isLink;
+    }
+
+    public Boolean getIsHide() {
+        return isHide;
+    }
+
+    public void setIsHide(Boolean isHide) {
+        this.isHide = isHide;
+    }
+
+    public Boolean getIsKeepAlive() {
+        return isKeepAlive;
+    }
+
+    public void setIsKeepAlive(Boolean isKeepAlive) {
+        this.isKeepAlive = isKeepAlive;
+    }
+
+    public Boolean getIsAffix() {
+        return isAffix;
+    }
+
+    public void setIsAffix(Boolean isAffix) {
+        this.isAffix = isAffix;
+    }
+
+    public Boolean getIsIframe() {
+        return isIframe;
+    }
+
+    public void setIsIframe(Boolean isIframe) {
+        this.isIframe = isIframe;
+    }
+
+    public String getIcon() {
+        return icon;
+    }
+
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
+
+    public Boolean getHide() {
+        return isHide;
+    }
+
+    public void setHide(Boolean hide) {
+        isHide = hide;
+    }
+
+    public Boolean getKeepAlive() {
+        return isKeepAlive;
+    }
+
+    public void setKeepAlive(Boolean keepAlive) {
+        isKeepAlive = keepAlive;
+    }
+
+    public Boolean getAffix() {
+        return isAffix;
+    }
+
+    public void setAffix(Boolean affix) {
+        isAffix = affix;
+    }
+
+    public Boolean getIframe() {
+        return isIframe;
+    }
+
+    public void setIframe(Boolean iframe) {
+        isIframe = iframe;
+    }
+
+    public List<Long> getRoles() {
+        return roles;
+    }
+
+    public void setRoles(List<Long> roles) {
+        this.roles = roles;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/MenuManageController.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/MenuManageController.java
new file mode 100644
index 0000000..0d653d3
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/MenuManageController.java
@@ -0,0 +1,91 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.sysAdmin;
+
+import com.gkhy.fourierSpecialGasMonitor.api.controller.sysAdmin.converter.MenuInfoApiConverter;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.model.dto.resp.MenuItemApiDTO;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.sysAdmin.dto.req.AddAndUpdateMenuItemApiDTO;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.sysAdmin.dto.req.MenuItemBindRoleApiDTO;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.sysAdmin.dto.req.RoleBindMenuApiDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.model.dto.req.*;
+import com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.model.dto.resp.MenuItemAppDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.service.MenuAppService;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.model.dto.MenuItemDomainDTO;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+@RequestMapping("/sys/console/menu")
+public class MenuManageController {
+
+    @Autowired
+    private MenuAppService menuAppService;
+
+    @Autowired
+    private MenuInfoApiConverter menuInfoApiConverter;
+
+    @PostMapping("/add")
+    public Result addMenuItems(@RequestBody AddAndUpdateMenuItemApiDTO addAndUpdateMenuItemApiDTO){
+        Result result = new Result<>();
+        NewMenuItemAppDTO appDTO = menuInfoApiConverter.toCreateMenuDto(addAndUpdateMenuItemApiDTO);
+        result = menuAppService.addMenuItem(appDTO);
+        return result;
+    }
+
+
+    @PostMapping("/mod")
+    public Result modifyMenuItem(@RequestBody AddAndUpdateMenuItemApiDTO addAndUpdateMenuItemApiDTO){
+        Result result = new Result();
+        AddAndUpdateMenuItemAppDTO appDTO = menuInfoApiConverter.toAddAndUpdateAppDTO(addAndUpdateMenuItemApiDTO);
+        result = menuAppService.modifyMenuItem(appDTO);
+        return result;
+    }
+
+    @GetMapping("/get/all")
+    public SearchResult getAll(){
+        SearchResult result = new SearchResult<>();
+        SearchResult<MenuItemDomainDTO> rs = menuAppService.getAllMenuItems();
+        BeanUtils.copyProperties(rs,result);
+        if(rs.isSuccess() && rs.getData() != null){
+            List<MenuItemAppDTO> dtoList = (List<MenuItemAppDTO>) rs.getData();
+            if(dtoList != null && !dtoList.isEmpty()){
+                List<MenuItemApiDTO> apiDTOList = new ArrayList<>();
+                dtoList.forEach(d -> {
+                    apiDTOList.add(menuInfoApiConverter.toMenuItemApiDTO(d));
+                });
+                result.setData(apiDTOList);
+            }
+        }
+//        result = menuAppService.getAllMenuItems();
+        return result;
+    }
+
+    @GetMapping("/del")
+    public Result deleteOne(Long menuItemId){
+        Result result = menuAppService.deleteMenuItem(menuItemId);
+        return result;
+    }
+
+    @PostMapping("/bind/role2menu")
+    public Result roleBindMenu(@RequestBody RoleBindMenuApiDTO bindMenuApiDTO){
+        Result result = new Result<>();
+        RoleBindMenuAppDTO bindAppDTO = new RoleBindMenuAppDTO();
+        BeanUtils.copyProperties(bindMenuApiDTO,bindAppDTO);
+        result = menuAppService.roleBindMenu(bindAppDTO);
+        return result;
+    }
+
+    @PostMapping("/bind/menu2role")
+    public Result menuBindRole(@RequestBody MenuItemBindRoleApiDTO bindRoleApiDTO){
+        Result result = new Result<>();
+        MenuItemBindRoleAppDTO bindAppDTO = new MenuItemBindRoleAppDTO();
+        BeanUtils.copyProperties(bindRoleApiDTO,bindAppDTO);
+        result = menuAppService.menuBindRole(bindAppDTO);
+        return result;
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/UserMenuController.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/UserMenuController.java
new file mode 100644
index 0000000..dd968b3
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/UserMenuController.java
@@ -0,0 +1,47 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.sysAdmin;
+
+import com.gkhy.fourierSpecialGasMonitor.api.controller.common.BaseController;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.sysAdmin.converter.MenuInfoApiConverter;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.model.dto.resp.MenuItemApiDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.model.dto.resp.MenuItemAppDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.service.impl.AccountMenuAppServiceImpl;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+@RequestMapping("/sys/menu")
+public class UserMenuController extends BaseController {
+
+    @Autowired
+    private AccountMenuAppServiceImpl accountMenuAppService;
+
+    @Autowired
+    private MenuInfoApiConverter menuInfoApiConverter;
+
+
+    @GetMapping("/get/u")
+    Result<List<MenuItemAppDTO>> getAllMenuList(){
+        SearchResult result = new SearchResult<>();
+        SearchResult<MenuItemAppDTO> rs = accountMenuAppService.findAllMenuItemByUserId(getCurrentUserId());
+        BeanUtils.copyProperties(rs,result);
+        if(rs.isSuccess() && rs.getData() != null){
+            List<MenuItemAppDTO> dtoList = (List<MenuItemAppDTO>) rs.getData();
+            if(dtoList != null && !dtoList.isEmpty()){
+                List<MenuItemApiDTO> apiDTOList = new ArrayList<>();
+                dtoList.forEach(d -> {
+                    apiDTOList.add(menuInfoApiConverter.toMenuItemApiDTO(d));
+                });
+                result.setData(apiDTOList);
+            }
+        }
+        return result;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/converter/MenuInfoApiConverter.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/converter/MenuInfoApiConverter.java
new file mode 100644
index 0000000..85fa0a9
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/converter/MenuInfoApiConverter.java
@@ -0,0 +1,119 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.sysAdmin.converter;
+
+import com.gkhy.fourierSpecialGasMonitor.api.controller.model.dto.resp.MenuItemApiDTO;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.model.dto.resp.MenuItemMetaApiDTO;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.sysAdmin.dto.req.AddAndUpdateMenuItemApiDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.model.dto.req.AddAndUpdateMenuItemAppDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.model.dto.req.NewMenuItemAppDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.model.dto.resp.MenuItemAppDTO;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class MenuInfoApiConverter {
+
+    public MenuItemApiDTO toMenuItemApiDTO(MenuItemAppDTO menuItemAppDTO){
+        if(menuItemAppDTO == null)
+            return null;
+        MenuItemApiDTO apiDTO = new MenuItemApiDTO();
+        copyMenuItemInfoProperities(menuItemAppDTO,apiDTO);
+        apiDTO.setChildren(toMenuItemApiDTOList(menuItemAppDTO.getSubMenuItemList()));
+        return apiDTO;
+    }
+
+    private List<MenuItemApiDTO> toMenuItemApiDTOList(List<MenuItemAppDTO> dtoList){
+        if(dtoList == null)
+            return null;
+        List<MenuItemApiDTO> targetList = new ArrayList<>();
+        dtoList.forEach(d -> {
+            MenuItemApiDTO apiDTO = new MenuItemApiDTO();
+            copyMenuItemInfoProperities(d,apiDTO);
+            if(d.getSubMenuItemList() != null){
+                apiDTO.setChildren(toMenuItemApiDTOList(d.getSubMenuItemList()));
+            }
+            targetList.add(apiDTO);
+        });
+        return targetList;
+    }
+
+    private void copyMenuItemInfoProperities(MenuItemAppDTO orignDTO, MenuItemApiDTO targetDTO){
+        if(orignDTO == null || targetDTO == null)
+            return;
+        targetDTO.setId(orignDTO.getId());
+        targetDTO.setLevel(orignDTO.getLevel());
+        targetDTO.setParentId(orignDTO.getParentId());
+        targetDTO.setName(orignDTO.getName());
+        targetDTO.setPath(orignDTO.getPath());
+        targetDTO.setRedirect(orignDTO.getRedirect());
+        targetDTO.setDescription(orignDTO.getDescInfo());
+        targetDTO.setComponent(orignDTO.getComponent());
+        targetDTO.setPriority(orignDTO.getPriority());
+        targetDTO.setPublic(orignDTO.getPublicable());
+        MenuItemMetaApiDTO meta = new MenuItemMetaApiDTO();
+        meta.setTitle(orignDTO.getTitle());
+        meta.setIcon(orignDTO.getIcon());
+        meta.setIsHide(orignDTO.getVisiable());
+        meta.setIsAffix(orignDTO.getAffixable());
+        meta.setIsIframe(orignDTO.getIframeable());
+        meta.setIsKeepAlive(orignDTO.getAliveable());
+        meta.setIsLink(orignDTO.getLink());
+        meta.setRoles(orignDTO.getRoles());
+        if(meta.getIsLink() == null)
+            meta.setIsLink("");
+        targetDTO.setMeta(meta);
+        if(orignDTO.getSubMenuItemList() != null && !orignDTO.getSubMenuItemList().isEmpty()){
+            List<MenuItemApiDTO> childs = new ArrayList<>();
+            orignDTO.getSubMenuItemList().forEach(orign -> {
+                MenuItemApiDTO dd = new MenuItemApiDTO();
+                copyMenuItemInfoProperities(orign,dd);
+                childs.add(dd);
+            });
+            targetDTO.setChildren(childs);
+        }
+    }
+
+    public NewMenuItemAppDTO toCreateMenuDto(AddAndUpdateMenuItemApiDTO addAndUpdateMenuItemApiDTO){
+        if(addAndUpdateMenuItemApiDTO == null)
+            return null;
+        NewMenuItemAppDTO dto = new NewMenuItemAppDTO();
+        BeanUtils.copyProperties(addAndUpdateMenuItemApiDTO,dto);
+        //
+        dto.setDescInfo(addAndUpdateMenuItemApiDTO.getDescription());
+        //
+        if(addAndUpdateMenuItemApiDTO.getMeta() != null){
+            dto.setLink(addAndUpdateMenuItemApiDTO.getMeta().getIsLink());
+            dto.setTitle(addAndUpdateMenuItemApiDTO.getMeta().getTitle());
+            dto.setVisiable(addAndUpdateMenuItemApiDTO.getMeta().getIsHide());
+            dto.setIframeable(addAndUpdateMenuItemApiDTO.getMeta().getIsIframe());
+            dto.setAliveable(addAndUpdateMenuItemApiDTO.getMeta().getIsKeepAlive());
+            dto.setAffixable(addAndUpdateMenuItemApiDTO.getMeta().getIsAffix());
+            dto.setIcon(addAndUpdateMenuItemApiDTO.getMeta().getIcon());
+            dto.setRoles(addAndUpdateMenuItemApiDTO.getMeta().getRoles());
+        }
+        //
+        return dto;
+    }
+
+    public AddAndUpdateMenuItemAppDTO toAddAndUpdateAppDTO(AddAndUpdateMenuItemApiDTO addAndUpdateMenuItemApiDTO){
+        if(addAndUpdateMenuItemApiDTO == null)
+            return null;
+        AddAndUpdateMenuItemAppDTO appDTO = new AddAndUpdateMenuItemAppDTO();
+        BeanUtils.copyProperties(addAndUpdateMenuItemApiDTO,appDTO);
+        appDTO.setMenuItemId(addAndUpdateMenuItemApiDTO.getId());
+        appDTO.setDescInfo(addAndUpdateMenuItemApiDTO.getDescription());
+        if(addAndUpdateMenuItemApiDTO.getMeta() != null){
+            appDTO.setLink(addAndUpdateMenuItemApiDTO.getMeta().getIsLink());
+            appDTO.setTitle(addAndUpdateMenuItemApiDTO.getMeta().getTitle());
+            appDTO.setVisiable(addAndUpdateMenuItemApiDTO.getMeta().getIsHide());
+            appDTO.setIframeable(addAndUpdateMenuItemApiDTO.getMeta().getIsIframe());
+            appDTO.setAliveable(addAndUpdateMenuItemApiDTO.getMeta().getIsKeepAlive());
+            appDTO.setAffixable(addAndUpdateMenuItemApiDTO.getMeta().getIsAffix());
+            appDTO.setIcon(addAndUpdateMenuItemApiDTO.getMeta().getIcon());
+            appDTO.setRoles(addAndUpdateMenuItemApiDTO.getMeta().getRoles());
+        }
+        return appDTO;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/AddAndUpdateMenuItemApiDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/AddAndUpdateMenuItemApiDTO.java
new file mode 100644
index 0000000..1443a20
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/AddAndUpdateMenuItemApiDTO.java
@@ -0,0 +1,104 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.sysAdmin.dto.req;
+
+public class AddAndUpdateMenuItemApiDTO {
+
+    private Long id;
+
+    private Long parentId;
+
+    private String description;
+
+    private String name;
+
+    private String path;
+
+    private String redirect;
+
+    private Byte priority;
+
+    private String component;
+
+    private Boolean publicable;
+
+    private MenuItemMetaDTO meta;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getRedirect() {
+        return redirect;
+    }
+
+    public void setRedirect(String redirect) {
+        this.redirect = redirect;
+    }
+
+    public Byte getPriority() {
+        return priority;
+    }
+
+    public void setPriority(Byte priority) {
+        this.priority = priority;
+    }
+
+    public String getComponent() {
+        return component;
+    }
+
+    public void setComponent(String component) {
+        this.component = component;
+    }
+
+    public Boolean getPublicable() {
+        return publicable;
+    }
+
+    public void setPublicable(Boolean publicable) {
+        this.publicable = publicable;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public MenuItemMetaDTO getMeta() {
+        return meta;
+    }
+
+    public void setMeta(MenuItemMetaDTO meta) {
+        this.meta = meta;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/MenuItemBindRoleApiDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/MenuItemBindRoleApiDTO.java
new file mode 100644
index 0000000..7d4b6b1
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/MenuItemBindRoleApiDTO.java
@@ -0,0 +1,36 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.sysAdmin.dto.req;
+
+import java.util.List;
+
+public class MenuItemBindRoleApiDTO {
+
+    private Long menuItemId;
+
+    private List<Long> bindRoleIdList;
+
+    private List<Long> unbindRoleIdList;
+
+    public Long getMenuItemId() {
+        return menuItemId;
+    }
+
+    public void setMenuItemId(Long menuItemId) {
+        this.menuItemId = menuItemId;
+    }
+
+    public List<Long> getBindRoleIdList() {
+        return bindRoleIdList;
+    }
+
+    public void setBindRoleIdList(List<Long> bindRoleIdList) {
+        this.bindRoleIdList = bindRoleIdList;
+    }
+
+    public List<Long> getUnbindRoleIdList() {
+        return unbindRoleIdList;
+    }
+
+    public void setUnbindRoleIdList(List<Long> unbindRoleIdList) {
+        this.unbindRoleIdList = unbindRoleIdList;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/MenuItemMetaDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/MenuItemMetaDTO.java
new file mode 100644
index 0000000..45cde99
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/MenuItemMetaDTO.java
@@ -0,0 +1,117 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.sysAdmin.dto.req;
+
+import java.util.List;
+
+public class MenuItemMetaDTO {
+    private String title;
+
+    private String isLink;
+
+    private Boolean isHide;
+
+    private Boolean isKeepAlive;
+
+    private Boolean isAffix;
+
+    private Boolean isIframe;
+
+    private String icon;
+
+    private List<Long> roles;
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getIsLink() {
+        return isLink;
+    }
+
+    public void setIsLink(String isLink) {
+        this.isLink = isLink;
+    }
+
+    public Boolean getIsHide() {
+        return isHide;
+    }
+
+    public void setIsHide(Boolean hide) {
+        isHide = hide;
+    }
+
+    public Boolean getIsKeepAlive() {
+        return isKeepAlive;
+    }
+
+    public void setIsKeepAlive(Boolean keepAlive) {
+        isKeepAlive = keepAlive;
+    }
+
+    public Boolean getIsAffix() {
+        return isAffix;
+    }
+
+    public void setIsAffix(Boolean affix) {
+        isAffix = affix;
+    }
+
+    public Boolean getIsIframe() {
+        return isIframe;
+    }
+
+    public void setIsIframe(Boolean iframe) {
+        isIframe = iframe;
+    }
+
+    public String getIcon() {
+        return icon;
+    }
+
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
+
+    public Boolean getHide() {
+        return isHide;
+    }
+
+    public void setHide(Boolean hide) {
+        isHide = hide;
+    }
+
+    public Boolean getKeepAlive() {
+        return isKeepAlive;
+    }
+
+    public void setKeepAlive(Boolean keepAlive) {
+        isKeepAlive = keepAlive;
+    }
+
+    public Boolean getAffix() {
+        return isAffix;
+    }
+
+    public void setAffix(Boolean affix) {
+        isAffix = affix;
+    }
+
+    public Boolean getIframe() {
+        return isIframe;
+    }
+
+    public void setIframe(Boolean iframe) {
+        isIframe = iframe;
+    }
+
+    public List<Long> getRoles() {
+        return roles;
+    }
+
+    public void setRoles(List<Long> roles) {
+        this.roles = roles;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/ModifyMenuItemApiDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/ModifyMenuItemApiDTO.java
new file mode 100644
index 0000000..fd52fa5
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/ModifyMenuItemApiDTO.java
@@ -0,0 +1,104 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.sysAdmin.dto.req;
+
+public class ModifyMenuItemApiDTO {
+
+    private Long id;
+
+    private Long parentId;
+
+    private String description;
+
+    private String name;
+
+    private String path;
+
+    private String redirect;
+
+    private Byte priority;
+
+    private String component;
+
+    private Boolean publicable;
+
+    private MenuItemMetaDTO meta;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getRedirect() {
+        return redirect;
+    }
+
+    public void setRedirect(String redirect) {
+        this.redirect = redirect;
+    }
+
+    public Byte getPriority() {
+        return priority;
+    }
+
+    public void setPriority(Byte priority) {
+        this.priority = priority;
+    }
+
+    public String getComponent() {
+        return component;
+    }
+
+    public void setComponent(String component) {
+        this.component = component;
+    }
+
+    public Boolean getPublicable() {
+        return publicable;
+    }
+
+    public void setPublicable(Boolean publicable) {
+        this.publicable = publicable;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public MenuItemMetaDTO getMeta() {
+        return meta;
+    }
+
+    public void setMeta(MenuItemMetaDTO meta) {
+        this.meta = meta;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/RoleBindMenuApiDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/RoleBindMenuApiDTO.java
new file mode 100644
index 0000000..81d5644
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/api/controller/sysAdmin/dto/req/RoleBindMenuApiDTO.java
@@ -0,0 +1,36 @@
+package com.gkhy.fourierSpecialGasMonitor.api.controller.sysAdmin.dto.req;
+
+import java.util.List;
+
+public class RoleBindMenuApiDTO {
+
+    private Long roleId;
+
+    private List<Long> bindMenuItemIdList;
+
+    private List<Long> unbindMenuItemIdList;
+
+    public Long getRoleId() {
+        return roleId;
+    }
+
+    public void setRoleId(Long roleId) {
+        this.roleId = roleId;
+    }
+
+    public List<Long> getBindMenuItemIdList() {
+        return bindMenuItemIdList;
+    }
+
+    public void setBindMenuItemIdList(List<Long> bindMenuItemIdList) {
+        this.bindMenuItemIdList = bindMenuItemIdList;
+    }
+
+    public List<Long> getUnbindMenuItemIdList() {
+        return unbindMenuItemIdList;
+    }
+
+    public void setUnbindMenuItemIdList(List<Long> unbindMenuItemIdList) {
+        this.unbindMenuItemIdList = unbindMenuItemIdList;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/converter/RoleInfoAppConverter.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/converter/RoleInfoAppConverter.java
new file mode 100644
index 0000000..698e5d0
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/converter/RoleInfoAppConverter.java
@@ -0,0 +1,18 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.converter;
+
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.RoleRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.RoleInfoDoaminDTO;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+@Service
+public class RoleInfoAppConverter {
+
+    public RoleRespDTO toRoleRespDTO(RoleInfoDoaminDTO roleInfoDoaminDTO){
+        if(roleInfoDoaminDTO == null)
+            return null;
+        RoleRespDTO respDTO = new RoleRespDTO();
+        BeanUtils.copyProperties(roleInfoDoaminDTO,respDTO);
+        return respDTO;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/converter/UserIndentityAppConverter.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/converter/UserIndentityAppConverter.java
new file mode 100644
index 0000000..286facd
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/converter/UserIndentityAppConverter.java
@@ -0,0 +1,27 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.converter;
+
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.UserIndentityAppDTO;
+import com.gkhy.fourierSpecialGasMonitor.commons.utils.BeanCopyUtils;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.UserIdentityDomainDTO;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/4
+ * @time: 14:08
+ */
+@Component
+public class UserIndentityAppConverter {
+    public List<UserIndentityAppDTO> toUserIndentityAppDTO(List<UserIdentityDomainDTO> list) {
+        List<UserIndentityAppDTO> respList = new ArrayList<>();
+        if(!CollectionUtils.isEmpty(list)){
+            respList = BeanCopyUtils.copyBeanList(list,UserIndentityAppDTO.class);
+        }
+        return respList;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/converter/UserInfoAppConverter.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/converter/UserInfoAppConverter.java
new file mode 100644
index 0000000..f1eb90a
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/converter/UserInfoAppConverter.java
@@ -0,0 +1,67 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.converter;
+
+
+import cn.hutool.core.util.ObjectUtil;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.UserIdentityBindAppRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.UserInfoAppRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.UserRoleBindAppRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.attachment.service.dto.resp.AttachmentAppRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.commons.utils.BeanCopyUtils;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.SysUserRoleBindDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.UserInfoDomainDTO;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class UserInfoAppConverter {
+
+    public List<UserInfoAppRespDTO> toAppDtoList(List<UserInfoDomainDTO> domainDtoList){
+        if(domainDtoList == null || domainDtoList.isEmpty())
+            return null;
+        List<UserInfoAppRespDTO> appRespDTOList = new ArrayList<>();
+        domainDtoList.forEach(d -> {
+            appRespDTOList.add(toAppDto(d));
+        });
+        return appRespDTOList;
+    }
+
+    public UserInfoAppRespDTO toAppDto(UserInfoDomainDTO domainDto){
+        if(domainDto == null)
+            return null;
+        UserInfoAppRespDTO appDto = new UserInfoAppRespDTO();
+        BeanUtils.copyProperties(domainDto,appDto);
+        List<UserRoleBindAppRespDTO> userRoleBindAppRespDTOS = new ArrayList<>();
+        if(ObjectUtil.isNotEmpty(domainDto.getRoles())){
+            domainDto.getRoles().forEach(role -> {
+                userRoleBindAppRespDTOS.add(toUserRoleAppRestDTO(role));
+            });
+        }
+        appDto.setRoles(userRoleBindAppRespDTOS);
+        //身份
+        List<UserIdentityBindAppRespDTO> userIdentityBindAppDTOS = new ArrayList<>();
+        if(domainDto.getUserIdentities() != null){
+            userIdentityBindAppDTOS = BeanCopyUtils.copyBeanList(domainDto.getUserIdentities(), UserIdentityBindAppRespDTO.class);
+        }
+        //资质附件
+        if(domainDto.getQualificationAttDomainDTO() != null){
+            AttachmentAppRespDTO attachmentAppRespDTO = new AttachmentAppRespDTO();
+            BeanUtils.copyProperties(domainDto.getQualificationAttDomainDTO(),attachmentAppRespDTO);
+            appDto.setQualificationAttaAppRespDTO(attachmentAppRespDTO);
+        }
+        appDto.setUserIdentities(userIdentityBindAppDTOS);
+        return appDto;
+    }
+
+    private UserRoleBindAppRespDTO toUserRoleAppRestDTO(SysUserRoleBindDomainDTO role) {
+        if(role == null){
+            return null;
+        }
+        UserRoleBindAppRespDTO userRoleBindAppRespDTO = new UserRoleBindAppRespDTO();
+        BeanUtils.copyProperties(role,userRoleBindAppRespDTO);
+        return userRoleBindAppRespDTO;
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/ChangePasswdReqDto.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/ChangePasswdReqDto.java
new file mode 100644
index 0000000..75ceaf2
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/ChangePasswdReqDto.java
@@ -0,0 +1,34 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto;
+
+public class ChangePasswdReqDto {
+
+    public Long uid;
+
+    private String oldPwd;
+
+    private String newPwd;
+
+    public Long getUid() {
+        return uid;
+    }
+
+    public void setUid(Long uid) {
+        this.uid = uid;
+    }
+
+    public String getOldPwd() {
+        return oldPwd;
+    }
+
+    public void setOldPwd(String oldPwd) {
+        this.oldPwd = oldPwd;
+    }
+
+    public String getNewPwd() {
+        return newPwd;
+    }
+
+    public void setNewPwd(String newPwd) {
+        this.newPwd = newPwd;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/CreateNewUserAppReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/CreateNewUserAppReqDTO.java
new file mode 100644
index 0000000..034ed00
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/CreateNewUserAppReqDTO.java
@@ -0,0 +1,32 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class CreateNewUserAppReqDTO {
+
+    private String name;
+
+    private String realName;
+
+    private String pwd;
+
+    private List<Long> roleIds;
+
+
+    private String phone;
+
+    private Byte idType;
+
+    private String idSerial;
+
+    private Long depId;
+
+    private Byte identityStatus;
+
+    private List<Long> identityIds;
+
+    private Long qualificationAttId;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/LoginReqAppDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/LoginReqAppDTO.java
new file mode 100644
index 0000000..c4108d0
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/LoginReqAppDTO.java
@@ -0,0 +1,34 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto;
+
+public class LoginReqAppDTO {
+
+    private String name;
+
+    private String phone;
+
+    private String pwd;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public String getPwd() {
+        return pwd;
+    }
+
+    public void setPwd(String pwd) {
+        this.pwd = pwd;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/SysDepartmentAppAddReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/SysDepartmentAppAddReqDTO.java
new file mode 100644
index 0000000..60ab9fe
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/SysDepartmentAppAddReqDTO.java
@@ -0,0 +1,32 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto;
+
+import lombok.Data;
+
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/7
+ * @time: 17:00
+ */
+@Data
+public class SysDepartmentAppAddReqDTO {
+
+    private Long id;
+    /**
+     * 部门
+     */
+    private String depName;
+    /**
+     * 等级
+     */
+    private Byte level;
+    /**
+     * 父级id
+     */
+    private Long parentId;
+    /**
+     * 描述
+     */
+    private String info;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/SysDepartmentAppUpdateReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/SysDepartmentAppUpdateReqDTO.java
new file mode 100644
index 0000000..3ebcf5b
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/SysDepartmentAppUpdateReqDTO.java
@@ -0,0 +1,24 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto;
+
+import lombok.Data;
+
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/7
+ * @time: 13:25
+ */
+@Data
+public class SysDepartmentAppUpdateReqDTO {
+
+    private Long id;
+    /**
+     * 部门
+     */
+    private String depName;
+    /**
+     * 描述
+     */
+    private String info;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/UpdateUserAppReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/UpdateUserAppReqDTO.java
new file mode 100644
index 0000000..73bcc87
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/repDto/UpdateUserAppReqDTO.java
@@ -0,0 +1,32 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto;
+
+import lombok.Data;
+
+import java.util.List;
+@Data
+public class UpdateUserAppReqDTO {
+
+    private Long id;
+
+    private String name;
+
+    private String realName;
+
+    private List<Long> roleIds;
+
+
+    private String phone;
+
+    private Byte idType;
+
+    private String idSerial;
+
+    private Long depId;
+
+    private Byte identityStatus;
+
+    private List<Long> identityIds;
+
+    private Long qualificationAttId;
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/ContextUserDto.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/ContextUserDto.java
new file mode 100644
index 0000000..f8f82cd
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/ContextUserDto.java
@@ -0,0 +1,57 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto;
+
+public class ContextUserDto {
+
+    private Long id;
+
+    //用户账号状态
+    private Byte status;
+
+    //所属角色ID
+    private Long roleId;
+
+    private String name;
+
+    //真实姓名
+    private String realName;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Byte getStatus() {
+        return status;
+    }
+
+    public void setStatus(Byte status) {
+        this.status = status;
+    }
+
+    public Long getRoleId() {
+        return roleId;
+    }
+
+    public void setRoleId(Long roleId) {
+        this.roleId = roleId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getRealName() {
+        return realName;
+    }
+
+    public void setRealName(String realName) {
+        this.realName = realName;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/LoginRespDto.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/LoginRespDto.java
new file mode 100644
index 0000000..0d63963
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/LoginRespDto.java
@@ -0,0 +1,21 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class LoginRespDto {
+
+    private Long uid;
+
+    private String name;
+
+    private String realName;
+
+    private String tk;
+
+    private List<UserRoleBindRespDTO> roles;
+
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/RoleRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/RoleRespDTO.java
new file mode 100644
index 0000000..54c8115
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/RoleRespDTO.java
@@ -0,0 +1,24 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto;
+
+public class RoleRespDTO {
+
+    private Long id;
+
+    private String name;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/SysDepartmentAppDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/SysDepartmentAppDTO.java
new file mode 100644
index 0000000..d63a9ea
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/SysDepartmentAppDTO.java
@@ -0,0 +1,34 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/9
+ * @time: 10:10
+ */
+@Data
+public class SysDepartmentAppDTO {
+    private Long id;
+    /**
+     * 部门
+     */
+    private String depName;
+    /**
+     * 等级
+     */
+    private Byte level;
+    /**
+     * 父级id
+     */
+    private Long parentId;
+    /**
+     * 描述
+     */
+    private String info;
+
+    private List<SysDepartmentAppDTO> children;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/TokenInfoDto.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/TokenInfoDto.java
new file mode 100644
index 0000000..5939bf5
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/TokenInfoDto.java
@@ -0,0 +1,34 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto;
+
+public class TokenInfoDto {
+
+    private Long uid;
+
+    private String tk;
+
+    private Long remainSecond;
+
+    public Long getUid() {
+        return uid;
+    }
+
+    public void setUid(Long uid) {
+        this.uid = uid;
+    }
+
+    public String getTk() {
+        return tk;
+    }
+
+    public void setTk(String tk) {
+        this.tk = tk;
+    }
+
+    public Long getRemainSecond() {
+        return remainSecond;
+    }
+
+    public void setRemainSecond(Long remainSecond) {
+        this.remainSecond = remainSecond;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserIdentityBindAppRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserIdentityBindAppRespDTO.java
new file mode 100644
index 0000000..dc27b7c
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserIdentityBindAppRespDTO.java
@@ -0,0 +1,15 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto;
+
+import lombok.Data;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/4
+ * @time: 10:16
+ */
+@Data
+public class UserIdentityBindAppRespDTO {
+    private Long userIdentityId;
+    private String userIdentity;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserIndentityAppDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserIndentityAppDTO.java
new file mode 100644
index 0000000..ff3aa0c
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserIndentityAppDTO.java
@@ -0,0 +1,18 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto;
+
+import lombok.Data;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/4
+ * @time: 13:48
+ */
+@Data
+public class UserIndentityAppDTO {
+
+    private Long id ;
+    private String identity;
+
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserInfoAppRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserInfoAppRespDTO.java
new file mode 100644
index 0000000..3a094b7
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserInfoAppRespDTO.java
@@ -0,0 +1,49 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto;
+
+import com.gkhy.fourierSpecialGasMonitor.application.attachment.service.dto.resp.AttachmentAppRespDTO;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+import java.util.List;
+@Data
+public class    UserInfoAppRespDTO {
+
+    private Long id;
+
+    //用户账号状态
+    private Byte status;
+
+    //创建时间
+    private LocalDateTime gmtCreate;
+
+    //修改时间
+    private LocalDateTime gmtModified;
+
+    private String name;
+
+    //真实姓名
+    private String realName;
+
+    private String phone;
+
+    private Byte idType;
+
+    private String idSerial;
+    private Long depId;
+
+    private String depName;
+    /**
+     * 身份(0专家,1非专家)
+     */
+    private Byte identityStatus;
+    //资质证书id
+    private Long qualificationAttId;
+
+    private List<UserRoleBindAppRespDTO> roles;
+
+    private List<UserIdentityBindAppRespDTO> userIdentities;
+
+    private AttachmentAppRespDTO qualificationAttaAppRespDTO;
+
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserRoleBindAppRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserRoleBindAppRespDTO.java
new file mode 100644
index 0000000..51de3a6
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserRoleBindAppRespDTO.java
@@ -0,0 +1,15 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto;
+
+import lombok.Data;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/13
+ * @time: 10:46
+ */
+@Data
+public class UserRoleBindAppRespDTO {
+    private Long roleId;
+    private String roleName;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserRoleBindRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserRoleBindRespDTO.java
new file mode 100644
index 0000000..136149f
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/dto/respDto/UserRoleBindRespDTO.java
@@ -0,0 +1,15 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto;
+
+import lombok.Data;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/4/13
+ * @time: 10:35
+ */
+@Data
+public class UserRoleBindRespDTO {
+    private Long roleId;
+    private String roleName;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/AccountAppService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/AccountAppService.java
new file mode 100644
index 0000000..b5338fa
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/AccountAppService.java
@@ -0,0 +1,45 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.service;
+
+import com.gkhy.fourierSpecialGasMonitor.api.controller.account.query.UserQuery;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto.ChangePasswdReqDto;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto.CreateNewUserAppReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto.LoginReqAppDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto.UpdateUserAppReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.UserInfoAppRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+
+import java.util.List;
+
+public interface AccountAppService {
+    SearchResult<UserInfoAppRespDTO> findUserByLoginName(String loginName);
+    SearchResult<List<UserInfoAppRespDTO>> findUserByRealName(String name);
+    SearchResult<List<UserInfoAppRespDTO>> findUserByRole(Long roleId,boolean usePage,Integer page,Integer pageSize);
+
+
+
+    SearchResult<UserInfoAppRespDTO> findUserByUserId(Long userId);
+
+    SearchResult<List<UserInfoAppRespDTO>> findUserListByUserIdList(List<Long> userIdList);
+
+    Result updateUserPassword(ChangePasswdReqDto changePasswdReqDto);
+
+    Result updateUserStatus(Long userId, Byte status);
+
+    Result updateUserRole(Long userId, List<Long> roleId);
+
+    Result login(LoginReqAppDTO loginReqAppDTO);
+
+    Result logout(Long userId);
+
+    Result createNewUser(CreateNewUserAppReqDTO createNewUserAppReqDTO);
+
+    Result updateUser(UpdateUserAppReqDTO updateUserAppReqDTO);
+
+    Result deleteUser(Long userId);
+
+    SearchResult<List<UserInfoAppRespDTO>> findUser(PageQuery<UserQuery> pageQuery);
+
+    SearchResult<List<UserInfoAppRespDTO>> findExpert(PageQuery<UserQuery> pageQuery);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/AccountMenuAppService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/AccountMenuAppService.java
new file mode 100644
index 0000000..e7cd954
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/AccountMenuAppService.java
@@ -0,0 +1,9 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.service;
+
+import com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.model.dto.resp.MenuItemAppDTO;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+
+public interface AccountMenuAppService {
+
+    SearchResult<MenuItemAppDTO> findAllMenuItemByUserId(Long userId);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/RoleAppService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/RoleAppService.java
new file mode 100644
index 0000000..298daa7
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/RoleAppService.java
@@ -0,0 +1,18 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.service;
+
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.RoleRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+
+import java.util.List;
+
+public interface RoleAppService {
+
+    Result newRole(String roleName);
+
+    Result deleteRole(Long roleId);
+
+    SearchResult<List<RoleRespDTO>> findAllRoleList();
+
+    Result updateRoleName(Long roleId,String name);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/SysDepartmentAppService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/SysDepartmentAppService.java
new file mode 100644
index 0000000..d3bef95
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/SysDepartmentAppService.java
@@ -0,0 +1,22 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.service;
+
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto.SysDepartmentAppAddReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto.SysDepartmentAppUpdateReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/7
+ * @time: 17:12
+ */
+public interface SysDepartmentAppService {
+
+    Result save(SysDepartmentAppAddReqDTO req, Long currentUserId);
+
+    Result update(SysDepartmentAppUpdateReqDTO req,Long currentUserId);
+
+    Result delete(Long id, Long currentUserId);
+
+    Result list();
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/TokenAppService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/TokenAppService.java
new file mode 100644
index 0000000..19b06e4
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/TokenAppService.java
@@ -0,0 +1,15 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.service;
+
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.TokenInfoDto;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+
+public interface TokenAppService {
+
+    Result<TokenInfoDto> setToken(Long uid);
+
+    Result resetTokenTime(Long uid);
+
+    Result removeToken(Long uid);
+
+    Result<TokenInfoDto> getToken(Long uid);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/UserIdentityAppService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/UserIdentityAppService.java
new file mode 100644
index 0000000..9553e74
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/UserIdentityAppService.java
@@ -0,0 +1,15 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.service;
+
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.UserIndentityAppDTO;
+
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/4
+ * @time: 13:49
+ */
+public interface UserIdentityAppService {
+    List<UserIndentityAppDTO> list();
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/AccountAppServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/AccountAppServiceImpl.java
new file mode 100644
index 0000000..be9a045
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/AccountAppServiceImpl.java
@@ -0,0 +1,407 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.service.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.account.query.UserQuery;
+import com.gkhy.fourierSpecialGasMonitor.application.account.converter.UserInfoAppConverter;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto.CreateNewUserAppReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto.UpdateUserAppReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.converter.UserInfoDomainConverter;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto.ChangePasswdReqDto;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto.LoginReqAppDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.LoginRespDto;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.TokenInfoDto;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.converter.UserRoleBindConverter;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.enums.IdentityStatusEnum;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.enums.UserStatusEnum;
+import com.gkhy.fourierSpecialGasMonitor.application.account.service.AccountAppService;
+import com.gkhy.fourierSpecialGasMonitor.application.account.service.TokenAppService;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.UserInfoAppRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo.CreateUserBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo.UpdateUserBO;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.SysUserRoleBindDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.SysUserIdentityBindDomainService;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.UserDomainService;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.UserInfoDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.UserRoleDomainService;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class AccountAppServiceImpl implements AccountAppService {
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+    @Autowired
+    private ObjectMapper objectMapper;
+
+    @Autowired
+    private TokenAppService tokenService;
+
+    @Autowired
+    private UserDomainService userDomainService;
+
+    @Autowired
+    private UserInfoAppConverter userInfoAppConverter;
+
+    @Autowired
+    private UserRoleDomainService userRoleDomainService;
+
+    @Autowired
+    private SysUserIdentityBindDomainService identityBindDomainService;
+
+    @Autowired
+    private UserRoleBindConverter converter;
+
+    @Override
+    public SearchResult<UserInfoAppRespDTO> findUserByLoginName(String loginName){
+        SearchResult<UserInfoAppRespDTO> result = new SearchResult<>();
+        result.execSuccess();
+        if(loginName == null || loginName.isEmpty())
+            return result;
+        UserInfoDomainDTO userInfoDomainDTO = userDomainService.getUserInfoByName(loginName);
+        if(userInfoDomainDTO != null){
+            UserInfoAppRespDTO userInfoAppRespDTO = new UserInfoDomainConverter().toUserInfoRespDTO(userInfoDomainDTO);
+            result.setCount(1);
+            result.setData(userInfoAppRespDTO);
+        }
+        return result;
+    }
+
+    @Override
+    public SearchResult<List<UserInfoAppRespDTO>> findUserByRealName(String name) {
+        SearchResult<List<UserInfoAppRespDTO>> result = new SearchResult<>();
+        result.setSuccess();
+        List<UserInfoDomainDTO> userInfoDomainDTOS = userDomainService.findUserListByRealName(name);
+        if(userInfoDomainDTOS != null && !userInfoDomainDTOS.isEmpty()){
+            List<UserInfoAppRespDTO> appRespDTOS = userInfoAppConverter.toAppDtoList(userInfoDomainDTOS);
+            result.setCount(appRespDTOS.size());
+            result.setData(appRespDTOS);
+        }
+        return result;
+    }
+
+    @Override
+    public SearchResult<List<UserInfoAppRespDTO>> findUserByRole(Long roleId, boolean usePage, Integer page, Integer pageSize) {
+        SearchResult<List<UserInfoAppRespDTO>> searchResult = new SearchResult<>();
+        searchResult.setSuccess();
+        searchResult.setUsePage(usePage);
+        if(usePage){
+            searchResult.setPageIndex(page);
+            searchResult.setPageSize(pageSize);
+        }
+        SearchResult<List<UserInfoDomainDTO>> userResult = userDomainService.findUserListByRole(roleId,usePage,page,
+                pageSize);
+        BeanUtils.copyProperties(userResult,searchResult);
+        searchResult.setData(userInfoAppConverter.toAppDtoList((List<UserInfoDomainDTO>) userResult.getData()));
+        return searchResult;
+    }
+
+    @Override
+    public SearchResult<UserInfoAppRespDTO> findUserByUserId(Long userId) {
+        SearchResult<UserInfoAppRespDTO> result = new SearchResult<>();
+        result.execSuccess();
+        if(userId == null || userId < 0)
+            return result;
+        UserInfoDomainDTO userInfoDomainDTO = userDomainService.getUserInfoById(userId);
+        if(userInfoDomainDTO == null){
+            result.setCount(1);
+            return result;
+        }
+        UserInfoAppRespDTO respDTO = new UserInfoDomainConverter().toUserInfoRespDTO(userInfoDomainDTO);
+        result.setCount(1);
+        result.setData(respDTO);
+        return result;
+    }
+
+    @Override
+    public SearchResult<List<UserInfoAppRespDTO>> findUserListByUserIdList(List<Long> userIdList) {
+        SearchResult<List<UserInfoAppRespDTO>> result = new SearchResult<>();
+        result.execSuccess();
+        if(userIdList == null || userIdList.isEmpty())
+            return result;
+        List<UserInfoDomainDTO> userInfoDomainDTOList = userDomainService.getUserInfoListByIds(userIdList);
+        if(userInfoDomainDTOList != null && userInfoDomainDTOList.size() > 0){
+            UserInfoDomainConverter userInfoDomainConverter = new UserInfoDomainConverter();
+            List<UserInfoAppRespDTO> userInfoAppRespDTOList = new ArrayList<>();
+            for(UserInfoDomainDTO userInfoDomainDTO : userInfoDomainDTOList){
+                UserInfoAppRespDTO dto = userInfoDomainConverter.toUserInfoRespDTO(userInfoDomainDTO);
+                userInfoAppRespDTOList.add(dto);
+            }
+            result.setCount(userInfoAppRespDTOList.size());
+            result.setData(userInfoAppRespDTOList);
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional
+    public Result updateUserPassword(ChangePasswdReqDto dto) {
+        Result result = new Result<>();
+        if(userDomainService.updateUserPwd(dto.getUid(),dto.getOldPwd(),dto.getNewPwd()) == true){
+            result.setSuccess();
+        }else {
+            result.setCode(ResultCode.SYSTEM_ERROR.getCode());
+            result.setMsg("修改密码失败");
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional
+    public Result updateUserStatus(Long userId, Byte status) {
+        Result result = new Result<>();
+        if(userId == null || userId < 1 || status == null){
+            result.setCode(ResultCode.PARAM_ERROR_NULL.getCode());
+            result.setMsg("参数缺失");
+            return result;
+        }
+        if(UserStatusEnum.prase(status) == null){
+            result.setCode(ResultCode.BUSINESS_ERROR_NOT_ALLOWED.getCode());
+            result.setMsg("状态不支持");
+            return result;
+        }
+        if(userDomainService.updateUserStatus(userId,status) == true){
+            result.setSuccess();
+        }else {
+            result.setCode(ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode());
+            result.setMsg("数据库更新失败");
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional
+    public Result updateUserRole(Long userId, List<Long> roleIds) {
+        Result result = new Result<>();
+        if(userId == null || userId < 1 || roleIds == null ||  roleIds.size() == 0){
+            result.setCode(ResultCode.PARAM_ERROR_NULL.getCode());
+            result.setMsg("参数缺失");
+            return result;
+        }
+        userRoleDomainService.updateUserRole(userId,roleIds);
+        result.setSuccess();
+        return result;
+    }
+
+    @Override
+    public Result login(LoginReqAppDTO loginReqAppDTO) {
+        Result result = new Result<>();
+        //1、参数校验
+        if(loginReqAppDTO == null || loginReqAppDTO.getName() == null || loginReqAppDTO.getPwd() == null){
+            result.setCode(ResultCode.PARAM_ERROR_NULL.getCode());
+            result.setMsg("用户名或密码不全");
+            return result;
+        }
+        //2、密码校验
+        UserInfoDomainDTO userInfoDomainDTO = userDomainService.getUserInfoByName(loginReqAppDTO.getName());
+        if(userInfoDomainDTO == null){
+            result.setCode(ResultCode.BUSINESS_ERROR_ACCOUNT_NOT_EXIST.getCode());
+            result.setMsg("用户不存在");
+            return result;
+        }
+
+        if(!userDomainService.checkPassword(loginReqAppDTO.getPwd(), userInfoDomainDTO.getHash(), userInfoDomainDTO.getSalt())){
+            result.setCode(ResultCode.BUSINESS_ERROR_NOT_ALLOWED.getCode());
+            result.setMsg("密码错误");
+            return result;
+        }
+        //检查用户状态
+        if(userInfoDomainDTO.getStatus().equals(UserStatusEnum.STATUS_FROZEN.getStatus())){
+            result.setCode(ResultCode.BUSINESS_ERROR_ACCOUNT_STATU_ABNORMAL.getCode());
+            result.setMsg("该账号已被冻结");
+            return result;
+        }
+        if(userInfoDomainDTO.getStatus().equals(UserStatusEnum.STATUS_DELETE.getStatus())){
+            result.setCode(ResultCode.BUSINESS_ERROR_ACCOUNT_STATU_ABNORMAL.getCode());
+            result.setMsg("账号无效");
+            return result;
+        }
+        //设置token
+        Result<TokenInfoDto> setTokenResult = tokenService.setToken(userInfoDomainDTO.getId());
+        if(!setTokenResult.isSuccess()){
+            result.setCode(ResultCode.BUSINESS_ERROR.getCode());
+            result.setMsg("系统出错");
+            return result;
+        }
+        TokenInfoDto tokenInfoDto = (TokenInfoDto) setTokenResult.getData();
+        if(tokenInfoDto == null || tokenInfoDto.getTk() == null || tokenInfoDto.getTk().isEmpty()){
+            result.setCode(ResultCode.BUSINESS_ERROR.getCode());
+            result.setMsg("系统出错");
+            return result;
+        }
+        LoginRespDto loginRespDto = new LoginRespDto();
+        loginRespDto.setUid(userInfoDomainDTO.getId());
+        loginRespDto.setName(userInfoDomainDTO.getName());
+        loginRespDto.setRealName(userInfoDomainDTO.getRealName());
+        loginRespDto.setTk(tokenInfoDto.getTk());
+        loginRespDto.setRoles(converter.userRoleBindConverter(userInfoDomainDTO.getRoles()));
+        //todo:获取其他需返回的信息
+
+        result.setSuccess();
+        result.setData(loginRespDto);
+
+        return result;
+    }
+
+    @Override
+    public Result logout(Long userId) {
+        Result result = new Result<>();
+        if(userId == null){
+            result.setCode(ResultCode.PARAM_ERROR_NULL);
+            return result;
+        }
+        result = tokenService.removeToken(userId);
+        return result;
+    }
+
+    @Override
+    @Transactional
+    public Result createNewUser(CreateNewUserAppReqDTO createNewUserAppReqDTO) {
+        Result result = new Result();
+        //校验参数
+        if(createNewUserAppReqDTO == null || createNewUserAppReqDTO.getName() == null || createNewUserAppReqDTO.getName().isEmpty()
+                || createNewUserAppReqDTO.getRealName() == null || createNewUserAppReqDTO.getRealName().isEmpty()
+                || createNewUserAppReqDTO.getRoleIds() == null || createNewUserAppReqDTO.getRoleIds().size() == 0 ){
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR.getCode(),"用户信息不全");
+        }
+        //if(IdentityStatusEnum.prase(createNewUserAppReqDTO.getIdentityStatus()) == null){
+        //    throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_ILLEGAL.getCode(),"用户用户身份不合法");
+        //}
+        //if(createNewUserAppReqDTO.getIdentityStatus().equals(IdentityStatusEnum.EXPERT.getStatus()) && createNewUserAppReqDTO.getIdentityIds() == null){
+        //    throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL.getCode(),"请选择用户身份!");
+        //}
+        //校验角色信息
+        CreateUserBO createUserBO = new CreateUserBO();
+        createUserBO.setName(createNewUserAppReqDTO.getName());
+        createUserBO.setRealName(createNewUserAppReqDTO.getRealName());
+        //如果没有提供密码,初始密码为“123456”
+        if(createNewUserAppReqDTO.getPwd() == null || createNewUserAppReqDTO.getPwd().isEmpty()){
+            createNewUserAppReqDTO.setPwd("123456");
+        }
+        createUserBO.setPwd(createNewUserAppReqDTO.getPwd());
+        createUserBO.setPhone(createNewUserAppReqDTO.getPhone());
+        //createUserBO.setIdType(createNewUserAppReqDTO.getIdType());
+        createUserBO.setIdSerial(createNewUserAppReqDTO.getIdSerial());
+        createUserBO.setDepId(createNewUserAppReqDTO.getDepId());
+        //createUserBO.setIdentityStatus(createNewUserAppReqDTO.getIdentityStatus());
+        //createUserBO.setQualificationAttId(createNewUserAppReqDTO.getQualificationAttId());
+        UserInfoDomainDTO userInfoDomainDTO = userDomainService.newUser(createUserBO);
+        //绑定角色
+        List<SysUserRoleBindDomainDTO> sysUserRoleBindDomainDTOS = userRoleDomainService.insertBatchUserBindRole(createNewUserAppReqDTO.getRoleIds(), userInfoDomainDTO.getId());
+        ////绑定身份
+        //if(createNewUserAppReqDTO.getIdentityStatus().equals(IdentityStatusEnum.EXPERT.getStatus()) && ObjectUtil.isNotEmpty(createNewUserAppReqDTO.getIdentityIds())){
+        //    identityBindDomainService.insertBatchUserIndentityBind(createNewUserAppReqDTO.getIdentityIds(), userInfoDomainDTO.getId());
+        //}
+
+        if(userInfoDomainDTO != null){
+            result.setSuccess();
+            result.setCount(1);
+            UserInfoAppRespDTO userInfoAppRespDTO = new UserInfoDomainConverter().toUserInfoRespDTO(userInfoDomainDTO);
+            userInfoAppRespDTO.setRoles(converter.userRoleBindAppConverter(sysUserRoleBindDomainDTOS));
+            result.setData(userInfoAppRespDTO);
+        }else {
+            throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR.getCode(),"创建新用户失败");
+        }
+        return result;
+    }
+
+    @Transactional
+    @Override
+    public Result updateUser(UpdateUserAppReqDTO updateUserAppReqDTO) {
+        Result result = new Result<>();
+        if(updateUserAppReqDTO == null){
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR.getCode(),"参数缺失");
+        }
+        //if(IdentityStatusEnum.prase(updateUserAppReqDTO.getIdentityStatus()) == null){
+        //    throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_ILLEGAL.getCode(),"用户用户身份不合法");
+        //}
+        //if(updateUserAppReqDTO.getIdentityStatus().equals(IdentityStatusEnum.EXPERT.getStatus()) && CollectionUtils.isEmpty(updateUserAppReqDTO.getIdentityIds())){
+        //    throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL.getCode(),"请选择用户身份!");
+        //}
+        UpdateUserBO bo = new UpdateUserBO();
+        bo.setId(updateUserAppReqDTO.getId());
+        bo.setName(updateUserAppReqDTO.getName());
+        bo.setRealName(updateUserAppReqDTO.getRealName());
+        //bo.setIdType(updateUserAppReqDTO.getIdType());
+        bo.setIdSerial(updateUserAppReqDTO.getIdSerial());
+        bo.setPhone(updateUserAppReqDTO.getPhone());
+        bo.setDepId(updateUserAppReqDTO.getDepId());
+        //bo.setIdentityStatus(updateUserAppReqDTO.getIdentityStatus());
+        //bo.setQualificationAttId(updateUserAppReqDTO.getQualificationAttId());
+        UserInfoDomainDTO updateRs = userDomainService.updateUserInfo(bo);
+        //修改用户绑定角色
+        userRoleDomainService.updateUserRole(updateUserAppReqDTO.getId(), updateUserAppReqDTO.getRoleIds());
+        //绑定身份
+        //if(updateUserAppReqDTO.getIdentityStatus().equals(IdentityStatusEnum.EXPERT.getStatus())){
+        //    identityBindDomainService.updateBatchUserIndentityBind(updateUserAppReqDTO.getIdentityIds(), updateUserAppReqDTO.getId());
+        //}
+        //if(updateUserAppReqDTO.getIdentityStatus().equals(IdentityStatusEnum.NOT_EXPERT.getStatus())){
+        //    identityBindDomainService.deleteByUser(updateUserAppReqDTO.getId());
+        //}
+
+        if(updateRs != null){
+            result.setSuccess();
+            result.setCount(1);
+            result.setData(updateRs);
+        }else {
+            result.setCode(ResultCode.BUSINESS_ERROR);
+        }
+        return result;
+    }
+
+    @Transactional
+    @Override
+    public Result deleteUser(Long userId) {
+        Result result = new Result<>();
+        if(userId == null){
+            result.setCode(ResultCode.PARAM_ERROR_NULL.getCode());
+            result.setMsg("参数缺失");
+            return result;
+        }
+        if(userDomainService.deleteUser(userId) == true && userRoleDomainService.deleteByUser(userId) == true){
+            result.setCode(ResultCode.OK);
+            result.setMsg("数据库更新成功");
+        }else {
+            result.setCode(ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode());
+            result.setMsg("数据库更新失败");
+        }
+        return result;
+    }
+
+    @Override
+    public SearchResult<List<UserInfoAppRespDTO>> findUser(PageQuery<UserQuery> pageQuery) {
+        SearchResult<List<UserInfoAppRespDTO>> searchResult = new SearchResult<>();
+        searchResult.setSuccess();
+        SearchResult<List<UserInfoDomainDTO>> userResult = userDomainService.findUserList(pageQuery);
+        BeanUtils.copyProperties(userResult,searchResult);
+        searchResult.setData(userInfoAppConverter.toAppDtoList((List<UserInfoDomainDTO>) userResult.getData()));
+        return searchResult;
+    }
+
+    @Override
+    public SearchResult<List<UserInfoAppRespDTO>> findExpert(PageQuery<UserQuery> pageQuery) {
+        SearchResult<List<UserInfoAppRespDTO>> searchResult = new SearchResult<>();
+        searchResult.setSuccess();
+        SearchResult<List<UserInfoDomainDTO>> userResult = userDomainService.findExpertList(pageQuery);
+        BeanUtils.copyProperties(userResult,searchResult);
+        searchResult.setData(userInfoAppConverter.toAppDtoList((List<UserInfoDomainDTO>) userResult.getData()));
+        return searchResult;
+    }
+
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/AccountMenuAppServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/AccountMenuAppServiceImpl.java
new file mode 100644
index 0000000..b3b4fc7
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/AccountMenuAppServiceImpl.java
@@ -0,0 +1,122 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.service.impl;
+
+import com.gkhy.fourierSpecialGasMonitor.application.account.service.AccountMenuAppService;
+import com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.convert.MenuItemAppConvert;
+import com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.model.dto.resp.MenuItemAppDTO;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.SysUserRoleBindDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.UserInfoDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.RoleMenuDomainService;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.UserDomainService;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.model.dto.MenuItemDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.service.MenuDomainService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+public class AccountMenuAppServiceImpl implements AccountMenuAppService {
+
+    @Autowired
+    private UserDomainService userDomainService;
+
+    @Autowired
+    private MenuDomainService menuDomainService;
+
+
+    @Autowired
+    private RoleMenuDomainService roleMenuDomainService;
+
+    @Autowired
+    private MenuItemAppConvert menuItemAppConvert;
+
+    //@Override
+    /*public SearchResult<MenuItemAppDTO> findAllMenuItemByUserId1(Long userId) {
+        SearchResult result = new SearchResult<>();
+        UserInfoDomainDTO userInfo = userDomainService.getUserInfoById(userId);
+        if(userInfo == null){
+            result.setCode(ResultCode.BUSINESS_ERROR_ACCOUNT_NOT_EXIST);
+            result.setMsg("用户不存在");
+            return result;
+        }
+
+        if(userInfo.getRoles() == null || userInfo.getRoles().size() == 0){
+            result.setCode(ResultCode.BUSINESS_ERROR_NOT_ALLOWED);
+            result.setMsg("用户未绑定角色");
+            return result;
+        }
+        //获取用户角色id
+        List<Long> roleIds = userInfo.getRoles().stream().map(SysUserRoleBindDomainDTO::getRoleId).collect(Collectors.toList());
+        List<MenuItemDomainDTO> menuList = roleMenuDomainService.getMenuInfoByRole(roleIds);
+        List<MenuItemAppDTO> appDTOList = menuItemAppConvert.toAppDtoList(menuList);
+        if(appDTOList != null && !appDTOList.isEmpty()){
+            result.setData(appDTOList);
+            result.setCount(appDTOList.size());
+        }
+        result.setSuccess();
+        return result;
+    }*/
+
+    @Override
+    public SearchResult<MenuItemAppDTO> findAllMenuItemByUserId(Long userId) {
+        SearchResult result = new SearchResult<>();
+        UserInfoDomainDTO userInfo = userDomainService.getUserInfoById(userId);
+        if(userInfo == null){
+            result.setCode(ResultCode.BUSINESS_ERROR_ACCOUNT_NOT_EXIST);
+            result.setMsg("用户不存在");
+            return result;
+        }
+        //获取用户角色
+        List<SysUserRoleBindDomainDTO> roles = userInfo.getRoles();
+        if(roles == null || roles.size() == 0){
+            result.setCode(ResultCode.BUSINESS_ERROR_NOT_ALLOWED);
+            result.setMsg("用户未绑定角色");
+            return result;
+        }
+        Boolean flag = false;
+        for(SysUserRoleBindDomainDTO role : roles){
+            if ("超级管理员".equals(role.getRoleName())  || "管理员".equals(role.getRoleName())){
+                flag = true;
+            }
+        }
+        List<MenuItemDomainDTO> menuList = new ArrayList<>();
+        if(flag){
+            //管理员
+            menuList = menuDomainService.getAllActiveMenuItems();
+
+        }else {
+            //非管理员
+            //获取用户角色id
+            List<Long> roleIds = roles.stream().map(SysUserRoleBindDomainDTO::getRoleId).collect(Collectors.toList());
+            menuList = roleMenuDomainService.getMenuInfoByRole(roleIds);
+        }
+
+        List<MenuItemAppDTO> appDTOList = convertToMenuItemAppDtos(menuList);
+        if(appDTOList != null && !appDTOList.isEmpty()){
+            result.setData(appDTOList);
+            result.setCount(appDTOList.size());
+        }
+        result.setSuccess();
+        return result;
+    }
+
+    private List<MenuItemAppDTO> convertToMenuItemAppDtos(List<MenuItemDomainDTO> orignList){
+        if(orignList == null || orignList.isEmpty())
+            return null;
+        List<MenuItemAppDTO> targetList = new ArrayList<>();
+        orignList.forEach(o -> {
+            MenuItemAppDTO appDTO = menuItemAppConvert.toAppDto(o);
+            List<Long> bindRoles = roleMenuDomainService.getBindRolesByMenuItemId(o.getId());
+            appDTO.setRoles(bindRoles);
+            if(o.getSubMenuItemList() != null && !o.getSubMenuItemList().isEmpty()){
+                appDTO.setSubMenuItemList(convertToMenuItemAppDtos(o.getSubMenuItemList()));
+            }
+            targetList.add(appDTO);
+        });
+        return targetList;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/RoleAppServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/RoleAppServiceImpl.java
new file mode 100644
index 0000000..ee9796d
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/RoleAppServiceImpl.java
@@ -0,0 +1,88 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.service.impl;
+
+import com.gkhy.fourierSpecialGasMonitor.application.account.converter.RoleInfoAppConverter;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.RoleRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.service.RoleAppService;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.RoleInfoDoaminDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.RoleDomainService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class RoleAppServiceImpl implements RoleAppService {
+
+    @Autowired
+    private RoleDomainService roleDomainService;
+
+    @Autowired
+    private RoleInfoAppConverter roleInfoAppConverter;
+
+    @Override
+    @Transactional
+    public Result newRole(String roleName) {
+        Result result = new Result<>();
+        if(roleName == null || roleName.isEmpty()){
+            result.setCode(ResultCode.PARAM_ERROR_NULL.getCode());
+            result.setMsg("参数缺失");
+            return result;
+        }
+        RoleInfoDoaminDTO roleInfoDoaminDTO = roleDomainService.createNewRole(roleName);
+        if(roleInfoDoaminDTO == null){
+            result.setCode(ResultCode.BUSINESS_ERROR.getCode());
+            result.setMsg("创建角色失败");
+            return result;
+        }
+        result.setSuccess();
+        return result;
+    }
+
+    @Override
+    @Transactional
+    public Result deleteRole(Long roleId) {
+        Result result = new Result<>();
+        if(roleDomainService.deleteRole(roleId) == true){
+            result.setSuccess();
+            return result;
+        }else {
+            result.setCode(ResultCode.BUSINESS_ERROR);
+            result.setMsg("删除菜单出错");
+        }
+        return result;
+    }
+
+    @Override
+    public SearchResult<List<RoleRespDTO>> findAllRoleList() {
+        SearchResult<List<RoleRespDTO>> result = new SearchResult<>(false);
+        result.setSuccess();
+        List<RoleInfoDoaminDTO> roleInfoDoaminDTOList = roleDomainService.findAllActiveRoleList();
+        if(roleInfoDoaminDTOList != null && !roleInfoDoaminDTOList.isEmpty()){
+            List<RoleRespDTO> list = new ArrayList<>();
+            roleInfoDoaminDTOList.forEach(d -> {
+                list.add(roleInfoAppConverter.toRoleRespDTO(d));
+            });
+            result.setData(list);
+            result.setCount(list.size());
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional
+    public Result updateRoleName(Long roleId, String name) {
+        Result result = new Result();
+        if(roleDomainService.updateRoleName(roleId,name) == true){
+            result.setSuccess();
+        }else {
+            result.setCode(ResultCode.BUSINESS_ERROR.getCode());
+            result.setMsg("更新出错");
+        }
+        return result;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/SysDepartmentAppServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/SysDepartmentAppServiceImpl.java
new file mode 100644
index 0000000..0948140
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/SysDepartmentAppServiceImpl.java
@@ -0,0 +1,86 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.service.impl;
+
+
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto.SysDepartmentAppAddReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.repDto.SysDepartmentAppUpdateReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.SysDepartmentAppDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.service.SysDepartmentAppService;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.converter.SysDeparmentConverter;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo.SysDepartmentBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.SysDepartmentDomainService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/7
+ * @time: 17:13
+ */
+@Service
+public class SysDepartmentAppServiceImpl implements SysDepartmentAppService {
+
+    @Autowired
+    private SysDepartmentDomainService sysDepartmentDomainService;
+    @Autowired
+    private SysDeparmentConverter converter;
+
+    @Override
+    public Result save(SysDepartmentAppAddReqDTO req, Long currentUserId) {
+        Result result = new Result();
+        result.setCode(ResultCode.OK);
+        result.setMsg("新增成功!");
+        SysDepartmentBO sysDepartmentBO = new SysDepartmentBO();
+        sysDepartmentBO.setDepName(req.getDepName());
+        sysDepartmentBO.setParentId(req.getParentId());
+        sysDepartmentBO.setLevel(req.getLevel());
+        sysDepartmentBO.setInfo(req.getInfo());
+        if(null == sysDepartmentDomainService.save(sysDepartmentBO,currentUserId)){
+            result.setCode(ResultCode.NOT_OK);
+            result.setMsg("新增失败!");
+        }
+        return result;
+    }
+
+    @Override
+    public Result update(SysDepartmentAppUpdateReqDTO req,Long currentUserId) {
+        Result result = new Result();
+        result.setCode(ResultCode.OK);
+        result.setMsg("修改成功!");
+        SysDepartmentBO sysDepartmentBO = new SysDepartmentBO();
+        sysDepartmentBO.setId(req.getId());
+        sysDepartmentBO.setInfo(req.getInfo());
+        sysDepartmentBO.setDepName(req.getDepName());
+        if(null == sysDepartmentDomainService.update(sysDepartmentBO,currentUserId)){
+            result.setCode(ResultCode.NOT_OK);
+            result.setMsg("修改失败!");
+        }
+        return result;
+    }
+
+    @Override
+    public Result delete(Long id, Long currentUserId) {
+        Result result = new Result();
+        result.setCode(ResultCode.OK);
+        result.setMsg("删除成功!");
+        if(null == sysDepartmentDomainService.delete(id,currentUserId)){
+            result.setCode(ResultCode.NOT_OK);
+            result.setMsg("删除失败!");
+        }
+        return result;
+    }
+
+    @Override
+    public Result<SysDepartmentAppDTO> list() {
+        Result result = new Result();
+        result.setCode(ResultCode.OK);
+        result.setMsg("查询成功!");
+        List<SysDepartmentAppDTO> appDTOList = converter.sysDepAppDTOListConverter(sysDepartmentDomainService.list());
+        result.setData(appDTOList);
+        return result;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/TokenAppServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/TokenAppServiceImpl.java
new file mode 100644
index 0000000..c80d8c8
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/TokenAppServiceImpl.java
@@ -0,0 +1,121 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.service.impl;
+
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.TokenInfoDto;
+import com.gkhy.fourierSpecialGasMonitor.application.account.service.TokenAppService;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.SystemCacheKeyEnum;
+import com.google.common.collect.Range;
+import com.google.common.hash.Hashing;
+import org.redisson.api.RMapCache;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.TimeUnit;
+
+@Service
+public class TokenAppServiceImpl implements TokenAppService {
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+    @Override
+    public Result<TokenInfoDto> setToken(Long uid) {
+        Result result = new Result<>();
+        if(uid == null){
+            result.setCode(ResultCode.PARAM_ERROR_NULL.getCode());
+            result.setMsg("参数缺失");
+            return result;
+        }
+        String loginUserId = ""+uid;
+        //生成Token
+        String seed = loginUserId+ Range.atLeast(1) +System.nanoTime();
+        String hash = String.valueOf(Hashing.hmacMd5(loginUserId.getBytes(StandardCharsets.UTF_8)).hashString(seed,
+                StandardCharsets.UTF_8));
+        //存入redis
+        String accessTokenKey = SystemCacheKeyEnum.KEY_USER_TOKEN.getKey();
+        try {
+            RMapCache<String,Object> tokenCacheMap = redissonClient.getMapCache(accessTokenKey);
+            tokenCacheMap.remove(loginUserId);
+            tokenCacheMap.put(loginUserId,hash,120, TimeUnit.MINUTES);
+            result.setSuccess();
+            TokenInfoDto tokenInfoDto = new TokenInfoDto();
+            tokenInfoDto.setTk(hash);
+            tokenInfoDto.setUid(uid);
+            tokenInfoDto.setRemainSecond(tokenCacheMap.remainTimeToLive(loginUserId));
+            result.setData(tokenInfoDto);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+    @Override
+    public Result resetTokenTime(Long uid) {
+        Result result = new Result<>();
+        if(uid == null){
+            result.setCode(ResultCode.PARAM_ERROR_NULL.getCode());
+            result.setMsg("参数缺失");
+            return result;
+        }
+        String loginUserId = ""+uid;
+        String accessTokenKey = SystemCacheKeyEnum.KEY_USER_TOKEN.getKey();
+        try {
+            RMapCache<String,Object> tokenCacheMap = redissonClient.getMapCache(accessTokenKey);
+            String tk = (String) tokenCacheMap.get(loginUserId);
+            tokenCacheMap.put(loginUserId,tk,120, TimeUnit.MINUTES);
+            result.setSuccess();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+    @Override
+    public Result removeToken(Long uid) {
+        Result result = new Result<>();
+        if(uid == null){
+            result.setCode(ResultCode.PARAM_ERROR_NULL.getCode());
+            result.setMsg("参数缺失");
+            return result;
+        }
+        String loginUserId = ""+uid;
+        String accessTokenKey = SystemCacheKeyEnum.KEY_USER_TOKEN.getKey();
+        RMapCache<String,Object> tokenCacheMap = redissonClient.getMapCache(accessTokenKey);
+        tokenCacheMap.remove(loginUserId);
+        result.setSuccess();
+        return result;
+    }
+
+    @Override
+    public Result<TokenInfoDto> getToken(Long uid) {
+        Result<TokenInfoDto> result = new Result<>();
+        result.setCode(ResultCode.BUSINESS_ERROR_PERMISSION_DENIALED.getCode());
+        result.setMsg("TOKEN不存在");
+        if(uid == null){
+            result.setCode(ResultCode.PARAM_ERROR_NULL.getCode());
+            result.setMsg("参数缺失");
+            return result;
+        }
+        String loginUserId = ""+uid;
+        String accessTokenKey = SystemCacheKeyEnum.KEY_USER_TOKEN.getKey();
+        RMapCache<String,Object> tokenCacheMap = redissonClient.getMapCache(accessTokenKey);
+        Object tokenObject = tokenCacheMap.get(loginUserId);
+        String cacheToken;
+        if(tokenObject != null){
+            cacheToken = (String) tokenObject;
+            Long tokenRemainTimeToLive = tokenCacheMap.remainTimeToLive(loginUserId);
+            if(cacheToken != null && !cacheToken.isEmpty()){
+                result.setSuccess();
+                TokenInfoDto tokenInfoDto = new TokenInfoDto();
+                tokenInfoDto.setUid(uid);
+                tokenInfoDto.setTk(cacheToken);
+                tokenInfoDto.setRemainSecond(tokenRemainTimeToLive/1000);
+                result.setData(tokenInfoDto);
+            }
+        }
+        return result;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/UserIdentityAppServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/UserIdentityAppServiceImpl.java
new file mode 100644
index 0000000..4ba0140
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/account/service/impl/UserIdentityAppServiceImpl.java
@@ -0,0 +1,30 @@
+package com.gkhy.fourierSpecialGasMonitor.application.account.service.impl;
+
+import com.gkhy.fourierSpecialGasMonitor.application.account.converter.UserIndentityAppConverter;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.UserIndentityAppDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.service.UserIdentityAppService;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.UserIdentityDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.UserIdentityDomainService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/4
+ * @time: 13:49
+ */
+@Service
+public class UserIdentityAppServiceImpl implements UserIdentityAppService {
+    @Autowired
+    private UserIdentityDomainService userIdentityDomainService;
+    @Autowired
+    private UserIndentityAppConverter userIndentityAppConverter;
+    @Override
+    public List<UserIndentityAppDTO> list() {
+        List<UserIdentityDomainDTO> list = userIdentityDomainService.getList();
+        return userIndentityAppConverter.toUserIndentityAppDTO(list);
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/converter/AttachmentAppConverter.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/converter/AttachmentAppConverter.java
new file mode 100644
index 0000000..03f31bb
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/converter/AttachmentAppConverter.java
@@ -0,0 +1,24 @@
+package com.gkhy.fourierSpecialGasMonitor.application.attachment.converter;
+
+import com.gkhy.fourierSpecialGasMonitor.application.attachment.service.dto.resp.AttachmentAppRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.attachment.dto.resp.AttachmentDomainDTO;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Component;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/7
+ * @time: 17:12
+ */
+@Component
+public class AttachmentAppConverter {
+    public AttachmentAppRespDTO getAppRespDTO(AttachmentDomainDTO attachmentDomainDTO){
+        if(attachmentDomainDTO == null){
+            return null;
+        }
+        AttachmentAppRespDTO appRespDTO = new AttachmentAppRespDTO();
+        BeanUtils.copyProperties(attachmentDomainDTO,appRespDTO);
+        return appRespDTO;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/service/AttachmentAppService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/service/AttachmentAppService.java
new file mode 100644
index 0000000..8296ba9
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/service/AttachmentAppService.java
@@ -0,0 +1,27 @@
+package com.gkhy.fourierSpecialGasMonitor.application.attachment.service;
+
+import com.gkhy.fourierSpecialGasMonitor.application.attachment.service.dto.resp.AttachmentAppRespDTO;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/7
+ * @time: 13:38
+ */
+public interface AttachmentAppService {
+    Object saveFileToPath(MultipartFile file, String module, Integer detail,Long currentUserId);
+
+    AttachmentAppRespDTO findByKey(String key);
+    AttachmentAppRespDTO findById(Long id);
+
+
+    void delete(Long id);
+
+    void downloadByKey(HttpServletResponse response, HttpServletRequest request, String key);
+
+    void downloadForStream(HttpServletResponse response, String key);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/service/dto/req/AttachmentAppReq.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/service/dto/req/AttachmentAppReq.java
new file mode 100644
index 0000000..a3e024d
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/service/dto/req/AttachmentAppReq.java
@@ -0,0 +1,48 @@
+package com.gkhy.fourierSpecialGasMonitor.application.attachment.service.dto.req;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/7
+ * @time: 15:00
+ */
+@Data
+public class AttachmentAppReq {
+    private Long id;
+    //文件标识
+    private String fileKey;
+    //文件本地址
+    private String filePath;
+    //文件访问路径
+    private String fileUrl;
+    //文件名称
+    private String fileName;
+    //文件后缀
+    private String fileSuffix;
+    //文件描述
+    private String fileDesc;
+    //文件大小
+    private Long fileSize;
+    //文件类型
+    private String fileType;
+    //模块
+    private String module;
+    //删除标识 0-未删除,1-删除
+    private Integer delFlag;
+    //创建时间
+    private LocalDateTime createTime;
+    //创建人id
+    private Long createUid;
+    //创建人姓名
+    private String createUname;
+    //修改时间
+    private LocalDateTime updateTime;
+    //修改人id
+    private Long updateUid;
+    //修改人姓名
+    private String updateUname;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/service/dto/resp/AttachmentAppRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/service/dto/resp/AttachmentAppRespDTO.java
new file mode 100644
index 0000000..83bbf43
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/service/dto/resp/AttachmentAppRespDTO.java
@@ -0,0 +1,48 @@
+package com.gkhy.fourierSpecialGasMonitor.application.attachment.service.dto.resp;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/7
+ * @time: 16:56
+ */
+@Data
+public class AttachmentAppRespDTO {
+    private Long id;
+    //文件标识
+    private String fileKey;
+    //文件本地址
+    private String filePath;
+    //文件访问路径
+    private String fileUrl;
+    //文件名称
+    private String fileName;
+    //文件后缀
+    private String fileSuffix;
+    //文件描述
+    private String fileDesc;
+    //文件大小
+    private Long fileSize;
+    //文件类型
+    private String fileType;
+    //模块
+    private String module;
+    //删除标识 0-未删除,1-删除
+    private Integer delFlag;
+    //创建时间
+    private LocalDateTime createTime;
+    //创建人id
+    private Long createUid;
+    //创建人姓名
+    private String createUname;
+    //修改时间
+    private LocalDateTime updateTime;
+    //修改人id
+    private Long updateUid;
+    //修改人姓名
+    private String updateUname;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/service/impl/AttachmentAppServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/service/impl/AttachmentAppServiceImpl.java
new file mode 100644
index 0000000..3acda74
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/attachment/service/impl/AttachmentAppServiceImpl.java
@@ -0,0 +1,245 @@
+package com.gkhy.fourierSpecialGasMonitor.application.attachment.service.impl;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.servlet.ServletUtil;
+import com.alibaba.druid.util.StringUtils;
+import com.gkhy.fourierSpecialGasMonitor.application.attachment.converter.AttachmentAppConverter;
+import com.gkhy.fourierSpecialGasMonitor.application.attachment.service.AttachmentAppService;
+import com.gkhy.fourierSpecialGasMonitor.application.attachment.service.dto.req.AttachmentAppReq;
+import com.gkhy.fourierSpecialGasMonitor.application.attachment.service.dto.resp.AttachmentAppRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.config.file.FilePathConfig;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.UserInfoDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.UserDomainService;
+import com.gkhy.fourierSpecialGasMonitor.domain.attachment.dto.resp.AttachmentDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.attachment.enums.FileProjectConstants;
+import com.gkhy.fourierSpecialGasMonitor.domain.attachment.service.AttachmentDomainService;
+import lombok.SneakyThrows;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.Assert;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.UUID;
+
+import static cn.hutool.core.io.FileTypeUtil.getType;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/7
+ * @time: 13:37
+ */
+@Service
+public class AttachmentAppServiceImpl implements AttachmentAppService {
+
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+    /**
+     * 错误信息格式
+     */
+    private static final String ERROR_FORMATTER = "{}:{}";
+
+    @Resource
+    private FilePathConfig filePathConfig;
+
+    @Autowired
+    private UserDomainService userDomainService;
+
+    @Autowired
+    private AttachmentDomainService attachmentDomainService;
+
+    @Autowired
+    private AttachmentAppConverter converter;
+
+
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Object saveFileToPath(MultipartFile file, String module, Integer type, Long currentUserId){
+        UserInfoDomainDTO userInfo = userDomainService.getUserInfoById(currentUserId);
+        //获取对应模块路径
+        String path;
+        //获取对应模块根路径
+        String dcPath;
+        path = filePathConfig.getModule().get(module);
+        dcPath = filePathConfig.getDcPath();
+
+        String originalFilename = file.getOriginalFilename();
+        if (StringUtils.isEmpty(originalFilename)) {
+            logger.error(ERROR_FORMATTER,module,ResultCode.PATH_NOT_EXISIST.getDesc());
+            throw new BusinessException(this.getClass(), ResultCode.FILE_NOT_EXISIST);
+        }
+        if (StringUtils.isEmpty(path)) {
+            logger.error(ERROR_FORMATTER, module, ResultCode.PATH_NOT_EXISIST.getDesc());
+            throw new BusinessException(this.getClass(), ResultCode.PATH_NOT_EXISIST);
+        }
+        assert originalFilename != null;
+        LocalDateTime now = LocalDateTime.now();
+        File newFile = null;
+        try {
+            //文件标识 UUID 如4d6873609b144945935ae84442711fd6
+            String key = "";
+            String suffix = "";
+            if (originalFilename.contains(".mp3")) {
+                key = originalFilename;
+                suffix = "";
+            } else {
+                key = UUID.randomUUID().toString().replace("-", "");
+                //文件后缀  包含.
+                suffix = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
+            }
+
+            path = path.replace("/", File.separator);
+            //文件模块路径 如 2021/base/build/0421
+            String modulePath = now.getYear() + path + now.format(DateTimeFormatter.ofPattern("MMdd"));
+            //文件路径  如 2021/base/build/0421/4d6873609b144945935ae84442711fd6.后缀
+            String newFilePath = modulePath + File.separator + key + suffix;
+            //文件绝对路径 如 /home/img/2021/base/build/0421/4d6873609b144945935ae84442711fd6.后缀
+            String localPath = dcPath + newFilePath;
+            //文件访问路径 如 /upload/2021/base/build/0421/4d6873609b144945935ae84442711fd6.后缀
+            String url = filePathConfig.getUrlRootPath() + newFilePath.replace(File.separator, "/");
+            newFile = new File(localPath);
+            if (!newFile.exists() && !newFile.mkdirs()) {
+                logger.error(ERROR_FORMATTER, newFilePath, ResultCode.FILE_UPLOAD_FAIL.getDesc());
+                throw new BusinessException(this.getClass(),ResultCode.FILE_UPLOAD_FAIL);
+            }
+            file.transferTo(newFile);
+            //创建文件信息
+            AttachmentAppReq attachmentAppReq = new AttachmentAppReq();
+            attachmentAppReq.setDelFlag(0);
+            attachmentAppReq.setFileKey(key);
+            attachmentAppReq.setFileSuffix(suffix);
+            attachmentAppReq.setFilePath(localPath);
+            attachmentAppReq.setFileUrl(url);
+            attachmentAppReq.setFileName(file.getOriginalFilename());
+            attachmentAppReq.setFileSize(file.getSize());
+            attachmentAppReq.setModule(module);
+            attachmentAppReq.setFileType(getType(suffix));
+            attachmentAppReq.setCreateUid(userInfo.getId());
+            attachmentAppReq.setCreateUname(userInfo.getName());
+            attachmentAppReq.setUpdateUid(userInfo.getId());
+            attachmentAppReq.setUpdateUname(userInfo.getName());
+            AttachmentDomainDTO attachmentDomainDTO = attachmentDomainService.save(attachmentAppReq);
+            switch (type) {
+                case FileProjectConstants.ReturnType.URL:
+                    return url;
+                case FileProjectConstants.ReturnType.KEY:
+                    return key;
+                case FileProjectConstants.ReturnType.DETAIL:
+                    return attachmentDomainDTO;
+                default:
+                    return null;
+            }
+        } catch (IOException e) {
+            if (newFile != null && newFile.exists()) {
+                newFile.delete();
+            }
+            logger.error(ERROR_FORMATTER, ResultCode.FILE_UPLOAD_FAIL, e.getMessage());
+            throw new BusinessException(this.getClass(),ResultCode.FILE_UPLOAD_FAIL);
+        }
+    }
+
+    @Override
+    public AttachmentAppRespDTO findByKey(String key) {
+        if(StringUtils.isEmpty(key)){
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL);
+        }
+        AttachmentDomainDTO byKey = attachmentDomainService.findByKey(key);
+        return converter.getAppRespDTO(byKey);
+    }
+    @Override
+    public AttachmentAppRespDTO findById(Long id) {
+        if(id == null){
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL);
+        }
+        AttachmentDomainDTO findById = attachmentDomainService.findById(id);
+        return converter.getAppRespDTO(findById);
+    }
+
+    @Override
+    public void delete(Long id) {
+        if(id == null){
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL);
+        }
+        attachmentDomainService.delete(id);
+    }
+
+    @Override
+    public void downloadByKey(HttpServletResponse response, HttpServletRequest request, String key) {
+        Assert.isTrue(StrUtil.isNotBlank(key) && !StrUtil.isNullOrUndefined(key), "文件key未知异常");
+        AttachmentAppRespDTO byKey = findByKey(key);
+        downloadByEntity(response, request, byKey);
+    }
+
+    @SneakyThrows
+    @Override
+    public void downloadForStream(HttpServletResponse response, String key) {
+        AttachmentAppRespDTO byKey = findByKey(key);
+        File file;
+        try {
+            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode(byKey.getFileName(), StandardCharsets.UTF_8.name()));
+            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
+            file = new File(byKey.getFilePath());
+            if (!file.exists()) {
+                logger.error(ERROR_FORMATTER, key, ResultCode.FILE_NOT_EXISIST.getDesc());
+                throw new BusinessException(this.getClass(),ResultCode.FILE_NOT_EXISIST);
+            }
+            OutputStream outputStream = response.getOutputStream();
+            FileInputStream inputStream = new FileInputStream(file);
+            IoUtil.copy(inputStream, outputStream);
+            outputStream.close();
+        } catch (UnsupportedEncodingException e) {
+            logger.error(e.getMessage());
+            throw new BusinessException(this.getClass(),ResultCode.FILE_DOWNLOAD_EXPERTION);
+        }
+
+    }
+
+    //@Override
+    public void downloadByEntity(HttpServletResponse response, HttpServletRequest request, AttachmentAppRespDTO appRespDTO) {
+        if (ObjectUtil.isNotNull(appRespDTO)) {
+            String type = appRespDTO.getFileType();
+            if (StrUtil.isBlank(type)) {
+                type = "application/octet-stream";
+            }
+            type = type + ";charset=utf-8";
+            String fileName = appRespDTO.getFileName();
+            response.setContentType("multipart/form-data;charset=utf-8");
+            ServletUtil.setHeader(response, "Access-Control-Expose-Headers", "Content-Disposition");
+            //本地文件下载
+            File file = FileUtil.file(appRespDTO.getFilePath());
+            if (!FileUtil.exist(file)) {
+                throw new BusinessException(this.getClass(),ResultCode.FILE_NOT_EXISIST,appRespDTO.getFileKey() + "文件不存在");
+            }
+            InputStream is = null;
+            try {
+                is = IoUtil.toStream(file);
+                ServletUtil.write(response, is, type, fileName);
+            } catch (Exception e) {
+                throw new BusinessException(this.getClass(),ResultCode.FILE_DOWNLOAD_EXPERTION);
+            } finally {
+                IoUtil.close(is);
+            }
+        } else {
+            throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_DATA_NOT_EXISIST,"文件记录不存在");
+        }
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/convert/MenuItemAppConvert.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/convert/MenuItemAppConvert.java
new file mode 100644
index 0000000..551b5fb
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/convert/MenuItemAppConvert.java
@@ -0,0 +1,39 @@
+package com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.convert;
+
+import com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.model.dto.resp.MenuItemAppDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.model.dto.MenuItemDomainDTO;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class MenuItemAppConvert {
+
+    public List<MenuItemAppDTO> toAppDtoList(List<MenuItemDomainDTO> domainDTOList){
+        if(domainDTOList == null || domainDTOList.isEmpty())
+            return null;
+        List<MenuItemAppDTO> appDTOList = new ArrayList<>();
+        domainDTOList.forEach(domainDTO -> {
+            appDTOList.add(toAppDto(domainDTO));
+        });
+        return appDTOList;
+    }
+
+    public MenuItemAppDTO toAppDto(MenuItemDomainDTO dto){
+        if(dto == null)
+            return null;
+        MenuItemAppDTO appDTO = new MenuItemAppDTO();
+        BeanUtils.copyProperties(dto,appDTO);
+        if(dto.getSubMenuItemList() != null && !dto.getSubMenuItemList().isEmpty()){
+            List<MenuItemAppDTO> childs = new ArrayList<>();
+            dto.getSubMenuItemList().forEach(c -> {
+                MenuItemAppDTO childAppDto = toAppDto(c);
+                childs.add(childAppDto);
+            });
+            appDTO.setSubMenuItemList(childs);
+        }
+        return appDTO;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/AddAndUpdateMenuItemAppDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/AddAndUpdateMenuItemAppDTO.java
new file mode 100644
index 0000000..c4d5938
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/AddAndUpdateMenuItemAppDTO.java
@@ -0,0 +1,185 @@
+package com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.model.dto.req;
+
+import java.util.List;
+
+public class AddAndUpdateMenuItemAppDTO {
+
+    private Long menuItemId;
+
+    //父级菜单
+    private Long parentId;
+
+    //菜单项显示标题
+    private String title;
+
+    //菜单项描述信息
+    private String descInfo;
+
+    //菜单项名称
+    private String name;
+
+    //路径
+    private String path;
+
+    //重定向路径
+    private String redirect;
+
+    private String link;
+
+    //
+    private boolean visiable;
+
+    //
+    private String icon;
+
+    //
+    private Byte priority;
+
+    private String component;
+
+    private Boolean aliveable;
+
+    private Boolean affixable;
+
+    private Boolean iframeable;
+
+    private Boolean publicable;
+
+    private List<Long> roles;
+
+    public Long getMenuItemId() {
+        return menuItemId;
+    }
+
+    public void setMenuItemId(Long menuItemId) {
+        this.menuItemId = menuItemId;
+    }
+
+    public Long getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescInfo() {
+        return descInfo;
+    }
+
+    public void setDescInfo(String descInfo) {
+        this.descInfo = descInfo;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getRedirect() {
+        return redirect;
+    }
+
+    public void setRedirect(String redirect) {
+        this.redirect = redirect;
+    }
+
+    public String getLink() {
+        return link;
+    }
+
+    public void setLink(String link) {
+        this.link = link;
+    }
+
+    public boolean isVisiable() {
+        return visiable;
+    }
+
+    public void setVisiable(boolean visiable) {
+        this.visiable = visiable;
+    }
+
+    public String getIcon() {
+        return icon;
+    }
+
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
+
+    public Byte getPriority() {
+        return priority;
+    }
+
+    public void setPriority(Byte priority) {
+        this.priority = priority;
+    }
+
+    public String getComponent() {
+        return component;
+    }
+
+    public void setComponent(String component) {
+        this.component = component;
+    }
+
+    public Boolean getAliveable() {
+        return aliveable;
+    }
+
+    public void setAliveable(Boolean aliveable) {
+        this.aliveable = aliveable;
+    }
+
+    public Boolean getAffixable() {
+        return affixable;
+    }
+
+    public void setAffixable(Boolean affixable) {
+        this.affixable = affixable;
+    }
+
+    public Boolean getIframeable() {
+        return iframeable;
+    }
+
+    public void setIframeable(Boolean iframeable) {
+        this.iframeable = iframeable;
+    }
+
+    public Boolean getPublicable() {
+        return publicable;
+    }
+
+    public void setPublicable(Boolean publicable) {
+        this.publicable = publicable;
+    }
+
+    public List<Long> getRoles() {
+        return roles;
+    }
+
+    public void setRoles(List<Long> roles) {
+        this.roles = roles;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/MenuItemBindRoleAppDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/MenuItemBindRoleAppDTO.java
new file mode 100644
index 0000000..a252a7f
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/MenuItemBindRoleAppDTO.java
@@ -0,0 +1,36 @@
+package com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.model.dto.req;
+
+import java.util.List;
+
+public class MenuItemBindRoleAppDTO {
+
+    private Long menuItemId;
+
+    private List<Long> bindRoleIdList;
+
+    private List<Long> unbindRoleIdList;
+
+    public Long getMenuItemId() {
+        return menuItemId;
+    }
+
+    public void setMenuItemId(Long menuItemId) {
+        this.menuItemId = menuItemId;
+    }
+
+    public List<Long> getBindRoleIdList() {
+        return bindRoleIdList;
+    }
+
+    public void setBindRoleIdList(List<Long> bindRoleIdList) {
+        this.bindRoleIdList = bindRoleIdList;
+    }
+
+    public List<Long> getUnbindRoleIdList() {
+        return unbindRoleIdList;
+    }
+
+    public void setUnbindRoleIdList(List<Long> unbindRoleIdList) {
+        this.unbindRoleIdList = unbindRoleIdList;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/ModifyMenuItemAppDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/ModifyMenuItemAppDTO.java
new file mode 100644
index 0000000..710162d
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/ModifyMenuItemAppDTO.java
@@ -0,0 +1,185 @@
+package com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.model.dto.req;
+
+public class ModifyMenuItemAppDTO {
+
+    private Long menuItemId;
+
+    //父级菜单
+    private Long parentId;
+
+    //菜单项显示标题
+    private String title;
+
+    //菜单项描述信息
+    private String descInfo;
+
+    //菜单项名称
+    private String name;
+
+    //路径
+    private String path;
+
+    //重定向路径
+    private String redirect;
+
+    //
+    private Boolean linkable;
+
+    private String link;
+
+    //
+    private Boolean visiable;
+
+    //
+    private String icon;
+
+    //
+    private Byte priority;
+
+    private String component;
+
+    private Boolean aliveable;
+
+    private Boolean affixable;
+
+    private Boolean iframeable;
+
+    private Boolean publicable;
+
+    public Long getMenuItemId() {
+        return menuItemId;
+    }
+
+    public void setMenuItemId(Long menuItemId) {
+        this.menuItemId = menuItemId;
+    }
+
+    public Long getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescInfo() {
+        return descInfo;
+    }
+
+    public void setDescInfo(String descInfo) {
+        this.descInfo = descInfo;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getRedirect() {
+        return redirect;
+    }
+
+    public void setRedirect(String redirect) {
+        this.redirect = redirect;
+    }
+
+    public Boolean getLinkable() {
+        return linkable;
+    }
+
+    public void setLinkable(Boolean linkable) {
+        this.linkable = linkable;
+    }
+
+    public Boolean getVisiable() {
+        return visiable;
+    }
+
+    public void setVisiable(Boolean visiable) {
+        this.visiable = visiable;
+    }
+
+    public String getLink() {
+        return link;
+    }
+
+    public void setLink(String link) {
+        this.link = link;
+    }
+
+    public String getIcon() {
+        return icon;
+    }
+
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
+
+    public Byte getPriority() {
+        return priority;
+    }
+
+    public void setPriority(Byte priority) {
+        this.priority = priority;
+    }
+
+
+    public String getComponent() {
+        return component;
+    }
+
+    public void setComponent(String component) {
+        this.component = component;
+    }
+
+    public Boolean getAliveable() {
+        return aliveable;
+    }
+
+    public void setAliveable(Boolean aliveable) {
+        this.aliveable = aliveable;
+    }
+
+    public Boolean getAffixable() {
+        return affixable;
+    }
+
+    public void setAffixable(Boolean affixable) {
+        this.affixable = affixable;
+    }
+
+    public Boolean getIframeable() {
+        return iframeable;
+    }
+
+    public void setIframeable(Boolean iframeable) {
+        this.iframeable = iframeable;
+    }
+
+    public Boolean getPublicable() {
+        return publicable;
+    }
+
+    public void setPublicable(Boolean publicable) {
+        this.publicable = publicable;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/NewMenuItemAppDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/NewMenuItemAppDTO.java
new file mode 100644
index 0000000..53e7070
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/NewMenuItemAppDTO.java
@@ -0,0 +1,175 @@
+package com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.model.dto.req;
+
+import java.util.List;
+
+public class NewMenuItemAppDTO {
+
+    //父级菜单
+    private Long parentId;
+
+    //菜单项显示标题
+    private String title;
+
+    //菜单项描述信息
+    private String descInfo;
+
+    //菜单项名称
+    private String name;
+
+    //路径
+    private String path;
+
+    //重定向路径
+    private String redirect;
+
+    private String link;
+
+    //
+    private boolean visiable;
+
+    //
+    private String icon;
+
+    //
+    private Byte priority;
+
+    private String component;
+
+    private Boolean aliveable;
+
+    private Boolean affixable;
+
+    private Boolean iframeable;
+
+    private Boolean publicable;
+
+    private List<Long> roles;
+
+    public Long getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescInfo() {
+        return descInfo;
+    }
+
+    public void setDescInfo(String descInfo) {
+        this.descInfo = descInfo;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getRedirect() {
+        return redirect;
+    }
+
+    public void setRedirect(String redirect) {
+        this.redirect = redirect;
+    }
+
+    public String getLink() {
+        return link;
+    }
+
+    public void setLink(String link) {
+        this.link = link;
+    }
+
+    public boolean isVisiable() {
+        return visiable;
+    }
+
+    public void setVisiable(boolean visiable) {
+        this.visiable = visiable;
+    }
+
+    public String getIcon() {
+        return icon;
+    }
+
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
+
+    public Byte getPriority() {
+        return priority;
+    }
+
+    public void setPriority(Byte priority) {
+        this.priority = priority;
+    }
+
+    public String getComponent() {
+        return component;
+    }
+
+    public void setComponent(String component) {
+        this.component = component;
+    }
+
+    public Boolean getAliveable() {
+        return aliveable;
+    }
+
+    public void setAliveable(Boolean aliveable) {
+        this.aliveable = aliveable;
+    }
+
+    public Boolean getAffixable() {
+        return affixable;
+    }
+
+    public void setAffixable(Boolean affixable) {
+        this.affixable = affixable;
+    }
+
+    public Boolean getIframeable() {
+        return iframeable;
+    }
+
+    public void setIframeable(Boolean iframeable) {
+        this.iframeable = iframeable;
+    }
+
+    public Boolean getPublicable() {
+        return publicable;
+    }
+
+    public void setPublicable(Boolean publicable) {
+        this.publicable = publicable;
+    }
+
+    public List<Long> getRoles() {
+        return roles;
+    }
+
+    public void setRoles(List<Long> roles) {
+        this.roles = roles;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/RoleBindMenuAppDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/RoleBindMenuAppDTO.java
new file mode 100644
index 0000000..6818072
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/req/RoleBindMenuAppDTO.java
@@ -0,0 +1,36 @@
+package com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.model.dto.req;
+
+import java.util.List;
+
+public class RoleBindMenuAppDTO {
+
+    private Long roleId;
+
+    private List<Long> bindMenuItemIdList;
+
+    private List<Long> unbindMenuItemIdList;
+
+    public Long getRoleId() {
+        return roleId;
+    }
+
+    public void setRoleId(Long roleId) {
+        this.roleId = roleId;
+    }
+
+    public List<Long> getBindMenuItemIdList() {
+        return bindMenuItemIdList;
+    }
+
+    public void setBindMenuItemIdList(List<Long> bindMenuItemIdList) {
+        this.bindMenuItemIdList = bindMenuItemIdList;
+    }
+
+    public List<Long> getUnbindMenuItemIdList() {
+        return unbindMenuItemIdList;
+    }
+
+    public void setUnbindMenuItemIdList(List<Long> unbindMenuItemIdList) {
+        this.unbindMenuItemIdList = unbindMenuItemIdList;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/resp/MenuItemAppDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/resp/MenuItemAppDTO.java
new file mode 100644
index 0000000..570932f
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/model/dto/resp/MenuItemAppDTO.java
@@ -0,0 +1,217 @@
+package com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.model.dto.resp;
+
+import java.util.List;
+
+public class MenuItemAppDTO {
+
+    private Long id;
+
+    //菜单级别
+    private Integer level;
+
+    //父级菜单
+    private Long parentId;
+
+    //菜单项显示标题
+    private String title;
+
+    private Byte priority;
+
+    //菜单项描述信息
+    private String descInfo;
+
+
+    private String component;
+
+    //菜单项名称
+    private String name;
+
+    //路径
+    private String path;
+
+    //重定向路径
+    private String redirect;
+
+    //
+    private Boolean linkable;
+
+    //
+    private Boolean visiable;
+
+    private Boolean aliveable;
+
+    private Boolean affixable;
+
+    private Boolean iframeable;
+
+    private Boolean publicable;
+
+    //
+    private String icon;
+
+    private String link;
+
+    private List<Long> roles;
+
+    private List<MenuItemAppDTO> subMenuItemList;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Integer getLevel() {
+        return level;
+    }
+
+    public void setLevel(Integer level) {
+        this.level = level;
+    }
+
+    public Long getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescInfo() {
+        return descInfo;
+    }
+
+    public void setDescInfo(String descInfo) {
+        this.descInfo = descInfo;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getRedirect() {
+        return redirect;
+    }
+
+    public void setRedirect(String redirect) {
+        this.redirect = redirect;
+    }
+
+    public Boolean getLinkable() {
+        return linkable;
+    }
+
+    public void setLinkable(Boolean linkable) {
+        this.linkable = linkable;
+    }
+
+    public Boolean getVisiable() {
+        return visiable;
+    }
+
+    public void setVisiable(Boolean visiable) {
+        this.visiable = visiable;
+    }
+
+    public String getIcon() {
+        return icon;
+    }
+
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
+
+    public Byte getPriority() {
+        return priority;
+    }
+
+    public void setPriority(Byte priority) {
+        this.priority = priority;
+    }
+
+    public String getComponent() {
+        return component;
+    }
+
+    public void setComponent(String component) {
+        this.component = component;
+    }
+
+    public Boolean getAliveable() {
+        return aliveable;
+    }
+
+    public void setAliveable(Boolean aliveable) {
+        this.aliveable = aliveable;
+    }
+
+    public Boolean getAffixable() {
+        return affixable;
+    }
+
+    public void setAffixable(Boolean affixable) {
+        this.affixable = affixable;
+    }
+
+    public Boolean getIframeable() {
+        return iframeable;
+    }
+
+    public void setIframeable(Boolean iframeable) {
+        this.iframeable = iframeable;
+    }
+
+    public Boolean getPublicable() {
+        return publicable;
+    }
+
+    public void setPublicable(Boolean publicable) {
+        this.publicable = publicable;
+    }
+
+    public String getLink() {
+        return link;
+    }
+
+    public void setLink(String link) {
+        this.link = link;
+    }
+
+    public List<Long> getRoles() {
+        return roles;
+    }
+
+    public void setRoles(List<Long> roles) {
+        this.roles = roles;
+    }
+
+    public List<MenuItemAppDTO> getSubMenuItemList() {
+        return subMenuItemList;
+    }
+
+    public void setSubMenuItemList(List<MenuItemAppDTO> subMenuItemList) {
+        this.subMenuItemList = subMenuItemList;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/service/MenuAppService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/service/MenuAppService.java
new file mode 100644
index 0000000..72e3d26
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/service/MenuAppService.java
@@ -0,0 +1,39 @@
+package com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.service;
+
+import com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.model.dto.req.*;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+
+public interface MenuAppService {
+
+    /**
+     * 新建菜单项
+     * @param dto
+     * @return
+     */
+    Result addMenuItem(NewMenuItemAppDTO dto);
+
+    /**
+     * 修改菜单项
+     * @param dto
+     * @return
+     */
+    Result modifyMenuItem(AddAndUpdateMenuItemAppDTO dto);
+
+    /**
+     * 删除菜单项
+     * @param menuItemId
+     * @return
+     */
+    Result deleteMenuItem(Long menuItemId);
+
+    /**
+     * 获取全部可用菜单项
+     * @return
+     */
+    SearchResult getAllMenuItems();
+
+    Result roleBindMenu(RoleBindMenuAppDTO bindDTO);
+
+    Result menuBindRole(MenuItemBindRoleAppDTO bindDTO);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/service/impl/MenuAppServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/service/impl/MenuAppServiceImpl.java
new file mode 100644
index 0000000..071d4ba
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/application/sysAdmin/service/impl/MenuAppServiceImpl.java
@@ -0,0 +1,298 @@
+package com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.service.impl;
+
+import com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.convert.MenuItemAppConvert;
+import com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.model.dto.req.*;
+import com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.model.dto.resp.MenuItemAppDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.sysAdmin.service.MenuAppService;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo.MenuItemBindRoleBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo.RoleBindMenuItemBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.RoleDomainService;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.RoleMenuDomainService;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.model.bo.CreateNewMenuItemBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.model.bo.ModifyMenuItemBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.model.dto.MenuItemDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.service.MenuDomainService;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@Service
+public class MenuAppServiceImpl implements MenuAppService {
+
+    @Autowired
+    private MenuDomainService menuDomainService;
+
+    @Autowired
+    private RoleMenuDomainService roleMenuDomainService;
+
+    @Autowired
+    private MenuItemAppConvert menuItemAppConvert;
+
+    @Autowired
+    private RoleDomainService roleDomainService;
+
+    @Override
+    @Transactional
+    public Result addMenuItem(NewMenuItemAppDTO dto) {
+        Result result = new Result<>();
+        if(dto == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        if(dto.getName() == null || dto.getName().isEmpty())
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"菜单参数不能为空");
+        CreateNewMenuItemBO createBO = new CreateNewMenuItemBO();
+        if(dto.getParentId() != null){
+            MenuItemDomainDTO parant = menuDomainService.getMenuItemById(dto.getParentId());
+            if(parant == null)
+                throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_OBJECT_NOT_EXIST.getCode(), "上一级菜单不存在");
+            createBO.setParentId(dto.getParentId());
+        }
+        createBO.setName(dto.getName());
+        createBO.setTitle(dto.getTitle());
+        createBO.setPath(dto.getPath());
+        createBO.setDescInfo(dto.getDescInfo());
+        createBO.setVisiable(dto.isVisiable());
+        createBO.setRedirect(dto.getRedirect());
+        createBO.setIcon(dto.getIcon());
+        createBO.setLink(dto.getLink());
+        if(createBO.getLink() == null)
+            createBO.setLink("");
+        //
+        createBO.setPriority(dto.getPriority());
+        createBO.setComponent(dto.getComponent());
+        createBO.setAliveable(dto.getAliveable());
+        createBO.setAffixable(dto.getAffixable());
+        createBO.setIframeable(dto.getIframeable());
+        createBO.setPublicable(dto.getPublicable());
+        createBO.setRoles(dto.getRoles());
+        MenuItemDomainDTO createResultDTO = menuDomainService.createNewMenuItem(createBO);
+        if(createResultDTO == null)
+            throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR.getCode(),"创建菜单项出错");
+        result.setSuccess();
+        return result;
+    }
+
+    @Override
+    @Transactional
+    public Result modifyMenuItem(AddAndUpdateMenuItemAppDTO dto) {
+        Result result = new Result<>();
+        if(dto == null || dto.getMenuItemId() == null || dto.getMenuItemId() < 1)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        MenuItemDomainDTO orign = menuDomainService.getMenuItemById(dto.getMenuItemId());
+        if(orign == null)
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_OBJECT_NOT_EXIST.getCode(),"菜单项不存在");
+        List<Long> orignRoles = roleMenuDomainService.getBindRolesByMenuItemId(dto.getMenuItemId());
+        //检查是否发生变更
+        if(!checkMenuItemHasModified(orign,dto) && !checkBindRolesHashModified(orignRoles,dto.getRoles())){
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR.getCode(),"菜单项配置未发生变化");
+        }
+        //包装修改业务对象
+        ModifyMenuItemBO modifyBO = new ModifyMenuItemBO();
+        BeanUtils.copyProperties(dto,modifyBO);
+        modifyBO.setRoles(dto.getRoles());
+        if(menuDomainService.modifyMenuItem(modifyBO) == false){
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR.getCode(),"变更菜单项配置出错");
+        }
+        result.setSuccess();
+        return result;
+    }
+
+    @Override
+    @Transactional
+    public Result deleteMenuItem(Long menuItemId) {
+        if(menuItemId == null || menuItemId < 1)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        Result result = new Result<>();
+        if(menuDomainService.deleteMenuItem(menuItemId))
+            result.setSuccess();
+        else {
+            result.setCode(ResultCode.BUSINESS_ERROR.getCode());
+            result.setMsg("删除菜单项出错");
+        }
+        return result;
+    }
+
+    @Override
+    public SearchResult getAllMenuItems() {
+        SearchResult result = new SearchResult<>();
+        result.setSuccess();
+        List<MenuItemDomainDTO> menuItemDomainDTOList = menuDomainService.getAllActiveMenuItems();
+        if(menuItemDomainDTOList == null || menuItemDomainDTOList.isEmpty())
+            result.setCount(0);
+        else {
+            //数据转换
+            List<MenuItemAppDTO> appDTOList = convertToMenuItemAppDtos(menuItemDomainDTOList);
+            result.setData(appDTOList);
+            result.setCount(appDTOList.size());
+        }
+        return result;
+    }
+
+    private List<MenuItemAppDTO> convertToMenuItemAppDtos(List<MenuItemDomainDTO> orignList){
+        if(orignList == null || orignList.isEmpty())
+            return null;
+        List<MenuItemAppDTO> targetList = new ArrayList<>();
+        orignList.forEach(o -> {
+            MenuItemAppDTO appDTO = menuItemAppConvert.toAppDto(o);
+            List<Long> bindRoles = roleMenuDomainService.getBindRolesByMenuItemId(o.getId());
+            appDTO.setRoles(bindRoles);
+            if(o.getSubMenuItemList() != null && !o.getSubMenuItemList().isEmpty()){
+                appDTO.setSubMenuItemList(convertToMenuItemAppDtos(o.getSubMenuItemList()));
+            }
+            targetList.add(appDTO);
+        });
+        return targetList;
+    }
+
+    @Override
+    @Transactional
+    public Result roleBindMenu(RoleBindMenuAppDTO bindDTO) {
+        Result result = new Result<>();
+        if(bindDTO == null || bindDTO.getRoleId() == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        RoleBindMenuItemBO bindBO = new RoleBindMenuItemBO();
+        BeanUtils.copyProperties(bindDTO,bindBO);
+        boolean bindResult = roleMenuDomainService.roleBindMenu(bindBO);
+        if(bindResult == true){
+            result.setSuccess();
+        }else {
+            result.setCode(ResultCode.BUSINESS_ERROR.getCode());
+            result.setMsg("角色绑定菜单项出错");
+        }
+        return result;
+    }
+
+    @Override
+    public Result menuBindRole(MenuItemBindRoleAppDTO bindDTO) {
+        Result result = new Result<>();
+        if(bindDTO == null || bindDTO.getMenuItemId() == null){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        }
+        MenuItemBindRoleBO bindBO = new MenuItemBindRoleBO();
+        BeanUtils.copyProperties(bindDTO,bindBO);
+        boolean bindResult = roleMenuDomainService.menuBindRole(bindBO);
+        if(bindResult == true){
+            result.setSuccess();
+        }else {
+            result.setCode(ResultCode.BUSINESS_ERROR.getCode());
+            result.setMsg("菜单项绑定角色出错");
+        }
+        return result;
+    }
+
+    /**
+     * 检查菜单项绑定的角色是否发生变化
+     * @param orign
+     * @param now
+     * @return
+     */
+    private boolean checkBindRolesHashModified(List<Long> orign,List<Long> now){
+        if(orign == null && now == null) {
+            return false;
+        }
+        if(orign == null && now != null && !now.isEmpty()) {
+            return true;
+        }
+        if(orign == null && orign != null && now.size() == 0) {
+            return false;
+        }
+        if(now == null && orign != null && !orign.isEmpty()) {
+            return true;
+        }
+        if(now == null && orign != null && orign.size() == 0){
+            return false;
+        }
+//        if((orign == null || orign.isEmpty()) && now != null && !now.isEmpty()) {
+//            return true;
+//        }
+//        if(orign != null && !orign.isEmpty() && (now == null || now.isEmpty())) {
+//            return true;
+//        }
+        if(orign != null && now != null && orign.size() != now.size()) {
+            return true;
+        }
+        Set<Long> set = new HashSet<>();
+        orign.forEach(id -> {
+            set.add(id);
+        });
+        for(int i=0;i< now.size();i++){
+            if(!set.contains(now.get(i))){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 检查菜单项是否发生变更
+     * @param orign
+     * @param dto
+     * @return
+     */
+    private boolean checkMenuItemHasModified(MenuItemDomainDTO orign, AddAndUpdateMenuItemAppDTO dto){
+        if(checkStringHasChanged(orign.getName(),dto.getName()))
+            return true;
+        if(checkStringHasChanged(orign.getTitle(),dto.getTitle()))
+            return true;
+        if(checkStringHasChanged(orign.getDescInfo(),dto.getDescInfo()))
+            return true;
+        if(checkStringHasChanged(orign.getIcon(),dto.getIcon()))
+            return true;
+        if(checkStringHasChanged(orign.getPath(),dto.getPath()))
+            return true;
+        if(checkStringHasChanged(orign.getRedirect(),dto.getRedirect()))
+            return true;
+        if(checkStringHasChanged(orign.getLink(),dto.getLink()))
+            return true;
+        if(orign.getParentId() == null && dto.getParentId() != null)
+            return true;
+        if(orign.getParentId() != null && dto.getParentId() == null)
+            return true;
+        if(orign.getParentId() != null && dto.getParentId() != null && !orign.getParentId().equals(dto.getParentId()))
+            return true;
+        if(orign.getVisiable() != dto.isVisiable())
+            return true;
+        if(orign.getPriority() != dto.getPriority())
+            return true;
+        if(checkStringHasChanged(orign.getComponent(), dto.getComponent()))
+            return true;
+        if(orign.getAliveable() != dto.getAliveable())
+            return true;
+        if(orign.getAffixable() != dto.getAffixable())
+            return true;
+        if(orign.getIframeable() != dto.getIframeable())
+            return true;
+        if(orign.getPublicable() != dto.getPublicable())
+            return true;
+        return false;
+    }
+
+    /**
+     * 检查对象字符串是否发生变化
+     * @param orign
+     * @param now
+     * @return
+     */
+    private boolean checkStringHasChanged(String orign,String now){
+        if(orign == null && now == null)
+            return false;
+        if(orign == null && !now.isEmpty())
+            return true;
+        if(orign != null && now == null)
+            return true;
+        if(orign != null && orign.isEmpty() && now != null && now.isEmpty())
+            return false;
+        if(orign.equals(now))
+            return false;
+        return true;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/domain/ForeignResult.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/domain/ForeignResult.java
new file mode 100644
index 0000000..9aa7f4c
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/domain/ForeignResult.java
@@ -0,0 +1,106 @@
+package com.gkhy.fourierSpecialGasMonitor.commons.domain;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ForeignResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+public class ForeignResult<T> implements Serializable {
+
+    private Integer code;
+
+    private String time;
+
+    private T data;
+
+    private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+    public static ForeignResult success(){
+        ForeignResult resultVO = new ForeignResult();
+        resultVO.setCode(ForeignResultCode.OK.getCode());
+        resultVO.setTime(LocalDateTime.now().format(formatter));
+        return resultVO;
+    }
+
+    public void execSuccess(){
+        this.code = ForeignResultCode.OK.getCode();
+    }
+
+    public void setSuccess(){
+        this.code = ForeignResultCode.OK.getCode();
+        this.time = LocalDateTime.now().format(formatter);
+    }
+
+    public ForeignResult() {
+        this.code = ForeignResultCode.NOT_OK.getCode();
+    }
+
+
+    public ForeignResult(Integer code, String time) {
+        this.code = code;
+        this.time = time;
+    }
+
+    public ForeignResult(ForeignResultCode resultCode, String time){
+        this.code = resultCode.getCode();
+        if(time != null && !time.isEmpty()){
+            this.time = time;
+        }else {
+            this.time = LocalDateTime.now().format(formatter);
+        }
+    }
+
+    public ForeignResult(ForeignResultCode code, T data) {
+        this.code = code.getCode();
+        this.time = LocalDateTime.now().format(formatter);
+        this.data = data;
+    }
+
+
+    public ForeignResult(ForeignResultCode code) {
+        this.code = code.getCode();
+        this.time = LocalDateTime.now().format(formatter);
+    }
+
+    //public boolean isSuccess(){
+    //    if(this.code == null)
+    //        return false;
+    //    if(this.code.equals(ForeignResultCode.OK.getCode())){
+    //        return true;
+    //    }else {
+    //        return false;
+    //    }
+    //}
+
+
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public void setCode(ForeignResultCode resultCode){
+        this.code = resultCode.getCode();
+    }
+
+    public String getTime() {
+        return time;
+    }
+
+    public void setTime(String time) {
+        this.time = time;
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/domain/Result.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/domain/Result.java
new file mode 100644
index 0000000..ea8f80d
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/domain/Result.java
@@ -0,0 +1,111 @@
+package com.gkhy.fourierSpecialGasMonitor.commons.domain;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+
+import java.io.Serializable;
+
+public class Result<T> implements Serializable {
+
+    private Integer code;
+
+    private Integer count;
+
+    private String msg;
+
+    private T data;
+
+    public static Result success(){
+        Result resultVO = new Result();
+        resultVO.setCode(ResultCode.OK.getCode());
+        resultVO.setMsg(ResultCode.OK.getDesc());
+        return resultVO;
+    }
+
+    public void execSuccess(){
+        this.code = ResultCode.OK.getCode();
+    }
+
+    public void setSuccess(){
+        this.code = ResultCode.OK.getCode();
+        this.msg = ResultCode.OK.getDesc();
+    }
+
+    public Result() {
+        this.code = ResultCode.NOT_OK.getCode();
+    }
+
+
+    public Result(Integer code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public Result(ResultCode resultCode,String msg){
+        this.code = resultCode.getCode();
+        if(msg != null && !msg.isEmpty()){
+            this.msg = msg;
+        }else {
+            this.msg = resultCode.getDesc();
+        }
+    }
+
+    public Result(ResultCode code, T data) {
+        this.code = code.getCode();
+        this.msg = code.getDesc();
+        this.data = data;
+    }
+
+
+    public Result(ResultCode code) {
+        this.code = code.getCode();
+        this.msg = code.getDesc();
+    }
+
+    public boolean isSuccess(){
+        if(this.code == null)
+            return false;
+        if(this.code.equals(ResultCode.OK.getCode())){
+            return true;
+        }else {
+            return false;
+        }
+    }
+
+
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public void setCode(ResultCode resultCode){
+        this.code = resultCode.getCode();
+    }
+
+    public Integer getCount() {
+        return count;
+    }
+
+    public void setCount(Integer count) {
+        this.count = count;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/domain/SearchResult.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/domain/SearchResult.java
new file mode 100644
index 0000000..e600b5b
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/domain/SearchResult.java
@@ -0,0 +1,86 @@
+package com.gkhy.fourierSpecialGasMonitor.commons.domain;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+
+public class SearchResult<T> extends Result<T> {
+
+    private boolean usePage;
+
+    private Long total;
+
+    private Integer pages;
+
+    private Integer pageSize;
+
+    private Integer pageIndex;
+
+
+
+    public static SearchResult success(){
+        SearchResult searchResultVO = new SearchResult();
+        searchResultVO.setCode(ResultCode.OK.getCode());
+        return searchResultVO;
+    }
+
+
+    public SearchResult() {
+    }
+
+    public SearchResult(boolean usePage) {
+        if(usePage == false){
+            this.setUsePage(false);
+            this.setPageSize(-1);
+            this.setPageIndex(-1);
+        }else {
+            this.setUsePage(true);
+        }
+    }
+
+    public SearchResult(boolean usePage, Long total, Integer pages, Integer pageSize, Integer pageIndex) {
+        this.usePage = usePage;
+        this.total = total;
+        this.pages = pages;
+        this.pageSize = pageSize;
+        this.pageIndex = pageIndex;
+    }
+
+    public boolean isUsePage() {
+        return usePage;
+    }
+
+    public void setUsePage(boolean usePage) {
+        this.usePage = usePage;
+    }
+
+    public Long getTotal() {
+        return total;
+    }
+
+    public void setTotal(Long total) {
+        this.total = total;
+    }
+
+    public Integer getPages() {
+        return pages;
+    }
+
+    public void setPages(Integer pages) {
+        this.pages = pages;
+    }
+
+    public Integer getPageSize() {
+        return pageSize;
+    }
+
+    public void setPageSize(Integer pageSize) {
+        this.pageSize = pageSize;
+    }
+
+    public Integer getPageIndex() {
+        return pageIndex;
+    }
+
+    public void setPageIndex(Integer pageIndex) {
+        this.pageIndex = pageIndex;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/ForeignResultCode.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/ForeignResultCode.java
new file mode 100644
index 0000000..5812113
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/ForeignResultCode.java
@@ -0,0 +1,88 @@
+package com.gkhy.fourierSpecialGasMonitor.commons.enums;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum ForeignResultCode {
+
+    //正常
+    OK(200,"上传成功"),
+
+    NOT_OK(100,"上传错误"),
+
+    //参数错误
+    PARAM_ERROR(300,"参数错误"),
+    PARAM_ERROR_NULL(301,"参数不能为空"),
+    PARAM_ERROR_ILLEGAL(301,"参数格式错误"),
+    PARAM_ERROR_OUT_OF_RANGE(302,"参数超出限制"),
+
+
+
+    //业务错误
+    BUSINESS_ERROR(400,"业务错误"),
+    BUSINESS_ERROR_ACCOUNT_NOT_EXIST(401,"用户不存在"),
+    BUSINESS_ERROR_ACCOUNT_STATU_ABNORMAL(402,"账号异常"),
+    BUSINESS_ERROR_ACCOUNT_OFFLINE(403,"用户未登录"),
+    BUSINESS_ERROR_PERMISSION_DENIALED(405,"操作未授权"),
+    BUSINESS_ERROR_OUT_OF_TIME(406,"业务超时"),
+    BUSINESS_ERROR_OBJECT_NOT_EXIST(407,"业务单元不存在"),
+    BUSINESS_ERROR_NOT_ALLOWED(408,"业务不允许"),
+    BUSINESS_ERROR_HTTP_METHOD_NOT_SUPPORT(409,"HTTP请求方法不支持"),
+    BUSINESS_ERROR_DATA_NOT_EXISIST(410,"数据不存在"),
+
+
+
+    //系统错误
+    SYSTEM_ERROR(500,"系统出错"),
+    SYSTEM_ERROR_API_FAIL(501,"接口错误"),
+    SYSTEM_ERROR_API_OUT_OF_TIME(502,"接口超时"),
+    SYSTEM_ERROR_DATABASE_FAIL(503,"数据库错误"),
+    SYSTEM_ERROR_SERIALIZA_FAIL(504,"序列化错误"),
+    //文件
+    FILE_NOT_EXISIST(600,"文件不存在"),
+    PATH_NOT_EXISIST(601,"文件路径不存在"),
+    MODULE_NOT_EXISIST(602,"模块不存在"),
+    FILE_UPLOAD_FAIL(603,"文件上传失败"),
+    FILE_DOWNLOAD_FAIL(604,"文件下载失败"),
+    FILE_DOWNLOAD_EXPERTION(605,"文件下载异常"),
+    ;
+
+
+
+    ForeignResultCode(Integer code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    private Integer code;
+    private String desc;
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+
+    static Map<Integer, ForeignResultCode> map;
+
+    static {
+        map = new HashMap<>();
+        for(ForeignResultCode rc : ForeignResultCode.values()){
+            map.put(rc.getCode(),rc);
+        }
+    }
+
+    public static ForeignResultCode prase(Integer code){
+        return map.get(code);
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/MethodEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/MethodEnum.java
new file mode 100644
index 0000000..5c35032
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/MethodEnum.java
@@ -0,0 +1,52 @@
+package com.gkhy.fourierSpecialGasMonitor.commons.enums;
+
+public enum MethodEnum {
+
+    IDENTIFICATION_METHOD_PHA((byte) 1,"PHA"),
+    IDENTIFICATION_METHOD_JHA((byte) 2,"JHA"),
+    IDENTIFICATION_METHOD_SCL((byte) 3,"SCL"),
+    IDENTIFICATION_METHOD_HAZOP((byte) 4,"HAZOP"),
+    IDENTIFICATION_METHOD_ANALOGY((byte) 5,"类比法"),
+
+    EVALUATE_METHOD_LEC((byte) 1,"LEC"),
+    EVALUATE_METHOD_LS((byte) 2,"LS"),
+    EVALUATE_METHOD_MES((byte) 3,"MES"),
+    EVALUATE_METHOD_RS((byte) 4,"RS"),
+
+    RISK_EVALUATE_VALUE_1((byte) 10,"一级"),
+    RISK_EVALUATE_VALUE_2((byte) 20,"二级"),
+    RISK_EVALUATE_VALUE_3((byte) 30,"三级"),
+//    RISK_EVALUATE_VALUE_4((byte) 40,"四级"),
+
+    RISK_LEVEL_1((byte) 1,"低-蓝"),
+    RISK_LEVEL_2((byte) 2,"一般-黄"),
+    RISK_LEVEL_3((byte) 3,"较大-橙"),
+    RISK_LEVEL_4((byte) 4,"重大-红"),
+
+    ;
+
+
+    MethodEnum(Byte code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    private Byte code;
+    private String desc;
+
+    public Byte getCode() {
+        return code;
+    }
+
+    public void setCode(Byte code) {
+        this.code = code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/ResultCode.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/ResultCode.java
new file mode 100644
index 0000000..edfbc0a
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/ResultCode.java
@@ -0,0 +1,88 @@
+package com.gkhy.fourierSpecialGasMonitor.commons.enums;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum ResultCode {
+
+    //正常
+    OK(100,"成功"),
+
+    NOT_OK(200,"错误"),
+
+    //参数错误
+    PARAM_ERROR(300,"参数错误"),
+    PARAM_ERROR_NULL(301,"参数不能为空"),
+    PARAM_ERROR_ILLEGAL(301,"参数格式错误"),
+    PARAM_ERROR_OUT_OF_RANGE(302,"参数超出限制"),
+
+
+
+    //业务错误
+    BUSINESS_ERROR(400,"业务错误"),
+    BUSINESS_ERROR_ACCOUNT_NOT_EXIST(401,"用户不存在"),
+    BUSINESS_ERROR_ACCOUNT_STATU_ABNORMAL(402,"账号异常"),
+    BUSINESS_ERROR_ACCOUNT_OFFLINE(403,"用户未登录"),
+    BUSINESS_ERROR_PERMISSION_DENIALED(405,"操作未授权"),
+    BUSINESS_ERROR_OUT_OF_TIME(406,"业务超时"),
+    BUSINESS_ERROR_OBJECT_NOT_EXIST(407,"业务单元不存在"),
+    BUSINESS_ERROR_NOT_ALLOWED(408,"业务不允许"),
+    BUSINESS_ERROR_HTTP_METHOD_NOT_SUPPORT(409,"HTTP请求方法不支持"),
+    BUSINESS_ERROR_DATA_NOT_EXISIST(410,"数据不存在"),
+
+
+
+    //系统错误
+    SYSTEM_ERROR(500,"系统出错"),
+    SYSTEM_ERROR_API_FAIL(501,"接口错误"),
+    SYSTEM_ERROR_API_OUT_OF_TIME(502,"接口超时"),
+    SYSTEM_ERROR_DATABASE_FAIL(503,"数据库错误"),
+    SYSTEM_ERROR_SERIALIZA_FAIL(504,"序列化错误"),
+    //文件
+    FILE_NOT_EXISIST(600,"文件不存在"),
+    PATH_NOT_EXISIST(601,"文件路径不存在"),
+    MODULE_NOT_EXISIST(602,"模块不存在"),
+    FILE_UPLOAD_FAIL(603,"文件上传失败"),
+    FILE_DOWNLOAD_FAIL(604,"文件下载失败"),
+    FILE_DOWNLOAD_EXPERTION(605,"文件下载异常"),
+    ;
+
+
+
+    ResultCode(Integer code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    private Integer code;
+    private String desc;
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+
+    static Map<Integer,ResultCode> map;
+
+    static {
+        map = new HashMap<>();
+        for(ResultCode rc : ResultCode.values()){
+            map.put(rc.getCode(),rc);
+        }
+    }
+
+    public static ResultCode prase(Integer code){
+        return map.get(code);
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/StatusEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/StatusEnum.java
new file mode 100644
index 0000000..5900fa4
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/StatusEnum.java
@@ -0,0 +1,99 @@
+package com.gkhy.fourierSpecialGasMonitor.commons.enums;
+
+public enum StatusEnum {
+
+    SUCCESS(1,"操作成功"),
+
+    FAIL(0,"操作失败"),
+
+
+    DELETE_NOT(0,"未删除"),
+
+    DELETED(1,"已删除"),
+
+
+    EVALUATE_NOT(1,"未评价"),
+
+    EVALUATE(2,"已评价"),
+
+    EVALUATE_WAIT(3,"待评估"),
+
+
+    INHERENT_RISK(1,"固有风险"),
+
+    EXPERIMENT_RISK(2,"实验风险"),
+
+
+    PLAN_SELL_NOT(1,"未派发"),
+
+    PLAN_SELL(2,"已派发"),
+
+
+    PLAN_STATUS_NOT_START(1,"未开始"),
+
+    PLAN_STATUS_START(2,"评估中"),
+
+    PLAN_STATUS_TIMEOUT(3,"已超期"),
+
+
+    PLAN_EXEC_NOT_START(1,"未开始"),
+
+    PLAN_EXEC_IDENTIFICATION(2,"辨识阶段"),
+
+    PLAN_EXEC_EVALUATE(3,"评价阶段"),
+
+    PLAN_EXEC_OVER(4,"评估完成"),
+
+
+    EXPERIMENT_STATUS_NOT_START(1,"未开始"),
+
+    EXPERIMENT_STATUS_START(2,"评估中"),
+
+    EXPERIMENT_STATUS_FINISH(3,"评估完成"),
+
+    EXPERIMENT_STATUS_REPORT(4,"生成报告"),
+
+
+    APPROVED_WAIT(1,"未审批"),
+
+    APPROVED_PASS(2,"已通过"),
+
+    APPROVED_NOT_PASS(3,"不通过"),
+
+
+    REPORT_NOT_START(1,"未开始"),
+
+    REPORT_APPROVED(2,"管理审核通过"),
+
+    REPORT_NOT_APPROVED(3,"审核不通过"),
+
+    REPORT_APPROVED_LEAD(4,"领导审核通过"),
+
+    RECTIFY(1,"退回整改"),
+    ;
+
+
+    StatusEnum(Integer code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    private Integer code;
+    private String desc;
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/SystemCacheKeyEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/SystemCacheKeyEnum.java
new file mode 100644
index 0000000..168f939
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/SystemCacheKeyEnum.java
@@ -0,0 +1,35 @@
+package com.gkhy.fourierSpecialGasMonitor.commons.enums;
+
+/**
+ * 系统缓存KEY
+ */
+public enum SystemCacheKeyEnum {
+    KEY_SYSTEM_PROP("gkhy-fourier-sys","系统配置"),
+    KEY_SYSTEM_LICENSE_INFO("license","授权证书"),
+    KEY_USER_TOKEN("gkhy-fourier-token","登录用户TOKEN"),
+    KEY_CACHE_USER("gkhy-fourier-cache-user","用户信息缓存")
+    ;
+    private String key;
+    private String desc;
+
+    SystemCacheKeyEnum(String key, String desc) {
+        this.key = key;
+        this.desc = desc;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/SystemConfigKeyEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/SystemConfigKeyEnum.java
new file mode 100644
index 0000000..8e5eaf0
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/SystemConfigKeyEnum.java
@@ -0,0 +1,31 @@
+package com.gkhy.fourierSpecialGasMonitor.commons.enums;
+
+public enum SystemConfigKeyEnum {
+    LICENSE_TXT("license-value","系统授权License文本"),
+    LICENSE_U_KEY("license-u-key","系统授权客户私有KEY文本")
+    ;
+
+    private String key;
+    private String desc;
+
+    SystemConfigKeyEnum(String key, String desc) {
+        this.key = key;
+        this.desc = desc;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/UserRoleEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/UserRoleEnum.java
new file mode 100644
index 0000000..e99888d
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/UserRoleEnum.java
@@ -0,0 +1,43 @@
+package com.gkhy.fourierSpecialGasMonitor.commons.enums;
+
+public enum UserRoleEnum {
+
+    USER_ROLE_1(1,"实验负责人"),
+
+    USER_ROLE_2(2,"辨识专家"),
+
+    USER_ROLE_3(3,"评价专家"),
+
+    USER_ROLE_4(4,"实验管理者"),
+
+    USER_ROLE_5(5,"现场专家"),
+
+    USER_ROLE_6(6,"综合办"),
+
+    ;
+
+
+    UserRoleEnum(Integer code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    private Integer code;
+    private String desc;
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/UserTagEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/UserTagEnum.java
new file mode 100644
index 0000000..977b055
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/enums/UserTagEnum.java
@@ -0,0 +1,37 @@
+package com.gkhy.fourierSpecialGasMonitor.commons.enums;
+
+public enum UserTagEnum {
+
+    USER_TAG_0(0,"一般用户"),
+
+    USER_TAG_1(1,"管理"),
+
+    USER_TAG_2(2,"领导"),
+
+    ;
+
+
+    UserTagEnum(Integer code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    private Integer code;
+    private String desc;
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/exception/BusinessException.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/exception/BusinessException.java
new file mode 100644
index 0000000..05e8ec3
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/exception/BusinessException.java
@@ -0,0 +1,74 @@
+package com.gkhy.fourierSpecialGasMonitor.commons.exception;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+
+public class BusinessException extends RuntimeException {
+
+    private Class causeClass;
+
+    private Integer code;
+
+    private String message;
+
+//    public BusinessException(ResultCode error) {
+//        super(error.getDesc());
+//        this.code = error.getCode();
+//        this.message = error.getDesc();
+//    }
+
+    public BusinessException(Class causeClass,ResultCode error) {
+        super(error.getDesc());
+        this.causeClass = causeClass;
+        this.code = error.getCode();
+        this.message = error.getDesc();
+    }
+
+    public BusinessException(Class causeClass,ResultCode error, String message) {
+        super(error.getDesc());
+        this.causeClass = causeClass;
+        this.code = error.getCode();
+        if(message != null && !message.isEmpty()){
+            this.message = message;
+        }else {
+            this.message = error.getDesc();
+        }
+    }
+
+//    public BusinessException(Integer code, String message) {
+//        super(message);
+//        this.code = code;
+//        this.message = message;
+//    }
+
+    public BusinessException(Class causeClass,Integer code, String message) {
+        super(message);
+        this.causeClass = causeClass;
+        this.code = code;
+        this.message = message;
+    }
+
+    public Class getCauseClass() {
+        return causeClass;
+    }
+
+    public void setCauseClass(Class causeClass) {
+        this.causeClass = causeClass;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    @Override
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/exception/DataReceiveException.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/exception/DataReceiveException.java
new file mode 100644
index 0000000..3752bd6
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/exception/DataReceiveException.java
@@ -0,0 +1,74 @@
+package com.gkhy.fourierSpecialGasMonitor.commons.exception;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+
+public class DataReceiveException extends RuntimeException {
+
+    private Class causeClass;
+
+    private Integer code;
+
+    private String message;
+
+//    public BusinessException(ResultCode error) {
+//        super(error.getDesc());
+//        this.code = error.getCode();
+//        this.message = error.getDesc();
+//    }
+
+    public DataReceiveException(Class causeClass, ResultCode error) {
+        super(error.getDesc());
+        this.causeClass = causeClass;
+        this.code = error.getCode();
+        this.message = error.getDesc();
+    }
+
+    public DataReceiveException(Class causeClass, ResultCode error, String message) {
+        super(error.getDesc());
+        this.causeClass = causeClass;
+        this.code = error.getCode();
+        if(message != null && !message.isEmpty()){
+            this.message = message;
+        }else {
+            this.message = error.getDesc();
+        }
+    }
+
+//    public BusinessException(Integer code, String message) {
+//        super(message);
+//        this.code = code;
+//        this.message = message;
+//    }
+
+    public DataReceiveException(Class causeClass, Integer code, String message) {
+        super(message);
+        this.causeClass = causeClass;
+        this.code = code;
+        this.message = message;
+    }
+
+    public Class getCauseClass() {
+        return causeClass;
+    }
+
+    public void setCauseClass(Class causeClass) {
+        this.causeClass = causeClass;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    @Override
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/exception/ExceptionInfo.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/exception/ExceptionInfo.java
new file mode 100644
index 0000000..13ce213
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/exception/ExceptionInfo.java
@@ -0,0 +1,46 @@
+package com.gkhy.fourierSpecialGasMonitor.commons.exception;
+
+import java.time.LocalDateTime;
+
+public class ExceptionInfo {
+
+    private Class causeClass;
+
+    private LocalDateTime time;
+
+    private Integer code;
+
+    private String msg;
+
+    public Class getCauseClass() {
+        return causeClass;
+    }
+
+    public void setCauseClass(Class causeClass) {
+        this.causeClass = causeClass;
+    }
+
+    public LocalDateTime getTime() {
+        return time;
+    }
+
+    public void setTime(LocalDateTime time) {
+        this.time = time;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/model/PageQuery.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/model/PageQuery.java
new file mode 100644
index 0000000..fc7a737
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/model/PageQuery.java
@@ -0,0 +1,47 @@
+package com.gkhy.fourierSpecialGasMonitor.commons.model;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2022/12/26
+ * @time: 15:12
+ */
+public class PageQuery <T> {
+    private Integer  pageIndex;
+
+    private Integer  pageSize;
+
+    private T searchParams;
+
+    public Integer getPageIndex() {
+        return pageIndex;
+    }
+
+    public void setPageIndex(Integer pageIndex) {
+        if(null == pageIndex || pageIndex < 0){
+            this.pageIndex = 0;
+        }else{
+            this.pageIndex = pageIndex;
+        }
+    }
+
+    public Integer getPageSize() {
+        return pageSize;
+    }
+
+    public void setPageSize(Integer pageSize) {
+        if(null == pageSize || pageSize < 0){
+            this.pageSize = 10;
+        }else{
+            this.pageSize = pageSize;
+        }
+    }
+
+    public T getSearchParams() {
+        return searchParams;
+    }
+
+    public void setSearchParams(T searchParams) {
+        this.searchParams = searchParams;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/utils/BeanCopyUtils.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/utils/BeanCopyUtils.java
new file mode 100644
index 0000000..b7d54c9
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/utils/BeanCopyUtils.java
@@ -0,0 +1,56 @@
+package com.gkhy.fourierSpecialGasMonitor.commons.utils;
+
+import org.springframework.beans.BeanUtils;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class BeanCopyUtils {
+
+    private BeanCopyUtils() {
+    }
+
+    /**练习
+    public static Object copyBean(Object source, Class clazz) {
+        //创建目标对象
+        Object result = null;
+        try {
+            result = clazz.newInstance();
+            //实现属性copy
+            BeanUtils.copyProperties(source, result);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        //返回结果
+        return result;
+    }*/
+
+    public static <V> V copyBean(Object source,Class<V> clazz) {
+        //创建目标对象
+        V result = null;
+        try {
+            result = clazz.newInstance();
+            //实现属性copy
+            BeanUtils.copyProperties(source, result);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        //返回结果
+        return result;
+    }
+
+    /**练习
+     *  public static <V> List<V>  copyBeanList(List<Object> list, Class<V> clazz){
+            return list.stream()
+                    .map(o -> copyBean(o, clazz))
+                    .collect(Collectors.toList());
+        }*/
+
+    public static <O,V> List<V> copyBeanList(List<O> list, Class<V> clazz){
+        return list.stream()
+                .map(o -> copyBean(o, clazz))
+                .collect(Collectors.toList());
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/utils/PageUtils.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/utils/PageUtils.java
new file mode 100644
index 0000000..3a85d53
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/utils/PageUtils.java
@@ -0,0 +1,30 @@
+package com.gkhy.fourierSpecialGasMonitor.commons.utils;
+
+
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+
+public class PageUtils {
+
+
+    /**
+    * @Description: 校验pageIndex pageSize 并设置值
+    * @date 2022/6/29 11:05
+    */
+    public static void checkCheck(PageQuery page) {
+
+        if (page.getPageIndex() == null || page.getPageIndex() < 1) {
+            page.setPageIndex(1);
+        }
+
+        if (page.getPageSize() == null || page.getPageSize() < 1) {
+            page.setPageSize(10);
+        }
+
+        // pageSize 不能大于500
+        if (page.getPageSize() > 500) {
+            page.setPageSize(500);
+        }
+
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/utils/SpringUtils.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/utils/SpringUtils.java
new file mode 100644
index 0000000..5f1e965
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/commons/utils/SpringUtils.java
@@ -0,0 +1,17 @@
+package com.gkhy.fourierSpecialGasMonitor.commons.utils;
+
+import org.springframework.context.ApplicationContext;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/7
+ * @time: 14:31
+ */
+public class SpringUtils {
+    public static ApplicationContext applicationContext;
+
+    public void setApplicationContext(ApplicationContext context){
+        applicationContext = context;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/MyWebMvcConfigurerAdapter.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/MyWebMvcConfigurerAdapter.java
new file mode 100644
index 0000000..24c12cc
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/MyWebMvcConfigurerAdapter.java
@@ -0,0 +1,26 @@
+package com.gkhy.fourierSpecialGasMonitor.config.authorization;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/8
+ * @time: 10:45
+ */
+@Configuration
+public class MyWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
+    /**
+     * 配置静态访问资源
+     * @param registry
+     */
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {
+        registry.addResourceHandler("/uploadtest/**").addResourceLocations("file:E:\\file\\fourier\\test\\");
+        //registry.addResourceHandler("/upload/**").addResourceLocations("file:/home/upload/laboratoryRiskManage/");
+        registry.addResourceHandler("/upload/**").addResourceLocations("file:/home/gkhy/upload/fourier/");
+        super.addResourceHandlers(registry);
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/TokenAuthenticationFilter.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/TokenAuthenticationFilter.java
new file mode 100644
index 0000000..3982acb
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/TokenAuthenticationFilter.java
@@ -0,0 +1,148 @@
+package com.gkhy.fourierSpecialGasMonitor.config.authorization;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.ContextUserDto;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.TokenInfoDto;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.UserInfoAppRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.service.AccountAppService;
+import com.gkhy.fourierSpecialGasMonitor.application.account.service.TokenAppService;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import org.redisson.api.RMapCache;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import javax.annotation.Resource;
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+* @Description: token登录过滤器
+*/
+@Component
+public class TokenAuthenticationFilter extends OncePerRequestFilter  {
+
+    @Resource
+    private TokenConfig tokenConfig;
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+    @Autowired
+    private AccountAppService accountAppService;
+
+    @Autowired
+    private TokenAppService tokenService;
+
+
+
+    @Override
+    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse resp, FilterChain chain) throws IOException, ServletException {
+
+        try {
+            //获取当前认证成功用户权限信息
+            UsernamePasswordAuthenticationToken authRequest = getAuthentication(req, resp);
+            if (authRequest != null) {
+                SecurityContextHolder.getContext().setAuthentication(authRequest);
+            }
+            // 执行下一个 filter 过滤器链
+            chain.doFilter(req, resp);
+        } catch (BusinessException e) {
+            // 返回异常
+            this.writeJSON(req, resp, new Result<>(e.getCode(),e.getMessage()));
+        }
+
+    }
+
+
+    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest req,HttpServletResponse resp) {
+        // header获取token
+        String authToken = req.getHeader(tokenConfig.getHeader());
+        String loginUserId = req.getHeader(tokenConfig.getLoginUserHeader());
+
+        RMapCache<String,Object> tokenCacheMap = null;
+
+        //外部接口只能携带专门token访问特定的几个接口
+        if (req.getRequestURI().startsWith("/api")){
+            if (tokenConfig.getExternalAccessKey().equals(req.getHeader(tokenConfig.getExternalAccessHeader()))){
+                return new UsernamePasswordAuthenticationToken(null,null,null);
+            }
+            throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_PERMISSION_DENIALED);
+        }
+
+        if(authToken != null) {
+            // header 传入 userId
+            if (loginUserId == null || loginUserId.isEmpty()) {
+                throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL);
+            }
+            // 登录成功时,会将权限数据存入redis
+            // 这里是验证获取权限信息
+            // 1.从redis中获取对应该用户的权限信息
+            Long userId = Long.parseLong(loginUserId);
+            Result<TokenInfoDto> getTokenInfoResult = tokenService.getToken(userId);
+            TokenInfoDto tokenInfoDto = null;
+            if(getTokenInfoResult.isSuccess()){
+                tokenInfoDto = (TokenInfoDto) getTokenInfoResult.getData();
+                if(tokenInfoDto == null || tokenInfoDto.getTk() == null || !tokenInfoDto.getTk().equals(authToken)){
+                    throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_PERMISSION_DENIALED);
+                }
+            }else {
+                throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_PERMISSION_DENIALED);
+            }
+
+            SearchResult<UserInfoAppRespDTO> userResult = accountAppService.findUserByUserId(userId);
+            if(!userResult.isSuccess() || userResult.getData() == null){
+                throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_ACCOUNT_NOT_EXIST);
+            }
+            UserInfoAppRespDTO user = (UserInfoAppRespDTO) userResult.getData();
+            ContextUserDto contextUserDto = new ContextUserDto();
+            BeanUtils.copyProperties(user,contextUserDto);
+
+            //获取授权信息
+            //todo
+            List<GrantedAuthority> authorities = new ArrayList<>();
+
+            //token续期,提前60分钟
+            Long tokenRemainTimeToLive = tokenInfoDto.getRemainSecond();
+            if(tokenRemainTimeToLive/60 <= 60){
+                tokenService.resetTokenTime(userId);
+            }
+            // security对象中存入登陆者信息
+            return new UsernamePasswordAuthenticationToken(contextUserDto,authToken,authorities);
+        }
+        return null;
+    }
+
+
+
+    protected void writeJSON(HttpServletRequest req,
+                             HttpServletResponse resp,
+                             Result result) throws IOException {
+        // 设置编码格式
+        resp.setContentType("text/json;charset=utf-8");
+        // 处理跨域问题
+        resp.setHeader("Access-Control-Allow-Origin", "*");
+        resp.setHeader("Access-Control-Allow-Methods", "POST, GET");
+
+        //输出JSON
+        PrintWriter out = resp.getWriter();
+        ObjectMapper om = new ObjectMapper();
+        out.write(om.writeValueAsString(result));
+        out.flush();
+        out.close();
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/TokenCheckWhiteListEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/TokenCheckWhiteListEnum.java
new file mode 100644
index 0000000..de89ad3
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/TokenCheckWhiteListEnum.java
@@ -0,0 +1,79 @@
+package com.gkhy.fourierSpecialGasMonitor.config.authorization;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Token校验白名单
+ */
+public enum TokenCheckWhiteListEnum {
+    PATH_LOGIN("/account/auth/login","登录接口",true),
+    PATH_FORGET_PASSWORD("/account/auth/pwd/forget/reset","忘记密码重置密码接口",true),
+    PATH_LICENSE("/sys/lic/**","授权证书查看",true),
+    PATH_ACCOUNT_AUTH("/account/auth/**","用户认证",true),
+    /*PATH_TEST_ACCOUNT("/account/user/**","账号测试接口",true),
+    //basic部分测试接口
+    PATH_TEST_BASIC("/basic/**","账号测试接口",true),
+    //risk部分测试接口
+    PATH_TEST_RISK("/risk/**","账号测试接口",true),
+    //实验部分测试接口
+    PATH_EXPERIMENT_INFO("/experimentInfo/**","实验测试接口",true),
+    //部门测试
+    PATH_DEPARTMENT("/account/department/**","部门测试接口",true),
+    PATH_ACCOUNT_ROLE("/account/role/**","用户认证",true),
+    PATH_ATTACHMENT("/attachment/**","文件上传",true),
+    PATH_ATTACHMENT_WINDOWN_VEIW("/uploadtest/**","文件上传",true),
+    PATH_ATTACHMENT_LINUX_VEIW("/upload/**","文件上传",true),*/
+    ;
+
+
+    private String path;
+
+    private String desc;
+
+    private Boolean enable;
+
+    TokenCheckWhiteListEnum(String path, String desc, Boolean enable) {
+        this.path = path;
+        this.desc = desc;
+        this.enable = enable;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+
+    public Boolean getEnable() {
+        return enable;
+    }
+
+    public void setEnable(Boolean enable) {
+        this.enable = enable;
+    }
+
+    public static String[] getWhitePathArray(){
+        List<String> list = new ArrayList<>();
+        for(TokenCheckWhiteListEnum e : TokenCheckWhiteListEnum.values()){
+            if(e.enable == true){
+                list.add(e.getPath());
+            }
+        }
+        if(list.isEmpty())
+            return null;
+        String[] pathArray = new String[0];
+        pathArray = list.toArray(pathArray);
+        return pathArray;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/TokenConfig.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/TokenConfig.java
new file mode 100644
index 0000000..47aecdb
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/TokenConfig.java
@@ -0,0 +1,69 @@
+package com.gkhy.fourierSpecialGasMonitor.config.authorization;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+
+/**
+* @Description: jwt工具类
+* @date 2022/6/14 10:34
+*/
+@Component
+@ConfigurationProperties(prefix = "system.token")
+public class TokenConfig {
+
+    private Long expiration;
+    private Long refreshExpiration;
+    private String header;
+    private String loginUserHeader;
+    private String externalAccessHeader;
+    private String externalAccessKey;
+
+    public String getExternalAccessHeader() {
+        return externalAccessHeader;
+    }
+
+    public void setExternalAccessHeader(String externalAccessHeader) {
+        this.externalAccessHeader = externalAccessHeader;
+    }
+
+    public String getExternalAccessKey() {
+        return externalAccessKey;
+    }
+
+    public void setExternalAccessKey(String externalAccessKey) {
+        this.externalAccessKey = externalAccessKey;
+    }
+
+    public Long getExpiration() {
+        return expiration;
+    }
+
+    public void setExpiration(Long expiration) {
+        this.expiration = expiration;
+    }
+
+    public Long getRefreshExpiration() {
+        return refreshExpiration;
+    }
+
+    public void setRefreshExpiration(Long refreshExpiration) {
+        this.refreshExpiration = refreshExpiration;
+    }
+
+    public String getHeader() {
+        return header;
+    }
+
+    public void setHeader(String header) {
+        this.header = header;
+    }
+
+    public String getLoginUserHeader() {
+        return loginUserHeader;
+    }
+
+    public void setLoginUserHeader(String loginUserHeader) {
+        this.loginUserHeader = loginUserHeader;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/WebMvcConfig.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/WebMvcConfig.java
new file mode 100644
index 0000000..015f9f8
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/WebMvcConfig.java
@@ -0,0 +1,20 @@
+package com.gkhy.fourierSpecialGasMonitor.config.authorization;
+
+import com.gkhy.fourierSpecialGasMonitor.config.interceptor.TokenInterceptor;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/7/11 13:46
+ */
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer {
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        registry.addInterceptor(new TokenInterceptor()).addPathPatterns("/**");
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/WebSecurityConfig.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/WebSecurityConfig.java
new file mode 100644
index 0000000..0d46ebf
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/authorization/WebSecurityConfig.java
@@ -0,0 +1,76 @@
+package com.gkhy.fourierSpecialGasMonitor.config.authorization;
+
+import com.gkhy.fourierSpecialGasMonitor.infra.cache.domain.CacheUserInfo;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+
+import javax.annotation.Resource;
+
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+
+    @Resource
+    private TokenAuthenticationFilter tokenAuthenticationFilter;
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        // 关闭跨域攻击
+        http.csrf().disable();
+        // 关闭session
+        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
+        // 登录json放行 | websocket | 普通人员密码自行修改
+//        http.authorizeRequests().antMatchers("/auth/login", "/ws/test/**", "/account/pwd/forget","/sys/lic/**").permitAll();
+
+        //从白名单里面获取放行的接口
+        http.authorizeRequests().antMatchers(TokenCheckWhiteListEnum.getWhitePathArray()).permitAll();
+
+        // 关闭
+        http.headers().cacheControl();
+        // token过滤器
+        http.addFilterBefore(tokenAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
+        // 请求认证访问
+        http.authorizeRequests().anyRequest().authenticated();
+        // 允许跨域访问
+        http.cors();
+
+    }
+
+
+
+
+
+    /**
+    * @Description: 自定义查询逻辑 & 密码处理器
+    */
+    @Override
+    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+        auth.userDetailsService(userDetailsService());
+    }
+
+    /**
+    * @Description: 自定义查询逻辑
+    */
+    @Bean
+    @Qualifier("myUserDetailService")
+    protected UserDetailsService userDetailsService(){
+        return (username)-> new CacheUserInfo();
+    }
+
+
+    @Override
+    public void configure(WebSecurity web) {
+        web.ignoring().mvcMatchers();
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/cache/RedisConfig.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/cache/RedisConfig.java
new file mode 100644
index 0000000..0310aa0
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/cache/RedisConfig.java
@@ -0,0 +1,36 @@
+package com.gkhy.fourierSpecialGasMonitor.config.cache;
+
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+@Configuration
+@AutoConfigureAfter(RedisAutoConfiguration.class)
+public class RedisConfig {
+
+    @Bean
+    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory connectionFactory){
+        RedisTemplate<String,Object> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+        // json序列化对象
+        GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
+        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
+        // key=>string
+        template.setKeySerializer(stringRedisSerializer);
+        // hash=>string
+        template.setHashKeySerializer(stringRedisSerializer);
+        // value=>json
+        template.setValueSerializer(jackson2JsonRedisSerializer);
+        // hashValue=>json
+        template.setHashValueSerializer(jackson2JsonRedisSerializer);
+        // set
+        template.afterPropertiesSet();
+        return template;
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/cache/RedisUtils.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/cache/RedisUtils.java
new file mode 100644
index 0000000..5d62cd9
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/cache/RedisUtils.java
@@ -0,0 +1,261 @@
+package com.gkhy.fourierSpecialGasMonitor.config.cache;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.redis.connection.RedisClusterConnection;
+import org.springframework.data.redis.connection.RedisClusterNode;
+import org.springframework.data.redis.connection.RedisConnection;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.connection.jedis.JedisClusterConnection;
+import org.springframework.data.redis.connection.jedis.JedisConnection;
+import org.springframework.data.redis.core.*;
+import org.springframework.stereotype.Repository;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+* @Description: redis工具类
+*/
+
+@Repository("configRedisRepository")
+@SuppressWarnings(value = { "unchecked", "rawtypes" })
+public class RedisUtils {
+
+
+    @Resource
+    private RedisTemplate redisTemplate;
+    /**
+     * logger
+     */
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+
+    @PostConstruct
+    public void initRepository(){
+        try {
+            this.set("test:module:Web", "testConnection", 60L, TimeUnit.SECONDS);
+            logger.info("[ModuleRedis][Web] is connected");
+        } catch (Exception e) {
+            logger.error("[ModuleRedis][Web] connected failed!!");
+        }
+    }
+
+    /**
+     * 写入缓存
+     * @param key
+     * @param value
+     * @return
+     */
+    public boolean set(final String key, Object value) {
+        boolean result = false;
+        try {
+            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
+            operations.set(key, value);
+            result = true;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+    /**
+     * 写入缓存设置时效时间
+     * @param key
+     * @param value
+     * @return
+     */
+    public boolean set(final String key, Object value, Long expireTime ,TimeUnit timeUnit) {
+        boolean result = false;
+        try {
+            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
+            operations.set(key, value);
+            redisTemplate.expire(key, expireTime, timeUnit);
+            result = true;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+    /**
+     * 批量删除对应的value
+     * @param keys
+     */
+    public void remove(final String... keys) {
+        for (String key : keys) {
+            remove(key);
+        }
+    }
+    /**
+     * 批量删除key
+     * @param pattern
+     */
+    public void removePattern(final String pattern) {
+        Set<Serializable> keys = redisTemplate.keys(pattern);
+        if (keys.size() > 0){
+            redisTemplate.delete(keys);
+        }
+    }
+    /**
+     * 删除对应的value
+     * @param key
+     */
+    public void remove(final String key) {
+        if (exists(key)) {
+            redisTemplate.delete(key);
+        }
+    }
+    /**
+     * 判断缓存中是否有对应的value
+     * @param key
+     * @return
+     */
+    public boolean exists(final String key) {
+        return redisTemplate.hasKey(key);
+    }
+    /**
+     * 读取缓存
+     * @param key
+     * @return
+     */
+    public Object get(final String key) {
+        Object result = null;
+        ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
+        result = operations.get(key);
+        return result;
+    }
+    /**
+     * 哈希 添加
+     * @param key
+     * @param hashKey
+     * @param value
+     */
+    public void hmSet(String key, Object hashKey, Object value){
+        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
+        hash.put(key,hashKey,value);
+    }
+    /**
+     * 哈希获取数据
+     * @param key
+     * @param hashKey
+     * @return
+     */
+    public Object hmGet(String key, Object hashKey){
+        HashOperations<String, Object, Object>  hash = redisTemplate.opsForHash();
+        return hash.get(key,hashKey);
+    }
+    /**
+     * 列表添加
+     * @param k
+     * @param v
+     */
+    public void lPush(String k,Object v){
+        ListOperations<String, Object> list = redisTemplate.opsForList();
+        list.rightPush(k,v);
+    }
+    /**
+     * 列表获取
+     * @param k
+     * @param l
+     * @param l1
+     * @return
+     */
+    public List<Object> lRange(String k, long l, long l1){
+        ListOperations<String, Object> list = redisTemplate.opsForList();
+        return list.range(k,l,l1);
+    }
+    /**
+     * 集合添加
+     * @param key
+     * @param value
+     */
+    public void add(String key,Object value){
+        SetOperations<String, Object> set = redisTemplate.opsForSet();
+        set.add(key,value);
+    }
+    /**
+     * 集合获取
+     * @param key
+     * @return
+     */
+    public Set<Object> setMembers(String key){
+        SetOperations<String, Object> set = redisTemplate.opsForSet();
+        return set.members(key);
+    }
+    /**
+     * 有序集合添加
+     * @param key
+     * @param value
+     * @param scoure
+     */
+    public void zAdd(String key,Object value,double scoure){
+        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
+        zset.add(key,value,scoure);
+    }
+    /**
+     * 有序集合获取
+     * @param key
+     * @param scoure
+     * @param scoure1
+     * @return
+     */
+    public Set<Object> rangeByScore(String key,double scoure,double scoure1){
+        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
+        return zset.rangeByScore(key, scoure, scoure1);
+    }
+
+    /**
+    * @Description: 获取过期时间 返回 秒
+    */
+
+    public Long getExpireTime(String key) {
+        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
+    }
+
+
+    /**
+     * @Description: 重置key 的 过期时间
+     */
+    public void resetKeyExpireTime(String key, Long seconds) {
+        redisTemplate.expire(key, seconds, TimeUnit.SECONDS);
+    }
+
+    public  Set<String> scanMatch(String matchKey) {
+    Set<String> keys = new HashSet();
+    RedisConnectionFactory connectionFactory = redisTemplate.getConnectionFactory();
+    RedisConnection redisConnection = connectionFactory.getConnection();
+    Cursor<byte[]> scan = null;
+        if(redisConnection instanceof JedisClusterConnection){
+        RedisClusterConnection clusterConnection = connectionFactory.getClusterConnection();
+        Iterable<RedisClusterNode> redisClusterNodes = clusterConnection.clusterGetNodes();
+        Iterator<RedisClusterNode> iterator = redisClusterNodes.iterator();
+        while (iterator.hasNext()) {
+            RedisClusterNode next = iterator.next();
+            scan = clusterConnection.scan(next, ScanOptions.scanOptions().match(matchKey).count(Integer.MAX_VALUE).build());
+            while (scan.hasNext()) {
+                keys.add(new String(scan.next()));
+            }
+            scan.close();
+        }
+        return keys;
+    }
+        if(redisConnection instanceof JedisConnection){
+        scan = redisConnection.scan(ScanOptions.scanOptions().match(matchKey).count(Integer.MAX_VALUE).build());
+        while (scan.hasNext()){
+            //找到一次就添加一次
+            keys.add(new String(scan.next()));
+        }
+            scan.close();
+            return keys;
+    }
+
+        return keys;
+}
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/cors/CorsConfig.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/cors/CorsConfig.java
new file mode 100644
index 0000000..6895200
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/cors/CorsConfig.java
@@ -0,0 +1,39 @@
+package com.gkhy.fourierSpecialGasMonitor.config.cors;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+
+@Configuration
+public class CorsConfig {
+
+    @Value("${system.enableCors}")
+    private Boolean enableCors;
+
+    private CorsConfiguration buildConfig() {
+        CorsConfiguration corsConfiguration = new CorsConfiguration();
+        //  你需要跨域的地址  注意这里的 127.0.0.1 != localhost
+        // * 表示对所有的地址都可以访问
+        corsConfiguration.addAllowedOriginPattern("*");  // 1
+        //  跨域的请求方法
+        corsConfiguration.addAllowedMethod("*"); // 3
+        //  跨域的请求头
+        corsConfiguration.addAllowedHeader("*"); // 2
+        //加上了这一句,大致意思是可以携带 cookie
+        //最终的结果是可以 在跨域请求的时候获取同一个 session
+        corsConfiguration.setAllowCredentials(true);
+        return corsConfiguration;
+    }
+    @Bean
+    public CorsFilter corsFilter() {
+        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+        //配置 可以访问的地址
+        if(enableCors == true)
+            source.registerCorsConfiguration("/**", buildConfig());
+        return new CorsFilter(source);
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/exception/GlobalExceptionHandler.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/exception/GlobalExceptionHandler.java
new file mode 100644
index 0000000..cb55785
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/exception/GlobalExceptionHandler.java
@@ -0,0 +1,163 @@
+package com.gkhy.fourierSpecialGasMonitor.config.exception;
+
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.ForeignResult;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.DataReceiveException;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.ExceptionInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+@ControllerAdvice
+public class GlobalExceptionHandler {
+
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+    @Autowired
+    private ObjectMapper objectMapper;
+
+    /**
+     * 通用异常
+     */
+    @ResponseBody
+    @ExceptionHandler(value = BusinessException.class)
+    public Result businessExceptionHandler(BusinessException e) throws JsonProcessingException {
+        ExceptionInfo exceptionInfo = new ExceptionInfo();
+        exceptionInfo.setTime(LocalDateTime.now());
+        exceptionInfo.setCode(e.getCode());
+        exceptionInfo.setMsg(e.getMessage());
+        exceptionInfo.setCauseClass(e.getCauseClass());
+        logger.error(objectMapper.writeValueAsString(exceptionInfo));
+        Result result = new Result();
+        result.setCode(e.getCode());
+        if(e.getMessage() == null || e.getMessage().isEmpty()){
+            ResultCode code = ResultCode.prase(e.getCode());
+            if(code != null)
+                result.setMsg(code.getDesc());
+        }else {
+            result.setMsg(e.getMessage());
+        }
+        return result;
+    }
+
+    /**
+     * 通用异常
+     */
+    @ResponseBody
+    @ExceptionHandler(value = DataReceiveException.class)
+    public ForeignResult dataReceiveExceptionHandler(DataReceiveException e) throws JsonProcessingException {
+        ExceptionInfo exceptionInfo = new ExceptionInfo();
+        LocalDateTime now = LocalDateTime.now();
+        exceptionInfo.setTime(now);
+        exceptionInfo.setCode(e.getCode());
+        exceptionInfo.setMsg(e.getMessage());
+        exceptionInfo.setCauseClass(e.getCauseClass());
+        logger.error(objectMapper.writeValueAsString(exceptionInfo));
+        ForeignResult result = new ForeignResult<>();
+        result.setCode(e.getCode());
+        result.setTime(now.format(formatter));
+        if(e.getMessage() == null || e.getMessage().isEmpty()){
+            ResultCode code = ResultCode.prase(e.getCode());
+            if(code != null)
+                result.setData(code.getDesc());
+        }else {
+            result.setData(e.getMessage());
+        }
+        return result;
+    }
+
+
+    /**
+    * @Description: AuthenticationException
+    */
+
+    @ResponseBody
+    @ExceptionHandler(value = AuthenticationException.class)
+    public Result CHandler(AuthenticationException e) {
+        logger.warn(e.getMessage());
+        return new Result(ResultCode.BUSINESS_ERROR_PERMISSION_DENIALED);
+    }
+
+
+    /**
+     * @Description: AuthenticationException
+     */
+
+    @ResponseBody
+    @ExceptionHandler(value = AccessDeniedException.class)
+    public Result DHandler(AccessDeniedException e) {
+        logger.warn(e.getMessage());
+        return new Result(ResultCode.BUSINESS_ERROR_PERMISSION_DENIALED);
+
+    }
+
+    /**
+    * @Description: 请求方法
+    */
+    @ResponseBody
+    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
+    public Result DHandler(HttpRequestMethodNotSupportedException e) {
+        Result resultVO = new Result();
+        resultVO.setCode(ResultCode.BUSINESS_ERROR_HTTP_METHOD_NOT_SUPPORT.getCode());
+        resultVO.setMsg(e.getMessage());
+        return resultVO;
+    }
+
+
+    /**
+    * @Description: @RequestBody 请求体解析问题
+    */
+    @ResponseBody
+    @ExceptionHandler(value = HttpMessageNotReadableException.class)
+    public Result DHandler(HttpMessageNotReadableException e) {
+        Result resultVO = new Result();
+        resultVO.setCode(ResultCode.PARAM_ERROR_ILLEGAL.getCode());
+        resultVO.setMsg(e.getMessage());
+        return resultVO;
+
+    }
+
+
+
+    @ResponseBody
+    @ExceptionHandler(value = Exception.class)
+    public Result errorHandler(Exception e) {
+        e.printStackTrace();
+        logger.error(e.getMessage());
+        Result resultVO = new Result();
+        resultVO.setCode(ResultCode.SYSTEM_ERROR.getCode());
+        return resultVO;
+//        return new ResultVO(ResultCodes.SERVER_ERROR);
+    }
+
+    /**
+     * 处理入参异常
+     * @param e
+     * @return
+     */
+    @ResponseBody
+    @ExceptionHandler(MethodArgumentNotValidException.class)
+    public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException e){
+        logger.warn(e.getBindingResult().getFieldError().getDefaultMessage());
+        return new Result(ResultCode.PARAM_ERROR,
+                e.getBindingResult().getFieldError().getDefaultMessage());
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/file/FilePathConfig.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/file/FilePathConfig.java
new file mode 100644
index 0000000..f491c3e
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/file/FilePathConfig.java
@@ -0,0 +1,32 @@
+package com.gkhy.fourierSpecialGasMonitor.config.file;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * @author :Li9527
+ * @date :Created in 2019-09-02 9:57
+ * @description:${description}
+ * @modified By:
+ * @version: 1.0.0
+ */
+@Component
+@Data
+@ConfigurationProperties(prefix = "file.path")
+public class FilePathConfig {
+    /**
+     * 文件保存根路径
+     */
+    private String dcPath;
+    /**
+     * 访问跟路径
+     */
+    private String urlRootPath;
+    /**
+     * 模块路径
+     */
+    private Map<String,String> module;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/file/InitConfig.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/file/InitConfig.java
new file mode 100644
index 0000000..734319c
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/file/InitConfig.java
@@ -0,0 +1,40 @@
+
+package com.gkhy.fourierSpecialGasMonitor.config.file;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.InitializingBean;
+
+import javax.annotation.Resource;
+import java.lang.reflect.Field;
+
+/**
+ * @author :Li9527
+ * @date :Created in 2019-04-01 17:17
+ * @description:项目启动就执行的工具类
+ * @modified By:
+ * @version: 1.0
+ */
+@Slf4j
+//@Component
+public class InitConfig implements InitializingBean {
+
+    @Resource
+    FilePathConfig filePathConfig;
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        log.info("文件配置路径开始加载");
+        reflect(filePathConfig);
+        log.info("设置模块文件路径缓存");
+    }
+
+    public static void reflect(Object o) throws IllegalAccessException {
+        Class cls = o.getClass();
+        Field[] fields = cls.getDeclaredFields();
+        for (int i = 0; i < fields.length; i++) {
+            Field f = fields[i];
+            f.setAccessible(true);
+            log.info(f.getName() + "----:" + f.get(o));
+        }
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/file/ReportFilePathConfig.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/file/ReportFilePathConfig.java
new file mode 100644
index 0000000..38d14dc
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/file/ReportFilePathConfig.java
@@ -0,0 +1,22 @@
+package com.gkhy.fourierSpecialGasMonitor.config.file;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+
+@Component
+@Data
+@ConfigurationProperties(prefix = "reportfile.path")
+public class ReportFilePathConfig {
+    /**
+     * 文件保存根路径
+     */
+    private String dcPath;
+    /**
+     * 访问跟路径
+     */
+    private String urlRootPath;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/interceptor/TokenInterceptor.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/interceptor/TokenInterceptor.java
new file mode 100644
index 0000000..b24b6d2
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/interceptor/TokenInterceptor.java
@@ -0,0 +1,33 @@
+package com.gkhy.fourierSpecialGasMonitor.config.interceptor;
+
+
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.User;
+import com.gkhy.fourierSpecialGasMonitor.utils.ThreadLocalUtil;
+import io.micrometer.core.instrument.util.StringUtils;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/7/4 16:20
+ */
+public class TokenInterceptor implements HandlerInterceptor {
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        String id = request.getHeader("uid");
+        if (!StringUtils.isBlank(id)){
+            User user = new User();
+            user.setId(Long.valueOf(id));
+            ThreadLocalUtil.set(user);
+        }
+        return true;
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
+        ThreadLocalUtil.clear();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/CompanyLicenseDataCache.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/CompanyLicenseDataCache.java
new file mode 100644
index 0000000..4241b5a
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/CompanyLicenseDataCache.java
@@ -0,0 +1,403 @@
+package com.gkhy.fourierSpecialGasMonitor.config.license;
+
+import cn.hutool.crypto.asymmetric.KeyType;
+import cn.hutool.crypto.asymmetric.RSA;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.SystemCacheKeyEnum;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.SystemConfigKeyEnum;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.entity.SysConfig;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.repository.jpa.SysConfigRepository;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.StandardCharsets;
+import java.security.*;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Base64;
+import java.util.Optional;
+
+public class CompanyLicenseDataCache {
+
+    @Autowired
+    private SysConfigRepository sysConfigRepository;
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+    //授权信息
+    private LicenseInfo licenseInfo;
+
+    //部署模式
+    private String deployMode;
+
+    public CompanyLicenseDataCache(String deployMode) {
+        this.deployMode = deployMode;
+        initLicenseInfo(this.deployMode);
+    }
+
+    private void initLicenseInfo(String deployMode){
+        //初始化授权信息,系统启动时执行
+
+    }
+
+    /**
+     * 获取授权证书信息
+     * @return
+     */
+    public LicenseInfo getLicenseInfo(){
+        if(deployMode != null && deployMode.equals("standalone")){
+            //单机模式
+            return getLocalLicenseInfo();
+        }else if(deployMode != null && deployMode.equals("cluster")){
+            //集群模式
+            return getClusterLicenseInfo();
+        }else {
+            //配置错误
+            return null;
+        }
+    }
+
+    /**
+     * 单机部署,获取本地授权信息
+     * @return
+     */
+    private LicenseInfo getLocalLicenseInfo() {
+        //已经存在授权信息,直接返回
+        if(licenseInfo != null){
+            return licenseInfo;
+        }
+        //本地不存在授权信息,从数据库读取证书数据
+        Optional<SysConfig> sysConfigOptional = sysConfigRepository.findById(SystemConfigKeyEnum.LICENSE_TXT.getKey());
+        if(!sysConfigOptional.isPresent() || sysConfigOptional.get().getSysValue().isEmpty()){
+            //数据库没有证书信息,返回无效授权
+            licenseInfo = genEmptyLicense();
+        } else{
+            //解码证书文本,获取授权信息
+            String licenseTxt = sysConfigOptional.get().getSysValue();
+            LicenseInfo lic = decodeLicenseData(licenseTxt);
+            if(lic != null){
+                licenseInfo = lic;
+            }else {
+                licenseInfo = genEmptyLicense();
+            }
+        }
+        return licenseInfo;
+    }
+
+    /**
+     * 集群部署,获取redis授权信息
+     * @return
+     */
+    private LicenseInfo getClusterLicenseInfo() {
+        //已经存在授权信息,直接返回
+        if(licenseInfo != null){
+            return licenseInfo;
+        }
+        //本地不存在授权信息,从数据库读取证书数据
+        Optional<SysConfig> sysConfigOptional = sysConfigRepository.findById(SystemConfigKeyEnum.LICENSE_TXT.getKey());
+        if(!sysConfigOptional.isPresent() || sysConfigOptional.get().getSysValue().isEmpty()){
+            //数据库没有证书信息,返回无效授权
+            licenseInfo = genEmptyLicense();
+        } else{
+            //解码证书文本,获取授权信息
+            String licenseTxt = sysConfigOptional.get().getSysValue();
+            LicenseInfo lic = decodeLicenseData(licenseTxt);
+            if(lic != null){
+                licenseInfo = lic;
+                //将授权信息同步到redis
+                if(updateRedisLicenseInfo(lic).isSuccess()){
+
+                }else {
+                    //todo:更新redis缓存失败
+                }
+            }else {
+                licenseInfo = genEmptyLicense();
+            }
+        }
+        return licenseInfo;
+    }
+
+    /**
+     * 更新授权信息
+     * @param licenseTxt
+     * @return
+     */
+    public Result updateLicense(String licenseTxt){
+        Result result = new Result<>();
+        if(licenseTxt == null || licenseTxt.isEmpty()){
+            result.setCode(ResultCode.PARAM_ERROR_NULL.getCode());
+            result.setMsg("license为空");
+            return result;
+        }
+        LicenseInfo licInfo = decodeLicenseData(licenseTxt);
+        if(licInfo == null){
+            result.setCode(ResultCode.BUSINESS_ERROR.getCode());
+            result.setMsg("license错误");
+            return result;
+        }
+        //1、先更新redis缓存
+        if(updateRedisLicenseInfo(licInfo).isSuccess()){
+            //2、再更新本地缓存
+            licenseInfo = licInfo;
+            result.execSuccess();
+        }else {
+            result.setCode(ResultCode.SYSTEM_ERROR.getCode());
+            result.setMsg("更新redis缓存的license出错");
+        }
+        return result;
+    }
+
+    /**
+     * 更新redis缓存的license
+     * @param licenseInfo
+     * @return
+     */
+    private Result updateRedisLicenseInfo(LicenseInfo licenseInfo){
+        Result result = new Result<>();
+        if(redissonClient == null)
+            throw new RuntimeException("redis客户端异常");
+        ObjectMapper om = new ObjectMapper();
+        try {
+            String licenseJson = om.writeValueAsString(licenseInfo);
+            redissonClient.getMap(SystemCacheKeyEnum.KEY_SYSTEM_PROP.getKey()).put(SystemCacheKeyEnum.KEY_SYSTEM_LICENSE_INFO.getKey(),licenseJson);
+            result.setCode(ResultCode.OK.getCode());
+        } catch (JsonProcessingException e) {
+            result.setCode(ResultCode.SYSTEM_ERROR.getCode());
+            result.setMsg("license序列化为JSON出错");
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+    /**
+     * 创建无效授权信息
+     * @return
+     */
+    private LicenseInfo genEmptyLicense(){
+        LicenseInfo empty = new LicenseInfo();
+        empty.setLicenseType(LicenseTypeEnum.INVALID.getType());
+        empty.setCompanyName(null);
+        empty.setBeginTime(null);
+        empty.setEndTime(null);
+        return empty;
+    }
+
+    private LicenseInfo decodeLicenseDataRsa(String licenseTxt){
+        LicenseInfo licenseInfo = null;
+        if(licenseTxt == null || licenseTxt.isEmpty())
+            return null;
+        String aesTxt = null;
+        byte[] aesTxtBytes = Base64.getDecoder().decode(licenseTxt.getBytes(StandardCharsets.UTF_8));
+        try {
+            aesTxt = String.valueOf(Base64.getDecoder().decode(licenseTxt.getBytes(StandardCharsets.UTF_8)));
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+        if(aesTxt == null || aesTxt.isEmpty())
+            return null;
+        if(aesTxtBytes == null || aesTxtBytes.length == 0)
+            return null;
+        //解析本地KEY
+
+        //todo
+        return null;
+
+    }
+
+    /**
+     * 解码license数据
+     * @param licenseTxt
+     * @return
+     */
+    private LicenseInfo decodeLicenseData(String licenseTxt){
+        LicenseInfo licenseInfo = null;
+        if(licenseTxt == null || licenseTxt.isEmpty())
+            return null;
+        String aesTxt = null;
+        byte[] aesTxtBytes = Base64.getDecoder().decode(licenseTxt.getBytes(StandardCharsets.UTF_8));
+        try {
+            aesTxt = String.valueOf(Base64.getDecoder().decode(licenseTxt.getBytes(StandardCharsets.UTF_8)));
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+        if(aesTxt == null || aesTxt.isEmpty())
+            return null;
+        if(aesTxtBytes == null || aesTxtBytes.length == 0)
+            return null;
+        //解析本地KEY
+        LicenseKCon sysKey = getSysKey();
+        if(sysKey == null)
+            return null;
+        //获取用户私有key
+//        LicenseKCon userPrivateKey = getUserPrivateKey(sysKey);
+        LicenseKCon userPrivateKey = getUserPrivateKeyRSA();
+        if(userPrivateKey == null)
+            return null;
+        //使用私有key解密license
+        try {
+            Cipher cipher =  Cipher.getInstance("AES/CBC/PKCS5Padding");
+            cipher.init(Cipher.DECRYPT_MODE,new SecretKeySpec(userPrivateKey.getKey().getBytes(),"AES"),
+                    new IvParameterSpec(userPrivateKey.getIv().getBytes()));
+            byte[] rsBytes = cipher.doFinal(aesTxtBytes);
+            String jsonStr = new String(rsBytes,StandardCharsets.UTF_8);
+//            System.out.println("解密后明文:\n"+jsonStr);
+            ObjectMapper om = new ObjectMapper();
+            om.registerModule(new JavaTimeModule());
+            licenseInfo = om.readValue(jsonStr,LicenseInfo.class);
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        } catch (NoSuchPaddingException e) {
+            e.printStackTrace();
+        } catch (InvalidKeyException e) {
+            e.printStackTrace();
+        } catch (InvalidAlgorithmParameterException e) {
+            e.printStackTrace();
+        } catch (IllegalBlockSizeException e) {
+            e.printStackTrace();
+        } catch (BadPaddingException e) {
+            e.printStackTrace();
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+        return licenseInfo;
+    }
+
+    /**
+     * 获取系统KEY
+     * @return
+     */
+    private LicenseKCon getSysKey(){
+        //解析本地KEY
+        String key = null;
+        String iv = null;
+
+        String sysKeyStr = new String(Base64.getDecoder().decode(LicenseDataCon.getCon().getPi().getBytes(StandardCharsets.UTF_8)),
+                StandardCharsets.UTF_8);
+        String[] kiArray =sysKeyStr.split("#");
+        if(kiArray == null || kiArray.length !=2){
+            return null;
+        }
+        key = kiArray[0];
+        iv = kiArray[1];
+
+        if(key == null || iv == null || key.isEmpty() || iv.isEmpty())
+            return null;
+        LicenseKCon licenseKCon = new LicenseKCon();
+        licenseKCon.setKey(key);
+        licenseKCon.setIv(iv);
+        return licenseKCon;
+    }
+
+    /**
+     * 用本地key解码获取用户私有key
+     * @param sysKey
+     * @return
+     */
+    private LicenseKCon getUserPrivateKey(LicenseKCon sysKey){
+        Optional<SysConfig> sysConfigOptional = sysConfigRepository.findById(SystemConfigKeyEnum.LICENSE_U_KEY.getKey());
+        if(sysConfigOptional == null || !sysConfigOptional.isPresent()){
+            return null;
+        }
+        SysConfig sysConfig = sysConfigOptional.get();
+        if(sysConfig.getSysValue() == null || sysConfig.getSysValue().isEmpty())
+            return null;
+        //加密:明文->转base64->aes->转base64
+        //解密:密文->反base64->aes->反base64
+        //明文规则: key#iv
+        String key = null;
+        String iv = null;
+
+
+        byte[] rsBytes = new byte[0];
+        try {
+            Cipher cipher =  Cipher.getInstance("AES/CBC/PKCS5Padding");
+            cipher.init(Cipher.DECRYPT_MODE,new SecretKeySpec(sysKey.getKey().getBytes(),"AES"),
+                    new IvParameterSpec(sysKey.getIv().getBytes()));
+            rsBytes = cipher.doFinal(Base64.getDecoder().decode(sysConfig.getSysValue().getBytes(StandardCharsets.UTF_8)));
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        } catch (NoSuchPaddingException e) {
+            e.printStackTrace();
+        } catch (InvalidKeyException e) {
+            e.printStackTrace();
+        } catch (InvalidAlgorithmParameterException e) {
+            e.printStackTrace();
+        } catch (IllegalBlockSizeException e) {
+            e.printStackTrace();
+        } catch (BadPaddingException e) {
+            e.printStackTrace();
+        }
+
+        String[] kiArray = new String(Base64.getDecoder().decode(rsBytes), StandardCharsets.UTF_8).split("#");
+        if(kiArray == null || kiArray.length != 2){
+            return null;
+        }
+        key = kiArray[0];
+        iv = kiArray[1];
+        if(key == null || iv == null || key.isEmpty() || iv.isEmpty())
+            return null;
+        LicenseKCon licenseKCon = new LicenseKCon();
+        licenseKCon.setKey(key);
+        licenseKCon.setIv(iv);
+        return licenseKCon;
+    }
+
+    private LicenseKCon getUserPrivateKeyRSA(){
+        //1、从数据库获取加密KEY
+        Optional<SysConfig> sysConfigOptional = sysConfigRepository.findById(SystemConfigKeyEnum.LICENSE_U_KEY.getKey());
+        if(sysConfigOptional == null || !sysConfigOptional.isPresent()){
+            return null;
+        }
+        SysConfig sysConfig = sysConfigOptional.get();
+        if(sysConfig.getSysValue() == null || sysConfig.getSysValue().isEmpty())
+            return null;
+        //2、解密取得secretKey 和 IV
+        LicenseDataCon dataConf = LicenseDataCon.getCon();
+        byte[] rsBytes = null;
+
+        RSA rsa = new RSA();
+        PublicKey pk =
+                null;
+        try {
+            pk = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(dataConf.getPublicKey())));
+        } catch (InvalidKeySpecException e) {
+            e.printStackTrace();
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        rsa.setPublicKey(pk);
+        rsBytes = rsa.decrypt(Base64.getDecoder().decode(sysConfig.getSysValue()), KeyType.PublicKey);
+
+        //解密后处理
+        if(rsBytes == null || rsBytes.length == 0){
+            return null;
+        }
+        //明文规则: key#iv
+        String kiStr = new String(rsBytes, StandardCharsets.UTF_8);
+        String[] kiArray = kiStr.split("#");
+        if(kiArray == null || kiArray.length != 2){
+            return null;
+        }
+        String key = kiArray[0];
+        String iv = kiArray[1];
+        if(key == null || iv == null || key.isEmpty() || iv.isEmpty())
+            return null;
+        LicenseKCon licenseKCon = new LicenseKCon();
+        licenseKCon.setKey(key);
+        licenseKCon.setIv(iv);
+        return licenseKCon;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseBizWhiteEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseBizWhiteEnum.java
new file mode 100644
index 0000000..8c86c0c
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseBizWhiteEnum.java
@@ -0,0 +1,51 @@
+package com.gkhy.fourierSpecialGasMonitor.config.license;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 业务接口授权白名单
+ * 配置在这里的业务接口前缀,不需要授权
+ */
+public enum LicenseBizWhiteEnum {
+    BIZ_RISK_IDENTIFY("sys","系统管理"),
+    BIZ_ACCOUNT("account","用户账号")
+    ;
+
+
+    private String biz;
+    private String bizName;
+
+    LicenseBizWhiteEnum(String biz, String bizName) {
+        this.biz = biz;
+        this.bizName = bizName;
+    }
+
+    public String getBiz() {
+        return biz;
+    }
+
+    public void setBiz(String biz) {
+        this.biz = biz;
+    }
+
+    public String getBizName() {
+        return bizName;
+    }
+
+    public void setBizName(String bizName) {
+        this.bizName = bizName;
+    }
+
+    static Map<String, LicenseBizWhiteEnum> map;
+    static {
+        map = new HashMap<>();
+        for (LicenseBizWhiteEnum bizEnum : LicenseBizWhiteEnum.values()) {
+            map.put(bizEnum.biz,bizEnum);
+        }
+    }
+
+    public static LicenseBizWhiteEnum parse(String biz) {
+        return map.get(biz);
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseDataCon.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseDataCon.java
new file mode 100644
index 0000000..25c32b1
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseDataCon.java
@@ -0,0 +1,34 @@
+package com.gkhy.fourierSpecialGasMonitor.config.license;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+
+public class LicenseDataCon {
+
+    private String p;
+
+    private String i;
+
+    private String pubk;
+
+    private LicenseDataCon(){
+        this.p = "ag3hs8jqodi1hs8g";
+        this.i = "8uhsgt16tsd623hd";
+        this.pubk = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwyJHfDUlEIhnATeh7nHH7Xa6gXLIahAoTsQ+/DchZXxVutptzYCVebPJDg8PX+iQvjtO4F1Lmu3OKQVFv5yOA5QAShlP163a0yGg50zNGhPesnODIhEOmEHqCTQZctEGK0x51+mxIhS0xIkCOYUpTleT8KfVS8Ab9+hDhcxQkrwIDAQAB";
+    }
+
+    public static LicenseDataCon getCon(){
+        return new LicenseDataCon();
+    }
+
+    public String getPi() {
+        if(p == null || i == null || p.isEmpty() || i.isEmpty())
+            return null;
+        String r = p+"#"+i;
+        return new String(Base64.getEncoder().encodeToString(r.getBytes(StandardCharsets.UTF_8)));
+    }
+
+    public String getPublicKey(){
+        return this.pubk;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseFilter.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseFilter.java
new file mode 100644
index 0000000..fd31993
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseFilter.java
@@ -0,0 +1,61 @@
+package com.gkhy.fourierSpecialGasMonitor.config.license;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+//@Component
+//@WebFilter(urlPatterns = "/*", filterName = "LicenseFilter")
+public class LicenseFilter implements Filter {
+
+//    @Autowired
+    private LicenseManageService licenseManageService;
+
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+        Filter.super.init(filterConfig);
+    }
+
+    @Override
+    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+        HttpServletRequest reqs = (HttpServletRequest) servletRequest;
+        HttpServletResponse response = (HttpServletResponse) servletResponse;
+        String reqUri = reqs.getRequestURI().toString();
+        //1、选择过滤的业务系统接口路径
+        String[] uris = reqUri.split("/");
+        if(uris.length < 2)
+            filterChain.doFilter(servletRequest,servletResponse);
+        String licenseBiz  = uris[1];
+        if(licenseBiz == null)
+            filterChain.doFilter(servletRequest,servletResponse);
+        //默认所有业务均需要授权访问
+        boolean checkFlag = true;
+        if(LicenseBizWhiteEnum.parse(licenseBiz) != null){
+            //业务接口在授权白名单清单中,不需要授权访问
+            checkFlag = false;
+        }
+        //2、检查授权
+        if(checkFlag == true){
+            if(licenseManageService.isActiveLicense()){
+                filterChain.doFilter(servletRequest,servletResponse);
+                //有授权,放行
+            }else {
+                //没有授权,拦截
+//                ResultDto resultDto = new ResultDto<>();
+//                resultDto.setCode(401);
+//                resultDto.setMsg("系统授权到期,请联系管理员");
+                response.setContentType("text/html;charset=UTF-8");
+                response.getWriter().print("系统授权到期,请联系管理员");
+                response.setStatus(401);
+            }
+        }else {
+            filterChain.doFilter(servletRequest,servletResponse);
+        }
+    }
+
+    @Override
+    public void destroy() {
+        Filter.super.destroy();
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseInfo.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseInfo.java
new file mode 100644
index 0000000..9146c92
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseInfo.java
@@ -0,0 +1,46 @@
+package com.gkhy.fourierSpecialGasMonitor.config.license;
+
+import java.time.LocalDateTime;
+
+public class LicenseInfo {
+
+    private String companyName;
+
+    private Byte licenseType;
+
+    private LocalDateTime beginTime;
+
+    private LocalDateTime endTime;
+
+    public String getCompanyName() {
+        return companyName;
+    }
+
+    public void setCompanyName(String companyName) {
+        this.companyName = companyName;
+    }
+
+    public Byte getLicenseType() {
+        return licenseType;
+    }
+
+    public void setLicenseType(Byte licenseType) {
+        this.licenseType = licenseType;
+    }
+
+    public LocalDateTime getBeginTime() {
+        return beginTime;
+    }
+
+    public void setBeginTime(LocalDateTime beginTime) {
+        this.beginTime = beginTime;
+    }
+
+    public LocalDateTime getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(LocalDateTime endTime) {
+        this.endTime = endTime;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseInit.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseInit.java
new file mode 100644
index 0000000..b6311ee
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseInit.java
@@ -0,0 +1,26 @@
+package com.gkhy.fourierSpecialGasMonitor.config.license;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Component;
+
+@Component
+public class LicenseInit {
+
+    @Value("${system.deployMode}")
+    private String deployMode;
+
+    @Bean
+    public CompanyLicenseDataCache companyLicenseDataCache(){
+//        //todo:从数据库加载授权信息
+//        if(deployMode != null && deployMode.equals("standalone")){
+//            //单机模式,直接从数据库读取数据
+//
+//        }else if(deployMode != null && deployMode.equals("cluster")){
+//            //集群模式,跟redis缓存同步
+//        }else {
+//            //配置错误
+//        }
+        return new CompanyLicenseDataCache(deployMode);
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseKCon.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseKCon.java
new file mode 100644
index 0000000..2ddf6d8
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseKCon.java
@@ -0,0 +1,22 @@
+package com.gkhy.fourierSpecialGasMonitor.config.license;
+
+public class LicenseKCon {
+    private String key;
+    private String iv;
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public String getIv() {
+        return iv;
+    }
+
+    public void setIv(String iv) {
+        this.iv = iv;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseManageService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseManageService.java
new file mode 100644
index 0000000..db696d7
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseManageService.java
@@ -0,0 +1,63 @@
+package com.gkhy.fourierSpecialGasMonitor.config.license;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+
+@Service
+public class LicenseManageService {
+
+    @Value("${system.deployMode}")
+    private String deployMode;
+
+    @Autowired
+    private CompanyLicenseDataCache companyLicenseDataCache;
+
+    /**
+     * 检查license有效性
+     * @return
+     */
+    public boolean isActiveLicense(){
+        LicenseInfo licenseInfo = companyLicenseDataCache.getLicenseInfo();
+        if(licenseInfo == null){
+            return false;
+        }
+        if(licenseInfo.getLicenseType().equals(LicenseTypeEnum.INVALID.getType())){
+            //无效授权
+            return false;
+        }
+        LocalDateTime nowTime = LocalDateTime.now();
+        if(licenseInfo.getLicenseType().equals(LicenseTypeEnum.TRAIL.getType())){
+            //试用授权
+            if(licenseInfo.getBeginTime() == null || licenseInfo.getEndTime() == null){
+                return false;
+            }
+            if(licenseInfo.getBeginTime().isAfter(nowTime) || licenseInfo.getEndTime().isBefore(nowTime)){
+                return false;
+            }else {
+                return true;
+            }
+        }
+        if(licenseInfo.getLicenseType().equals(LicenseTypeEnum.LIMIT.getType())){
+            //有限期授权
+            if(licenseInfo.getBeginTime() == null || licenseInfo.getEndTime() == null){
+                return false;
+            }
+            if(licenseInfo.getBeginTime().isAfter(nowTime) || licenseInfo.getEndTime().isBefore(nowTime)){
+                return false;
+            }else {
+                return true;
+            }
+        }
+        if(licenseInfo.getLicenseType().equals(LicenseTypeEnum.LONG_TIME.getType())){
+            //长期授权
+            return true;
+        }
+        //证书类型不支持,默认无效
+        return false;
+    }
+
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseTypeEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseTypeEnum.java
new file mode 100644
index 0000000..1d800d9
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/license/LicenseTypeEnum.java
@@ -0,0 +1,47 @@
+package com.gkhy.fourierSpecialGasMonitor.config.license;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum LicenseTypeEnum {
+    INVALID((byte)0,"无效授权"),
+    TRAIL((byte)1,"试用授权"),
+    LIMIT((byte)2,"有限期授权"),
+    LONG_TIME((byte)3,"长期有效授权")
+    ;
+
+    private Byte type;
+    private String desc;
+
+    LicenseTypeEnum(Byte type, String desc) {
+        this.type = type;
+        this.desc = desc;
+    }
+
+    public Byte getType() {
+        return type;
+    }
+
+    public void setType(Byte type) {
+        this.type = type;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+    static Map<Byte, LicenseTypeEnum> map;
+    static {
+        map = new HashMap<>();
+        for (LicenseTypeEnum typeEnum : LicenseTypeEnum.values()) {
+            map.put(typeEnum.type,typeEnum);
+        }
+    }
+    public static LicenseTypeEnum parse(Byte type) {
+        return map.get(type);
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/serializa/JacksonConfiguration.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/serializa/JacksonConfiguration.java
new file mode 100644
index 0000000..bcb771e
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/serializa/JacksonConfiguration.java
@@ -0,0 +1,32 @@
+package com.gkhy.fourierSpecialGasMonitor.config.serializa;
+
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+@Configuration
+public class JacksonConfiguration {
+
+    @Bean
+    @Primary
+    @ConditionalOnMissingBean(ObjectMapper.class)
+    public ObjectMapper jacksonObjectMapper()
+    {
+        ObjectMapper mapper = new ObjectMapper();
+        JavaTimeModule javaTimeModule = new JavaTimeModule();
+        javaTimeModule.addDeserializer(LocalDateTime.class,
+                new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        javaTimeModule.addSerializer(LocalDateTime.class,
+                new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        mapper.registerModule(javaTimeModule);
+        return mapper;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/serializa/JavaTimeAutoConfiguration.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/serializa/JavaTimeAutoConfiguration.java
new file mode 100644
index 0000000..d06974a
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/serializa/JavaTimeAutoConfiguration.java
@@ -0,0 +1,30 @@
+package com.gkhy.fourierSpecialGasMonitor.config.serializa;
+
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+@Configuration
+@ConditionalOnClass(JavaTimeModule.class)
+public class JavaTimeAutoConfiguration {
+    @Bean
+    @ConditionalOnProperty("spring.jackson.date-format")
+    Jackson2ObjectMapperBuilderCustomizer customizeLocalDateTimeFormat(@Value("${spring.jackson.date-format}") String dateFormat){
+        return jacksonObjectMapperBuilder -> {
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
+
+            jacksonObjectMapperBuilder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
+            jacksonObjectMapperBuilder.deserializerByType(LocalDateTime.class,
+                    new LocalDateTimeDeserializer(formatter));
+        };
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/threadExecutor/ExecutorConfig.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/threadExecutor/ExecutorConfig.java
new file mode 100644
index 0000000..0a0e768
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/threadExecutor/ExecutorConfig.java
@@ -0,0 +1,82 @@
+package com.gkhy.fourierSpecialGasMonitor.config.threadExecutor;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.AsyncConfigurer;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+import java.lang.reflect.Method;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ThreadPoolExecutor;
+
+@Configuration
+@EnableAsync
+public class ExecutorConfig implements AsyncConfigurer{
+    private Logger logger = LoggerFactory.getLogger(ExecutorConfig.class);
+
+    /**
+     * 最小线程数(核心线程数)
+     */
+    @Value("${threadPool.corePoolSize}")
+    private int corePoolSize;
+    /**
+     * 最大线程数
+     */
+    @Value("${threadPool.maxPoolSize}")
+    private int maxPoolSize;
+    /**
+     * 等待队列(队列最大长度)
+     */
+    @Value("${threadPool.queueCapacity}")
+    private int queueCapacity;
+
+    @Bean(name = "SocketTaskExecutor")
+    public Executor asyncServiceExecutor() {
+        logger.info("start asyncServiceExecutor");
+
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        //配置核心线程数
+        executor.setCorePoolSize(corePoolSize);
+        //配置最大线程数
+        executor.setMaxPoolSize(maxPoolSize);
+        //配置队列大小
+        executor.setQueueCapacity(queueCapacity);
+        //配置线程池中的线程的名称前缀
+        executor.setThreadNamePrefix("async-service-");
+        // rejection-policy:当pool已经达到max size的时候,如何处理新任务
+        // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+
+        //执行初始化
+        executor.initialize();
+        return executor;
+    }
+
+    /**
+     * 异步异常处理
+     *
+     * @return
+     */
+    @Override
+    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+        return new SpringAsyncExceptionHandler();
+    }
+
+
+    class SpringAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
+        @Override
+        public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
+            logger.error("Exception occurs in async method", throwable.getMessage());
+        }
+    }
+
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/websocket/WebSocketConfig.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/websocket/WebSocketConfig.java
new file mode 100644
index 0000000..a40df01
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/config/websocket/WebSocketConfig.java
@@ -0,0 +1,15 @@
+package com.gkhy.fourierSpecialGasMonitor.config.websocket;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+@Configuration
+public class WebSocketConfig {
+
+    @Bean
+    public ServerEndpointExporter serverEndpointExporter() {
+        return new ServerEndpointExporter();
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/DataReceiveController.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/DataReceiveController.java
new file mode 100644
index 0000000..ec65961
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/DataReceiveController.java
@@ -0,0 +1,46 @@
+package com.gkhy.fourierSpecialGasMonitor.controller;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.ForeignResult;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.DeviceMonitorReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UploadGasConcentrationReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UploadGasFluxReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.service.DataReceiveService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/7 14:19
+ */
+@RestController
+@RequestMapping("/api")
+public class DataReceiveController {
+
+    @Autowired
+    private DataReceiveService dataReceiveService;
+
+    @PostMapping("/upload/gasConcentration")
+    public ForeignResult uploadGasConcentration(@RequestBody UploadGasConcentrationReqDTO reqDto){
+        ForeignResult result = dataReceiveService.uploadGasConcentration(reqDto);
+        return result;
+    }
+
+    @PostMapping("/upload/gasFlux")
+    public ForeignResult uploadGasFlux(@RequestBody UploadGasFluxReqDTO reqDto){
+        ForeignResult result = dataReceiveService.uploadGasFlux(reqDto);
+        return result;
+    }
+
+    @PostMapping("/list/gasCategory")
+    public ForeignResult listGasCategory(){
+        ForeignResult result = dataReceiveService.listGasCategory();
+        return result;
+    }
+
+    @PostMapping("/device/monitor")
+    public ForeignResult deviceMonitor(@RequestBody DeviceMonitorReqDTO reqDTO){
+        ForeignResult result = dataReceiveService.deviceMonitor(reqDTO);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasCategoryController.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasCategoryController.java
new file mode 100644
index 0000000..7d8d93c
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasCategoryController.java
@@ -0,0 +1,75 @@
+package com.gkhy.fourierSpecialGasMonitor.controller;
+
+import com.gkhy.fourierSpecialGasMonitor.api.controller.common.BaseController;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindGasCategoryPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindRegionPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.CreateGasCategoryReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UpdateGasCategoryReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.service.GasCategoryService;
+import org.redisson.api.RBucket;
+import org.redisson.api.RedissonClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.PostConstruct;
+
+@RestController
+@RequestMapping("/gasCategory")
+public class GasCategoryController extends BaseController {
+
+    @Autowired
+    private GasCategoryService gasCategoryService;
+
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+    @PostMapping("/add")
+    public Result createGasCategory(@RequestBody CreateGasCategoryReqDTO reqDto){
+        Result result = gasCategoryService.createGasCategory(reqDto);
+        return result;
+    }
+
+    @PostMapping("/update")
+    public Result updateGasCategory(@RequestBody UpdateGasCategoryReqDTO reqDto){
+        Result result = gasCategoryService.updateGasCategory(reqDto);
+        return result;
+    }
+
+
+    @GetMapping("/findById")
+    public Result findGasCategoryById(@RequestParam Integer id){
+        Result result = gasCategoryService.findGasCategoryById(id);
+        return result;
+    }
+
+    @PostMapping("/page")
+    public Result findGasCategoryPage(@RequestBody PageQuery<FindGasCategoryPageQuery> pageQuery){
+        Result result = gasCategoryService.findGasCategoryPage(pageQuery);
+        return result;
+    }
+
+    @PostMapping("/list")
+    public Result gasCategoryList(){
+        Result result = gasCategoryService.gasCategoryList();
+        return result;
+    }
+
+    @PostConstruct
+    private void gasCategoryListCache(){
+        //清除redis缓存
+        RBucket<Object> bucket = redissonClient.getBucket("gas_category_cache_info");
+        if (bucket.isExists()) {
+            bucket.delete();
+        }
+        this.gasCategoryList();
+        logger.info("【气体对照表】已加入缓存");
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasMonitorDataController.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasMonitorDataController.java
new file mode 100644
index 0000000..d4b6511
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasMonitorDataController.java
@@ -0,0 +1,67 @@
+package com.gkhy.fourierSpecialGasMonitor.controller;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindGasWarnLogPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.GasAtmospherePageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.GasFluxPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.GasPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.CreateGasCategoryReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.GasAtmosphereLineChartReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.GasFluxLineChartReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.GasLineChartReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.service.MonitorDataService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 9:06
+ */
+@RestController
+@RequestMapping("/gasMonitorData")
+public class GasMonitorDataController {
+
+    @Autowired
+    private MonitorDataService monitorDataService;
+
+    @PostMapping("/gas/lineChart")
+    public Result gasLineChart(@RequestBody GasLineChartReqDTO reqDto){
+        Result result = monitorDataService.gasLineChart(reqDto);
+        return result;
+    }
+
+    @PostMapping("/gas/page")
+    public Result gasPage(@RequestBody PageQuery<GasPageQuery> pageQuery){
+        Result result = monitorDataService.gasPage(pageQuery);
+        return result;
+    }
+
+    @PostMapping("/gasFlux/lineChart")
+    public Result gasFluxLineChart(@RequestBody GasFluxLineChartReqDTO reqDto){
+        Result result = monitorDataService.gasFluxLineChart(reqDto);
+        return result;
+    }
+
+    @PostMapping("/gasFlux/page")
+    public Result gasFluxPage(@RequestBody PageQuery<GasFluxPageQuery> pageQuery){
+        Result result = monitorDataService.gasFluxPage(pageQuery);
+        return result;
+    }
+
+    @PostMapping("/gasAtmosphere/lineChart")
+    public Result gasAtmosphereLineChart(@RequestBody GasAtmosphereLineChartReqDTO reqDto){
+        Result result = monitorDataService.gasAtmosphereLineChart(reqDto);
+        return result;
+    }
+
+    @PostMapping("/gasAtmosphere/page")
+    public Result gasAtmospherePage(@RequestBody PageQuery<GasAtmospherePageQuery> pageQuery){
+        Result result = monitorDataService.gasAtmospherePage(pageQuery);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasThresholdController.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasThresholdController.java
new file mode 100644
index 0000000..6182828
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasThresholdController.java
@@ -0,0 +1,36 @@
+package com.gkhy.fourierSpecialGasMonitor.controller;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UpdateGasThresholdReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UpdateRegionReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.service.GasThresholdService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 14:22
+ */
+@RestController
+@RequestMapping("/gasThreshold")
+public class GasThresholdController {
+
+    @Autowired
+    private GasThresholdService gasThresholdService;
+
+    @PostMapping("/list")
+    public Result gasThresholdList(){
+        Result result = gasThresholdService.gasThresholdList();
+        return result;
+    }
+
+    @PostMapping("/update")
+    public Result updateGasThreshold(@RequestBody UpdateGasThresholdReqDTO reqDto){
+        Result result = gasThresholdService.updateGasThreshold(reqDto);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasWarnLogController.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasWarnLogController.java
new file mode 100644
index 0000000..97a68b6
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasWarnLogController.java
@@ -0,0 +1,34 @@
+package com.gkhy.fourierSpecialGasMonitor.controller;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindGasCategoryPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindGasWarnLogPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.service.GasWarnLogService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 16:46
+ */
+@RestController
+@RequestMapping("/gasWarnLog")
+public class GasWarnLogController {
+
+    @Autowired
+    private GasWarnLogService gasWarnLogService;
+
+    @PostMapping("/page")
+    public Result findGasWarnLogPage(@RequestBody PageQuery<FindGasWarnLogPageQuery> pageQuery){
+        Result result = gasWarnLogService.findGasWarnLogPage(pageQuery);
+        return result;
+    }
+
+    @PostMapping("/handleById")
+    public Result handleGasWarnLog(@RequestParam Long id){
+        Result result = gasWarnLogService.handleGasWarnLog(id);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasWarnUserController.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasWarnUserController.java
new file mode 100644
index 0000000..f9d4bef
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/GasWarnUserController.java
@@ -0,0 +1,49 @@
+package com.gkhy.fourierSpecialGasMonitor.controller;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindGasCategoryPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindGasWarnUserPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.*;
+import com.gkhy.fourierSpecialGasMonitor.service.GasThresholdService;
+import com.gkhy.fourierSpecialGasMonitor.service.GasWarnUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 14:22
+ */
+@RestController
+@RequestMapping("/gasWarnUser")
+public class GasWarnUserController {
+
+    @Autowired
+    private GasWarnUserService gasWarnUserService;
+
+
+    @PostMapping("/add")
+    public Result createGasWarnUser(@RequestBody CreateGasWarnUserReqDTO reqDto){
+        Result result = gasWarnUserService.createGasWarnUser(reqDto);
+        return result;
+    }
+
+    @PostMapping("/del")
+    public Result delGasWarnUserById(@RequestBody DelGasWarnUserByIdReqDTO reqDto){
+        Result result = gasWarnUserService.delGasWarnUserById(reqDto);
+        return result;
+    }
+
+    @PostMapping("/update")
+    public Result updateGasWarnUser(@RequestBody UpdateGasWarnUserReqDTO reqDto){
+        Result result = gasWarnUserService.updateGasWarnUser(reqDto);
+        return result;
+    }
+
+    @PostMapping("/page")
+    public Result findGasWarnUserPage(@RequestBody PageQuery<FindGasWarnUserPageQuery> pageQuery){
+        Result result = gasWarnUserService.findGasWarnUserPage(pageQuery);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/MonitorDailyReportController.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/MonitorDailyReportController.java
new file mode 100644
index 0000000..252ce45
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/MonitorDailyReportController.java
@@ -0,0 +1,31 @@
+package com.gkhy.fourierSpecialGasMonitor.controller;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindDailyReportPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindRegionPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.service.MonitorDailyReportService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 15:42
+ */
+@RestController
+@RequestMapping("/dailyReport")
+public class MonitorDailyReportController {
+
+    @Autowired
+    private MonitorDailyReportService monitorDailyReportService;
+
+    @PostMapping("/page")
+    public Result findDailyReportPage(@RequestBody PageQuery<FindDailyReportPageQuery> pageQuery){
+        Result result = monitorDailyReportService.findDailyReportPage(pageQuery);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/RegionController.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/RegionController.java
new file mode 100644
index 0000000..043f01f
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/controller/RegionController.java
@@ -0,0 +1,53 @@
+package com.gkhy.fourierSpecialGasMonitor.controller;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindRegionPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.*;
+import com.gkhy.fourierSpecialGasMonitor.service.RegionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 10:03
+ */
+@RestController
+@RequestMapping("/region")
+public class RegionController {
+
+    @Autowired
+    private RegionService regionService;
+
+    @PostMapping("/add")
+    public Result createRegion(@RequestBody CreateRegionReqDTO reqDto){
+        Result result = regionService.createRegion(reqDto);
+        return result;
+    }
+
+    @PostMapping("/del")
+    public Result delRegionById(@RequestBody DelRegionByIdReqDTO reqDto){
+        Result result = regionService.delRegionById(reqDto);
+        return result;
+    }
+
+    @PostMapping("/update")
+    public Result updateRegion(@RequestBody UpdateRegionReqDTO reqDto){
+        Result result = regionService.updateRegion(reqDto);
+        return result;
+    }
+
+
+    @GetMapping("/findById")
+    public Result findRegionById(@RequestParam Integer id){
+        Result result = regionService.findRegionById(id);
+        return result;
+    }
+
+    @PostMapping("/page")
+    public Result findRegionPage(@RequestBody PageQuery<FindRegionPageQuery> pageQuery){
+        Result result = regionService.findRegionPage(pageQuery);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/decorator/WarningThresholdUpdateEvent.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/decorator/WarningThresholdUpdateEvent.java
new file mode 100644
index 0000000..4a44f98
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/decorator/WarningThresholdUpdateEvent.java
@@ -0,0 +1,14 @@
+package com.gkhy.fourierSpecialGasMonitor.decorator;
+
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 15:27
+ */
+public class WarningThresholdUpdateEvent extends ApplicationEvent {
+    public WarningThresholdUpdateEvent(Object source) {
+        super(source);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/RoleInfoConverter.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/RoleInfoConverter.java
new file mode 100644
index 0000000..4b77b8c
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/RoleInfoConverter.java
@@ -0,0 +1,18 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.converter;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.Role;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.RoleInfoDoaminDTO;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+@Service
+public class RoleInfoConverter {
+
+    public RoleInfoDoaminDTO roleRoleInfoDTO(Role role){
+        if(role == null)
+            return null;
+        RoleInfoDoaminDTO roleInfoDoaminDTO = new RoleInfoDoaminDTO();
+        BeanUtils.copyProperties(role, roleInfoDoaminDTO);
+        return roleInfoDoaminDTO;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/SysDeparmentConverter.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/SysDeparmentConverter.java
new file mode 100644
index 0000000..79d00af
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/SysDeparmentConverter.java
@@ -0,0 +1,42 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.converter;
+
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.SysDepartmentAppDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.SysDepartment;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.SysDepartmentDomainDTO;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/9
+ * @time: 8:55
+ */
+@Component
+public class SysDeparmentConverter {
+    public SysDepartmentDomainDTO sysDepDomainDTOConverter(SysDepartment sysDepartment){
+        if (sysDepartment == null){
+            return null;
+        }
+        SysDepartmentDomainDTO sysDepartmentDomainDTO = new SysDepartmentDomainDTO();
+        BeanUtils.copyProperties(sysDepartment,sysDepartmentDomainDTO);
+        return sysDepartmentDomainDTO;
+    }
+
+    public List<SysDepartmentAppDTO> sysDepAppDTOListConverter(List<SysDepartmentDomainDTO> list) {
+        List<SysDepartmentAppDTO> appDTOList = new ArrayList<>();
+        if(!CollectionUtils.isEmpty(list)){
+            for (SysDepartmentDomainDTO sysDepartmentDomainDTO : list){
+                SysDepartmentAppDTO sysDepartmentAppDTO = new SysDepartmentAppDTO();
+                BeanUtils.copyProperties(sysDepartmentDomainDTO,sysDepartmentAppDTO);
+                sysDepartmentAppDTO.setChildren(sysDepAppDTOListConverter(sysDepartmentDomainDTO.getChildren()));
+                appDTOList.add(sysDepartmentAppDTO);
+            }
+        }
+        return appDTOList;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/SysUserIndentityBindConverter.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/SysUserIndentityBindConverter.java
new file mode 100644
index 0000000..b206d16
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/SysUserIndentityBindConverter.java
@@ -0,0 +1,44 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.converter;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.UserRoleBindAppRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.UserRoleBindRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.commons.utils.BeanCopyUtils;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.SysUserRoleBind;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.SysUserRoleBindDomainDTO;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/13
+ * @time: 10:34
+ */
+@Component
+public class SysUserIndentityBindConverter {
+    public List<SysUserRoleBindDomainDTO> userRoleBindDomainConverter(List<SysUserRoleBind> list){
+        List<SysUserRoleBindDomainDTO> respDTO = new ArrayList<>();
+        if(ObjectUtil.isNotEmpty(list)){
+           respDTO = BeanCopyUtils.copyBeanList(list, SysUserRoleBindDomainDTO.class);
+        }
+        return respDTO;
+    }
+    public List<UserRoleBindAppRespDTO> userRoleBindAppConverter(List<SysUserRoleBindDomainDTO> list){
+        List<UserRoleBindAppRespDTO> respDTO = new ArrayList<>();
+        if(ObjectUtil.isNotEmpty(list)){
+            respDTO = BeanCopyUtils.copyBeanList(list, UserRoleBindAppRespDTO.class);
+        }
+        return respDTO;
+    }
+    public List<UserRoleBindRespDTO> userRoleBindConverter(List<SysUserRoleBindDomainDTO> list){
+        List<UserRoleBindRespDTO> respDTO = new ArrayList<>();
+        if(ObjectUtil.isNotEmpty(list)){
+            respDTO = BeanCopyUtils.copyBeanList(list, UserRoleBindRespDTO.class);
+        }
+        return respDTO;
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/UserIdentityConverter.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/UserIdentityConverter.java
new file mode 100644
index 0000000..c25ee21
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/UserIdentityConverter.java
@@ -0,0 +1,30 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.converter;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.gkhy.fourierSpecialGasMonitor.commons.utils.BeanCopyUtils;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.UserIdentity;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.UserIdentityDomainDTO;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/13
+ * @time: 10:34
+ */
+@Component
+public class UserIdentityConverter {
+
+
+    public List<UserIdentityDomainDTO> userIdentityDomainConverter(List<UserIdentity> list){
+        List<UserIdentityDomainDTO> respDTO = new ArrayList<>();
+        if(ObjectUtil.isNotEmpty(list)){
+           respDTO = BeanCopyUtils.copyBeanList(list, UserIdentityDomainDTO.class);
+        }
+        return respDTO;
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/UserInfoDomainConverter.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/UserInfoDomainConverter.java
new file mode 100644
index 0000000..2da0278
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/UserInfoDomainConverter.java
@@ -0,0 +1,90 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.converter;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.SysUserIdentityBind;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.SysUserRoleBind;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.User;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.UserInfoAppRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.SysUserIdentityBindDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.SysUserRoleBindDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.UserInfoDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.attachment.dto.resp.AttachmentDomainDTO;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class UserInfoDomainConverter {
+
+    public UserInfoAppRespDTO toUserInfoRespDTO(UserInfoDomainDTO userInfoDomainDTO){
+        if(userInfoDomainDTO == null)
+            return null;
+        UserInfoAppRespDTO userInfoAppRespDTO = new UserInfoAppRespDTO();
+        BeanUtils.copyProperties(userInfoDomainDTO, userInfoAppRespDTO);
+        return userInfoAppRespDTO;
+    }
+
+    public UserInfoDomainDTO toUserInfoDTO(User user){
+        if(user == null)
+            return null;
+        UserInfoDomainDTO userInfoDomainDTO = new UserInfoDomainDTO();
+        BeanUtils.copyProperties(user, userInfoDomainDTO);
+        if(user.getSysDepartment() != null){
+            userInfoDomainDTO.setDepName(user.getSysDepartment().getDepName());
+        }
+        List<SysUserRoleBindDomainDTO> roleBindDomainDTOList = new ArrayList<>();
+        if(ObjectUtil.isNotEmpty(user.getSysUserRoleBinds())){
+            user.getSysUserRoleBinds().forEach(userRoleBind -> {
+                roleBindDomainDTOList.add(toUserRoleDomainDTO(userRoleBind));
+            });
+        }
+        userInfoDomainDTO.setRoles(roleBindDomainDTOList);
+
+        //身份
+        List<SysUserIdentityBindDomainDTO> userIdentityBindDomainDTOS = new ArrayList<>();
+        if(user.getSysUserIdentityBinds() != null){
+            user.getSysUserIdentityBinds().forEach(userIdentity ->{
+                userIdentityBindDomainDTOS.add(toUserIndentityDomainDTO(userIdentity));
+            });
+        }
+        userInfoDomainDTO.setUserIdentities(userIdentityBindDomainDTOS);
+        //资质附件
+        if(user.getQualificationAttachment() != null){
+            AttachmentDomainDTO attachmentDomainDTO = new AttachmentDomainDTO();
+            BeanUtils.copyProperties(user.getQualificationAttachment(),attachmentDomainDTO);
+            userInfoDomainDTO.setQualificationAttDomainDTO(attachmentDomainDTO);
+        }
+        return userInfoDomainDTO;
+    }
+    public SysUserIdentityBindDomainDTO toUserIndentityDomainDTO(SysUserIdentityBind sysUserIdentityBind){
+        if(sysUserIdentityBind == null)
+            return null;
+        SysUserIdentityBindDomainDTO sysUserRoleBindDomainDTO = new SysUserIdentityBindDomainDTO();
+        BeanUtils.copyProperties(sysUserIdentityBind, sysUserRoleBindDomainDTO);
+        if(sysUserIdentityBind.getUserIdentity() != null){
+            sysUserRoleBindDomainDTO.setUserIdentity(sysUserIdentityBind.getUserIdentity().getIdentity());
+        }
+        return sysUserRoleBindDomainDTO;
+    }
+    public SysUserRoleBindDomainDTO toUserRoleDomainDTO(SysUserRoleBind sysUserRoleBind){
+        if(sysUserRoleBind == null)
+            return null;
+        SysUserRoleBindDomainDTO sysUserRoleBindDomainDTO = new SysUserRoleBindDomainDTO();
+        BeanUtils.copyProperties(sysUserRoleBind, sysUserRoleBindDomainDTO);
+        sysUserRoleBindDomainDTO.setRoleName(sysUserRoleBind.getRole().getName());
+        return sysUserRoleBindDomainDTO;
+    }
+    public List<UserInfoDomainDTO> toDomainUserInfoList(List<User> userList){
+        if(userList == null || userList.isEmpty())
+            return null;
+        List<UserInfoDomainDTO> domainDTOList = new ArrayList<>();
+        userList.forEach(u -> {
+            domainDTOList.add(toUserInfoDTO(u));
+        });
+        return domainDTOList;
+    }
+
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/UserRoleBindConverter.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/UserRoleBindConverter.java
new file mode 100644
index 0000000..280095c
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/converter/UserRoleBindConverter.java
@@ -0,0 +1,44 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.converter;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.UserRoleBindAppRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.UserRoleBindRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.commons.utils.BeanCopyUtils;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.SysUserRoleBind;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.SysUserRoleBindDomainDTO;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/13
+ * @time: 10:34
+ */
+@Component
+public class UserRoleBindConverter {
+    public List<SysUserRoleBindDomainDTO> userRoleBindDomainConverter(List<SysUserRoleBind> list){
+        List<SysUserRoleBindDomainDTO> respDTO = new ArrayList<>();
+        if(ObjectUtil.isNotEmpty(list)){
+           respDTO = BeanCopyUtils.copyBeanList(list, SysUserRoleBindDomainDTO.class);
+        }
+        return respDTO;
+    }
+    public List<UserRoleBindAppRespDTO> userRoleBindAppConverter(List<SysUserRoleBindDomainDTO> list){
+        List<UserRoleBindAppRespDTO> respDTO = new ArrayList<>();
+        if(ObjectUtil.isNotEmpty(list)){
+            respDTO = BeanCopyUtils.copyBeanList(list, UserRoleBindAppRespDTO.class);
+        }
+        return respDTO;
+    }
+    public List<UserRoleBindRespDTO> userRoleBindConverter(List<SysUserRoleBindDomainDTO> list){
+        List<UserRoleBindRespDTO> respDTO = new ArrayList<>();
+        if(ObjectUtil.isNotEmpty(list)){
+            respDTO = BeanCopyUtils.copyBeanList(list, UserRoleBindRespDTO.class);
+        }
+        return respDTO;
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/Role.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/Role.java
new file mode 100644
index 0000000..5f72480
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/Role.java
@@ -0,0 +1,67 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.entity;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "sys_role")
+public class Role {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    //角色名
+    @Column
+    private String name;
+
+    //删除标志 0-未删除;1-删除
+    @Column
+    private Byte delFlag;
+
+    @Column
+    private LocalDateTime gmtCreate;
+
+    @Column
+    private LocalDateTime gmtModified;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Byte getDelFlag() {
+        return delFlag;
+    }
+
+    public void setDelFlag(Byte delFlag) {
+        this.delFlag = delFlag;
+    }
+
+    public LocalDateTime getGmtCreate() {
+        return gmtCreate;
+    }
+
+    public void setGmtCreate(LocalDateTime gmtCreate) {
+        this.gmtCreate = gmtCreate;
+    }
+
+    public LocalDateTime getGmtModified() {
+        return gmtModified;
+    }
+
+    public void setGmtModified(LocalDateTime gmtModified) {
+        this.gmtModified = gmtModified;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/RoleMenuBind.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/RoleMenuBind.java
new file mode 100644
index 0000000..a7aff21
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/RoleMenuBind.java
@@ -0,0 +1,65 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.entity;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "sys_role_menu_bind")
+public class RoleMenuBind {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @Column
+    private Long roleId;
+
+    @Column
+    private Long menuItemId;
+
+    @Column
+    private LocalDateTime gmtCreate;
+
+    @Column
+    private LocalDateTime gmtModified;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getRoleId() {
+        return roleId;
+    }
+
+    public void setRoleId(Long roleId) {
+        this.roleId = roleId;
+    }
+
+    public Long getMenuItemId() {
+        return menuItemId;
+    }
+
+    public void setMenuItemId(Long menuItemId) {
+        this.menuItemId = menuItemId;
+    }
+
+    public LocalDateTime getGmtCreate() {
+        return gmtCreate;
+    }
+
+    public void setGmtCreate(LocalDateTime gmtCreate) {
+        this.gmtCreate = gmtCreate;
+    }
+
+    public LocalDateTime getGmtModified() {
+        return gmtModified;
+    }
+
+    public void setGmtModified(LocalDateTime gmtModified) {
+        this.gmtModified = gmtModified;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/SysDepartment.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/SysDepartment.java
new file mode 100644
index 0000000..317a533
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/SysDepartment.java
@@ -0,0 +1,68 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/7
+ * @time: 13:25
+ */
+@EntityListeners(AuditingEntityListener.class)
+@Data
+@Entity
+@Table(name="sys_department")
+public class SysDepartment {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+    /**
+     * 部门
+     */
+    private String depName;
+    /**
+     * 等级
+     */
+    private Byte level;
+    /**
+     * 父级id
+     */
+    private Long parentId;
+    /**
+     * 描述
+     */
+    private String info;
+    /**
+     * 删除标识 0未删除,2删除
+     */
+    private Byte deleteStatus;
+    /**
+     * 创建时间
+     */
+    @JsonFormat
+    @CreatedDate
+    @Column(name = "create_time",updatable = false)
+    private LocalDateTime createTime;
+    /**
+     * 修改时间
+     */
+    @JsonFormat
+    @LastModifiedDate
+    private LocalDateTime updateTime;
+    /**
+     * 创建人
+     */
+    private Long createByUserId;
+    /**
+     * 更新人
+     */
+    private Long updateByUserId;
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/SysUserIdentityBind.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/SysUserIdentityBind.java
new file mode 100644
index 0000000..f74afd8
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/SysUserIdentityBind.java
@@ -0,0 +1,26 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/4/27
+ * @time: 16:09
+ */
+@Data
+@Entity
+@Table(name = "sys_user_identity_bind")
+public class SysUserIdentityBind {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+    private Long userId;
+    private Long userIdentityId;
+
+    @OneToOne(targetEntity = UserIdentity.class,fetch = FetchType.EAGER)
+    @JoinColumn(name = "userIdentityId",referencedColumnName = "id",insertable =false ,updatable = false)
+    private UserIdentity userIdentity;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/SysUserRoleBind.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/SysUserRoleBind.java
new file mode 100644
index 0000000..ab50867
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/SysUserRoleBind.java
@@ -0,0 +1,29 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/9
+ * @time: 15:43
+ */
+@Data
+@Entity
+@Table(name = "sys_user_role_bind")
+public class SysUserRoleBind {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    private Long userId;
+
+    private Long roleId;
+
+    @OneToOne(targetEntity = Role.class,fetch = FetchType.EAGER)
+    @JoinColumn(name = "roleId",referencedColumnName = "id",insertable =false ,updatable = false)
+    private Role role;
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/User.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/User.java
new file mode 100644
index 0000000..4d1bcfd
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/User.java
@@ -0,0 +1,88 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.entity;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.attachment.entity.AttachmentInfo;
+import lombok.Data;
+import org.hibernate.annotations.Fetch;
+import org.hibernate.annotations.FetchMode;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Entity
+//@JsonIgnoreProperties(value = { "hibernateLazyInitializer"})
+@Table(name = "sys_user")
+//@Proxy(lazy = false)
+@Data
+public class User {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    //用户账号状态
+    @Column
+    private Byte status;
+
+    //部门ID
+    private Long depId;
+
+    //创建时间
+    @Column
+    private LocalDateTime gmtCreate;
+
+    //修改时间
+    @Column
+    private LocalDateTime gmtModified;
+
+    @Column
+    private String name;
+
+    @Column
+    private String salt;
+
+    @Column
+    private String hash;
+
+    //真实姓名
+    @Column
+    private String realName;
+
+    //手机号
+    @Column
+    private String phone;
+
+    //证件类型
+    @Column
+    private Byte idType;
+
+    //身份证号
+    @Column
+    private String idSerial;
+    /**
+     * 身份(0专家,1非专家)
+     */
+    private Byte identityStatus;
+    //资质证书id
+    private Long qualificationAttId;
+
+
+    @OneToMany(fetch = FetchType.EAGER,cascade = {CascadeType.REFRESH})
+    @Fetch(FetchMode.SUBSELECT)
+    @JoinColumn(name = "userId",referencedColumnName = "id",insertable =false ,updatable = false)
+    private List<SysUserRoleBind> sysUserRoleBinds;
+
+    @OneToMany(fetch = FetchType.EAGER,cascade = {CascadeType.REFRESH})
+    @Fetch(FetchMode.SUBSELECT)
+    @JoinColumn(name = "userId",referencedColumnName = "id",insertable =false ,updatable = false)
+    private List<SysUserIdentityBind> sysUserIdentityBinds;
+
+    @ManyToOne(fetch = FetchType.EAGER,cascade = {CascadeType.REFRESH})
+    @JoinColumn(name = "depId",referencedColumnName = "id",insertable =false ,updatable = false)
+    private SysDepartment sysDepartment;
+
+    @OneToOne(fetch = FetchType.EAGER,cascade = {CascadeType.REFRESH})
+    @JoinColumn(name = "qualificationAttId",referencedColumnName = "id",insertable =false ,updatable = false)
+    private AttachmentInfo qualificationAttachment;
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/UserIdentity.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/UserIdentity.java
new file mode 100644
index 0000000..e371c0a
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/entity/UserIdentity.java
@@ -0,0 +1,24 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/4/27
+ * @time: 16:08
+ */
+@Data
+@Table(name = "user_identity")
+@Entity
+public class UserIdentity {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+    private String identity;
+    private String info;
+
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/enums/IdentityStatusEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/enums/IdentityStatusEnum.java
new file mode 100644
index 0000000..556acd3
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/enums/IdentityStatusEnum.java
@@ -0,0 +1,48 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.enums;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum IdentityStatusEnum {
+    EXPERT((byte)0,"专家"),
+    NOT_EXPERT((byte)1,"非专家")
+    ;
+
+    private Byte status;
+    private String dec;
+
+    IdentityStatusEnum(Byte status, String dec) {
+        this.status = status;
+        this.dec = dec;
+    }
+
+    public Byte getStatus() {
+        return status;
+    }
+
+    public void setStatus(Byte status) {
+        this.status = status;
+    }
+
+    public String getDec() {
+        return dec;
+    }
+
+    public void setDec(String dec) {
+        this.dec = dec;
+    }
+
+    static Map<Byte, IdentityStatusEnum> map;
+
+    static {
+        map = new HashMap<>();
+        for(IdentityStatusEnum e : IdentityStatusEnum.values()){
+            map.put(e.status,e);
+        }
+    }
+
+    public static IdentityStatusEnum prase(Byte status){
+        return map.get(status);
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/enums/UserIdTypeEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/enums/UserIdTypeEnum.java
new file mode 100644
index 0000000..7bea852
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/enums/UserIdTypeEnum.java
@@ -0,0 +1,54 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.enums;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum UserIdTypeEnum {
+    TYPE_JUMIN_SHENFENZHENG((byte)1,"居民身份证"),
+    ;
+
+    private Byte type;
+    private String dec;
+
+    UserIdTypeEnum(Byte type, String dec) {
+        this.type = type;
+        this.dec = dec;
+    }
+
+    public Byte getType() {
+        return type;
+    }
+
+    public void setType(Byte type) {
+        this.type = type;
+    }
+
+    public static Map<Byte, UserIdTypeEnum> getMap() {
+        return map;
+    }
+
+    public static void setMap(Map<Byte, UserIdTypeEnum> map) {
+        UserIdTypeEnum.map = map;
+    }
+
+    public String getDec() {
+        return dec;
+    }
+
+    public void setDec(String dec) {
+        this.dec = dec;
+    }
+
+    static Map<Byte, UserIdTypeEnum> map;
+
+    static {
+        map = new HashMap<>();
+        for(UserIdTypeEnum e : UserIdTypeEnum.values()){
+            map.put(e.type,e);
+        }
+    }
+
+    public static UserIdTypeEnum prase(Byte type){
+        return map.get(type);
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/enums/UserStatusEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/enums/UserStatusEnum.java
new file mode 100644
index 0000000..b990d36
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/enums/UserStatusEnum.java
@@ -0,0 +1,57 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.enums;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public enum UserStatusEnum {
+    STATUS_ACTIVE((byte)1,"正常使用"),
+    STATUS_FROZEN((byte)2,"冻结"),
+    STATUS_DELETE((byte)3,"删除")
+    ;
+
+    private Byte status;
+    private String dec;
+
+    UserStatusEnum(Byte status, String dec) {
+        this.status = status;
+        this.dec = dec;
+    }
+
+    public Byte getStatus() {
+        return status;
+    }
+
+    public void setStatus(Byte status) {
+        this.status = status;
+    }
+
+    public String getDec() {
+        return dec;
+    }
+
+    public void setDec(String dec) {
+        this.dec = dec;
+    }
+
+    static Map<Byte,UserStatusEnum> map;
+
+    static {
+        map = new HashMap<>();
+        for(UserStatusEnum e : UserStatusEnum.values()){
+            map.put(e.status,e);
+        }
+    }
+
+    public static UserStatusEnum prase(Byte status){
+        return map.get(status);
+    }
+
+    public static List<Integer> getActiveUserStatus(){
+        List<Integer> statusList = new ArrayList<>();
+        statusList.add(1);
+        statusList.add(2);
+        return statusList;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/CreateUserBO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/CreateUserBO.java
new file mode 100644
index 0000000..7a8c857
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/CreateUserBO.java
@@ -0,0 +1,25 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo;
+
+import lombok.Data;
+
+@Data
+public class CreateUserBO {
+
+    private String name;
+
+    private String realName;
+
+    private String phone;
+
+    private String pwd;
+
+    private Byte idType;
+
+    private String idSerial;
+
+    private Long depId;
+
+    private Byte identityStatus;
+
+    private Long qualificationAttId;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/MenuItemBindRoleBO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/MenuItemBindRoleBO.java
new file mode 100644
index 0000000..e78a917
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/MenuItemBindRoleBO.java
@@ -0,0 +1,36 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo;
+
+import java.util.List;
+
+public class MenuItemBindRoleBO {
+
+    private Long menuItemId;
+
+    private List<Long> bindRoleIdList;
+
+    private List<Long> unbindRoleIdList;
+
+    public Long getMenuItemId() {
+        return menuItemId;
+    }
+
+    public void setMenuItemId(Long menuItemId) {
+        this.menuItemId = menuItemId;
+    }
+
+    public List<Long> getBindRoleIdList() {
+        return bindRoleIdList;
+    }
+
+    public void setBindRoleIdList(List<Long> bindRoleIdList) {
+        this.bindRoleIdList = bindRoleIdList;
+    }
+
+    public List<Long> getUnbindRoleIdList() {
+        return unbindRoleIdList;
+    }
+
+    public void setUnbindRoleIdList(List<Long> unbindRoleIdList) {
+        this.unbindRoleIdList = unbindRoleIdList;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/RoleBindMenuItemBO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/RoleBindMenuItemBO.java
new file mode 100644
index 0000000..cc5a838
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/RoleBindMenuItemBO.java
@@ -0,0 +1,36 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo;
+
+import java.util.List;
+
+public class RoleBindMenuItemBO {
+
+    private Long roleId;
+
+    private List<Long> bindMenuItemIdList;
+
+    private List<Long> unbindMenuItemIdList;
+
+    public Long getRoleId() {
+        return roleId;
+    }
+
+    public void setRoleId(Long roleId) {
+        this.roleId = roleId;
+    }
+
+    public List<Long> getBindMenuItemIdList() {
+        return bindMenuItemIdList;
+    }
+
+    public void setBindMenuItemIdList(List<Long> bindMenuItemIdList) {
+        this.bindMenuItemIdList = bindMenuItemIdList;
+    }
+
+    public List<Long> getUnbindMenuItemIdList() {
+        return unbindMenuItemIdList;
+    }
+
+    public void setUnbindMenuItemIdList(List<Long> unbindMenuItemIdList) {
+        this.unbindMenuItemIdList = unbindMenuItemIdList;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/SysDepartmentBO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/SysDepartmentBO.java
new file mode 100644
index 0000000..943a503
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/SysDepartmentBO.java
@@ -0,0 +1,30 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo;
+
+import lombok.Data;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/7
+ * @time: 17:31
+ */
+@Data
+public class SysDepartmentBO {
+    private Long id;
+    /**
+     * 部门
+     */
+    private String depName;
+    /**
+     * 等级
+     */
+    private Byte level;
+    /**
+     * 父级id
+     */
+    private Long parentId;
+    /**
+     * 描述
+     */
+    private String info;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/UpdateUserBO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/UpdateUserBO.java
new file mode 100644
index 0000000..fb2570e
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/UpdateUserBO.java
@@ -0,0 +1,31 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class UpdateUserBO {
+
+    private Long id;
+
+    private String name;
+
+    private String realName;
+
+    private String phone;
+
+    private Byte idType;
+
+    private String idSerial;
+
+    private Long depId;
+
+    private Byte identityStatus;
+
+    private List<Long> identityIds;
+
+    private Long qualificationAttId;
+
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/UserBindRoleBO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/UserBindRoleBO.java
new file mode 100644
index 0000000..87cfbde
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/bo/UserBindRoleBO.java
@@ -0,0 +1,15 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo;
+
+import lombok.Data;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/13
+ * @time: 9:10
+ */
+@Data
+public class UserBindRoleBO {
+    private Long userId;
+    private Long RoleId;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/RoleInfoDoaminDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/RoleInfoDoaminDTO.java
new file mode 100644
index 0000000..84f0aec
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/RoleInfoDoaminDTO.java
@@ -0,0 +1,25 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto;
+
+public class RoleInfoDoaminDTO {
+
+    private Long id;
+
+    private String name;
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/SysDepartmentDomainDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/SysDepartmentDomainDTO.java
new file mode 100644
index 0000000..4c8796c
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/SysDepartmentDomainDTO.java
@@ -0,0 +1,34 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto;
+
+
+import lombok.Data;
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/9
+ * @time: 8:59
+ */
+@Data
+public class SysDepartmentDomainDTO {
+    private Long id;
+    /**
+     * 部门
+     */
+    private String depName;
+    /**
+     * 等级
+     */
+    private Byte level;
+    /**
+     * 父级id
+     */
+    private Long parentId;
+    /**
+     * 描述
+     */
+    private String info;
+
+    private List<SysDepartmentDomainDTO> children;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/SysUserIdentityBindDomainDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/SysUserIdentityBindDomainDTO.java
new file mode 100644
index 0000000..2b42eb8
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/SysUserIdentityBindDomainDTO.java
@@ -0,0 +1,15 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto;
+
+import lombok.Data;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/4
+ * @time: 10:45
+ */
+@Data
+public class SysUserIdentityBindDomainDTO {
+    private Long userIdentityId;
+    private String userIdentity;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/SysUserRoleBindDomainDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/SysUserRoleBindDomainDTO.java
new file mode 100644
index 0000000..7f9db9f
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/SysUserRoleBindDomainDTO.java
@@ -0,0 +1,17 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto;
+
+import lombok.Data;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/13
+ * @time: 10:35
+ */
+@Data
+public class SysUserRoleBindDomainDTO {
+    private Long id;
+    private Long userId;
+    private Long roleId;
+    private String roleName;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/UserIdentityDomainDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/UserIdentityDomainDTO.java
new file mode 100644
index 0000000..a11cce8
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/UserIdentityDomainDTO.java
@@ -0,0 +1,19 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto;
+
+import lombok.Data;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/4/28
+ * @time: 16:57
+ */
+@Data
+public class UserIdentityDomainDTO {
+
+    private Long id;
+    private String identity;
+    private String info;
+
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/UserInfoDomainDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/UserInfoDomainDTO.java
new file mode 100644
index 0000000..fe0aa94
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/model/dto/UserInfoDomainDTO.java
@@ -0,0 +1,55 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.attachment.dto.resp.AttachmentDomainDTO;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+import java.util.List;
+@Data
+public class UserInfoDomainDTO {
+
+    private Long id;
+
+    //用户账号状态
+    private Byte status;
+
+    //创建时间
+    private LocalDateTime gmtCreate;
+
+    //修改时间
+    private LocalDateTime gmtModified;
+
+    //登录用户名
+    private String name;
+
+    private String salt;
+
+    private String hash;
+
+    //真实姓名
+    private String realName;
+
+    private String phone;
+
+    private Byte idType;
+
+    private String idSerial;
+
+    private Long depId;
+
+    private String depName;
+
+    /**
+     * 身份(0专家,1非专家)
+     */
+    private Byte identityStatus;
+    //资质证书id
+    private Long qualificationAttId;
+
+    private List<SysUserRoleBindDomainDTO> roles;
+
+    private List<SysUserIdentityBindDomainDTO> userIdentities;
+
+    //资质附件
+    private AttachmentDomainDTO qualificationAttDomainDTO;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/RoleMenuBindRepository.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/RoleMenuBindRepository.java
new file mode 100644
index 0000000..b8a65da
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/RoleMenuBindRepository.java
@@ -0,0 +1,30 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.RoleMenuBind;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface RoleMenuBindRepository extends JpaRepository<RoleMenuBind,Long> {
+
+    List<RoleMenuBind> findAllByRoleIdAndMenuItemIdIn(Long roleId,List<Long> menuItemIds);
+
+    List<RoleMenuBind> findAllByMenuItemIdAndRoleIdIn(Long menuItemId,List<Long> roleIds);
+
+    List<RoleMenuBind> findAllByRoleId(Long roleId);
+
+    @Query(value = "select rb.roleId from RoleMenuBind rb where rb.menuItemId = :menuItemId")
+    List<Long> findBindRoleListByMenuItemId(Long menuItemId);
+
+    @Modifying
+    Integer deleteByMenuItemId(Long menuItemId);
+
+    @Modifying
+    Integer deleteByMenuItemIdAndRoleIdIn(Long menuItemId,List<Long> roleIds);
+
+    List<RoleMenuBind> findAllByRoleIdIn(List<Long> roleIds);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/RoleRepository.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/RoleRepository.java
new file mode 100644
index 0000000..23c1b61
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/RoleRepository.java
@@ -0,0 +1,34 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.Role;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Repository
+public interface RoleRepository extends JpaRepository<Role, Long> {
+
+    @Query(value = "select r from Role r where r.name = :name and r.delFlag = 0")
+    Role findRoleByName(String name);
+
+    List<Role> findAllByDelFlag(Byte delFlag);
+
+    @Query(value = "update Role r set r.delFlag = 1 where r.id = :roleId")
+    @Transactional
+    @Modifying
+    Integer deleteRole(Long roleId);
+
+    List<Role> findAllByIdIn(List<Long> idList);
+
+    @Query(value = "update Role r set r.name = :name where r.id = :roleId")
+    @Transactional
+    @Modifying
+    Integer updateRoleName(Long roleId,String name);
+    @Query(value = "select r from Role r where r.id in (:idList) and r.delFlag = 0")
+    List<Role> findAllByIdInAndDelFlag(List<Long> idList);
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/SysDeparmentRepository.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/SysDeparmentRepository.java
new file mode 100644
index 0000000..9f1d8e5
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/SysDeparmentRepository.java
@@ -0,0 +1,29 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.SysDepartment;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/8
+ * @time: 9:24
+ */
+public interface SysDeparmentRepository extends JpaRepository<SysDepartment, Long> {
+
+    @Query(value = "select s from SysDepartment s where s.id = :id and s.deleteStatus = 0")
+    SysDepartment findByIdAndDeleteStatus(Long id);
+    /**
+     * 根据父部门获取子部门
+     */
+    @Query(value = "select s from SysDepartment s where s.parentId = :parentId and s.deleteStatus = 0")
+    List<SysDepartment> findByParentIdAndDeleteStatus(Long parentId);
+    /**
+     * 获取所有部门
+     */
+    @Query(value = "select s from SysDepartment s where s.deleteStatus = 0")
+    List<SysDepartment> findByDeleteStatus();
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/SysUserIdentityBindReposity.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/SysUserIdentityBindReposity.java
new file mode 100644
index 0000000..3114f25
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/SysUserIdentityBindReposity.java
@@ -0,0 +1,28 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.SysUserIdentityBind;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/4/28
+ * @time: 17:07
+ */
+@Repository
+public interface SysUserIdentityBindReposity  extends JpaRepository<SysUserIdentityBind, Long> {
+    @Query(value = "select s.userIdentityId from SysUserIdentityBind s where s.userId = :userId")
+    List<Long> getByUserId(Long userId);
+    @Modifying
+    @Query(value = "delete from SysUserIdentityBind s where s.userId = :userId and s.userIdentityId in (:deleteUserIdentityIdList)")
+    int deleteByUserIdAndUserIdentityIds(Long userId, List<Long> deleteUserIdentityIdList);
+
+    @Modifying
+    @Query(value = "delete from SysUserIdentityBind s where s.userId = :userId")
+    int deleteByUserId(Long userId);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/UserIdentityRepository.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/UserIdentityRepository.java
new file mode 100644
index 0000000..805de55
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/UserIdentityRepository.java
@@ -0,0 +1,15 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.UserIdentity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/4/28
+ * @time: 16:52
+ */
+@Repository
+public interface UserIdentityRepository extends JpaRepository<UserIdentity, Long> {
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/UserRepository.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/UserRepository.java
new file mode 100644
index 0000000..4a37b20
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/UserRepository.java
@@ -0,0 +1,60 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Repository
+public interface UserRepository extends JpaRepository<User,Long> , JpaSpecificationExecutor<User> {
+
+    @Query(value = "select u from User u where u.name = :name  and u.status in (1,2)")
+    User findUserByName(String name);
+
+    List<User> findAllByIdIn(List<Long> userIdList);
+
+    @Modifying
+    @Query(value = "update User u set u.hash = :hash ,u.salt = :salt ,u.gmtModified = :time where u.id = :uid")
+    Integer updatePassword(Long uid, String hash, String salt, LocalDateTime time);
+
+    @Modifying
+    @Query(value = "update User u set u.status = :status ,u.gmtModified = :time where u.id = :uid")
+    Integer updateUserStatus(Long uid,Byte status,LocalDateTime time);
+
+    /*@Modifying
+    @Query(value = "update User u set u.roleId = :roleId ,u.gmtModified = :time where u.id = :uid")
+    Integer updateUserRole(Long uid,Long roleId,LocalDateTime time);*/
+
+    @Query(value = "select u from User u where u.phone = :phone and u.status in (1,2)")
+    User findUserByPhone(String phone);
+
+    @Query(value = "select u from User u where u.idType = :idType and u.idSerial = :idSerial and u.status in (1,2)")
+    User findByIdTypeAndIdSerial(Byte idType,String idSerial);
+
+    @Query("update User u set u.phone = :phone where u.id = :uid")
+    @Modifying
+    Integer updateUserPhone(Long uid,String phone);
+    /**
+     * 用户列表
+     */
+    @Query(value = "select * from sys_user  where status in (1,2)", nativeQuery = true)
+    List<User> getUserList();
+
+    @Query(value = "select u from User u where u.realName like %:name% and u.status in (1,2)")
+    List<User> getUsersByRealName(String name);
+
+    /**
+     * 用户列表
+     */
+    @Query(value = "select * from sys_user  where id = :evaluateUserId and status in (1,2)", nativeQuery = true)
+    User getUserInfoByIdAndSellInfo(Long evaluateUserId);
+    @Query(value = "select u from User u where u.id = :uid and u.status in (1,2)")
+    User getById(Long uid);
+
+    User findUserByIdAndStatus(Long userId, Byte status);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/UserRoleBindReposity.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/UserRoleBindReposity.java
new file mode 100644
index 0000000..a7f313a
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/repository/jpa/UserRoleBindReposity.java
@@ -0,0 +1,30 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.SysUserRoleBind;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/13
+ * @time: 9:48
+ */
+public interface UserRoleBindReposity extends JpaRepository<SysUserRoleBind, Long> {
+
+    List<SysUserRoleBind> findByUserId(Long userId);
+
+    @Query(value = "select s.roleId from SysUserRoleBind s where s.userId = :userId")
+    List<Long> getByUserId(Long userId);
+
+    @Modifying
+    @Query(value = "delete from SysUserRoleBind s where s.userId = :userId and s.roleId in (:roleIds)")
+    int deleteByUserIdAndRoleIds(Long userId,List<Long> roleIds);
+
+    @Modifying
+    @Query(value = "delete from SysUserRoleBind s where s.userId = :userId")
+    int deleteByUserId(Long userId);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/RoleDomainService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/RoleDomainService.java
new file mode 100644
index 0000000..28905c2
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/RoleDomainService.java
@@ -0,0 +1,32 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.service;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.RoleInfoDoaminDTO;
+
+import java.util.List;
+
+public interface RoleDomainService {
+
+    RoleInfoDoaminDTO createNewRole(String roleName);
+
+    RoleInfoDoaminDTO findRoleByName(String roleName);
+
+    RoleInfoDoaminDTO findRoleById(Long roleId);
+
+    List<RoleInfoDoaminDTO> findAllActiveRoleList();
+
+    List<RoleInfoDoaminDTO> findAllDeleteRoleList();
+
+    boolean deleteRole(Long roleId);
+
+    /**
+     * 变更用户角色
+     * @param uid
+     * @param roleId
+     * @return
+     */
+    boolean updateUserRole(Long uid,Long roleId);
+
+    boolean updateRoleName(Long roleId,String name);
+
+    List<RoleInfoDoaminDTO> findAllByIdIn(List<Long> idList);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/RoleMenuDomainService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/RoleMenuDomainService.java
new file mode 100644
index 0000000..cb5a7b7
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/RoleMenuDomainService.java
@@ -0,0 +1,18 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.service;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo.MenuItemBindRoleBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo.RoleBindMenuItemBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.model.dto.MenuItemDomainDTO;
+
+import java.util.List;
+
+public interface RoleMenuDomainService {
+
+    boolean roleBindMenu(RoleBindMenuItemBO bindBO);
+
+    boolean menuBindRole(MenuItemBindRoleBO bindBO);
+
+    List<MenuItemDomainDTO> getMenuInfoByRole(List<Long> roleIds);
+
+    List<Long> getBindRolesByMenuItemId(Long menuItemId);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/SysDepartmentDomainService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/SysDepartmentDomainService.java
new file mode 100644
index 0000000..53548e0
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/SysDepartmentDomainService.java
@@ -0,0 +1,24 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.service;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo.SysDepartmentBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.SysDepartmentDomainDTO;
+
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/7
+ * @time: 17:17
+ */
+public interface SysDepartmentDomainService {
+    SysDepartmentDomainDTO save(SysDepartmentBO sysDepartmentBO,Long currentUserId);
+    SysDepartmentDomainDTO update(SysDepartmentBO sysDepartmentBO,Long currentUserId);
+
+    SysDepartmentDomainDTO delete(Long id, Long currentUserId);
+
+    List<SysDepartmentDomainDTO> list();
+
+    SysDepartmentDomainDTO findById(Long id);
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/SysUserIdentityBindDomainService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/SysUserIdentityBindDomainService.java
new file mode 100644
index 0000000..981bf98
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/SysUserIdentityBindDomainService.java
@@ -0,0 +1,17 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.service;
+
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/4/28
+ * @time: 16:39
+ */
+public interface SysUserIdentityBindDomainService {
+    boolean insertBatchUserIndentityBind(List<Long> identityIds, Long userId);
+
+    boolean updateBatchUserIndentityBind(List<Long> identityIds, Long userId);
+
+    boolean deleteByUser(Long userId);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/UserDomainService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/UserDomainService.java
new file mode 100644
index 0000000..d24b4ad
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/UserDomainService.java
@@ -0,0 +1,136 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.service;
+
+import com.gkhy.fourierSpecialGasMonitor.api.controller.account.query.UserQuery;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo.CreateUserBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo.UpdateUserBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.UserInfoDomainDTO;
+
+import java.util.List;
+
+public interface UserDomainService {
+
+    /**
+     * 新增用户信息
+     * @param createUserBO
+     * @return
+     */
+    UserInfoDomainDTO newUser(CreateUserBO createUserBO);
+
+    /**
+     * 更新用户信息
+     * @param updateUserBO
+     * @return
+     */
+    UserInfoDomainDTO updateUserInfo(UpdateUserBO updateUserBO);
+
+    /**
+     * 根据用户ID获取用户信息
+     * @param uid
+     * @return
+     */
+    UserInfoDomainDTO getUserInfoById(Long uid);
+
+    /**
+     * 根据用户名获取用户信息
+     * @param name
+     * @return
+     */
+    UserInfoDomainDTO getUserInfoByName(String name);
+
+    List<UserInfoDomainDTO> findUserListByRealName(String name);
+
+    SearchResult<List<UserInfoDomainDTO>> findUserListByRole(Long roleId, boolean usePage, Integer page,
+                                                           Integer pageSize);
+
+    /**
+     * 根据用户ID列表批量获取用户信息
+     * @param uidList
+     * @return
+     */
+    List<UserInfoDomainDTO> getUserInfoListByIds(List<Long> uidList);
+
+    /**
+     * 更新用户密码
+     * @param uid
+     * @param oldPwd
+     * @param newPwd
+     * @return
+     */
+    boolean updateUserPwd(Long uid,String oldPwd,String newPwd);
+
+    /**
+     * 变更账号状态
+     * @param uid
+     * @param status
+     * @return
+     */
+    boolean updateUserStatus(Long uid,Byte status);
+
+    boolean updateUserRole(Long uid,Long roleId);
+
+    /**
+     * 校验密码
+     * @param pwd
+     * @param hash
+     * @param salt
+     * @return
+     */
+    boolean checkPassword(String pwd,String hash,String salt);
+
+    /**
+     * 手机号查找用户
+     * @param phoneNumber
+     * @return
+     */
+    UserInfoDomainDTO findUserByPhone(String phoneNumber);
+
+    /**
+     * 证件号查找用户
+     * @param idType
+     * @param idSerial
+     * @return
+     */
+    UserInfoDomainDTO findUserByIdSerial(Byte idType, String idSerial);
+
+    /**
+     * 修改手机号
+     * @param uid
+     * @param phoneNumber
+     * @return
+     */
+    boolean updateUserPhoneNumber(Long uid,String phoneNumber);
+
+    /**
+     * 删除用户
+     * @param uid
+     * @return
+     */
+    boolean deleteUser(Long uid);
+
+    UserInfoDomainDTO getUserById(Long id);
+    /**
+     * 用户列表
+     */
+    List<UserInfoDomainDTO> getUserList();
+
+    /**
+     * 用户查询
+     */
+    UserInfoDomainDTO getUserInfoByIdAndSellInfo(Long evaluateUserId, String info);
+
+    /**
+     * 用户列表
+     * @param pageQuery
+     * @return
+     */
+    SearchResult<List<UserInfoDomainDTO>> findUserList(PageQuery<UserQuery> pageQuery);
+
+    /**
+     * 专家库
+     * @param pageQuery
+     * @return
+     */
+    SearchResult<List<UserInfoDomainDTO>> findExpertList(PageQuery<UserQuery> pageQuery);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/UserIdentityDomainService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/UserIdentityDomainService.java
new file mode 100644
index 0000000..d771ba3
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/UserIdentityDomainService.java
@@ -0,0 +1,17 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.service;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.UserIdentityDomainDTO;
+
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/4/28
+ * @time: 16:29
+ */
+public interface UserIdentityDomainService {
+    List<UserIdentityDomainDTO> getListByIds(List<Long> identityIds);
+
+    List<UserIdentityDomainDTO> getList();
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/UserRoleDomainService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/UserRoleDomainService.java
new file mode 100644
index 0000000..7c77df7
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/UserRoleDomainService.java
@@ -0,0 +1,21 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.service;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.SysUserRoleBindDomainDTO;
+
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/13
+ * @time: 9:25
+ */
+public interface UserRoleDomainService {
+    List<SysUserRoleBindDomainDTO> insertBatchUserBindRole(List<Long> roleIds, Long id);
+
+    void updateUserRole(Long userId, List<Long> roleIds);
+
+    boolean deleteByUser(Long userId);
+
+    //List<SysUserRoleBindDomainDTO> getUserRoleBind(Long userId);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/RoleDomainServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/RoleDomainServiceImpl.java
new file mode 100644
index 0000000..e139b74
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/RoleDomainServiceImpl.java
@@ -0,0 +1,148 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.service.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.converter.RoleInfoConverter;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.Role;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.RoleInfoDoaminDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa.RoleRepository;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.RoleDomainService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+@Repository
+public class RoleDomainServiceImpl implements RoleDomainService {
+
+    @Autowired
+    private RoleRepository roleRepository;
+
+    @Autowired
+    private RoleInfoConverter roleInfoConverter;
+
+    @Override
+    @Transactional
+    public RoleInfoDoaminDTO createNewRole(String roleName) {
+        if(roleName == null || roleName.isEmpty())
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数缺失");
+        Role role = roleRepository.findRoleByName(roleName);
+        if(role != null)
+            throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_NOT_ALLOWED.getCode(),"角色名已经被使用");
+        role = new Role();
+        role.setName(roleName);
+        role.setDelFlag((byte)0);
+        role.setGmtCreate(LocalDateTime.now());
+        role.setGmtModified(role.getGmtCreate());
+        role = roleRepository.save(role);
+        if(role == null)
+            return null;
+        RoleInfoDoaminDTO roleInfoDoaminDTO = roleInfoConverter.roleRoleInfoDTO(role);
+        return roleInfoDoaminDTO;
+    }
+
+    @Override
+    public RoleInfoDoaminDTO findRoleByName(String roleName) {
+        Role role = roleRepository.findRoleByName(roleName);
+        if(role == null)
+            return null;
+        RoleInfoDoaminDTO roleInfoDoaminDTO = roleInfoConverter.roleRoleInfoDTO(role);
+        return roleInfoDoaminDTO;
+    }
+
+    @Override
+    public RoleInfoDoaminDTO findRoleById(Long roleId) {
+        if(roleId == null || roleId < 1)
+            return null;
+        Optional<Role> roleOptional = roleRepository.findById(roleId);
+        if(!roleOptional.isPresent())
+            return null;
+        RoleInfoDoaminDTO roleInfoDoaminDTO = roleInfoConverter.roleRoleInfoDTO(roleOptional.get());
+        return roleInfoDoaminDTO;
+    }
+
+    @Override
+    public List<RoleInfoDoaminDTO> findAllActiveRoleList() {
+        List<Role> roleList = roleRepository.findAllByDelFlag((byte)0);
+        if(roleList == null || roleList.isEmpty())
+            return null;
+        List<RoleInfoDoaminDTO> dtoList = new ArrayList<>();
+        for (Role role : roleList){
+            RoleInfoDoaminDTO dto = roleInfoConverter.roleRoleInfoDTO(role);
+            dtoList.add(dto);
+        }
+        return dtoList;
+    }
+
+    @Override
+    public List<RoleInfoDoaminDTO> findAllDeleteRoleList() {
+        List<Role> roleList = roleRepository.findAllByDelFlag((byte)1);
+        if(roleList == null || roleList.isEmpty())
+            return null;
+        List<RoleInfoDoaminDTO> dtoList = new ArrayList<>();
+        for (Role role : roleList){
+            RoleInfoDoaminDTO dto = roleInfoConverter.roleRoleInfoDTO(role);
+            dtoList.add(dto);
+        }
+        return dtoList;
+    }
+
+    @Override
+    @Transactional
+    public boolean deleteRole(Long roleId) {
+        if(roleId == null || roleId < 1)
+            return false;
+        if(roleRepository.deleteRole(roleId) == 1)
+            return true;
+        return false;
+    }
+
+    @Override
+    @Transactional
+    public boolean updateUserRole(Long uid, Long roleId) {
+        return false;
+    }
+
+    @Override
+    @Transactional
+    public boolean updateRoleName(Long roleId, String name) {
+        if(roleId == null || name == null || name.isEmpty())
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数缺失");
+        Optional<Role> roleOptional = roleRepository.findById(roleId);
+        if(!roleOptional.isPresent()){
+            throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_OBJECT_NOT_EXIST.getCode(),"角色不存在");
+        }
+        Role oldRole = roleOptional.get();
+        if(oldRole.getName() != null && !oldRole.getName().isEmpty() && oldRole.getName().equals(name)){
+            throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_NOT_ALLOWED.getCode(),"角色名称未发生变化");
+        }
+        Integer count = roleRepository.updateRoleName(roleId,name);
+        if(count == 1)
+            return true;
+        else
+            throw new BusinessException(this.getClass(),ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"数据库出错");
+    }
+
+    //根据ids获取角色
+    @Override
+    public List<RoleInfoDoaminDTO> findAllByIdIn(List<Long> idList){
+        if(ObjectUtil.isEmpty(idList)){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数缺失");
+        }
+        List<Role> roles = roleRepository.findAllByIdInAndDelFlag(idList);
+        List<RoleInfoDoaminDTO> roleInfoDoaminDTOS = new ArrayList<>();
+        for (Role role:roles){
+            RoleInfoDoaminDTO roleInfoDoaminDTO = new RoleInfoDoaminDTO();
+            roleInfoDoaminDTO.setId(role.getId());
+            roleInfoDoaminDTO.setName(role.getName());
+            roleInfoDoaminDTOS.add(roleInfoDoaminDTO);
+        }
+        return roleInfoDoaminDTOS;
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/RoleMenuDomainServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/RoleMenuDomainServiceImpl.java
new file mode 100644
index 0000000..9434b42
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/RoleMenuDomainServiceImpl.java
@@ -0,0 +1,151 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.service.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.Role;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.RoleMenuBind;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo.MenuItemBindRoleBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo.RoleBindMenuItemBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa.RoleMenuBindRepository;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa.RoleRepository;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.RoleMenuDomainService;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.model.dto.MenuItemDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.service.MenuDomainService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+@Service
+public class RoleMenuDomainServiceImpl implements RoleMenuDomainService {
+
+    @Autowired
+    private RoleMenuBindRepository roleMenuBindRepository;
+
+    @Autowired
+    private RoleRepository roleRepository;
+    @Autowired
+    private MenuDomainService menuDomainService;
+    @Override
+    @Transactional
+    public boolean roleBindMenu(RoleBindMenuItemBO bindBO) {
+        if(bindBO == null || bindBO.getRoleId() == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        //校验角色
+        Optional<Role> roleOptional = roleRepository.findById(bindBO.getRoleId());
+        if(!roleOptional.isPresent())
+            throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_OBJECT_NOT_EXIST.getCode(),"角色不存在");
+        if(bindBO.getUnbindMenuItemIdList() != null && bindBO.getUnbindMenuItemIdList().size() > 0){
+            //解绑菜单关联
+            //1、检查绑定状态
+            List<RoleMenuBind> unbindCheckList =
+                    roleMenuBindRepository.findAllByRoleIdAndMenuItemIdIn(bindBO.getRoleId(),
+                            bindBO.getUnbindMenuItemIdList());
+            if(unbindCheckList == null || unbindCheckList.size() != bindBO.getUnbindMenuItemIdList().size())
+                throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_OBJECT_NOT_EXIST.getCode(), "角色未拥有该菜单项访问权限");
+            try {
+                roleMenuBindRepository.deleteAllByIdInBatch(bindBO.getUnbindMenuItemIdList());
+            } catch (Exception e) {
+                throw new BusinessException(this.getClass(),ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(), "解除角色菜单项出错");
+            }
+        }
+        if(bindBO.getBindMenuItemIdList() != null && bindBO.getBindMenuItemIdList().size() > 0){
+            //增加菜单关联
+            //1、检查绑定状态
+            List<RoleMenuBind> bindCheckList =
+                    roleMenuBindRepository.findAllByRoleIdAndMenuItemIdIn(bindBO.getRoleId(),
+                            bindBO.getBindMenuItemIdList());
+            if(bindCheckList != null && bindCheckList.size() > 0)
+                throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_NOT_ALLOWED.getCode(), "角色已拥有菜单权限");
+            //2、校验菜单
+            List<MenuItemDomainDTO> checkBindMenuItems = menuDomainService.getActiveMenuItemListByIds(bindBO.getBindMenuItemIdList());
+            if(checkBindMenuItems == null || checkBindMenuItems.size() != bindBO.getBindMenuItemIdList().size()){
+                throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_OBJECT_NOT_EXIST.getCode(), "菜单项不存在");
+            }
+            //3、添加角色菜单项绑定
+            List<RoleMenuBind> bindList = new ArrayList<>();
+            checkBindMenuItems.forEach(item -> {
+                RoleMenuBind b = new RoleMenuBind();
+                b.setRoleId(bindBO.getRoleId());
+                b.setMenuItemId(item.getId());
+                b.setGmtCreate(LocalDateTime.now());
+                b.setGmtModified(b.getGmtCreate());
+                bindList.add(b);
+            });
+            List<RoleMenuBind> saveRs = roleMenuBindRepository.saveAll(bindList);
+            if(saveRs.size() != bindList.size())
+                throw new BusinessException(this.getClass(),ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"保存出错");
+        }
+        return true;
+    }
+
+    @Override
+    @Transactional
+    public boolean menuBindRole(MenuItemBindRoleBO bindBO) {
+        if(bindBO == null || bindBO.getMenuItemId() == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        //1、校验菜单
+        MenuItemDomainDTO menuItemDomainDTO = menuDomainService.getMenuItemById(bindBO.getMenuItemId());
+        if(menuItemDomainDTO == null)
+            throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_OBJECT_NOT_EXIST.getCode(),"菜单项不存在");
+        //2、校验绑定角色
+        if(bindBO.getBindRoleIdList() != null && !bindBO.getBindRoleIdList().isEmpty()){
+            List<Role> roleList = roleRepository.findAllByIdIn(bindBO.getBindRoleIdList());
+            if(roleList == null || roleList.isEmpty() || roleList.size() != bindBO.getBindRoleIdList().size()){
+                throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_OBJECT_NOT_EXIST.getCode(), "角色不存在");
+            }
+            //绑定角色菜单
+            List<RoleMenuBind> bindList = new ArrayList<>();
+            roleList.forEach(r -> {
+                RoleMenuBind bind = new RoleMenuBind();
+                bind.setRoleId(r.getId());
+                bind.setMenuItemId(bindBO.getMenuItemId());
+                bind.setGmtCreate(LocalDateTime.now());
+                bind.setGmtModified(bind.getGmtCreate());
+                bindList.add(bind);
+            });
+            List<RoleMenuBind> saveRs = roleMenuBindRepository.saveAll(bindList);
+            if(saveRs == null || saveRs.isEmpty() || saveRs.size() != bindList.size()){
+                throw new BusinessException(this.getClass(),ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"数据库错误");
+            }
+        }
+        //3、校验解绑角色
+        if(bindBO.getUnbindRoleIdList() != null && !bindBO.getUnbindRoleIdList().isEmpty()){
+            //解绑角色菜单
+            List<RoleMenuBind> bindList = roleMenuBindRepository.findAllByMenuItemIdAndRoleIdIn(bindBO.getMenuItemId(), bindBO.getUnbindRoleIdList());
+            if(bindList != null && !bindList.isEmpty()){
+                roleMenuBindRepository.deleteAll(bindList);
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public List<MenuItemDomainDTO> getMenuInfoByRole(List<Long> roleIds) {
+        if(ObjectUtil.isEmpty(roleIds))
+            return null;
+        List<RoleMenuBind> bindList = roleMenuBindRepository.findAllByRoleIdIn(roleIds);
+        if(bindList == null || bindList.isEmpty())
+            return null;
+        List<Long> menuItemIdList = new ArrayList<>();
+        bindList.forEach(b -> {
+            menuItemIdList.add(b.getMenuItemId());
+        });
+//        List<MenuItemDTO> menuItemList = menuDomainService.getActiveMenuItemListByIds(menuItemIdList);
+        List<MenuItemDomainDTO> menuItemList = menuDomainService.getActiveMenuItemListTreeByIds(menuItemIdList);
+        return menuItemList;
+    }
+
+    @Override
+    public List<Long> getBindRolesByMenuItemId(Long menuItemId) {
+        if(menuItemId == null || menuItemId < 1)
+            return null;
+        List<Long> bindRoles = roleMenuBindRepository.findBindRoleListByMenuItemId(menuItemId);
+        return bindRoles;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/SysDepartmentDomainServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/SysDepartmentDomainServiceImpl.java
new file mode 100644
index 0000000..2667a6b
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/SysDepartmentDomainServiceImpl.java
@@ -0,0 +1,166 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.service.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.converter.SysDeparmentConverter;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.SysDepartment;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo.SysDepartmentBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.SysDepartmentDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa.SysDeparmentRepository;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.SysDepartmentDomainService;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/7
+ * @time: 17:18
+ */
+@Service
+public class SysDepartmentDomainServiceImpl implements SysDepartmentDomainService {
+
+    @Autowired
+    private SysDeparmentRepository repository;
+
+    @Autowired
+    private SysDeparmentConverter converter;
+
+    @Override
+    public SysDepartmentDomainDTO save(SysDepartmentBO sysDepartmentBO,Long currentUserId) {
+        if (ObjectUtil.isEmpty(sysDepartmentBO.getDepName())) {
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR.getCode(),"请填写部门名称");
+        }
+        byte depLevel = 0;
+        if(ObjectUtil.isEmpty(sysDepartmentBO.getParentId())){
+            depLevel = 1;
+        }
+        if (!ObjectUtil.isEmpty(sysDepartmentBO.getParentId())) {
+            //验证父级部门
+            SysDepartment parentDep = repository.findByIdAndDeleteStatus(sysDepartmentBO.getParentId());
+            if(ObjectUtil.isEmpty(parentDep)){
+                throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_DATA_NOT_EXISIST.getCode(),"父级部门不存在!");
+            }
+            depLevel = (byte)(parentDep.getLevel()+1);
+        }
+
+        //复制
+        SysDepartment sysDepartment = new SysDepartment();
+        BeanUtils.copyProperties(sysDepartmentBO,sysDepartment);
+        sysDepartment.setDeleteStatus((byte)0);
+        sysDepartment.setLevel(depLevel);
+        sysDepartment.setCreateByUserId(currentUserId);
+        sysDepartment.setUpdateByUserId(currentUserId);
+        SysDepartmentDomainDTO sysDepartmentDomainDTO = converter.sysDepDomainDTOConverter(repository.save(sysDepartment));
+
+        return sysDepartmentDomainDTO;
+    }
+
+    @Override
+    public SysDepartmentDomainDTO update(SysDepartmentBO sysDepartmentBO,Long currentUserId) {
+        if (ObjectUtil.isEmpty(sysDepartmentBO.getId())) {
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR.getCode(),"主键不可为空!");
+        }
+        if (ObjectUtil.isEmpty(sysDepartmentBO.getDepName())) {
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR.getCode(),"请填写部门名称");
+        }
+        SysDepartment sysDepartment = repository.findByIdAndDeleteStatus(sysDepartmentBO.getId());
+        if(sysDepartment == null){
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_DATA_NOT_EXISIST.getCode(),"该部门不存在,不可修改!");
+        }
+
+        //复制
+        sysDepartment.setDepName(sysDepartmentBO.getDepName());
+        sysDepartment.setUpdateByUserId(currentUserId);
+        sysDepartment.setInfo(sysDepartmentBO.getInfo());
+        SysDepartmentDomainDTO sysDepartmentDomainDTO = converter.sysDepDomainDTOConverter(repository.save(sysDepartment));
+        return sysDepartmentDomainDTO;
+    }
+
+    @Override
+    public SysDepartmentDomainDTO delete(Long id, Long currentUserId) {
+        SysDepartment sysDepartment = repository.findByIdAndDeleteStatus(id);
+        if(sysDepartment == null){
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_DATA_NOT_EXISIST.getCode(),"该部门不存在,不可修改!");
+        }
+        //验证该部门下子部门
+        if (!checkDepChildren(id)) {
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_NOT_ALLOWED.getCode(),"该部门存在子部门,请先删除子部门!");
+        }
+        sysDepartment.setDeleteStatus((byte)1);
+        SysDepartmentDomainDTO sysDepartmentDomainDTO = converter.sysDepDomainDTOConverter(repository.save(sysDepartment));
+        return sysDepartmentDomainDTO;
+    }
+    @Override
+    public SysDepartmentDomainDTO findById(Long id){
+        if(ObjectUtil.isEmpty(id)){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR.getCode(),"主键不可为空!");
+        }
+        SysDepartment sysDepartment = repository.findByIdAndDeleteStatus(id);
+        SysDepartmentDomainDTO sysDepartmentDomainDTO = converter.sysDepDomainDTOConverter(sysDepartment);
+        return sysDepartmentDomainDTO;
+    }
+
+
+    @Override
+    public List<SysDepartmentDomainDTO> list() {
+        List<SysDepartment> list = repository.findByDeleteStatus();
+        List<SysDepartment> parentList = list.stream().filter(item -> item.getParentId() == null).collect(Collectors.toList());
+        List<SysDepartment> childList = list.stream().filter(item -> item.getParentId() != null).collect(Collectors.toList());
+        List<SysDepartmentDomainDTO> departmentDomainDTOList = new ArrayList<>();
+        if(parentList.size() > 0){
+            for(SysDepartment sysDepartment : parentList){
+                SysDepartmentDomainDTO sysDepartmentDomainDTO = converter.sysDepDomainDTOConverter(sysDepartment);
+                sysDepartmentDomainDTO.setChildren(recursion(sysDepartmentDomainDTO.getId(), childList));
+                departmentDomainDTOList.add(sysDepartmentDomainDTO);
+            }
+        }
+        return departmentDomainDTOList;
+    }
+    private List<SysDepartmentDomainDTO> recursion(Long parentId,List<SysDepartment> list){
+        List<SysDepartment> childList = list.stream().filter(item -> item.getParentId().equals(parentId)).collect(Collectors.toList());
+        List<SysDepartmentDomainDTO> departmentDomainDTOList = new ArrayList<>();
+        if(childList.size() > 0){
+            for(SysDepartment sysDepartment : childList){
+                SysDepartmentDomainDTO sysDepartmentDomainDTO = converter.sysDepDomainDTOConverter(sysDepartment);
+                sysDepartmentDomainDTO.setChildren(recursion(sysDepartmentDomainDTO.getId(), list));
+                departmentDomainDTOList.add(sysDepartmentDomainDTO);
+            }
+        }
+        return departmentDomainDTOList;
+    }
+
+
+
+    //验证部门
+    private boolean checkDep(Long id){
+        if(ObjectUtil.isEmpty(id)){
+            return false;
+        }
+        SysDepartment dep = repository.findByIdAndDeleteStatus(id);
+        if(ObjectUtil.isEmpty(dep)){
+            return false;
+        }
+        return true;
+    }
+    //验证部门是否存在子部门
+    private boolean checkDepChildren(Long parentId){
+        if (ObjectUtil.isEmpty(parentId)) {
+            return false;
+        }
+        List<SysDepartment> list = repository.findByParentIdAndDeleteStatus(parentId);
+        if(!CollectionUtils.isEmpty(list)){
+            return false;
+        }
+        return true;
+    }
+
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/SysUserIdentityBindDomainServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/SysUserIdentityBindDomainServiceImpl.java
new file mode 100644
index 0000000..79a0e8d
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/SysUserIdentityBindDomainServiceImpl.java
@@ -0,0 +1,115 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.service.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.SysUserIdentityBind;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.UserIdentityDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.UserInfoDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa.SysUserIdentityBindReposity;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.SysUserIdentityBindDomainService;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.UserDomainService;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.UserIdentityDomainService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/4/28
+ * @time: 16:40
+ */
+@Service
+public class SysUserIdentityBindDomainServiceImpl implements SysUserIdentityBindDomainService {
+    @Autowired
+    private UserIdentityDomainService userIdentityDomainService;
+    @Autowired
+    private UserDomainService userDomainService;
+    
+    @Autowired
+    private SysUserIdentityBindReposity sysUserIdentityBindReposity;
+
+    @Override
+    public boolean insertBatchUserIndentityBind(List<Long> identityIds, Long userId) {
+        if(CollectionUtils.isEmpty(identityIds) || userId == null){
+            return false;
+        }
+        //验证用户
+        UserInfoDomainDTO user = userDomainService.getUserInfoById(userId);
+        if(ObjectUtil.isEmpty(user)){
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_DATA_NOT_EXISIST.getCode(), "用户不存在");
+        }
+        //验证身份是否都存在
+        List<UserIdentityDomainDTO> userIdentityDomainDTOList = userIdentityDomainService.getListByIds(identityIds);
+        for(Long identityId : identityIds){
+            List<UserIdentityDomainDTO> collect = userIdentityDomainDTOList.stream().filter(identity -> identity.getId().equals(identityId)).collect(Collectors.toList());
+            if(collect.size() == 0){
+                throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_DATA_NOT_EXISIST.getCode(), "身份不存在");
+            }
+        }
+        //绑定用户身份
+        List<SysUserIdentityBind> sysUserIdentityBinds = new ArrayList<>();
+        for(Long identityId : identityIds){
+            SysUserIdentityBind userIdentityBind = new SysUserIdentityBind();
+            userIdentityBind.setUserIdentityId(identityId);
+            userIdentityBind.setUserId(userId);
+            sysUserIdentityBinds.add(userIdentityBind);
+        }
+        List<SysUserIdentityBind> result = sysUserIdentityBindReposity.saveAll(sysUserIdentityBinds);
+        if(CollectionUtils.isEmpty(result)){
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean updateBatchUserIndentityBind(List<Long> identityIds, Long userId) {
+        if(CollectionUtils.isEmpty(identityIds) || userId == null){
+            return false;
+        }
+        //获取原来的身份id
+        List<Long> oldUserIdentityIds = sysUserIdentityBindReposity.getByUserId(userId);
+        List<Long> deleteUserIdentityIdList = new ArrayList<>();
+        List<Long> addUserIdentityIdList = identityIds;
+        if (ObjectUtil.isNotEmpty(oldUserIdentityIds)) {
+            //新增
+            addUserIdentityIdList = identityIds.stream().filter(item -> !oldUserIdentityIds.contains(item)).collect(Collectors.toList());
+            //删除
+            deleteUserIdentityIdList = oldUserIdentityIds.stream().filter(item -> !identityIds.contains(item)).collect(Collectors.toList());
+
+        }
+        List<SysUserIdentityBind> saveList = new ArrayList<>();
+        for(Long userIdentityId : addUserIdentityIdList){
+            SysUserIdentityBind sysUserIdentityBind = new SysUserIdentityBind();
+            sysUserIdentityBind.setUserIdentityId(userIdentityId);
+            sysUserIdentityBind.setUserId(userId);
+            saveList.add(sysUserIdentityBind);
+        }
+        //删除不需要角色
+        if(deleteUserIdentityIdList.size()>0){
+            sysUserIdentityBindReposity.deleteByUserIdAndUserIdentityIds(userId, deleteUserIdentityIdList);
+        }
+        //绑定新增角色
+        if(saveList.size()>0){
+            sysUserIdentityBindReposity.saveAll(saveList);
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean deleteByUser(Long userId) {
+        if(null == userId){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "参数缺失");
+        }
+        if(sysUserIdentityBindReposity.deleteByUserId(userId) > 0){
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/UserDomainServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/UserDomainServiceImpl.java
new file mode 100644
index 0000000..f03d0bb
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/UserDomainServiceImpl.java
@@ -0,0 +1,647 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.service.impl;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.gkhy.fourierSpecialGasMonitor.api.controller.account.query.UserQuery;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.SystemCacheKeyEnum;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.commons.utils.BeanCopyUtils;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.converter.UserInfoDomainConverter;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.SysUserIdentityBind;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.SysUserRoleBind;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.User;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.enums.IdentityStatusEnum;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.enums.UserIdTypeEnum;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.enums.UserStatusEnum;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo.CreateUserBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.bo.UpdateUserBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.SysDepartmentDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa.UserRepository;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.RoleDomainService;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.SysDepartmentDomainService;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.UserDomainService;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.UserInfoDomainDTO;
+import com.google.common.collect.Range;
+import com.google.common.hash.Hashing;
+import org.redisson.api.RMapCache;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.ObjectUtils;
+
+import javax.persistence.criteria.*;
+import java.nio.charset.StandardCharsets;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+@Service
+public class UserDomainServiceImpl implements UserDomainService {
+
+    @Autowired
+    private UserRepository userRepository;
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+    @Autowired
+    private ObjectMapper objectMapper;
+
+    @Autowired
+    private UserInfoDomainConverter userInfoDomainConverter;
+
+    @Autowired
+    private RoleDomainService roleDomainService;
+
+    @Autowired
+    private SysDepartmentDomainService departmentDomainService;
+
+    @Override
+    @Transactional
+    public UserInfoDomainDTO newUser(CreateUserBO createUserBO) {
+        if(createUserBO == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "参数缺失");
+        User user = new User();
+        user.setName(createUserBO.getName());
+        user.setRealName(createUserBO.getRealName());
+        user.setStatus(UserStatusEnum.STATUS_ACTIVE.getStatus());
+        user.setSalt(genPasswordSalt());
+        user.setHash(genPasswordHash(createUserBO.getPwd(), user.getSalt()));
+        
+        //校验用户名称
+        User userInfo = userRepository.findUserByName(createUserBO.getName());
+        if(userInfo != null){
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR,"该用户名称已存在");
+        }
+        //部门校验
+        SysDepartmentDomainDTO dep = departmentDomainService.findById(createUserBO.getDepId());
+        if(dep == null){
+            throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_OBJECT_NOT_EXIST.getCode(),"部门不存在");
+        }
+        user.setDepId(dep.getId());
+        //校验证件
+        //if(UserIdTypeEnum.prase(createUserBO.getIdType()) == null){
+        //    throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_NOT_ALLOWED.getCode(),"证件类型不支持");
+        //}
+        /*User checkUser = userRepository.findByIdTypeAndIdSerial(createUserBO.getIdType(), createUserBO.getIdSerial());
+        if(checkUser != null){
+            throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_NOT_ALLOWED.getCode(),"证件已经被使用");
+        }*/
+        //手机号校验
+        User checkUser = userRepository.findUserByPhone(createUserBO.getPhone());
+        if(checkUser != null){
+            throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_NOT_ALLOWED.getCode(),"手机号已经被使用");
+        }
+        //if(IdentityStatusEnum.prase(createUserBO.getIdentityStatus()) == null){
+        //    throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_ILLEGAL.getCode(),"用户用户身份不合法");
+        //}
+        user.setPhone(createUserBO.getPhone());
+        user.setIdType(createUserBO.getIdType());
+        user.setIdSerial(createUserBO.getIdSerial());
+        user.setGmtCreate(LocalDateTime.now());
+        user.setGmtModified(LocalDateTime.now());
+        //user.setIdentityStatus(createUserBO.getIdentityStatus());
+        //user.setQualificationAttId(createUserBO.getQualificationAttId());
+
+        if(userRepository.save(user) != null){
+            UserInfoDomainDTO userInfoDomainDTO = new UserInfoDomainConverter().toUserInfoDTO(user);
+            return userInfoDomainDTO;
+        }else {
+            throw new BusinessException(this.getClass(), ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(), "数据库错误");
+        }
+    }
+
+    @Transactional
+    @Override
+    public UserInfoDomainDTO updateUserInfo(UpdateUserBO updateUserBO) {
+        if(updateUserBO == null || updateUserBO.getId() == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "参数缺失");
+        if(updateUserBO.getName() == null || updateUserBO.getName().isEmpty())
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "用户名不能为空");
+        if(updateUserBO.getRealName() == null || updateUserBO.getRealName().isEmpty())
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "真实姓名不能为空");
+        //if(updateUserBO.getIdType() == null || UserIdTypeEnum.prase(updateUserBO.getIdType()) == null)
+        //    throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "证件类型不支持");
+        SysDepartmentDomainDTO dep = departmentDomainService.findById(updateUserBO.getDepId());
+        if(dep == null){
+            throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_OBJECT_NOT_EXIST.getCode(),"部门不存在");
+        }
+        Optional<User> userOptional = userRepository.findById(updateUserBO.getId());
+        if(!userOptional.isPresent()){
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_ACCOUNT_NOT_EXIST.getCode(), "用户不存在");
+        }
+        //校验手机号
+        UserInfoDomainDTO u = findUserByPhone(updateUserBO.getPhone());
+        if(u != null && !u.getId().equals(updateUserBO.getId())){
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_NOT_ALLOWED, "手机号已经被使用");
+        }
+
+        User user = userOptional.get();
+        user.setName(updateUserBO.getName());
+        user.setRealName(updateUserBO.getRealName());
+        //user.setIdType(updateUserBO.getIdType());
+        user.setIdSerial(updateUserBO.getIdSerial());
+        user.setDepId(updateUserBO.getDepId());
+        user.setPhone(updateUserBO.getPhone());
+        //user.setIdentityStatus(updateUserBO.getIdentityStatus());
+        //user.setQualificationAttId(updateUserBO.getQualificationAttId());
+        //写库
+        User saveUserRs = userRepository.save(user);
+        return userInfoDomainConverter.toUserInfoDTO(saveUserRs);
+    }
+
+    @Override
+    public UserInfoDomainDTO getUserInfoById(Long uid) {
+        if(uid == null || uid < 0)
+            return null;
+        //1、先从redis缓存加载
+//        Object cacheUserObj = redissonClient.getMapCache(SystemCacheKeyEnum.KEY_CACHE_USER.getKey()).get(""+uid);
+//        if(cacheUserObj != null){
+//            String cacheUserJson = (String)cacheUserObj;
+//            User cacheUser = null;
+//            try {
+//                cacheUser = objectMapper.readValue(cacheUserJson,User.class);
+//            } catch (JsonProcessingException e) {
+//                e.printStackTrace();
+//            }
+//            //2、缓存命中,直接返回
+//            if(cacheUser != null){
+//                UserInfoDTO userInfoDTO = new UserInfoConverter().toUserInfoDTO(cacheUser);
+//                return userInfoDTO;
+//            }
+//        }
+        //3、缓存未命中,入库查
+        Optional<User> userOptional = userRepository.findById(uid);
+        if(!userOptional.isPresent()){
+            return null;
+        }
+        User user = userOptional.get();
+        //获取角色信息
+       // RoleInfoDoaminDTO roleInfoDoaminDTO = roleDomainService.findRoleById(user.getRoleId());
+        UserInfoDomainDTO userInfoDomainDTO = new UserInfoDomainConverter().toUserInfoDTO(user);
+//        if(roleInfoDoaminDTO != null)
+//            userInfoDomainDTO.setRole(roleInfoDoaminDTO);
+        //重置缓存数据
+//        resetUserCache(user);
+        return userInfoDomainDTO;
+    }
+
+    @Override
+    public UserInfoDomainDTO getUserInfoByName(String name) {
+        if(name == null || name.isEmpty())
+            return null;
+        User user = userRepository.findUserByName(name);
+        if(user == null)
+            return null;
+        UserInfoDomainDTO userInfoDomainDTO = new UserInfoDomainConverter().toUserInfoDTO(user);
+        return userInfoDomainDTO;
+    }
+
+    @Override
+    public List<UserInfoDomainDTO> findUserListByRealName(String name) {
+        if(name == null || name.isEmpty())
+            return null;
+        List<User> userList = userRepository.getUsersByRealName(name);
+        if(userList == null || userList.isEmpty())
+            return null;
+        List<UserInfoDomainDTO> dtoList = new ArrayList<>();
+        userList.forEach(u -> {
+            dtoList.add(userInfoDomainConverter.toUserInfoDTO(u));
+        });
+        return dtoList;
+    }
+
+    @Override
+    public SearchResult<List<UserInfoDomainDTO>> findUserListByRole(Long roleId, boolean usePage, Integer page,
+                                                                   Integer pageSize) {
+        SearchResult<List<UserInfoDomainDTO>> result = new SearchResult<>();
+        result.setSuccess();
+        result.setUsePage(usePage);
+        if(roleId == null || roleId < 0)
+            return null;
+        Specification<User> userSpecification = new Specification<User>() {
+            @Override
+            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
+                List<Predicate> predicateList = new ArrayList<>();
+                predicateList.add(root.get("status").in(UserStatusEnum.getActiveUserStatus()));
+                Join<User, SysUserRoleBind> userRoleJion = root.join("sysUserRoleBinds", JoinType.LEFT);
+                predicateList.add(criteriaBuilder.equal(userRoleJion.get("roleId"), roleId));
+
+                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
+            }
+        };
+        PageRequest pageRequest = null;
+        if(usePage == true){
+            if(page <= 0){
+                page = 1;
+                result.setPageIndex(1);
+            }
+            if(pageSize <= 0 || pageSize > 50){
+                pageSize = 20;
+                result.setPageSize(20);
+            }
+            pageRequest = PageRequest.of(page-1,pageSize);
+        }
+        List<User> userList = null;
+        if(pageRequest != null){
+            Page<User> userListPage = userRepository.findAll(userSpecification,pageRequest);
+            result.setTotal(userListPage.getTotalElements());
+            result.setPages(userListPage.getTotalPages());
+            result.setPageIndex(page);
+            result.setPageSize(userListPage.getSize());
+            userList = userListPage.getContent();
+        }else {
+            userList = userRepository.findAll(userSpecification);
+        }
+        if(userList != null && !userList.isEmpty()){
+            result.setCount(userList.size());
+            result.setData(userInfoDomainConverter.toDomainUserInfoList(userList));
+        }
+        return result;
+    }
+
+    @Override
+    public List<UserInfoDomainDTO> getUserInfoListByIds(List<Long> uidList) {
+        if(uidList == null || uidList.size() == 0)
+            return null;
+        List<User> userList = userRepository.findAllByIdIn(uidList);
+        if(userList == null || userList.size() == 0)
+            return null;
+        List<UserInfoDomainDTO> doList = new ArrayList<>();
+        UserInfoDomainConverter converter = new UserInfoDomainConverter();
+        for(User u : userList){
+            UserInfoDomainDTO userInfoDomainDTO = converter.toUserInfoDTO(u);
+            doList.add(userInfoDomainDTO);
+        }
+        return doList;
+    }
+
+    @Override
+    @Transactional
+    public boolean updateUserPwd(Long uid, String oldPwd, String newPwd) {
+        if(uid == null || oldPwd == null || newPwd == null || oldPwd.isEmpty() || newPwd.isEmpty())
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "参数缺失");
+        Optional<User> userOptional = userRepository.findById(uid);
+        if(!userOptional.isPresent()){
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_ACCOUNT_NOT_EXIST.getCode(), "用户不存在");
+        }
+        User user = userOptional.get();
+        //验证旧密码
+        String hash = String.valueOf(Hashing.hmacMd5(user.getSalt().getBytes(StandardCharsets.UTF_8)).hashString(oldPwd,
+                StandardCharsets.UTF_8));
+        if(!hash.equals(user.getHash()))
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_NOT_ALLOWED.getCode(), "旧密码错误");
+        String newSalt = String.valueOf(Hashing.hmacMd5("".getBytes()).hashString(""+uid+Range.atLeast(1)+System.nanoTime(),
+                StandardCharsets.UTF_8));
+        String newHash = String.valueOf(Hashing.hmacMd5(newSalt.getBytes(StandardCharsets.UTF_8)).hashString(newPwd,
+                StandardCharsets.UTF_8));
+        if(userRepository.updatePassword(uid,newHash,newSalt, LocalDateTime.now()) == 1){
+//            deleteUserCache(uid);
+            return true;
+        }else {
+            throw new BusinessException(this.getClass(), ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(), "数据库错误");
+        }
+    }
+
+    @Override
+    @Transactional
+    public boolean updateUserStatus(Long uid, Byte status) {
+        if(uid == null || status == null || UserStatusEnum.prase(status) == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "参数缺失");
+        Optional<User> userOptional = userRepository.findById(uid);
+        if(!userOptional.isPresent()){
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_ACCOUNT_NOT_EXIST.getCode(), "用户不存在");
+        }
+        User user = userOptional.get();
+        if(user.getStatus().equals(status))
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_NOT_ALLOWED.getCode(), "用户状态未发生改变");
+        if(userRepository.updateUserStatus(uid,status,LocalDateTime.now()) == 1){
+//            deleteUserCache(uid);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    @Transactional
+    public boolean updateUserRole(Long uid, Long roleId) {
+        if(uid == null || roleId == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "参数缺失");
+        Optional<User> userOptional = userRepository.findById(uid);
+        if(!userOptional.isPresent()){
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_ACCOUNT_NOT_EXIST.getCode(), "用户不存在");
+        }
+        User user = userOptional.get();
+        /*if(user.getRoleId() != null && user.getRoleId().equals(roleId))
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_NOT_ALLOWED.getCode(), "用户角色未发生改变");*/
+        //todo:校验角色信息
+        /*if(userRepository.updateUserRole(uid,roleId,LocalDateTime.now()) != null){
+//            deleteUserCache(uid);
+            return true;
+        }*/
+        return false;
+    }
+
+    @Override
+    public boolean checkPassword(String pwd, String hash, String salt) {
+        if(pwd == null || pwd.isEmpty() || salt == null || salt.isEmpty() || hash == null || hash.isEmpty())
+            return false;
+        if(Hashing.hmacMd5(salt.getBytes(StandardCharsets.UTF_8)).hashString(pwd, StandardCharsets.UTF_8).toString().equals(hash)){
+            return true;
+        }else {
+            return true;
+        }
+    }
+
+    @Override
+    public UserInfoDomainDTO findUserByPhone(String phoneNumber) {
+        if(phoneNumber == null || phoneNumber.isEmpty() || phoneNumber.length() < 11)
+            return null;
+        User user = userRepository.findUserByPhone(phoneNumber);
+        if(user == null)
+            return null;
+        UserInfoDomainDTO userInfoDomainDTO = userInfoDomainConverter.toUserInfoDTO(user);
+        return userInfoDomainDTO;
+    }
+
+    @Override
+    public UserInfoDomainDTO findUserByIdSerial(Byte idType, String idSerial) {
+        if(idType == null || idSerial == null || idSerial.isEmpty() || idSerial.length() < 10)
+            return null;
+        User user = userRepository.findByIdTypeAndIdSerial(idType,idSerial);
+        if(user == null)
+            return null;
+        UserInfoDomainDTO userInfoDomainDTO = userInfoDomainConverter.toUserInfoDTO(user);
+        return userInfoDomainDTO;
+    }
+
+    @Override
+    @Transactional
+    public boolean updateUserPhoneNumber(Long uid, String phoneNumber) {
+        if(uid == null || phoneNumber == null || phoneNumber.isEmpty())
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "参数缺失");
+        User user = userRepository.findUserByPhone(phoneNumber);
+        if(user != null && !user.getId().equals(uid))
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_NOT_ALLOWED.getCode(), "手机号码已经被使用");
+        Optional<User> userOptional = userRepository.findById(uid);
+        if(!userOptional.isPresent())
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_ACCOUNT_NOT_EXIST.getCode(), "用户不存在");
+        user = userOptional.get();
+        if(user.getPhone().equals(phoneNumber))
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_NOT_ALLOWED.getCode(), "手机号码未发生变化");
+        if(userRepository.updateUserPhone(uid,phoneNumber) == 1){
+//            deleteUserCache(uid);
+            return true;
+        }else {
+            throw new BusinessException(this.getClass(),ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"数据库更新出错");
+        }
+    }
+
+    @Override
+    @Transactional
+    public boolean deleteUser(Long uid) {
+        if(uid == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "参数缺失");
+        Optional<User> userOptional = userRepository.findById(uid);
+        if(!userOptional.isPresent())
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_ACCOUNT_NOT_EXIST.getCode(), "用户不存在");
+        User user = userOptional.get();
+        if(user.getStatus().equals(UserStatusEnum.STATUS_DELETE.getStatus())){
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_NOT_ALLOWED.getCode(), "用户不存在");
+        }
+        if(userRepository.updateUserStatus(uid,UserStatusEnum.STATUS_DELETE.getStatus(), LocalDateTime.now()) ==1){
+//            deleteUserCache(uid);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 用户列表
+     */
+    @Override
+    public List<UserInfoDomainDTO> getUserList() {
+
+        return BeanCopyUtils.copyBeanList(userRepository.getUserList(), UserInfoDomainDTO.class);
+    }
+    /**
+     * 根据用户id获取信息
+     */
+    public UserInfoDomainDTO getUserById(Long id){
+        if(id == null)
+            return null;
+        User user = userRepository.getById(id);
+        UserInfoDomainDTO userInfoDomainDTO = userInfoDomainConverter.toUserInfoDTO(user);
+        return userInfoDomainDTO;
+    }
+
+
+    /**
+     * 根据用户获取数据
+     */
+    public List<UserInfoDomainDTO> getUserByRoleId(Long roleId){
+        if(null == roleId){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "参数缺失");
+        }
+        Specification<User> userSpecification = new Specification<User>() {
+            @Override
+            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
+                List<Predicate> predicateList = new ArrayList<>();
+                predicateList.add(root.get("status").in(UserStatusEnum.getActiveUserStatus()));
+                Join<User, SysUserRoleBind> userRoleJion = root.join("sysUserRoleBinds", JoinType.LEFT);
+                predicateList.add(criteriaBuilder.equal(userRoleJion.get("roleId"), roleId));
+
+                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
+            }
+        };
+        List<User> userList = userRepository.findAll(userSpecification);
+        return userInfoDomainConverter.toDomainUserInfoList(userList);
+
+    }
+
+    /**
+     *
+     * @param pageQuery
+     * @return
+     */
+    @Override
+    public SearchResult<List<UserInfoDomainDTO>> findUserList(PageQuery<UserQuery> pageQuery) {
+        SearchResult searchResult = new SearchResult<>();
+        searchResult.setPageIndex(pageQuery.getPageIndex());
+        searchResult.setPageSize(pageQuery.getPageSize());
+        searchResult.setSuccess();
+
+        UserQuery userQuery = pageQuery.getSearchParams();
+        Specification<User> userSpecification = new Specification<User>() {
+            @Override
+            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
+                List<Predicate> predicateList = new ArrayList<>();
+                if(query != null){
+                    if(!ObjectUtils.isEmpty(userQuery.getRoleId())){
+                        Join<User, SysUserRoleBind> userRoleJion = root.join("sysUserRoleBinds", JoinType.LEFT);
+                        predicateList.add(criteriaBuilder.equal(userRoleJion.get("roleId"), userQuery.getRoleId()));
+                    }
+                    if(!ObjectUtils.isEmpty(userQuery.getName())){
+                        predicateList.add(criteriaBuilder.like(root.get("name"),userQuery.getName()));
+                    }
+                    if(!ObjectUtils.isEmpty(userQuery.getRealName())){
+                        predicateList.add(criteriaBuilder.like(root.get("realName"),userQuery.getRealName()));
+                    }
+                }
+                predicateList.add(root.get("status").in(UserStatusEnum.getActiveUserStatus()));
+
+                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
+            }
+        };
+        Pageable pageable = PageRequest.of(pageQuery.getPageIndex()-1, pageQuery.getPageSize(), Sort.Direction.DESC, "gmtCreate");
+        Page<User> pageResult = userRepository.findAll(userSpecification, pageable);
+
+        searchResult.setTotal(pageResult.getTotalElements());
+        searchResult.setPages(pageResult.getTotalPages());
+        searchResult.setData(userInfoDomainConverter.toDomainUserInfoList(pageResult.getContent()));
+
+        return searchResult;
+    }
+
+    @Override
+    public SearchResult<List<UserInfoDomainDTO>> findExpertList(PageQuery<UserQuery> pageQuery) {
+        SearchResult searchResult = new SearchResult<>();
+        searchResult.setPageIndex(pageQuery.getPageIndex());
+        searchResult.setPageSize(pageQuery.getPageSize());
+        searchResult.setSuccess();
+
+        UserQuery userQuery = pageQuery.getSearchParams();
+        Specification<User> userSpecification = new Specification<User>() {
+            @Override
+            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
+                List<Predicate> predicateList = new ArrayList<>();
+                predicateList.add(root.get("status").in(UserStatusEnum.getActiveUserStatus()));
+                predicateList.add(criteriaBuilder.equal(root.get("identityStatus"),IdentityStatusEnum.EXPERT.getStatus()));
+                if(query != null){
+                    if(!ObjectUtils.isEmpty(userQuery.getRoleId())){
+                        Join<User, SysUserRoleBind> userRoleJion = root.join("sysUserRoleBinds", JoinType.LEFT);
+                        predicateList.add(criteriaBuilder.equal(userRoleJion.get("roleId"), userQuery.getRoleId()));
+                    }
+                    if(!ObjectUtils.isEmpty(userQuery.getName())){
+                        predicateList.add(criteriaBuilder.like(root.get("name"),userQuery.getName()));
+                    }
+                    if(!ObjectUtils.isEmpty(userQuery.getRealName())){
+                        predicateList.add(criteriaBuilder.like(root.get("realName"),userQuery.getRealName()));
+                    }
+                    if(!ObjectUtils.isEmpty(userQuery.getUserIndentityId())){
+                        Join<User, SysUserIdentityBind> userIdentityBindJion = root.join("sysUserIdentityBinds", JoinType.LEFT);
+                        predicateList.add(criteriaBuilder.equal(userIdentityBindJion.get("userIdentityId"), userQuery.getUserIndentityId()));
+                    }
+                }
+
+
+                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
+            }
+        };
+        Pageable pageable = PageRequest.of(pageQuery.getPageIndex()-1, pageQuery.getPageSize(), Sort.Direction.DESC, "gmtCreate");
+        Page<User> pageResult = userRepository.findAll(userSpecification, pageable);
+
+        searchResult.setTotal(pageResult.getTotalElements());
+        searchResult.setPages(pageResult.getTotalPages());
+        searchResult.setData(userInfoDomainConverter.toDomainUserInfoList(pageResult.getContent()));
+
+        return searchResult;
+    }
+
+
+    /**
+     * 用户查询
+     */
+    @Override
+    public UserInfoDomainDTO getUserInfoByIdAndSellInfo(Long evaluateUserId, String info) {
+
+        if (ObjectUtils.isEmpty(evaluateUserId)){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "请求参数不能为空");
+        }
+
+        User userInfo = userRepository.getUserInfoByIdAndSellInfo(evaluateUserId);
+
+        if (ObjectUtils.isEmpty(userInfo)){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR.getCode(), info + "不存在,请检查是否输入有误或人员已被删除");
+        }
+        return BeanCopyUtils.copyBean(userInfo, UserInfoDomainDTO.class);
+    }
+
+
+    /**
+     * 清除REDIS缓存的用户数据
+     * @param userId
+     * @return
+     */
+    public Result deleteUserCache(Long userId){
+        Result result = new Result<>();
+        if(userId == null){
+            return result;
+        }
+        RMapCache<String,Object> userCacheMap = redissonClient.getMapCache(SystemCacheKeyEnum.KEY_CACHE_USER.getKey());
+        String userKey = ""+userId;
+        userCacheMap.remove(userKey);
+        result.setSuccess();
+        return result;
+    }
+
+    /**
+     * 重置缓存的用户数据
+     * @param user
+     * @return
+     */
+    public boolean resetUserCache(User user){
+        if(user == null)
+            return false;
+        String cacheJson = null;
+        try {
+            cacheJson = objectMapper.writeValueAsString(user);
+        } catch (JsonProcessingException e) {
+            throw new BusinessException(this.getClass(), ResultCode.SYSTEM_ERROR.getCode(),"序列化对象出错");
+        }
+        RMapCache<String,Object> userCacheMap = redissonClient.getMapCache(SystemCacheKeyEnum.KEY_CACHE_USER.getKey());
+        String userKey = ""+user.getId();
+        //写入redis缓存,有效期1小时
+        userCacheMap.put(userKey,cacheJson,60, TimeUnit.MINUTES);
+        return true;
+    }
+
+    /**
+     * 生成salt
+     * @return
+     */
+    private String genPasswordSalt(){
+        String seed = ""+System.nanoTime();
+        String m = ""+ Range.atLeast(1).toString();
+        String salt = Hashing.hmacMd5(seed.getBytes(StandardCharsets.UTF_8)).hashBytes(m.getBytes(StandardCharsets.UTF_8)).toString();
+        return salt;
+    }
+
+    /**
+     * 生成hash
+     * @param password
+     * @param salt
+     * @return
+     */
+    private String genPasswordHash(String password,String salt){
+        if(password == null || salt == null || password.isEmpty() || salt.isEmpty())
+            return null;
+        String hash = Hashing.hmacMd5(salt.getBytes(StandardCharsets.UTF_8)).hashBytes(password.getBytes(StandardCharsets.UTF_8)).toString();
+        return hash;
+    }
+
+
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/UserIdentityDomainServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/UserIdentityDomainServiceImpl.java
new file mode 100644
index 0000000..532d42f
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/UserIdentityDomainServiceImpl.java
@@ -0,0 +1,37 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.service.impl;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.account.converter.UserIdentityConverter;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.UserIdentity;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.UserIdentityDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa.UserIdentityRepository;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.UserIdentityDomainService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/4/28
+ * @time: 16:38
+ */
+@Service
+public class UserIdentityDomainServiceImpl implements UserIdentityDomainService {
+    @Autowired
+    private UserIdentityRepository userIdentityRepository;
+    @Autowired
+    private UserIdentityConverter converter;
+
+    @Override
+    public List<UserIdentityDomainDTO> getListByIds(List<Long> identityIds) {
+        List<UserIdentity> userIdentities = userIdentityRepository.findAllById(identityIds);
+        return converter.userIdentityDomainConverter(userIdentities);
+    }
+
+    @Override
+    public List<UserIdentityDomainDTO> getList() {
+        List<UserIdentity> userIdentities = userIdentityRepository.findAll();
+        return converter.userIdentityDomainConverter(userIdentities);
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/UserRoleDomainServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/UserRoleDomainServiceImpl.java
new file mode 100644
index 0000000..4d6b346
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/account/service/impl/UserRoleDomainServiceImpl.java
@@ -0,0 +1,126 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.account.service.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.converter.UserRoleBindConverter;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.SysUserRoleBind;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.RoleInfoDoaminDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.SysUserRoleBindDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.model.dto.UserInfoDomainDTO;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa.UserRoleBindReposity;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.RoleDomainService;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.UserDomainService;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.service.UserRoleDomainService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/3/13
+ * @time: 9:26
+ */
+@Service
+public class UserRoleDomainServiceImpl implements UserRoleDomainService {
+    @Autowired
+    private UserRoleBindReposity userRoleBindReposity;
+
+    @Autowired
+    private RoleDomainService roleDomainService;
+
+    @Autowired
+    private UserDomainService userDomainService;
+
+    @Autowired
+    private UserRoleBindConverter converter;
+
+    @Override
+    public List<SysUserRoleBindDomainDTO> insertBatchUserBindRole(List<Long> roleIds, Long userId) {
+        if(ObjectUtil.isEmpty(roleIds) || ObjectUtil.isEmpty(userId)){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "参数缺失");
+        }
+        //验证用户
+        UserInfoDomainDTO user = userDomainService.getUserInfoById(userId);
+        if(ObjectUtil.isEmpty(user)){
+            throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_DATA_NOT_EXISIST.getCode(), "用户不存在");
+        }
+        //验证角色是否都存在
+        List<RoleInfoDoaminDTO> roleList = roleDomainService.findAllByIdIn(roleIds);
+        for(Long roleId : roleIds){
+            List<RoleInfoDoaminDTO> collect = roleList.stream().filter(role -> role.getId().equals(roleId)).collect(Collectors.toList());
+            if(collect.size() == 0){
+                throw new BusinessException(this.getClass(), ResultCode.BUSINESS_ERROR_DATA_NOT_EXISIST.getCode(), "角色不存在");
+            }
+        }
+        //绑定用户角色
+        List<SysUserRoleBind> sysUserRoleBindList = new ArrayList<>();
+        for(Long roleId : roleIds){
+            SysUserRoleBind sysUserRoleBind = new SysUserRoleBind();
+            sysUserRoleBind.setRoleId(roleId);
+            sysUserRoleBind.setUserId(userId);
+            sysUserRoleBindList.add(sysUserRoleBind);
+        }
+        List<SysUserRoleBindDomainDTO> list = converter.userRoleBindDomainConverter(userRoleBindReposity.saveAll(sysUserRoleBindList));
+        return list;
+    }
+
+    @Transactional
+    @Override
+    public void updateUserRole(Long userId, List<Long> roleIds) {
+        if(ObjectUtil.isEmpty(roleIds) || ObjectUtil.isEmpty(userId)){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "参数缺失");
+        }
+        //获取原来的角色id
+        List<Long> oldRoleIds = userRoleBindReposity.getByUserId(userId);
+        List<Long> deleteRoleIdList = new ArrayList<>();
+        List<Long> addRoleIdList = roleIds;
+        if (ObjectUtil.isNotEmpty(oldRoleIds)) {
+            //新增
+            addRoleIdList = roleIds.stream().filter(item -> !oldRoleIds.contains(item)).collect(Collectors.toList());
+            //删除
+            deleteRoleIdList = oldRoleIds.stream().filter(item -> !roleIds.contains(item)).collect(Collectors.toList());
+
+        }
+        List<SysUserRoleBind> saveList = new ArrayList<>();
+        for(Long roleId : addRoleIdList){
+            SysUserRoleBind sysUserRoleBind = new SysUserRoleBind();
+            sysUserRoleBind.setRoleId(roleId);
+            sysUserRoleBind.setUserId(userId);
+            saveList.add(sysUserRoleBind);
+        }
+        //删除不需要角色
+        if(deleteRoleIdList.size()>0){
+            userRoleBindReposity.deleteByUserIdAndRoleIds(userId, deleteRoleIdList);
+        }
+        //绑定新增角色
+        if(saveList.size()>0){
+            userRoleBindReposity.saveAll(saveList);
+        }
+    }
+
+    @Override
+    public boolean deleteByUser(Long userId) {
+        if(null == userId){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "参数缺失");
+        }
+        if(userRoleBindReposity.deleteByUserId(userId) > 0){
+            return true;
+        }
+        return false;
+    }
+
+    /*@Override
+    public List<SysUserRoleBindDomainDTO> getUserRoleBind(Long userId) {
+        if(null == userId){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "参数缺失");
+        }
+        return null;
+    }*/
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/converter/AttachmentDomainConverter.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/converter/AttachmentDomainConverter.java
new file mode 100644
index 0000000..ec88e71
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/converter/AttachmentDomainConverter.java
@@ -0,0 +1,25 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.attachment.converter;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.attachment.dto.resp.AttachmentDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.attachment.entity.AttachmentInfo;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Component;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/7
+ * @time: 17:06
+ */
+@Component
+public class AttachmentDomainConverter {
+    public AttachmentDomainDTO getDomainDTO(AttachmentInfo attachmentInfo){
+        if(null == attachmentInfo){
+           return null;
+        }
+        AttachmentDomainDTO attachmentDomainDTO = new AttachmentDomainDTO();
+        BeanUtils.copyProperties(attachmentInfo,attachmentDomainDTO);
+        return attachmentDomainDTO;
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/dto/resp/AttachmentDomainDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/dto/resp/AttachmentDomainDTO.java
new file mode 100644
index 0000000..5c5190f
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/dto/resp/AttachmentDomainDTO.java
@@ -0,0 +1,49 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.attachment.dto.resp;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/7
+ * @time: 15:10
+ */
+@Data
+public class AttachmentDomainDTO {
+
+    private Long id;
+    //文件标识
+    private String fileKey;
+    //文件本地址
+    private String filePath;
+    //文件访问路径
+    private String fileUrl;
+    //文件名称
+    private String fileName;
+    //文件后缀
+    private String fileSuffix;
+    //文件描述
+    private String fileDesc;
+    //文件大小
+    private Long fileSize;
+    //文件类型
+    private String fileType;
+    //模块
+    private String module;
+    //删除标识 0-未删除,1-删除
+    private Integer delFlag;
+    //创建时间
+    private LocalDateTime createTime;
+    //创建人id
+    private Long createUid;
+    //创建人姓名
+    private String createUname;
+    //修改时间
+    private LocalDateTime updateTime;
+    //修改人id
+    private Long updateUid;
+    //修改人姓名
+    private String updateUname;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/entity/AttachmentInfo.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/entity/AttachmentInfo.java
new file mode 100644
index 0000000..a2f675d
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/entity/AttachmentInfo.java
@@ -0,0 +1,64 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.attachment.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/6
+ * @time: 14:54
+ */
+@EntityListeners(AuditingEntityListener.class)
+@Data
+@Entity
+@Table(name = "attachment")
+public class AttachmentInfo {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+    //文件标识
+    private String fileKey;
+    //文件本地址
+    private String filePath;
+    //文件访问路径
+    private String fileUrl;
+    //文件名称
+    private String fileName;
+    //文件后缀
+    private String fileSuffix;
+    //文件描述
+    private String fileDesc;
+    //文件大小
+    private Long fileSize;
+    //文件类型
+    private String fileType;
+    //模块
+    private String module;
+    //删除标识 0-未删除,1-删除
+    private Integer delFlag;
+    //创建时间
+    @JsonFormat
+    @CreatedDate
+    @Column(name = "create_time",updatable = false)
+    private LocalDateTime createTime;
+    //创建人id
+    private Long createUid;
+    //创建人姓名
+    private String createUname;
+    //修改时间
+    @JsonFormat
+    @LastModifiedDate
+    private LocalDateTime updateTime;
+    //修改人id
+    private Long updateUid;
+    //修改人姓名
+    private String updateUname;
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/enums/FileProjectConstants.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/enums/FileProjectConstants.java
new file mode 100644
index 0000000..b8fc9df
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/enums/FileProjectConstants.java
@@ -0,0 +1,20 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.attachment.enums;
+
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/7
+ * @time: 13:42
+ */
+public interface FileProjectConstants {
+    interface ReturnType {
+        int DETAIL = 1;
+        int KEY = 2;
+        int URL = 3;
+    }
+    enum FileError{
+
+    }
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/repository/jpa/AttachmentReposity.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/repository/jpa/AttachmentReposity.java
new file mode 100644
index 0000000..a8fca74
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/repository/jpa/AttachmentReposity.java
@@ -0,0 +1,28 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.attachment.repository.jpa;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.attachment.entity.AttachmentInfo;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/6
+ * @time: 21:28
+ */
+@Repository
+public interface AttachmentReposity extends JpaRepository<AttachmentInfo,Long>, JpaSpecificationExecutor<AttachmentInfo> {
+    @Query(value = "select a from AttachmentInfo a where a.fileKey = :fileKey and a.delFlag = 0")
+    AttachmentInfo findByFileKey(String fileKey);
+
+    @Query(value = "select a from AttachmentInfo a where a.id = :id and a.delFlag = 0")
+    AttachmentInfo getById(Long id);
+    @Transactional
+    @Query(value = "update AttachmentInfo a set a.delFlag = 1 where a.id = :id")
+    @Modifying
+    Integer deleteAttachment(Long id);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/service/AttachmentDomainService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/service/AttachmentDomainService.java
new file mode 100644
index 0000000..70ade28
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/service/AttachmentDomainService.java
@@ -0,0 +1,20 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.attachment.service;
+
+import com.gkhy.fourierSpecialGasMonitor.application.attachment.service.dto.req.AttachmentAppReq;
+import com.gkhy.fourierSpecialGasMonitor.domain.attachment.dto.resp.AttachmentDomainDTO;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/6
+ * @time: 14:51
+ */
+public interface AttachmentDomainService {
+
+    AttachmentDomainDTO save(AttachmentAppReq attachmentAppReq);
+
+    AttachmentDomainDTO findByKey(String key);
+    AttachmentDomainDTO findById(Long id);
+
+    int delete(Long id);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/service/impl/AttachmentDomainServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/service/impl/AttachmentDomainServiceImpl.java
new file mode 100644
index 0000000..632364c
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/attachment/service/impl/AttachmentDomainServiceImpl.java
@@ -0,0 +1,66 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.attachment.service.impl;
+
+import com.alibaba.druid.util.StringUtils;
+import com.gkhy.fourierSpecialGasMonitor.application.attachment.service.dto.req.AttachmentAppReq;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.domain.attachment.converter.AttachmentDomainConverter;
+import com.gkhy.fourierSpecialGasMonitor.domain.attachment.dto.resp.AttachmentDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.attachment.entity.AttachmentInfo;
+import com.gkhy.fourierSpecialGasMonitor.domain.attachment.repository.jpa.AttachmentReposity;
+import com.gkhy.fourierSpecialGasMonitor.domain.attachment.service.AttachmentDomainService;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.ObjectUtils;
+
+/**
+ * @email 1603559716@qq.com
+ * @author: zf
+ * @date: 2023/5/6
+ * @time: 14:50
+ */
+@Service
+public class AttachmentDomainServiceImpl implements AttachmentDomainService {
+    @Autowired
+    private AttachmentReposity reposity;
+
+    @Autowired
+    private AttachmentDomainConverter converter;
+
+    @Override
+    public AttachmentDomainDTO save(AttachmentAppReq attachmentAppReq) {
+        if(ObjectUtils.isEmpty(attachmentAppReq)){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL);
+        }
+        AttachmentInfo attachmentInfo = new AttachmentInfo();
+        BeanUtils.copyProperties(attachmentAppReq,attachmentInfo);
+        AttachmentInfo save = reposity.save(attachmentInfo);
+        return converter.getDomainDTO(save);
+    }
+
+    @Override
+    public AttachmentDomainDTO findByKey(String key) {
+        if (StringUtils.isEmpty(key)){
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL);
+        }
+        AttachmentInfo attachmentInfo = reposity.findByFileKey(key);
+        return converter.getDomainDTO(attachmentInfo);
+    }
+    @Override
+    public AttachmentDomainDTO findById(Long id) {
+        if (id == null){
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL);
+        }
+        AttachmentInfo attachmentInfo = reposity.getById(id);
+        return converter.getDomainDTO(attachmentInfo);
+    }
+
+    @Override
+    public int delete(Long id) {
+        if (id == null){
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL);
+        }
+        return reposity.deleteAttachment(id);
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/converter/MenuItemConverter.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/converter/MenuItemConverter.java
new file mode 100644
index 0000000..4385187
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/converter/MenuItemConverter.java
@@ -0,0 +1,18 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.converter;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.entity.MenuItem;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.model.dto.MenuItemDomainDTO;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+@Service
+public class MenuItemConverter {
+
+    public MenuItemDomainDTO toMenuItemDTO(MenuItem menuItem){
+        if(menuItem == null)
+            return null;
+        MenuItemDomainDTO dto = new MenuItemDomainDTO();
+        BeanUtils.copyProperties(menuItem,dto);
+        return dto;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/entity/MenuItem.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/entity/MenuItem.java
new file mode 100644
index 0000000..6458682
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/entity/MenuItem.java
@@ -0,0 +1,261 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.entity;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "sys_menu_item")
+public class MenuItem {
+
+    //主键
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    //菜单级别
+    @Column
+    private Integer level;
+
+    //父级菜单
+    @Column
+    private Long parentId;
+
+    //删除标识
+    @Column
+    private Byte del;
+
+    //类型:公共|私有
+    @Column
+    private Byte type;
+
+    //菜单项显示标题
+    @Column
+    private String title;
+
+    @Column
+    private Byte priority;
+
+    @Column
+    private String component;
+
+    //菜单项描述信息
+    @Column
+    private String descInfo;
+
+    //菜单项名称
+    @Column
+    private String name;
+
+    //路径
+    @Column
+    private String path;
+
+    //重定向路径
+    @Column
+    private String redirect;
+
+    //
+    @Column
+    private boolean visiable;
+
+    @Column
+    private Boolean aliveable;
+
+    @Column
+    private Boolean affixable;
+
+    @Column
+    private Boolean iframeable;
+
+    @Column
+    private Boolean publicable;
+
+
+    //
+    @Column
+    private String icon;
+
+    @Column
+    private String link;
+
+    //
+    @Column
+    private LocalDateTime gmtCreate;
+
+    //
+    @Column
+    private LocalDateTime gmtModified;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Integer getLevel() {
+        return level;
+    }
+
+    public void setLevel(Integer level) {
+        this.level = level;
+    }
+
+    public Long getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
+    }
+
+    public Byte getDel() {
+        return del;
+    }
+
+    public void setDel(Byte del) {
+        this.del = del;
+    }
+
+    public void setType(Byte type) {
+        this.type = type;
+    }
+
+    public byte getType() {
+        return type;
+    }
+
+    public void setType(byte type) {
+        this.type = type;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescInfo() {
+        return descInfo;
+    }
+
+    public void setDescInfo(String descInfo) {
+        this.descInfo = descInfo;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getRedirect() {
+        return redirect;
+    }
+
+    public void setRedirect(String redirect) {
+        this.redirect = redirect;
+    }
+
+    public boolean isVisiable() {
+        return visiable;
+    }
+
+    public void setVisiable(boolean visiable) {
+        this.visiable = visiable;
+    }
+
+    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;
+    }
+
+    public LocalDateTime getGmtCreate() {
+        return gmtCreate;
+    }
+
+    public void setGmtCreate(LocalDateTime gmtCreate) {
+        this.gmtCreate = gmtCreate;
+    }
+
+    public LocalDateTime getGmtModified() {
+        return gmtModified;
+    }
+
+    public void setGmtModified(LocalDateTime gmtModified) {
+        this.gmtModified = gmtModified;
+    }
+
+    public Byte getPriority() {
+        return priority;
+    }
+
+    public void setPriority(Byte priority) {
+        this.priority = priority;
+    }
+
+
+    public String getComponent() {
+        return component;
+    }
+
+    public void setComponent(String component) {
+        this.component = component;
+    }
+
+    public Boolean getAliveable() {
+        return aliveable;
+    }
+
+    public void setAliveable(Boolean aliveable) {
+        this.aliveable = aliveable;
+    }
+
+    public Boolean getAffixable() {
+        return affixable;
+    }
+
+    public void setAffixable(Boolean affixable) {
+        this.affixable = affixable;
+    }
+
+    public Boolean getIframeable() {
+        return iframeable;
+    }
+
+    public void setIframeable(Boolean iframeable) {
+        this.iframeable = iframeable;
+    }
+
+    public Boolean getPublicable() {
+        return publicable;
+    }
+
+    public void setPublicable(Boolean publicable) {
+        this.publicable = publicable;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/entity/SysConfig.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/entity/SysConfig.java
new file mode 100644
index 0000000..a240e44
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/entity/SysConfig.java
@@ -0,0 +1,49 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.entity;
+
+import org.hibernate.annotations.Proxy;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.time.LocalDateTime;
+
+@Entity(name = "sys_config")
+//@JsonIgnoreProperties(value = { "hibernateLazyInitializer"})
+@Proxy(lazy = false)
+public class SysConfig {
+
+    //系统配置项
+    @Id
+    private String sysProp;
+
+    //配置项的值
+    @Column
+    private String sysValue;
+
+    @Column
+    private LocalDateTime gmtModified;
+
+    public String getSysProp() {
+        return sysProp;
+    }
+
+    public void setSysProp(String sysProp) {
+        this.sysProp = sysProp;
+    }
+
+    public String getSysValue() {
+        return sysValue;
+    }
+
+    public void setSysValue(String sysValue) {
+        this.sysValue = sysValue;
+    }
+
+    public LocalDateTime getGmtModified() {
+        return gmtModified;
+    }
+
+    public void setGmtModified(LocalDateTime gmtModified) {
+        this.gmtModified = gmtModified;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/enums/MenuItemTypeEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/enums/MenuItemTypeEnum.java
new file mode 100644
index 0000000..418930b
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/enums/MenuItemTypeEnum.java
@@ -0,0 +1,55 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.enums;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum MenuItemTypeEnum {
+
+    PUBLIC((byte) 1, "公共菜单"),
+    PRIVATE((byte) 2, "私有菜单")
+    ;
+
+    byte type;
+    String desc;
+
+    MenuItemTypeEnum(byte type, String desc) {
+        this.type = type;
+        this.desc = desc;
+    }
+
+    public byte getType() {
+        return type;
+    }
+
+    public void setType(byte type) {
+        this.type = type;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+
+    public static Map<Byte, MenuItemTypeEnum> getMap() {
+        return map;
+    }
+
+    public static void setMap(Map<Byte, MenuItemTypeEnum> map) {
+        MenuItemTypeEnum.map = map;
+    }
+
+    static Map<Byte, MenuItemTypeEnum> map;
+    static {
+        map = new HashMap<>();
+        for (MenuItemTypeEnum e : MenuItemTypeEnum.values()) {
+            map.put(e.getType(), e);
+        }
+    }
+
+    public static MenuItemTypeEnum parse(Byte type) {
+        return map.get(type);
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/model/bo/CreateNewMenuItemBO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/model/bo/CreateNewMenuItemBO.java
new file mode 100644
index 0000000..278ccbc
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/model/bo/CreateNewMenuItemBO.java
@@ -0,0 +1,177 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.model.bo;
+
+import java.util.List;
+
+public class CreateNewMenuItemBO {
+
+    //父级菜单
+    private Long parentId;
+
+    //菜单项显示标题
+    private String title;
+
+    //菜单项描述信息
+    private String descInfo;
+
+    //菜单项名称
+    private String name;
+
+    //路径
+    private String path;
+
+    //重定向路径
+    private String redirect;
+
+    //
+    private boolean visiable;
+
+    //
+    private String icon;
+
+    private String link;
+
+    //
+
+    private Byte priority;
+
+    private String component;
+
+    private Boolean aliveable;
+
+    private Boolean affixable;
+
+    private Boolean iframeable;
+
+    private Boolean publicable;
+
+    private List<Long> roles;
+
+    public Long getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescInfo() {
+        return descInfo;
+    }
+
+    public void setDescInfo(String descInfo) {
+        this.descInfo = descInfo;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getRedirect() {
+        return redirect;
+    }
+
+    public void setRedirect(String redirect) {
+        this.redirect = redirect;
+    }
+
+    public boolean isVisiable() {
+        return visiable;
+    }
+
+    public void setVisiable(boolean visiable) {
+        this.visiable = visiable;
+    }
+
+    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;
+    }
+
+    public Byte getPriority() {
+        return priority;
+    }
+
+    public void setPriority(Byte priority) {
+        this.priority = priority;
+    }
+
+
+    public String getComponent() {
+        return component;
+    }
+
+    public void setComponent(String component) {
+        this.component = component;
+    }
+
+    public Boolean getAliveable() {
+        return aliveable;
+    }
+
+    public void setAliveable(Boolean aliveable) {
+        this.aliveable = aliveable;
+    }
+
+    public Boolean getAffixable() {
+        return affixable;
+    }
+
+    public void setAffixable(Boolean affixable) {
+        this.affixable = affixable;
+    }
+
+    public Boolean getIframeable() {
+        return iframeable;
+    }
+
+    public void setIframeable(Boolean iframeable) {
+        this.iframeable = iframeable;
+    }
+
+    public Boolean getPublicable() {
+        return publicable;
+    }
+
+    public void setPublicable(Boolean publicable) {
+        this.publicable = publicable;
+    }
+
+    public List<Long> getRoles() {
+        return roles;
+    }
+
+    public void setRoles(List<Long> roles) {
+        this.roles = roles;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/model/bo/ModifyMenuItemBO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/model/bo/ModifyMenuItemBO.java
new file mode 100644
index 0000000..72d5278
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/model/bo/ModifyMenuItemBO.java
@@ -0,0 +1,196 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.model.bo;
+
+import java.util.List;
+
+public class ModifyMenuItemBO {
+
+    private Long menuItemId;
+
+    private Long parentId;
+
+    //菜单项显示标题
+    private String title;
+
+    //菜单项描述信息
+    private String descInfo;
+
+    //菜单项名称
+    private String name;
+
+    //路径
+    private String path;
+
+    //重定向路径
+    private String redirect;
+
+    //
+    private Boolean linkable;
+
+    //
+    private Boolean visiable;
+
+    //
+    private String icon;
+
+    private String link;
+
+    //
+
+    private Byte priority;
+
+    private String component;
+
+    private Boolean aliveable;
+
+    private Boolean affixable;
+
+    private Boolean iframeable;
+
+    private Boolean publicable;
+
+    private List<Long> roles;
+
+    public Long getMenuItemId() {
+        return menuItemId;
+    }
+
+    public void setMenuItemId(Long menuItemId) {
+        this.menuItemId = menuItemId;
+    }
+
+    public Long getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescInfo() {
+        return descInfo;
+    }
+
+    public void setDescInfo(String descInfo) {
+        this.descInfo = descInfo;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getRedirect() {
+        return redirect;
+    }
+
+    public void setRedirect(String redirect) {
+        this.redirect = redirect;
+    }
+
+    public Boolean getLinkable() {
+        return linkable;
+    }
+
+    public void setLinkable(Boolean linkable) {
+        this.linkable = linkable;
+    }
+
+    public Boolean getVisiable() {
+        return visiable;
+    }
+
+    public void setVisiable(Boolean visiable) {
+        this.visiable = visiable;
+    }
+
+    public String getIcon() {
+        return icon;
+    }
+
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
+
+    public Byte getPriority() {
+        return priority;
+    }
+
+    public void setPriority(Byte priority) {
+        this.priority = priority;
+    }
+
+    public String getComponent() {
+        return component;
+    }
+
+    public void setComponent(String component) {
+        this.component = component;
+    }
+
+    public Boolean getAliveable() {
+        return aliveable;
+    }
+
+    public void setAliveable(Boolean aliveable) {
+        this.aliveable = aliveable;
+    }
+
+    public Boolean getAffixable() {
+        return affixable;
+    }
+
+    public void setAffixable(Boolean affixable) {
+        this.affixable = affixable;
+    }
+
+    public Boolean getIframeable() {
+        return iframeable;
+    }
+
+    public void setIframeable(Boolean iframeable) {
+        this.iframeable = iframeable;
+    }
+
+    public Boolean getPublicable() {
+        return publicable;
+    }
+
+    public void setPublicable(Boolean publicable) {
+        this.publicable = publicable;
+    }
+
+    public String getLink() {
+        return link;
+    }
+
+    public void setLink(String link) {
+        this.link = link;
+    }
+
+    public List<Long> getRoles() {
+        return roles;
+    }
+
+    public void setRoles(List<Long> roles) {
+        this.roles = roles;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/model/dto/MenuItemDomainDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/model/dto/MenuItemDomainDTO.java
new file mode 100644
index 0000000..8e569c1
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/model/dto/MenuItemDomainDTO.java
@@ -0,0 +1,207 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.model.dto;
+
+import java.util.List;
+
+public class MenuItemDomainDTO {
+
+    private Long id;
+
+    //菜单级别
+    private Integer level;
+
+    //父级菜单
+    private Long parentId;
+
+    //菜单项显示标题
+    private String title;
+
+    private Byte priority;
+
+    //菜单项描述信息
+    private String descInfo;
+
+
+    private String component;
+
+    //菜单项名称
+    private String name;
+
+    //路径
+    private String path;
+
+    //重定向路径
+    private String redirect;
+
+    //
+    private Boolean linkable;
+
+    //
+    private Boolean visiable;
+
+    private Boolean aliveable;
+
+    private Boolean affixable;
+
+    private Boolean iframeable;
+
+    private Boolean publicable;
+
+    //
+    private String icon;
+
+    private String link;
+
+    private List<MenuItemDomainDTO> subMenuItemList;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Integer getLevel() {
+        return level;
+    }
+
+    public void setLevel(Integer level) {
+        this.level = level;
+    }
+
+    public Long getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescInfo() {
+        return descInfo;
+    }
+
+    public void setDescInfo(String descInfo) {
+        this.descInfo = descInfo;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getRedirect() {
+        return redirect;
+    }
+
+    public void setRedirect(String redirect) {
+        this.redirect = redirect;
+    }
+
+    public Boolean getLinkable() {
+        return linkable;
+    }
+
+    public void setLinkable(Boolean linkable) {
+        this.linkable = linkable;
+    }
+
+    public Boolean getVisiable() {
+        return visiable;
+    }
+
+    public void setVisiable(Boolean visiable) {
+        this.visiable = visiable;
+    }
+
+    public String getIcon() {
+        return icon;
+    }
+
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
+
+    public Byte getPriority() {
+        return priority;
+    }
+
+    public void setPriority(Byte priority) {
+        this.priority = priority;
+    }
+
+    public String getComponent() {
+        return component;
+    }
+
+    public void setComponent(String component) {
+        this.component = component;
+    }
+
+    public Boolean getAliveable() {
+        return aliveable;
+    }
+
+    public void setAliveable(Boolean aliveable) {
+        this.aliveable = aliveable;
+    }
+
+    public Boolean getAffixable() {
+        return affixable;
+    }
+
+    public void setAffixable(Boolean affixable) {
+        this.affixable = affixable;
+    }
+
+    public Boolean getIframeable() {
+        return iframeable;
+    }
+
+    public void setIframeable(Boolean iframeable) {
+        this.iframeable = iframeable;
+    }
+
+    public Boolean getPublicable() {
+        return publicable;
+    }
+
+    public void setPublicable(Boolean publicable) {
+        this.publicable = publicable;
+    }
+
+    public String getLink() {
+        return link;
+    }
+
+    public void setLink(String link) {
+        this.link = link;
+    }
+
+    public List<MenuItemDomainDTO> getSubMenuItemList() {
+        return subMenuItemList;
+    }
+
+    public void setSubMenuItemList(List<MenuItemDomainDTO> subMenuItemList) {
+        this.subMenuItemList = subMenuItemList;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/repository/jpa/MenuItemRepository.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/repository/jpa/MenuItemRepository.java
new file mode 100644
index 0000000..2a0220d
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/repository/jpa/MenuItemRepository.java
@@ -0,0 +1,52 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.repository.jpa;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.entity.MenuItem;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+
+import java.util.List;
+
+public interface MenuItemRepository extends JpaRepository<MenuItem, Long> {
+
+    @Query(value = "select m from MenuItem m where m.id = :menuItemId and m.visiable = true and m.del = 0")
+    MenuItem findVisiableById(Long menuItemId);
+
+    @Query(value = "select m from MenuItem m where m.id = :menuId and m.visiable = false and m.del = 0")
+    MenuItem findDisVisiableById(Long menuId);
+
+    @Modifying
+    @Query(value = "update MenuItem m set m.del = 1 where m.id = :menuItemId")
+    Integer logicDeleteMenuItem(Long menuItemId);
+
+    @Modifying
+    @Query(value = "delete from MenuItem m where m.id = :menuItemId")
+    Integer deleteByMenuItemId(Long menuItemId);
+
+    @Modifying
+    @Query(value = "update MenuItem m set m.visiable = true where m.id = :menuItemId and m.visiable = false and m.del = 0")
+    Integer setMenuItemVisiabel(Long menuItemId);
+
+    @Modifying
+    @Query(value = "update MenuItem m set m.visiable = false where m.id = :menuItemId and m.visiable = true and m.del = 0")
+    Integer setMenuItemDisVisiabel(Long menuItemId);
+
+    @Query(value = "select m from MenuItem m where m.del = 0 order by m.priority asc ")
+    List findAllActive();
+
+    @Query(value = "select m from MenuItem m where m.del = 0 and m.visiable = true order by m.priority asc ")
+    List findAllVisiable();
+
+    @Query(value = "select m from MenuItem m where m.id in :idList and m.del = 0 order by m.priority asc ")
+    List<MenuItem> findAllActiveByIdIn(List<Long> idList);
+
+    @Query(value = "select m from MenuItem m where m.id in :idList and m.del = 0 and m.visiable = :visiable order by m.priority asc ")
+    List<MenuItem> findAllByIdInAndVisiable(List<Long> idList,Boolean visiable);
+
+
+    @Query(value = "select m from MenuItem m where m.type = 1 and m.del = 0 order by m.priority asc")
+    List<MenuItem> findAllActivePublicMenuItems();
+
+    @Query("select count(m) from MenuItem m where m.parentId = :parentId")
+    Integer countSubMenuItems(Long parentId);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/repository/jpa/SysConfigRepository.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/repository/jpa/SysConfigRepository.java
new file mode 100644
index 0000000..b24b472
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/repository/jpa/SysConfigRepository.java
@@ -0,0 +1,9 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.repository.jpa;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.entity.SysConfig;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface SysConfigRepository extends JpaRepository<SysConfig,String> {
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/service/MenuDomainService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/service/MenuDomainService.java
new file mode 100644
index 0000000..6d0c1e4
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/service/MenuDomainService.java
@@ -0,0 +1,33 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.service;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.model.bo.CreateNewMenuItemBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.model.bo.ModifyMenuItemBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.model.dto.MenuItemDomainDTO;
+
+import java.util.List;
+
+public interface MenuDomainService {
+
+    MenuItemDomainDTO createNewMenuItem(CreateNewMenuItemBO createBO);
+
+    boolean setMenuItemEnable(Long menuItemId);
+
+    boolean setMenuItemDisable(Long menuItemId);
+
+    boolean deleteMenuItem(Long menuItemId);
+
+    /**
+     * 获取全部可用的菜单项
+     * @return
+     */
+    List<MenuItemDomainDTO> getAllActiveMenuItems();
+
+    List<MenuItemDomainDTO> getActiveMenuItemListByIds(List<Long> idList);
+
+    List<MenuItemDomainDTO> getActiveMenuItemListTreeByIds(List<Long> idList);
+
+    MenuItemDomainDTO getMenuItemById(Long menuItemId);
+
+    boolean modifyMenuItem(ModifyMenuItemBO bo);
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/service/impl/MenuDomainServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/service/impl/MenuDomainServiceImpl.java
new file mode 100644
index 0000000..ddbff4f
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/domain/sysAdmin/service/impl/MenuDomainServiceImpl.java
@@ -0,0 +1,372 @@
+package com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.service.impl;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.Role;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.RoleMenuBind;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa.RoleMenuBindRepository;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa.RoleRepository;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.converter.MenuItemConverter;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.entity.MenuItem;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.model.bo.CreateNewMenuItemBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.model.bo.ModifyMenuItemBO;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.model.dto.MenuItemDomainDTO;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.repository.jpa.MenuItemRepository;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.service.MenuDomainService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+import java.util.*;
+
+@Service
+public class MenuDomainServiceImpl implements MenuDomainService {
+
+    @Autowired
+    private MenuItemRepository menuItemRepository;
+
+    @Autowired
+    private MenuItemConverter menuItemConverter;
+
+    @Autowired
+    private RoleMenuBindRepository roleMenuBindRepository;
+
+    @Autowired
+    private RoleRepository roleRepository;
+
+    @Override
+    @Transactional
+    public MenuItemDomainDTO createNewMenuItem(CreateNewMenuItemBO createBO) {
+        if(createBO == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        MenuItem menuItem = new MenuItem();
+        //获取父级菜单项信息
+        if(createBO.getParentId() != null && createBO.getParentId() > 0){
+            Optional<MenuItem> parantItemOptional = menuItemRepository.findById(createBO.getParentId());
+            if(!parantItemOptional.isPresent())
+                throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_OBJECT_NOT_EXIST.getCode(),
+                        "上一级菜单项不存在");
+            MenuItem parant = parantItemOptional.get();
+            menuItem.setParentId(parant.getId());
+            menuItem.setLevel(parant.getLevel()+1);
+        }else {
+            menuItem.setLevel(1);
+        }
+        menuItem.setName(createBO.getName());
+        menuItem.setDescInfo(createBO.getDescInfo());
+        menuItem.setPath(createBO.getPath());
+        menuItem.setTitle(createBO.getTitle());
+        menuItem.setIcon(createBO.getIcon());
+        menuItem.setLink(createBO.getLink());
+        menuItem.setRedirect(createBO.getRedirect());
+        menuItem.setVisiable(createBO.isVisiable());
+        menuItem.setDel((byte)0);
+        menuItem.setGmtCreate(LocalDateTime.now());
+        menuItem.setGmtModified(menuItem.getGmtCreate());
+        menuItem.setPriority(createBO.getPriority());
+        menuItem.setComponent(createBO.getComponent());
+        menuItem.setAliveable(createBO.getAliveable());
+        menuItem.setAffixable(createBO.getAffixable());
+        menuItem.setIframeable(createBO.getIframeable());
+        menuItem.setPublicable(createBO.getPublicable());
+        menuItem = menuItemRepository.save(menuItem);
+        if(menuItem == null)
+            throw new BusinessException(this.getClass(),ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"数据库错误");
+        //绑定角色
+        if(createBO.getRoles() != null && !createBO.getRoles().isEmpty()){
+            List<Role> roleList = roleRepository.findAllByIdIn(createBO.getRoles());
+            if(roleList == null || roleList.isEmpty() || roleList.size() != createBO.getRoles().size()){
+                throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_OBJECT_NOT_EXIST.getCode(), "角色不存在");
+            }
+            //绑定角色菜单
+            List<RoleMenuBind> bindList = new ArrayList<>();
+            Long menuId = menuItem.getId();
+            roleList.forEach(r -> {
+                RoleMenuBind bind = new RoleMenuBind();
+                bind.setRoleId(r.getId());
+                bind.setMenuItemId(menuId);
+                bind.setGmtCreate(LocalDateTime.now());
+                bind.setGmtModified(bind.getGmtCreate());
+                bindList.add(bind);
+            });
+            List<RoleMenuBind> saveRs = roleMenuBindRepository.saveAll(bindList);
+            if(saveRs == null || saveRs.isEmpty() || saveRs.size() != bindList.size()){
+                throw new BusinessException(this.getClass(),ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"数据库错误");
+            }
+
+        }
+        return menuItemConverter.toMenuItemDTO(menuItem);
+    }
+
+    @Override
+    @Transactional
+    public boolean setMenuItemEnable(Long menuItemId) {
+        if(menuItemId == null || menuItemId < 1)
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        MenuItem menuItem = menuItemRepository.findDisVisiableById(menuItemId);
+        if(menuItem == null)
+            throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_OBJECT_NOT_EXIST.getCode(),
+                    "菜单项不存在");
+        if(menuItemRepository.setMenuItemVisiabel(menuItemId) != 1)
+            throw new BusinessException(this.getClass(),ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"变更状态出错");
+        else
+            return true;
+    }
+
+    @Override
+    @Transactional
+    public boolean setMenuItemDisable(Long menuItemId) {
+        if(menuItemId == null || menuItemId < 1)
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        MenuItem menuItem = menuItemRepository.findVisiableById(menuItemId);
+        if(menuItem == null)
+            throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_OBJECT_NOT_EXIST.getCode(),
+                    "菜单项不存在");
+        if(menuItemRepository.setMenuItemDisVisiabel(menuItemId) != 1)
+            throw new BusinessException(this.getClass(),ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"变更状态出错");
+        else
+            return true;
+    }
+
+    @Override
+    @Transactional
+    public boolean deleteMenuItem(Long menuItemId) {
+        if(menuItemId == null || menuItemId < 1)
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        Optional<MenuItem> menuItemOptional = menuItemRepository.findById(menuItemId);
+        if(!menuItemOptional.isPresent())
+            throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_OBJECT_NOT_EXIST.getCode(),
+                    "菜单项不存在");
+        MenuItem menuItem = menuItemOptional.get();
+        //限制:存在子菜单就不允许删除
+        Integer subMenuItemCount = menuItemRepository.countSubMenuItems(menuItemId);
+        if(subMenuItemCount > 0){
+            throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_NOT_ALLOWED.getCode(), "该菜单项存在子菜单,不允许删除");
+        }
+//        //删除角色菜单绑定关系
+        roleMenuBindRepository.deleteByMenuItemId(menuItemId);
+        if(menuItemRepository.deleteByMenuItemId(menuItemId) != 1)
+            throw new BusinessException(this.getClass(),ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"变更状态出错");
+        return true;
+    }
+
+    @Override
+    public List<MenuItemDomainDTO> getAllActiveMenuItems() {
+        List<MenuItem> allActiveMenuItemList = menuItemRepository.findAllActive();
+        if(allActiveMenuItemList == null || allActiveMenuItemList.isEmpty())
+            return null;
+        List<MenuItemDomainDTO> dtoList = new ArrayList<>();
+        List<MenuItemDomainDTO> childList = new ArrayList<>();
+        allActiveMenuItemList.forEach(item -> {
+            MenuItemDomainDTO dto = menuItemConverter.toMenuItemDTO(item);
+            if(item.getLevel().equals(1) && item.getParentId() == null)
+                dtoList.add(dto);
+            else
+                childList.add(dto);
+        });
+        if(dtoList != null && dtoList.size() > 0 && childList != null && childList.size() > 0){
+            for(MenuItemDomainDTO dto : dtoList){
+                List<MenuItemDomainDTO> subMenuItemList = praseChildMenuItems(dto,childList);
+                if(subMenuItemList != null && subMenuItemList.size() > 0)
+                    dto.setSubMenuItemList(subMenuItemList);
+            }
+        }
+        return dtoList;
+    }
+
+    @Override
+    public List<MenuItemDomainDTO> getActiveMenuItemListByIds(List<Long> idList) {
+        if(idList == null || idList.size() == 0)
+            return null;
+        List<MenuItem> allActiveMenuItemList = menuItemRepository.findAllActiveByIdIn(idList);
+        if(allActiveMenuItemList == null || allActiveMenuItemList.isEmpty())
+            return null;
+        List<MenuItemDomainDTO> dtoList = new ArrayList<>();
+//        allActiveMenuItemList.forEach(item -> {
+//            MenuItemDomainDTO dto = menuItemConverter.toMenuItemDTO(item);
+//            dtoList.add(dto);
+//        });
+        for (MenuItem item : allActiveMenuItemList){
+            MenuItemDomainDTO dto = menuItemConverter.toMenuItemDTO(item);
+            dtoList.add(dto);
+        }
+        return dtoList;
+        //old - 解析成树结构
+//        List<MenuItemDTO> childList = new ArrayList<>();
+//        allActiveMenuItemList.forEach(item -> {
+//            MenuItemDTO dto = menuItemConverter.toMenuItemDTO(item);
+//            if(item.getLevel().equals(1) && item.getParantId() == null)
+//                dtoList.add(dto);
+//            else
+//                childList.add(dto);
+//        });
+//        if(dtoList != null && dtoList.size() > 0 && childList != null && childList.size() > 0){
+//            for(MenuItemDTO dto : dtoList){
+//                List<MenuItemDTO> subMenuItemList = praseChildMenuItems(dto,childList);
+//                if(subMenuItemList != null && subMenuItemList.size() > 0)
+//                    dto.setSubMenuItemList(subMenuItemList);
+//            }
+//        }
+//        return dtoList;
+    }
+    @Override
+    public MenuItemDomainDTO getMenuItemById(Long menuItemId) {
+        if(menuItemId == null || menuItemId < 1)
+            return null;
+        Optional<MenuItem> menuItemOptional = menuItemRepository.findById(menuItemId);
+        if(!menuItemOptional.isPresent())
+            return null;
+        MenuItem menuItem = menuItemOptional.get();
+        if(menuItem.getDel().equals(1))
+            return null;
+        return menuItemConverter.toMenuItemDTO(menuItem);
+    }
+
+    @Override
+    @Transactional
+    public boolean modifyMenuItem(ModifyMenuItemBO bo) {
+        if(bo == null)
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        if(bo.getMenuItemId() == null || bo.getMenuItemId() < 1)
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        Optional<MenuItem> menuItemOptional = menuItemRepository.findById(bo.getMenuItemId());
+        if(!menuItemOptional.isPresent())
+            throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_OBJECT_NOT_EXIST.getCode(),"菜单项不存在");
+        MenuItem menuItem = menuItemOptional.get();
+        menuItem.setParentId(bo.getParentId());
+        menuItem.setTitle(bo.getTitle());
+        menuItem.setName(bo.getName());
+        menuItem.setIcon(bo.getIcon());
+        menuItem.setPath(bo.getPath());
+        menuItem.setRedirect(bo.getRedirect());
+        menuItem.setDescInfo(bo.getDescInfo());
+        menuItem.setLink(bo.getLink());
+        menuItem.setVisiable(bo.getVisiable());
+        //
+        menuItem.setPriority(bo.getPriority());
+        menuItem.setComponent(bo.getComponent());
+        menuItem.setAliveable(bo.getAliveable());
+        menuItem.setAffixable(bo.getAffixable());
+        menuItem.setIframeable(bo.getIframeable());
+        menuItem.setPublicable(bo.getPublicable());
+        if(bo.getParentId() != null){
+            Optional<MenuItem> parantOptional = menuItemRepository.findById(bo.getParentId());
+            if(!parantOptional.isPresent())
+                throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_OBJECT_NOT_EXIST.getCode(),"上一级菜单项不存在");
+            MenuItem parantItem = parantOptional.get();
+            //重置父级菜单项ID
+            menuItem.setParentId(bo.getParentId());
+            //重置菜单项等级
+            menuItem.setLevel(parantItem.getLevel()+1);
+        }
+        if(menuItemRepository.save(menuItem) == null){
+            throw new BusinessException(this.getClass(),ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"修改菜单项出错");
+        }
+        //修改菜单项绑定角色信息
+        List<Long> bindRoles = new ArrayList<>();
+        List<Long> unbindRoles = new ArrayList<>();
+        List<Long> orignRoles = roleMenuBindRepository.findBindRoleListByMenuItemId(menuItem.getId());
+        Set<Long> orignRoleIds = new HashSet<>();
+        orignRoles.forEach(id -> {
+            orignRoleIds.add(id);
+        });
+        if(bo.getRoles() != null && !bo.getRoles().isEmpty()){
+            for(int i =0;i<bo.getRoles().size();i++){
+                if(!orignRoleIds.contains(bo.getRoles().get(i))){
+                    bindRoles.add(bo.getRoles().get(i));
+                }
+            }
+        }
+        Set<Long> nowRoles = new HashSet<>();
+        if(bo.getRoles() != null && !bo.getRoles().isEmpty()){
+            bo.getRoles().forEach(id -> {
+                nowRoles.add(id);
+            });
+        }
+        for(int i =0;i<orignRoles.size();i++){
+            if(!nowRoles.contains(orignRoles.get(i))){
+                unbindRoles.add(orignRoles.get(i));
+            }
+        }
+        if(!bindRoles.isEmpty()){
+            //绑定角色
+            //检查角色是否存在
+            List<Role> bindRoleList = roleRepository.findAllByIdIn(bindRoles);
+            if(bindRoleList == null || bindRoleList.size() != bindRoleList.size()){
+                throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_OBJECT_NOT_EXIST.getCode(), "角色不存在");
+            }
+            List<RoleMenuBind> roleMenuBindList = new ArrayList<>();
+            bindRoles.forEach(roleId -> {
+                RoleMenuBind b = new RoleMenuBind();
+                b.setMenuItemId(bo.getMenuItemId());
+                b.setRoleId(roleId);
+                b.setGmtCreate(LocalDateTime.now());
+                b.setGmtModified(b.getGmtCreate());
+                roleMenuBindList.add(b);
+            });
+            List<RoleMenuBind> saveRs = roleMenuBindRepository.saveAll(roleMenuBindList);
+            if(saveRs == null || saveRs.isEmpty() || saveRs.size() != roleMenuBindList.size()){
+                throw new BusinessException(this.getClass(),ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"数据库错误");
+            }
+        }
+        if(!unbindRoles.isEmpty()){
+            //解绑角色
+            Integer unbindCount = roleMenuBindRepository.deleteByMenuItemIdAndRoleIdIn(bo.getMenuItemId(),unbindRoles);
+        }
+        return true;
+    }
+
+    @Override
+    public List<MenuItemDomainDTO> getActiveMenuItemListTreeByIds(List<Long> idList) {
+        List<MenuItemDomainDTO> orignList = getActiveMenuItemListByIds(idList);
+        if(orignList == null || orignList.isEmpty())
+            return null;
+        List<MenuItemDomainDTO> parantList = new ArrayList<>();
+        List<MenuItemDomainDTO> childList = new ArrayList<>();
+        orignList.forEach(item -> {
+            if(item.getLevel().equals(1) && item.getParentId() == null)
+                parantList.add(item);
+            else
+                childList.add(item);
+        });
+        if(parantList != null && parantList.size() > 0 && childList != null && childList.size() > 0){
+            for(MenuItemDomainDTO dto : parantList){
+                List<MenuItemDomainDTO> subMenuItemList = praseChildMenuItems(dto,childList);
+                if(subMenuItemList != null && subMenuItemList.size() > 0)
+                    dto.setSubMenuItemList(subMenuItemList);
+            }
+        }
+        return parantList;
+    }
+
+    /**
+     * 递归解析菜单数据,获取菜单树状结构
+     * @param parantItem
+     * @param childItemList
+     * @return
+     */
+    private List<MenuItemDomainDTO> praseChildMenuItems(MenuItemDomainDTO parantItem, List<MenuItemDomainDTO> childItemList){
+        if(childItemList == null || childItemList.size() == 0 || parantItem == null)
+            return null;
+        List<MenuItemDomainDTO> resultList = new ArrayList<>();
+//        childItemList.forEach(child -> {
+//            if(parantItem.getId().equals(child.getParentId())){
+//                resultList.add(child);
+//            }
+//        });
+        for(MenuItemDomainDTO child : childItemList){
+            if(parantItem.getId().equals(child.getParentId())){
+                resultList.add(child);
+            }
+        }
+        if(resultList.size() > 0){
+            for (MenuItemDomainDTO child : childItemList){
+                List<MenuItemDomainDTO> childList = praseChildMenuItems(child,childItemList);
+                if(childList != null && childList.size() > 0)
+                    child.setSubMenuItemList(childList);
+            }
+        }
+        return resultList;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/DeviceExceptionLog.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/DeviceExceptionLog.java
new file mode 100644
index 0000000..7abf2f5
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/DeviceExceptionLog.java
@@ -0,0 +1,25 @@
+package com.gkhy.fourierSpecialGasMonitor.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/8 15:09
+ */
+@Entity
+@Table(name = "device_exception_log")
+@Data
+public class DeviceExceptionLog {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Integer id;
+
+    private LocalDateTime time;
+
+    private String execDesc;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasCategory.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasCategory.java
new file mode 100644
index 0000000..53dce30
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasCategory.java
@@ -0,0 +1,46 @@
+package com.gkhy.fourierSpecialGasMonitor.entity;
+
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import lombok.Data;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+
+@Entity
+@Table(name = "gas_category")
+@Data
+public class GasCategory {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Integer id;
+
+    private String molecularFormula;
+
+    private String name;
+
+    private String unit;
+
+    private Double threshold;
+
+    private String createdby;
+
+    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
+    @JsonSerialize(using = LocalDateTimeSerializer.class)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime gmtCreate;
+
+    private String lastmodifiedby;
+
+    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
+    @JsonSerialize(using = LocalDateTimeSerializer.class)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime gmtModified;
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasConcentration.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasConcentration.java
new file mode 100644
index 0000000..6d5f4e2
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasConcentration.java
@@ -0,0 +1,103 @@
+package com.gkhy.fourierSpecialGasMonitor.entity;
+
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "gas_concentration")
+@Data
+public class GasConcentration {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    private String equipmentId;
+
+    private LocalDateTime time;
+
+    private LocalDateTime dataReceivingTime;
+
+    private int type;
+
+    private String lng;
+
+    private String lat;
+
+    private String angle;
+
+    private Double temp;
+
+    private Double  humidity;
+
+    private Double windSpeed;
+
+    private int windDirection;
+
+    private Double pressure;
+
+    private int gasName01;
+    private Double gasValue01;
+    private int gasName02;
+    private Double gasValue02;
+    private int gasName03;
+    private Double gasValue03;
+    private int gasName04;
+    private Double gasValue04;
+    private int gasName05;
+    private Double gasValue05;
+    private int gasName06;
+    private Double gasValue06;
+    private int gasName07;
+    private Double gasValue07;
+    private int gasName08;
+    private Double gasValue08;
+    private int gasName09;
+    private Double gasValue09;
+    private int gasName10;
+    private Double gasValue10;
+    private int gasName11;
+    private Double gasValue11;
+    private int gasName12;
+    private Double gasValue12;
+    private int gasName13;
+    private Double gasValue13;
+    private int gasName14;
+    private Double gasValue14;
+    private int gasName15;
+    private Double gasValue15;
+    private int gasName16;
+    private Double gasValue16;
+    private int gasName17;
+    private Double gasValue17;
+    private int gasName18;
+    private Double gasValue18;
+    private int gasName19;
+    private Double gasValue19;
+    private int gasName20;
+    private Double gasValue20;
+    private int gasName21;
+    private Double gasValue21;
+    private int gasName22;
+    private Double gasValue22;
+    private int gasName23;
+    private Double gasValue23;
+    private int gasName24;
+    private Double gasValue24;
+    private int gasName25;
+    private Double gasValue25;
+    private int gasName26;
+    private Double gasValue26;
+    private int gasName27;
+    private Double gasValue27;
+    private int gasName28;
+    private Double gasValue28;
+    private int gasName29;
+    private Double gasValue29;
+    private int gasName30;
+    private Double gasValue30;
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasFlux.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasFlux.java
new file mode 100644
index 0000000..a3b08a5
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasFlux.java
@@ -0,0 +1,71 @@
+package com.gkhy.fourierSpecialGasMonitor.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "gas_flux")
+@Data
+public class GasFlux {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    private String equipmentId;
+
+    private LocalDateTime time;
+
+    private int areaId;
+
+    private LocalDateTime dataReceivingTime;
+
+    private int type;
+
+    private Double windSpeed;
+
+    private int windDirection;
+
+    private int gasName01;
+    private Double gasValue01;
+    private int gasName02;
+    private Double gasValue02;
+    private int gasName03;
+    private Double gasValue03;
+    private int gasName04;
+    private Double gasValue04;
+    private int gasName05;
+    private Double gasValue05;
+    private int gasName06;
+    private Double gasValue06;
+    private int gasName07;
+    private Double gasValue07;
+    private int gasName08;
+    private Double gasValue08;
+    private int gasName09;
+    private Double gasValue09;
+    private int gasName10;
+    private Double gasValue10;
+    private int gasName11;
+    private Double gasValue11;
+    private int gasName12;
+    private Double gasValue12;
+    private int gasName13;
+    private Double gasValue13;
+    private int gasName14;
+    private Double gasValue14;
+    private int gasName15;
+    private Double gasValue15;
+    private int gasName16;
+    private Double gasValue16;
+    private int gasName17;
+    private Double gasValue17;
+    private int gasName18;
+    private Double gasValue18;
+    private int gasName19;
+    private Double gasValue19;
+    private int gasName20;
+    private Double gasValue20;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasThreshold.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasThreshold.java
new file mode 100644
index 0000000..4f67c9a
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasThreshold.java
@@ -0,0 +1,33 @@
+package com.gkhy.fourierSpecialGasMonitor.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 14:29
+ */
+@Entity
+@Table(name = "gas_threshold")
+@Data
+public class GasThreshold {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Integer id;
+
+    private String name;
+
+    private int threshold;
+
+    private String createdby;
+
+    private LocalDateTime gmtCreate;
+
+    private String lastmodifiedby;
+
+    private LocalDateTime gmtModified;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasWarnLog.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasWarnLog.java
new file mode 100644
index 0000000..31cb94f
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasWarnLog.java
@@ -0,0 +1,60 @@
+package com.gkhy.fourierSpecialGasMonitor.entity;
+
+import lombok.Data;
+import org.hibernate.annotations.Fetch;
+import org.hibernate.annotations.FetchMode;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 16:34
+ */
+@Entity
+@Table(name = "gas_warn_log")
+@Data
+public class GasWarnLog {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    private String content;
+
+    private LocalDateTime warnTime;
+
+    private Integer gasCategoryId;
+
+    private String gasMolecularFormula;
+
+    private String gasName;
+
+    private String gasUnit;
+
+    private Double gasConcentrationThreshold;
+
+    private Double gasConcentration;
+
+    private Integer gasThresholdId;
+
+    private String gasThresholdName;
+
+    private Byte status;
+
+    private Long handlerId;
+
+    private String handlerName;
+
+    private String handlerRealName;
+
+    private LocalDateTime handlerTime;
+
+    @OneToMany(fetch = FetchType.EAGER,cascade = {CascadeType.REFRESH})
+    @Fetch(FetchMode.SUBSELECT)
+    @JoinColumn(name = "warnLogId",referencedColumnName = "id",insertable =false ,updatable = false)
+    private List<GasWarnLogSmsUser> gasWarnLogSmsUsers;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasWarnLogSmsUser.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasWarnLogSmsUser.java
new file mode 100644
index 0000000..968144c
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasWarnLogSmsUser.java
@@ -0,0 +1,32 @@
+package com.gkhy.fourierSpecialGasMonitor.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 16:34
+ */
+@Entity
+@Table(name = "gas_warn_log_sms_user")
+@Data
+public class GasWarnLogSmsUser {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    private Long warnLogId;
+
+    private Long userId;
+
+    private String name;
+
+    private String realName;
+
+    private String phone;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasWarnUser.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasWarnUser.java
new file mode 100644
index 0000000..0711ac8
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/GasWarnUser.java
@@ -0,0 +1,39 @@
+package com.gkhy.fourierSpecialGasMonitor.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 14:29
+ */
+@Entity
+@Table(name = "gas_warn_user")
+@Data
+public class GasWarnUser {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    private Long userId;
+
+    private String name;
+
+    private String realName;
+
+    private String phone;
+
+    private Byte status;
+
+    private String createdby;
+
+    private LocalDateTime gmtCreate;
+
+    private String lastmodifiedby;
+
+    private LocalDateTime gmtModified;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/MonitorDailyReport.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/MonitorDailyReport.java
new file mode 100644
index 0000000..10076e2
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/MonitorDailyReport.java
@@ -0,0 +1,29 @@
+package com.gkhy.fourierSpecialGasMonitor.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 15:39
+ */
+@Entity
+@Table(name = "monitor_daily_report")
+@Data
+public class MonitorDailyReport {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    private String name;
+
+    private LocalDateTime gmtCreate;
+
+    private LocalDateTime endTime;
+
+    private String fileUrl;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/Region.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/Region.java
new file mode 100644
index 0000000..5d1032f
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/Region.java
@@ -0,0 +1,49 @@
+package com.gkhy.fourierSpecialGasMonitor.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.SysUserRoleBind;
+import lombok.Data;
+import org.hibernate.annotations.Fetch;
+import org.hibernate.annotations.FetchMode;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 10:40
+ */
+@Entity
+@Table(name = "region")
+@Data
+public class Region {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Integer id;
+
+    private String name;
+
+    private String color;
+
+    private Byte status;
+
+    private String createdby;
+
+    private LocalDateTime gmtCreate;
+
+    private String lastmodifiedby;
+
+    private LocalDateTime gmtModified;
+
+    @OneToMany(fetch = FetchType.EAGER,cascade = {CascadeType.REFRESH})
+    @Fetch(FetchMode.SUBSELECT)
+    @JoinColumn(name = "regionId",referencedColumnName = "id",insertable =false ,updatable = false)
+    private List<RegionLngLat> regionLngLats;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/RegionLngLat.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/RegionLngLat.java
new file mode 100644
index 0000000..563136b
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/RegionLngLat.java
@@ -0,0 +1,26 @@
+package com.gkhy.fourierSpecialGasMonitor.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 10:42
+ */
+@Entity
+@Table(name = "region_lng_lat")
+@Data
+public class RegionLngLat {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    private Integer regionId;
+
+    private String lng;
+
+    private String lat;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/dtos/GasConcentrationDto.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/dtos/GasConcentrationDto.java
new file mode 100644
index 0000000..3250719
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/dtos/GasConcentrationDto.java
@@ -0,0 +1,97 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.dtos;
+
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+public class GasConcentrationDto {
+
+    private Long id;
+
+    private String equipmentId;
+
+    private LocalDateTime time;
+
+    private int type;
+
+    private String ing;
+
+    private String lat;
+
+    private String angle;
+
+    private Double temp;
+
+    private Double  humidity;
+
+    private Double windSpeed;
+
+    private Double windDirection;
+
+    private Double pressure;
+
+    private int gasName01;
+    private Double gasValue01;
+    private int gasName02;
+    private Double gasValue02;
+    private int gasName03;
+    private Double gasValue03;
+    private int gasName04;
+    private Double gasValue04;
+    private int gasName05;
+    private Double gasValue05;
+    private int gasName06;
+    private Double gasValue06;
+    private int gasName07;
+    private Double gasValue07;
+    private int gasName08;
+    private Double gasValue08;
+    private int gasName09;
+    private Double gasValue09;
+    private int gasName10;
+    private Double gasValue10;
+    private int gasName11;
+    private Double gasValue11;
+    private int gasName12;
+    private Double gasValue12;
+    private int gasName13;
+    private Double gasValue13;
+    private int gasName14;
+    private Double gasValue14;
+    private int gasName15;
+    private Double gasValue15;
+    private int gasName16;
+    private Double gasValue16;
+    private int gasName17;
+    private Double gasValue17;
+    private int gasName18;
+    private Double gasValue18;
+    private int gasName19;
+    private Double gasValue19;
+    private int gasName20;
+    private Double gasValue20;
+    private int gasName21;
+    private Double gasValue21;
+    private int gasName22;
+    private Double gasValue22;
+    private int gasName23;
+    private Double gasValue23;
+    private int gasName24;
+    private Double gasValue24;
+    private int gasName25;
+    private Double gasValue25;
+    private int gasName26;
+    private Double gasValue26;
+    private int gasName27;
+    private Double gasValue27;
+    private int gasName28;
+    private Double gasValue28;
+    private int gasName29;
+    private Double gasValue29;
+    private int gasName30;
+    private Double gasValue30;
+
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindDailyReportPageQuery.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindDailyReportPageQuery.java
new file mode 100644
index 0000000..be083a9
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindDailyReportPageQuery.java
@@ -0,0 +1,19 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.query;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 15:46
+ */
+@Data
+public class FindDailyReportPageQuery {
+
+    private Integer year;
+
+    private Integer month;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindGasCategoryPageQuery.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindGasCategoryPageQuery.java
new file mode 100644
index 0000000..602424b
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindGasCategoryPageQuery.java
@@ -0,0 +1,15 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.query;
+
+import lombok.Data;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 13:49
+ */
+@Data
+public class FindGasCategoryPageQuery {
+
+    private String name;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindGasWarnLogPageQuery.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindGasWarnLogPageQuery.java
new file mode 100644
index 0000000..30a26e8
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindGasWarnLogPageQuery.java
@@ -0,0 +1,24 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.query;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 16:49
+ */
+@Data
+public class FindGasWarnLogPageQuery {
+
+    private LocalDateTime startTime;
+
+    private LocalDateTime endTime;
+
+    private Integer gasCategoryId;
+
+    private Byte status;
+
+    private Long gasThresholdId;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindGasWarnUserPageQuery.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindGasWarnUserPageQuery.java
new file mode 100644
index 0000000..5e45ff5
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindGasWarnUserPageQuery.java
@@ -0,0 +1,15 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.query;
+
+import lombok.Data;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 13:49
+ */
+@Data
+public class FindGasWarnUserPageQuery {
+
+    private String realName;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindRegionPageQuery.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindRegionPageQuery.java
new file mode 100644
index 0000000..a2f7408
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/FindRegionPageQuery.java
@@ -0,0 +1,15 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.query;
+
+import lombok.Data;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 13:49
+ */
+@Data
+public class FindRegionPageQuery {
+
+    private String name;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/GasAtmospherePageQuery.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/GasAtmospherePageQuery.java
new file mode 100644
index 0000000..c61fb9b
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/GasAtmospherePageQuery.java
@@ -0,0 +1,21 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.query;
+
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 9:13
+ */
+@Data
+public class GasAtmospherePageQuery {
+
+    private LocalDateTime startTime;
+
+    private LocalDateTime endTime;
+
+    private String atmosphere;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/GasFluxPageQuery.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/GasFluxPageQuery.java
new file mode 100644
index 0000000..c612fbb
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/GasFluxPageQuery.java
@@ -0,0 +1,22 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.query;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 10:52
+ */
+@Data
+public class GasFluxPageQuery {
+
+    private LocalDateTime startTime;
+
+    private LocalDateTime endTime;
+
+    private Integer gasName;
+
+    private Integer areaId;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/GasPageQuery.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/GasPageQuery.java
new file mode 100644
index 0000000..7855241
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/query/GasPageQuery.java
@@ -0,0 +1,20 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.query;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 10:52
+ */
+@Data
+public class GasPageQuery {
+
+    private LocalDateTime startTime;
+
+    private LocalDateTime endTime;
+
+    private Integer gasName;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/CreateGasCategoryReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/CreateGasCategoryReqDTO.java
new file mode 100644
index 0000000..5dfe42c
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/CreateGasCategoryReqDTO.java
@@ -0,0 +1,22 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.req;
+
+import lombok.Data;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/7 13:36
+ */
+@Data
+public class CreateGasCategoryReqDTO {
+
+    private Integer id;
+
+    private String molecularFormula;
+
+    private String name;
+
+    private String unit;
+
+    private Double threshold;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/CreateGasWarnUserReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/CreateGasWarnUserReqDTO.java
new file mode 100644
index 0000000..90f9efe
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/CreateGasWarnUserReqDTO.java
@@ -0,0 +1,21 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.req;
+
+import lombok.Data;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 15:02
+ */
+@Data
+public class CreateGasWarnUserReqDTO {
+
+    private Long userId;
+
+    private String name;
+
+    private String realName;
+
+    private String phone;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/CreateRegionLngLatReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/CreateRegionLngLatReqDTO.java
new file mode 100644
index 0000000..d9719cb
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/CreateRegionLngLatReqDTO.java
@@ -0,0 +1,16 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.req;
+
+import lombok.Data;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 10:50
+ */
+@Data
+public class CreateRegionLngLatReqDTO {
+
+    private String lng;
+
+    private String lat;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/CreateRegionReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/CreateRegionReqDTO.java
new file mode 100644
index 0000000..cd0b90d
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/CreateRegionReqDTO.java
@@ -0,0 +1,22 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.req;
+
+import com.gkhy.fourierSpecialGasMonitor.entity.RegionLngLat;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 10:48
+ */
+@Data
+public class CreateRegionReqDTO {
+
+    private String name;
+
+    private String color;
+
+    private List<CreateRegionLngLatReqDTO> regionLngLats;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/DelGasWarnUserByIdReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/DelGasWarnUserByIdReqDTO.java
new file mode 100644
index 0000000..98b4dba
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/DelGasWarnUserByIdReqDTO.java
@@ -0,0 +1,14 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.req;
+
+import lombok.Data;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 15:09
+ */
+@Data
+public class DelGasWarnUserByIdReqDTO {
+
+    private Long id;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/DelRegionByIdReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/DelRegionByIdReqDTO.java
new file mode 100644
index 0000000..c9d6a68
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/DelRegionByIdReqDTO.java
@@ -0,0 +1,14 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.req;
+
+import lombok.Data;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 13:37
+ */
+@Data
+public class DelRegionByIdReqDTO {
+
+    private Integer id;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/DeviceMonitorReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/DeviceMonitorReqDTO.java
new file mode 100644
index 0000000..c81eef1
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/DeviceMonitorReqDTO.java
@@ -0,0 +1,25 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.req;
+
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/8 14:38
+ */
+@Data
+public class DeviceMonitorReqDTO {
+
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime time;
+
+    private List<Integer> hardwareState;
+
+    private int conState;
+
+    private int fluxState;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/GasAtmosphereLineChartReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/GasAtmosphereLineChartReqDTO.java
new file mode 100644
index 0000000..1ec2732
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/GasAtmosphereLineChartReqDTO.java
@@ -0,0 +1,21 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.req;
+
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 9:13
+ */
+@Data
+public class GasAtmosphereLineChartReqDTO {
+
+    private LocalDateTime startTime;
+
+    private LocalDateTime endTime;
+
+    private String atmosphere;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/GasFluxLineChartReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/GasFluxLineChartReqDTO.java
new file mode 100644
index 0000000..04fc42f
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/GasFluxLineChartReqDTO.java
@@ -0,0 +1,23 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.req;
+
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 9:13
+ */
+@Data
+public class GasFluxLineChartReqDTO {
+
+    private LocalDateTime startTime;
+
+    private LocalDateTime endTime;
+
+    private Integer gasName;
+
+    private Integer areaId;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/GasLineChartReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/GasLineChartReqDTO.java
new file mode 100644
index 0000000..6683094
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/GasLineChartReqDTO.java
@@ -0,0 +1,21 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.req;
+
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 9:13
+ */
+@Data
+public class GasLineChartReqDTO {
+
+    private LocalDateTime startTime;
+
+    private LocalDateTime endTime;
+
+    private Integer gasName;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateGasCategoryReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateGasCategoryReqDTO.java
new file mode 100644
index 0000000..5922143
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateGasCategoryReqDTO.java
@@ -0,0 +1,22 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.req;
+
+import lombok.Data;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/7 13:36
+ */
+@Data
+public class UpdateGasCategoryReqDTO {
+
+    private Integer id;
+
+    private String molecularFormula;
+
+    private String name;
+
+    private String unit;
+
+    private Double threshold;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateGasThresholdReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateGasThresholdReqDTO.java
new file mode 100644
index 0000000..bbe81ea
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateGasThresholdReqDTO.java
@@ -0,0 +1,16 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.req;
+
+import lombok.Data;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 14:39
+ */
+@Data
+public class UpdateGasThresholdReqDTO {
+
+    private Integer id;
+
+    private int threshold;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateGasWarnUserReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateGasWarnUserReqDTO.java
new file mode 100644
index 0000000..f043f0f
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateGasWarnUserReqDTO.java
@@ -0,0 +1,23 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.req;
+
+import lombok.Data;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 15:02
+ */
+@Data
+public class UpdateGasWarnUserReqDTO {
+
+    private Long id;
+
+    private Long userId;
+
+    private String name;
+
+    private String realName;
+
+    private String phone;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateRegionLngLatReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateRegionLngLatReqDTO.java
new file mode 100644
index 0000000..1f0ab2f
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateRegionLngLatReqDTO.java
@@ -0,0 +1,16 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.req;
+
+import lombok.Data;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 10:50
+ */
+@Data
+public class UpdateRegionLngLatReqDTO {
+
+    private String lng;
+
+    private String lat;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateRegionReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateRegionReqDTO.java
new file mode 100644
index 0000000..e17ef48
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UpdateRegionReqDTO.java
@@ -0,0 +1,23 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.req;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 10:48
+ */
+@Data
+public class UpdateRegionReqDTO {
+
+    private Integer id;
+
+    private String name;
+
+    private String color;
+
+    private List<UpdateRegionLngLatReqDTO> regionLngLats;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UploadGasConcentrationReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UploadGasConcentrationReqDTO.java
new file mode 100644
index 0000000..0c23d6b
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UploadGasConcentrationReqDTO.java
@@ -0,0 +1,99 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.req;
+
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/7 14:27
+ */
+@Data
+public class UploadGasConcentrationReqDTO {
+
+    private String equipmentId;
+
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime time;
+
+    private int type;
+
+    private String lng;
+
+    private String lat;
+
+    private String angle;
+
+    private Double temp;
+
+    private Double  humidity;
+
+    private Double windSpeed;
+
+    private int windDirection;
+
+    private Double pressure;
+
+    private int gasName01;
+    private Double gasValue01;
+    private int gasName02;
+    private Double gasValue02;
+    private int gasName03;
+    private Double gasValue03;
+    private int gasName04;
+    private Double gasValue04;
+    private int gasName05;
+    private Double gasValue05;
+    private int gasName06;
+    private Double gasValue06;
+    private int gasName07;
+    private Double gasValue07;
+    private int gasName08;
+    private Double gasValue08;
+    private int gasName09;
+    private Double gasValue09;
+    private int gasName10;
+    private Double gasValue10;
+    private int gasName11;
+    private Double gasValue11;
+    private int gasName12;
+    private Double gasValue12;
+    private int gasName13;
+    private Double gasValue13;
+    private int gasName14;
+    private Double gasValue14;
+    private int gasName15;
+    private Double gasValue15;
+    private int gasName16;
+    private Double gasValue16;
+    private int gasName17;
+    private Double gasValue17;
+    private int gasName18;
+    private Double gasValue18;
+    private int gasName19;
+    private Double gasValue19;
+    private int gasName20;
+    private Double gasValue20;
+    private int gasName21;
+    private Double gasValue21;
+    private int gasName22;
+    private Double gasValue22;
+    private int gasName23;
+    private Double gasValue23;
+    private int gasName24;
+    private Double gasValue24;
+    private int gasName25;
+    private Double gasValue25;
+    private int gasName26;
+    private Double gasValue26;
+    private int gasName27;
+    private Double gasValue27;
+    private int gasName28;
+    private Double gasValue28;
+    private int gasName29;
+    private Double gasValue29;
+    private int gasName30;
+    private Double gasValue30;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UploadGasFluxReqDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UploadGasFluxReqDTO.java
new file mode 100644
index 0000000..3e2499f
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/req/UploadGasFluxReqDTO.java
@@ -0,0 +1,64 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.req;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+
+@Data
+public class UploadGasFluxReqDTO {
+
+    private String equipmentId;
+
+    private LocalDateTime time;
+
+    private int areaId;
+
+    private int type;
+
+    private Double windSpeed;
+
+    private int windDirection;
+
+    private int gasName01;
+    private Double gasValue01;
+    private int gasName02;
+    private Double gasValue02;
+    private int gasName03;
+    private Double gasValue03;
+    private int gasName04;
+    private Double gasValue04;
+    private int gasName05;
+    private Double gasValue05;
+    private int gasName06;
+    private Double gasValue06;
+    private int gasName07;
+    private Double gasValue07;
+    private int gasName08;
+    private Double gasValue08;
+    private int gasName09;
+    private Double gasValue09;
+    private int gasName10;
+    private Double gasValue10;
+    private int gasName11;
+    private Double gasValue11;
+    private int gasName12;
+    private Double gasValue12;
+    private int gasName13;
+    private Double gasValue13;
+    private int gasName14;
+    private Double gasValue14;
+    private int gasName15;
+    private Double gasValue15;
+    private int gasName16;
+    private Double gasValue16;
+    private int gasName17;
+    private Double gasValue17;
+    private int gasName18;
+    private Double gasValue18;
+    private int gasName19;
+    private Double gasValue19;
+    private int gasName20;
+    private Double gasValue20;
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindDailyReportPageRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindDailyReportPageRespDTO.java
new file mode 100644
index 0000000..07f8c43
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindDailyReportPageRespDTO.java
@@ -0,0 +1,23 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.resp;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 16:03
+ */
+@Data
+public class FindDailyReportPageRespDTO implements Serializable {
+
+    private Long id;
+
+    private String name;
+
+    private LocalDateTime gmtCreate;
+
+    private String fileUrl;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasCategoryByIdRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasCategoryByIdRespDTO.java
new file mode 100644
index 0000000..1a6879e
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasCategoryByIdRespDTO.java
@@ -0,0 +1,24 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.resp;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/7 14:03
+ */
+@Data
+public class FindGasCategoryByIdRespDTO implements Serializable {
+
+    private Integer id;
+
+    private String molecularFormula;
+
+    private String name;
+
+    private String unit;
+
+    private Double threshold;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasCategoryPageRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasCategoryPageRespDTO.java
new file mode 100644
index 0000000..69082af
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasCategoryPageRespDTO.java
@@ -0,0 +1,24 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.resp;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 14:19
+ */
+@Data
+public class FindGasCategoryPageRespDTO implements Serializable {
+
+    private Integer id;
+
+    private String molecularFormula;
+
+    private String name;
+
+    private String unit;
+
+    private Double threshold;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasWarnLogPageRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasWarnLogPageRespDTO.java
new file mode 100644
index 0000000..98a0084
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasWarnLogPageRespDTO.java
@@ -0,0 +1,57 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.resp;
+
+import com.gkhy.fourierSpecialGasMonitor.entity.GasWarnLogSmsUser;
+import lombok.Data;
+import org.hibernate.annotations.Fetch;
+import org.hibernate.annotations.FetchMode;
+
+import javax.persistence.CascadeType;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToMany;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 16:56
+ */
+@Data
+public class FindGasWarnLogPageRespDTO implements Serializable {
+
+    private Long id;
+
+    private String content;
+
+    private LocalDateTime warnTime;
+
+    private Integer gasCategoryId;
+
+    private String gasMolecularFormula;
+
+    private String gasName;
+
+    private String gasUnit;
+
+    private Double gasConcentrationThreshold;
+
+    private Double gasConcentration;
+
+    private Long gasThresholdId;
+
+    private Long gasThresholdName;
+
+    private Byte status;
+
+    private Long handlerId;
+
+    private String handlerName;
+
+    private String handlerRealName;
+
+    private LocalDateTime handlerTime;
+
+    private List<FindGasWarnLogSmsUserPageRespDTO> gasWarnLogSmsUsers;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasWarnLogSmsUserPageRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasWarnLogSmsUserPageRespDTO.java
new file mode 100644
index 0000000..4056983
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasWarnLogSmsUserPageRespDTO.java
@@ -0,0 +1,26 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.resp;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 16:57
+ */
+@Data
+public class FindGasWarnLogSmsUserPageRespDTO implements Serializable {
+
+    private Long id;
+
+    private Long warnLogId;
+
+    private Long warnUserId;
+
+    private String warnUserName;
+
+    private String warnUserRealName;
+
+    private String warnUserPhone;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasWarnUserPageRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasWarnUserPageRespDTO.java
new file mode 100644
index 0000000..e5b687b
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindGasWarnUserPageRespDTO.java
@@ -0,0 +1,24 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.resp;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 15:29
+ */
+@Data
+public class FindGasWarnUserPageRespDTO implements Serializable {
+
+    private Long id;
+
+    private Long userId;
+
+    private String name;
+
+    private String realName;
+
+    private String phone;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindRegionByIdRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindRegionByIdRespDTO.java
new file mode 100644
index 0000000..87f6b63
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindRegionByIdRespDTO.java
@@ -0,0 +1,22 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.resp;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 13:45
+ */
+@Data
+public class FindRegionByIdRespDTO implements Serializable {
+
+    private Long id;
+
+    private Long regionId;
+
+    private String lng;
+
+    private String lat;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindRegionLngLatPageRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindRegionLngLatPageRespDTO.java
new file mode 100644
index 0000000..31bbed9
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindRegionLngLatPageRespDTO.java
@@ -0,0 +1,21 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.resp;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 13:53
+ */
+@Data
+public class FindRegionLngLatPageRespDTO implements Serializable {
+    private Long id;
+
+    private Long regionId;
+
+    private String lng;
+
+    private String lat;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindRegionPageRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindRegionPageRespDTO.java
new file mode 100644
index 0000000..6ba79be
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/FindRegionPageRespDTO.java
@@ -0,0 +1,24 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.resp;
+
+import com.gkhy.fourierSpecialGasMonitor.entity.RegionLngLat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 13:53
+ */
+@Data
+public class FindRegionPageRespDTO implements Serializable {
+
+    private Long id;
+
+    private String name;
+
+    private String color;
+
+    private List<FindRegionLngLatPageRespDTO> regionLngLats;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasAtmosphereLineChartRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasAtmosphereLineChartRespDTO.java
new file mode 100644
index 0000000..ce82d3a
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasAtmosphereLineChartRespDTO.java
@@ -0,0 +1,20 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.resp;
+
+import lombok.Data;
+
+import java.io.PipedReader;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 14:29
+ */
+@Data
+public class GasAtmosphereLineChartRespDTO implements Serializable {
+
+    private LocalDateTime time;
+
+    private Object value;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasAtmospherePageRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasAtmospherePageRespDTO.java
new file mode 100644
index 0000000..18db20d
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasAtmospherePageRespDTO.java
@@ -0,0 +1,19 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.resp;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 14:41
+ */
+@Data
+public class GasAtmospherePageRespDTO implements Serializable {
+
+    private LocalDateTime time;
+
+    private Object value;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasCategoryListRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasCategoryListRespDTO.java
new file mode 100644
index 0000000..d531801
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasCategoryListRespDTO.java
@@ -0,0 +1,24 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.resp;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/7 14:07
+ */
+@Data
+public class GasCategoryListRespDTO implements Serializable {
+
+    private Integer id;
+
+    private String molecularFormula;
+
+    private String name;
+
+    private String unit;
+
+    private Double threshold;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasFluxLineChartRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasFluxLineChartRespDTO.java
new file mode 100644
index 0000000..a6872e2
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasFluxLineChartRespDTO.java
@@ -0,0 +1,43 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.resp;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 9:33
+ */
+@Data
+public class GasFluxLineChartRespDTO implements Serializable {
+
+    private Long id;
+
+    private String equipmentId;
+
+    private LocalDateTime time;
+
+    private int type;
+
+    private Double windSpeed;
+
+    private int windDirection;
+
+    private int gasName;
+
+    private Double gasValue;
+
+    private String molecularFormula;
+
+    private String name;
+
+    private String unit;
+
+    private int areaId;
+
+    private String regionName;
+
+    private String color;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasFluxPageRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasFluxPageRespDTO.java
new file mode 100644
index 0000000..ec90d62
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasFluxPageRespDTO.java
@@ -0,0 +1,42 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.resp;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 9:33
+ */
+@Data
+public class GasFluxPageRespDTO implements Serializable {
+    private Long id;
+
+    private String equipmentId;
+
+    private LocalDateTime time;
+
+    private int type;
+
+    private Double windSpeed;
+
+    private int windDirection;
+
+    private int gasName;
+
+    private Double gasValue;
+
+    private String molecularFormula;
+
+    private String name;
+
+    private String unit;
+
+    private int areaId;
+
+    private String regionName;
+
+    private String color;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasLineChartRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasLineChartRespDTO.java
new file mode 100644
index 0000000..aad097c
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasLineChartRespDTO.java
@@ -0,0 +1,49 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.resp;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 9:33
+ */
+@Data
+public class GasLineChartRespDTO implements Serializable {
+
+    private Long id;
+
+    private String equipmentId;
+
+    private LocalDateTime time;
+
+    private int type;
+
+    private String lng;
+
+    private String lat;
+
+    private String angle;
+
+    private Double temp;
+
+    private Double  humidity;
+
+    private Double windSpeed;
+
+    private int windDirection;
+
+    private Double pressure;
+
+    private int gasName;
+
+    private Double gasValue;
+
+    private String molecularFormula;
+
+    private String name;
+
+    private String unit;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasPageRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasPageRespDTO.java
new file mode 100644
index 0000000..0ac9d85
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasPageRespDTO.java
@@ -0,0 +1,49 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.resp;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 9:33
+ */
+@Data
+public class GasPageRespDTO implements Serializable {
+
+    private Long id;
+
+    private String equipmentId;
+
+    private LocalDateTime time;
+
+    private int type;
+
+    private String lng;
+
+    private String lat;
+
+    private String angle;
+
+    private Double temp;
+
+    private Double  humidity;
+
+    private Double windSpeed;
+
+    private int windDirection;
+
+    private Double pressure;
+
+    private int gasName;
+
+    private Double gasValue;
+
+    private String molecularFormula;
+
+    private String name;
+
+    private String unit;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasThresholdListRespDTO.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasThresholdListRespDTO.java
new file mode 100644
index 0000000..3f17955
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/entity/resp/GasThresholdListRespDTO.java
@@ -0,0 +1,20 @@
+package com.gkhy.fourierSpecialGasMonitor.entity.resp;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 14:35
+ */
+@Data
+public class GasThresholdListRespDTO implements Serializable {
+
+    private Long id;
+
+    private String name;
+
+    private int threshold;
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/DeleteStatusEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/DeleteStatusEnum.java
new file mode 100644
index 0000000..2f681d8
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/DeleteStatusEnum.java
@@ -0,0 +1,32 @@
+package com.gkhy.fourierSpecialGasMonitor.enums;
+
+public enum DeleteStatusEnum {
+
+    DELECT_NO((byte)0,"有效"),
+    DELECT_YES((byte)1,"删除"),
+    ;
+
+    private Byte status;
+    private String desc;
+
+    DeleteStatusEnum(Byte status, String desc) {
+        this.status = status;
+        this.desc = desc;
+    }
+
+    public Byte getStatus() {
+        return status;
+    }
+
+    public void setStatus(Byte status) {
+        this.status = status;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/GasConcentrationStateEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/GasConcentrationStateEnum.java
new file mode 100644
index 0000000..a9d6d7b
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/GasConcentrationStateEnum.java
@@ -0,0 +1,30 @@
+package com.gkhy.fourierSpecialGasMonitor.enums;
+
+
+import lombok.Getter;
+
+@Getter
+public enum GasConcentrationStateEnum {
+
+
+    NORMAL((Integer) 0, "正常"),
+    NO_DATA_FROM_ONSITE_EQUIPMENT_FOR_5_MINUTES((Integer) 1, "现场设备连续5min无数据")
+    ;
+
+    private Integer state;
+    private String desc;
+
+    GasConcentrationStateEnum(Integer state, String desc) {
+        this.state = state;
+        this.desc = desc;
+    }
+
+    public static String getValue(Integer key){
+        for (GasConcentrationStateEnum value : GasConcentrationStateEnum.values()) {
+            if (value.state.equals(key)){
+                return value.desc;
+            }
+        }
+        return null;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/GasFluxStateEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/GasFluxStateEnum.java
new file mode 100644
index 0000000..5703f1b
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/GasFluxStateEnum.java
@@ -0,0 +1,30 @@
+package com.gkhy.fourierSpecialGasMonitor.enums;
+
+
+import lombok.Getter;
+
+@Getter
+public enum GasFluxStateEnum {
+
+
+    NORMAL((Integer) 0, "正常"),
+    INVERSION_FAILED_10_MINUTES_NO_DATA((Integer) 1, "现场设备连续5min无数据")
+    ;
+
+    private Integer state;
+    private String desc;
+
+    GasFluxStateEnum(Integer state, String desc) {
+        this.state = state;
+        this.desc = desc;
+    }
+
+    public static String getValue(Integer key){
+        for (GasFluxStateEnum value : GasFluxStateEnum.values()) {
+            if (value.state.equals(key)){
+                return value.desc;
+            }
+        }
+        return null;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/HardwareStateEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/HardwareStateEnum.java
new file mode 100644
index 0000000..c99572a
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/HardwareStateEnum.java
@@ -0,0 +1,32 @@
+package com.gkhy.fourierSpecialGasMonitor.enums;
+
+
+import lombok.Getter;
+
+@Getter
+public enum HardwareStateEnum {
+
+
+    NORMAL((Integer) 0, "正常"),
+    METEOROLOGICAL_INSTRUMENT_DATA_INTERRUPTION((Integer) 1, "气象仪数据中断"),
+    SCAN_HEAD_CONTROL_INTERRUPT((Integer) 2, "扫描头控制中断"),
+    SPECTROMETER_SIGNAL_WEAK((Integer) 3, "光谱仪信号太弱(光路失调、镜片被污染、光源老化、雨雾天气干扰)")
+    ;
+
+    private Integer state;
+    private String desc;
+
+    HardwareStateEnum(Integer state, String desc) {
+        this.state = state;
+        this.desc = desc;
+    }
+
+    public static String getValue(Integer key){
+        for (HardwareStateEnum value : HardwareStateEnum.values()) {
+            if (value.state.equals(key)){
+                return value.desc;
+            }
+        }
+        return null;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/HeartbeatExecEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/HeartbeatExecEnum.java
new file mode 100644
index 0000000..f031625
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/HeartbeatExecEnum.java
@@ -0,0 +1,37 @@
+package com.gkhy.fourierSpecialGasMonitor.enums;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 16:41
+ */
+public enum HeartbeatExecEnum {
+
+    GAS_CONCENTRATION((byte)1,"【气体浓度】实时推送心跳监测异常 ---> 1分钟内未收到远端数据"),
+    GAS_FLUX((byte)2,"【气体通量】实时推送心跳监测异常 ---> 30分钟内未收到远端数据"),
+    ;
+
+    private Byte status;
+    private String desc;
+
+    HeartbeatExecEnum(Byte status, String desc) {
+        this.status = status;
+        this.desc = desc;
+    }
+
+    public Byte getStatus() {
+        return status;
+    }
+
+    public void setStatus(Byte status) {
+        this.status = status;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/WarnHandleStatusEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/WarnHandleStatusEnum.java
new file mode 100644
index 0000000..c9e52bf
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/WarnHandleStatusEnum.java
@@ -0,0 +1,32 @@
+package com.gkhy.fourierSpecialGasMonitor.enums;
+
+public enum WarnHandleStatusEnum {
+
+    HANDLE_NO((byte)0,"未处理"),
+    HANDLE_YES((byte)1,"已处理"),
+    ;
+
+    private Byte status;
+    private String desc;
+
+    WarnHandleStatusEnum(Byte status, String desc) {
+        this.status = status;
+        this.desc = desc;
+    }
+
+    public Byte getStatus() {
+        return status;
+    }
+
+    public void setStatus(Byte status) {
+        this.status = status;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/WarningThresholdEnum.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/WarningThresholdEnum.java
new file mode 100644
index 0000000..90cb047
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/enums/WarningThresholdEnum.java
@@ -0,0 +1,41 @@
+package com.gkhy.fourierSpecialGasMonitor.enums;
+
+public enum WarningThresholdEnum {
+
+    YELLOW((Integer)1,"黄色预警"),
+    RED((Integer)2,"红色预警"),
+    ;
+
+    private Integer code;
+    private String desc;
+
+    WarningThresholdEnum(Integer code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+
+    public static String getValue(Integer code){
+        for (WarningThresholdEnum value : WarningThresholdEnum.values()) {
+            if (value.code.equals(code)){
+                return value.desc;
+            }
+        }
+        return null;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/infra/cache/domain/CacheUserInfo.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/infra/cache/domain/CacheUserInfo.java
new file mode 100644
index 0000000..0094acc
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/infra/cache/domain/CacheUserInfo.java
@@ -0,0 +1,83 @@
+package com.gkhy.fourierSpecialGasMonitor.infra.cache.domain;
+
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.Collection;
+
+public class CacheUserInfo implements UserDetails {
+    private Long userId;
+
+    private String loginName;
+
+    private String realName;
+
+    private Long roleId;
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public String getLoginName() {
+        return loginName;
+    }
+
+    public void setLoginName(String loginName) {
+        this.loginName = loginName;
+    }
+
+    public String getRealName() {
+        return realName;
+    }
+
+    public void setRealName(String realName) {
+        this.realName = realName;
+    }
+
+    public Long getRoleId() {
+        return roleId;
+    }
+
+    public void setRoleId(Long roleId) {
+        this.roleId = roleId;
+    }
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        return null;
+    }
+
+    @Override
+    public String getPassword() {
+        return null;
+    }
+
+    @Override
+    public String getUsername() {
+        return null;
+    }
+
+    @Override
+    public boolean isAccountNonExpired() {
+        return false;
+    }
+
+    @Override
+    public boolean isAccountNonLocked() {
+        return false;
+    }
+
+    @Override
+    public boolean isCredentialsNonExpired() {
+        return false;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return false;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/infra/cache/service/UserCacheInfraService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/infra/cache/service/UserCacheInfraService.java
new file mode 100644
index 0000000..864a2e0
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/infra/cache/service/UserCacheInfraService.java
@@ -0,0 +1,12 @@
+package com.gkhy.fourierSpecialGasMonitor.infra.cache.service;
+
+import com.gkhy.fourierSpecialGasMonitor.infra.cache.domain.CacheUserInfo;
+
+public interface UserCacheInfraService {
+
+    CacheUserInfo getCacheUser(String userId);
+
+    boolean putCacheUser(CacheUserInfo cacheUserInfo,String userId);
+
+    boolean removeCacheUser(String userId);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/infra/cache/service/impl/UserCacheInfraServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/infra/cache/service/impl/UserCacheInfraServiceImpl.java
new file mode 100644
index 0000000..8a77ee2
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/infra/cache/service/impl/UserCacheInfraServiceImpl.java
@@ -0,0 +1,62 @@
+package com.gkhy.fourierSpecialGasMonitor.infra.cache.service.impl;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.SystemCacheKeyEnum;
+import com.gkhy.fourierSpecialGasMonitor.infra.cache.domain.CacheUserInfo;
+import com.gkhy.fourierSpecialGasMonitor.infra.cache.service.UserCacheInfraService;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.concurrent.TimeUnit;
+
+@Service
+public class UserCacheInfraServiceImpl implements UserCacheInfraService {
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+    @Autowired
+    private ObjectMapper objectMapper;
+
+    @Override
+    public CacheUserInfo getCacheUser(String userId) {
+        if(userId == null || userId.isEmpty())
+            return null;
+        Object cacheUserObj = redissonClient.getMapCache(SystemCacheKeyEnum.KEY_CACHE_USER.getKey()).get(""+userId);
+        if(cacheUserObj != null){
+            String json = (String)cacheUserObj;
+            try {
+                CacheUserInfo cacheUserInfo = objectMapper.readValue(json,CacheUserInfo.class);
+                return cacheUserInfo;
+            } catch (JsonProcessingException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public boolean putCacheUser(CacheUserInfo cacheUserInfo, String userId) {
+        if(cacheUserInfo == null || userId == null || userId.isEmpty())
+            return false;
+        try {
+            String json = objectMapper.writeValueAsString(cacheUserInfo);
+            if(redissonClient.getMapCache(SystemCacheKeyEnum.KEY_CACHE_USER.getKey()).put(userId,json,120,
+                    TimeUnit.MINUTES) != null)
+                return true;
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+        return false;
+    }
+
+    @Override
+    public boolean removeCacheUser(String userId) {
+        if(redissonClient.getMapCache(SystemCacheKeyEnum.KEY_CACHE_USER.getKey()).remove(userId) != null)
+            return true;
+        else
+            return false;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/interface/sysManage/LicenseManage.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/interface/sysManage/LicenseManage.java
new file mode 100644
index 0000000..704760a
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/interface/sysManage/LicenseManage.java
@@ -0,0 +1,64 @@
+package com.gkhy.fourierSpecialGasMonitor.application.sysManage;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.gkhy.fourierSpecialGasMonitor.application.account.dto.respDto.UserInfoAppRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.application.account.service.AccountAppService;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.SystemConfigKeyEnum;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.entity.SysConfig;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa.UserRepository;
+import com.gkhy.fourierSpecialGasMonitor.domain.sysAdmin.repository.jpa.SysConfigRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.LocalDateTime;
+import java.util.Optional;
+
+@RestController
+@RequestMapping("/sys/lic")
+public class LicenseManage {
+
+    @Autowired
+    private SysConfigRepository sysConfigRepository;
+
+    @Autowired
+    private UserRepository userRepository;
+
+    @Autowired
+    private AccountAppService accountAppService;
+
+    @Autowired
+    private ObjectMapper objectMapper;
+
+    @GetMapping("/get")
+    public Object getLicenseTxt() throws JsonProcessingException {
+//        Optional<User> userOptional = userRepository.findById(1L);
+//        User user = userOptional.get();
+        Result<UserInfoAppRespDTO> r = accountAppService.findUserByUserId(1L);
+        if(r!= null && r.isSuccess() && r.getData() != null){
+            UserInfoAppRespDTO userInfoAppRespDTO = (UserInfoAppRespDTO) r.getData();
+        }
+        return r;
+    }
+
+    @GetMapping("/up")
+    public Object updateLicense(){
+        Optional<SysConfig> sysConfigOptional = sysConfigRepository.findById(SystemConfigKeyEnum.LICENSE_TXT.getKey());
+        if(sysConfigOptional.isPresent()){
+            SysConfig sysConfig = sysConfigOptional.get();
+            sysConfig.setSysValue("SSS");
+            sysConfigRepository.saveAndFlush(sysConfig);
+            return "OK";
+        }else {
+            SysConfig sysConfig = new SysConfig();
+            sysConfig.setSysProp(SystemConfigKeyEnum.LICENSE_TXT.getKey());
+            sysConfig.setSysValue("BBB");
+            sysConfig.setGmtModified(LocalDateTime.now());
+            sysConfigRepository.saveAndFlush(sysConfig);
+            return "NEW OK";
+        }
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/DeviceExceptionLogRepository.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/DeviceExceptionLogRepository.java
new file mode 100644
index 0000000..94a1bbf
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/DeviceExceptionLogRepository.java
@@ -0,0 +1,15 @@
+package com.gkhy.fourierSpecialGasMonitor.repository;
+
+import com.gkhy.fourierSpecialGasMonitor.entity.DeviceExceptionLog;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/8 15:11
+ */
+@Repository
+public interface DeviceExceptionLogRepository extends JpaRepository<DeviceExceptionLog,Long>, JpaSpecificationExecutor<DeviceExceptionLog> {
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasCategoryRepository.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasCategoryRepository.java
new file mode 100644
index 0000000..bfd0075
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasCategoryRepository.java
@@ -0,0 +1,14 @@
+package com.gkhy.fourierSpecialGasMonitor.repository;
+
+
+import com.gkhy.fourierSpecialGasMonitor.entity.GasCategory;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasFlux;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface GasCategoryRepository extends JpaRepository<GasCategory,Integer>, JpaSpecificationExecutor<GasCategory> {
+
+    GasCategory findByMolecularFormula(String molecularFormula);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasConcentrationRepository.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasConcentrationRepository.java
new file mode 100644
index 0000000..58ac639
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasConcentrationRepository.java
@@ -0,0 +1,17 @@
+package com.gkhy.fourierSpecialGasMonitor.repository;
+
+
+import com.gkhy.fourierSpecialGasMonitor.entity.GasCategory;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasConcentration;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+import javax.persistence.OrderBy;
+
+@Repository
+public interface GasConcentrationRepository extends JpaRepository<GasConcentration,Long>, JpaSpecificationExecutor<GasConcentration> {
+
+    @OrderBy("dataReceivingTime desc")
+    GasConcentration findTopByOrderByDataReceivingTimeDesc();
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasFluxRepository.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasFluxRepository.java
new file mode 100644
index 0000000..d9d32dd
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasFluxRepository.java
@@ -0,0 +1,20 @@
+package com.gkhy.fourierSpecialGasMonitor.repository;
+
+
+import com.gkhy.fourierSpecialGasMonitor.entity.GasConcentration;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasFlux;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+import javax.persistence.OrderBy;
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Repository
+public interface GasFluxRepository extends JpaRepository<GasFlux,Long>,JpaSpecificationExecutor<GasFlux> {
+
+    @OrderBy("dataReceivingTime desc")
+    GasFlux findTopByOrderByDataReceivingTimeDesc();
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasThresholdRepository.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasThresholdRepository.java
new file mode 100644
index 0000000..2eb747d
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasThresholdRepository.java
@@ -0,0 +1,17 @@
+package com.gkhy.fourierSpecialGasMonitor.repository;
+
+import com.gkhy.fourierSpecialGasMonitor.entity.GasThreshold;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 14:31
+ */
+@Repository
+public interface GasThresholdRepository extends JpaRepository<GasThreshold,Integer>, JpaSpecificationExecutor<GasThreshold> {
+
+    GasThreshold findByName(String name);
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasWarnLogRepository.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasWarnLogRepository.java
new file mode 100644
index 0000000..a8e73f9
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasWarnLogRepository.java
@@ -0,0 +1,18 @@
+package com.gkhy.fourierSpecialGasMonitor.repository;
+
+import com.gkhy.fourierSpecialGasMonitor.entity.GasThreshold;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasWarnLog;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 16:47
+ */
+@Repository
+public interface GasWarnLogRepository extends JpaRepository<GasWarnLog,Long>, JpaSpecificationExecutor<GasWarnLog> {
+
+    GasWarnLog findByIdAndStatus(Long id,Byte status);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasWarnLogSmsUserRepository.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasWarnLogSmsUserRepository.java
new file mode 100644
index 0000000..82e99f7
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasWarnLogSmsUserRepository.java
@@ -0,0 +1,16 @@
+package com.gkhy.fourierSpecialGasMonitor.repository;
+
+import com.gkhy.fourierSpecialGasMonitor.entity.GasWarnLogSmsUser;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasWarnUser;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 16:35
+ */
+@Repository
+public interface GasWarnLogSmsUserRepository extends JpaRepository<GasWarnLogSmsUser,Long>, JpaSpecificationExecutor<GasWarnLogSmsUser> {
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasWarnUserRepository.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasWarnUserRepository.java
new file mode 100644
index 0000000..11516d1
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/GasWarnUserRepository.java
@@ -0,0 +1,25 @@
+package com.gkhy.fourierSpecialGasMonitor.repository;
+
+import com.gkhy.fourierSpecialGasMonitor.entity.GasThreshold;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasWarnUser;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 14:31
+ */
+@Repository
+public interface GasWarnUserRepository extends JpaRepository<GasWarnUser,Long>, JpaSpecificationExecutor<GasWarnUser> {
+
+    GasWarnUser findByIdAndStatus(Long id,Byte status);
+
+    GasWarnUser findByUserIdAndStatus(Long id,Byte status);
+
+    List<GasWarnUser> findAllByStatus(Byte status);
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/MonitorDailyReportRepository.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/MonitorDailyReportRepository.java
new file mode 100644
index 0000000..716dc09
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/MonitorDailyReportRepository.java
@@ -0,0 +1,16 @@
+package com.gkhy.fourierSpecialGasMonitor.repository;
+
+import com.gkhy.fourierSpecialGasMonitor.entity.MonitorDailyReport;
+import com.gkhy.fourierSpecialGasMonitor.entity.RegionLngLat;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 15:41
+ */
+@Repository
+public interface MonitorDailyReportRepository extends JpaRepository<MonitorDailyReport,Long>, JpaSpecificationExecutor<MonitorDailyReport> {
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/RegionLngLatRepository.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/RegionLngLatRepository.java
new file mode 100644
index 0000000..674b309
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/RegionLngLatRepository.java
@@ -0,0 +1,18 @@
+package com.gkhy.fourierSpecialGasMonitor.repository;
+
+import com.gkhy.fourierSpecialGasMonitor.entity.Region;
+import com.gkhy.fourierSpecialGasMonitor.entity.RegionLngLat;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 10:46
+ */
+@Repository
+public interface RegionLngLatRepository extends JpaRepository<RegionLngLat,Long>, JpaSpecificationExecutor<RegionLngLat> {
+
+    void deleteAllByRegionId(Integer id);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/RegionRepository.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/RegionRepository.java
new file mode 100644
index 0000000..ca25a69
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/repository/RegionRepository.java
@@ -0,0 +1,24 @@
+package com.gkhy.fourierSpecialGasMonitor.repository;
+
+import com.gkhy.fourierSpecialGasMonitor.entity.GasFlux;
+import com.gkhy.fourierSpecialGasMonitor.entity.Region;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 10:46
+ */
+@Repository
+public interface RegionRepository extends JpaRepository<Region,Long>, JpaSpecificationExecutor<Region> {
+
+    Region findByNameAndStatus(String name,Byte status);
+
+    Region findByIdAndStatus(Integer id,Byte status);
+
+    List<Region> findAllByStatus(Byte status);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/schedule/DailyReportSchedule.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/schedule/DailyReportSchedule.java
new file mode 100644
index 0000000..722471f
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/schedule/DailyReportSchedule.java
@@ -0,0 +1,482 @@
+package com.gkhy.fourierSpecialGasMonitor.schedule;
+
+import com.alibaba.fastjson.JSON;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ForeignResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.DataReceiveException;
+import com.gkhy.fourierSpecialGasMonitor.config.file.ReportFilePathConfig;
+import com.gkhy.fourierSpecialGasMonitor.entity.*;
+import com.gkhy.fourierSpecialGasMonitor.service.*;
+import org.apache.commons.compress.utils.IOUtils;
+import org.apache.poi.ooxml.POIXMLDocument;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.xddf.usermodel.chart.*;
+import org.apache.poi.xddf.usermodel.text.XDDFTextBody;
+import org.apache.poi.xwpf.usermodel.*;
+import org.apache.xmlbeans.XmlException;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTCatAx;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
+import org.redisson.api.RBucket;
+import org.redisson.api.RedissonClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+import javax.annotation.PostConstruct;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.*;
+import java.lang.reflect.Field;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/11 13:25
+ */
+@Component
+public class DailyReportSchedule {
+
+    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
+
+    private static final DateTimeFormatter reportNameFormatter = DateTimeFormatter.ofPattern("yyyy_MM_dd");
+
+    private static final DateTimeFormatter execformatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+    private static final DateTimeFormatter lineChartXDataDisplay = DateTimeFormatter.ofPattern("HH:mm");
+
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    @Autowired
+    private GasWarnLogService gasWarnLogService;
+
+    @Autowired
+    private GasConcentrationService gasConcentrationService;
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+    @Autowired
+    private RegionService regionService;
+
+    @Autowired
+    private ReportFilePathConfig reportFilePathConfig;
+
+    @Autowired
+    private GasFluxService gasFluxService;
+
+    @Autowired
+    private MonitorDailyReportService monitorDailyReportService;
+
+    @Scheduled(cron = "0 0 2 * * ?") //每天两点执行一次
+    @Async(value = "SocketTaskExecutor")
+    public void generateDailyReport() {
+        LocalDateTime now = LocalDateTime.now();
+        String startTime = now.format(execformatter);
+        RBucket<List<GasCategory>> bucket = redissonClient.getBucket("gas_category_cache_info");
+        List<GasCategory> gasCategories = bucket.get();
+        //logger.info("【##】开始生成日报 ,时间:"+startTime);
+        OPCPackage opcPackage = null;
+        //加载文档
+        XWPFDocument doc = null;
+        try {
+            FileInputStream originalFileInputStream = new FileInputStream("src/main/resources/template/dailyReportTemplate.docx");
+            FileOutputStream copyFileOutputStream = new FileOutputStream("src/main/resources/temp/dailyReportTemplate.docx");
+            // 创建副本文件
+            IOUtils.copy(originalFileInputStream, copyFileOutputStream);
+            opcPackage = POIXMLDocument.openPackage("src/main/resources/temp/dailyReportTemplate.docx");
+            doc = new XWPFDocument(opcPackage);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        Map<String, Object> map = dataMap(gasCategories);
+
+        List<XWPFParagraph> paragraphList = doc.getParagraphs();
+        for (XWPFParagraph par : paragraphList) {
+            //获取段落的文本对象
+            List<XWPFRun> runs = par.getRuns();
+            for (XWPFRun run : runs) {
+                //获取文本的值
+                String text = run.getText(0);
+                //遍历map
+                for (Map.Entry<String, Object> entry : map.entrySet()) {
+                    //获取map的key
+                    String key = entry.getKey();
+                    //判断文本的值和map的key,文本中是否有和key一样的占位符
+                    if (text != null && text.indexOf(key) != -1) {
+                        //获取对应key的value
+                        Object value = entry.getValue();
+                        //把文本的内容,key替换为value
+                        text = text.replace(key, value.toString());
+                        //把替换好的文本内容,保存到当前这个文本对象
+                        run.setText(text, 0);
+                    }
+                }
+            }
+        }
+        String format = now.format(reportNameFormatter);
+        String fileName = "富城能源气体监测日报"+format+".docx";
+        String fileurl = reportFilePathConfig.getDcPath()+fileName;
+        File file = new File(fileurl);
+        if (!file.exists()){
+            try {
+                // 获取文件所在的文件夹路径
+                String folderPath = file.getParent();
+                // 创建文件夹(包括父目录)
+                File folder = new File(folderPath);
+                if (!folder.exists()){
+                    folder.mkdirs();
+                }
+                file.createNewFile();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        FileOutputStream fileOutputStream = null;
+        try {
+            fileOutputStream = new FileOutputStream(file);
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }
+        try {
+            doc.write(fileOutputStream);
+            fileOutputStream.close();
+            opcPackage.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        List<GasConcentration> gasConcentrations = gasConcentrationService.listDatabyTimeSlot(LocalDateTime.now().minusDays(2).with(LocalDate.MIN), LocalDateTime.now());
+        if (!CollectionUtils.isEmpty(gasConcentrations)) {
+            for (int i = 0; i < 30; i++) {
+                String series = gasCategories.get(i).getMolecularFormula() + "浓度观测结果";
+                String title = "—" + gasCategories.get(i).getMolecularFormula();
+                drawLineChart(gasConcentrations, fileurl, series, title, gasCategories.get(i).getMolecularFormula(), i);
+            }
+        }
+
+        List<GasFlux> gasFluxes = gasFluxService.listYesterday();
+        List<Integer> areaNum = gasFluxes.stream().map(GasFlux::getAreaId).distinct().collect(Collectors.toList());
+
+        List<Region> allRegion = regionService.findAll();
+        if (CollectionUtils.isEmpty(allRegion))
+            throw new BusinessException(this.getClass(), ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"区域信息为空");
+        Map<Integer, String> regionMap = allRegion.stream()
+                .collect(Collectors.toMap(Region::getId, Region::getName));
+        if (!CollectionUtils.isEmpty(gasFluxes)) {
+            for (int i = 1; i <= 1; i++) {
+                for (int j = 0; j < 1; j++) {
+                    drawBarChart(gasFluxes, fileurl, regionMap.get(i), "柱形图" + gasCategories.get(j).getMolecularFormula(), i, j + 1);
+                }
+            }
+        }
+        String endTime = LocalDateTime.now().format(execformatter);
+        long execTime = ChronoUnit.SECONDS.between(now, LocalDateTime.now());
+        MonitorDailyReport report = new MonitorDailyReport();
+        report.setName(fileName);
+        report.setGmtCreate(now);
+        report.setEndTime(LocalDateTime.now());
+        report.setFileUrl(reportFilePathConfig.getUrlRootPath()+fileName);
+        MonitorDailyReport save = monitorDailyReportService.save(report);
+        if (save == null)
+            throw new BusinessException(this.getClass(), ResultCode.SYSTEM_ERROR_DATABASE_FAIL,"日常报表保存失败");
+        //logger.info("【##】日报生成成功!!! ,时间:"+endTime+",所耗时间: "+execTime+"s");
+    }
+
+    public void drawBarChart(List<GasFlux> gasFluxes,String fileurl,String series,String molecularFormula,Integer i,Integer j) {
+        List<String> collect = gasFluxes.stream()
+                .map(gasFlux -> gasFlux.getTime().format(lineChartXDataDisplay))
+                .collect(Collectors.toList());
+        String[] x2 = collect.toArray(new String[collect.size()]);
+        String fieldName = "gasValue";
+        if (j<10){
+            fieldName = fieldName + "0" + j;
+        }else {
+            fieldName = fieldName + j;
+        }
+        final String fieldTempName = fieldName;
+        Double[] n = gasFluxes.stream().map(obj -> {
+            try {
+                Field field = obj.getClass().getDeclaredField(fieldTempName);
+                field.setAccessible(true);
+                return field.get(obj);
+            } catch (NoSuchFieldException | IllegalAccessException e) {
+                logger.info("柱状图反射获取字段值异常");
+                return null;
+            }
+        }).collect(Collectors.toList()).toArray(new Double[gasFluxes.size()]);
+
+        String templatePath = fileurl;
+        XWPFDocument doc=null;
+        InputStream is = null;
+        try{
+            is = new FileInputStream(new File(templatePath));
+            doc = new XWPFDocument(is);
+        } catch (Exception e){
+            System.out.println(e);
+        }
+        //区域名称
+        String[] series2 = {series};//
+        //y轴
+        List<Number[]> value2 = new ArrayList<>();//每一条折现图,第二个表1条
+        value2.add(n);
+
+        List<XWPFChart> charts = doc.getCharts();
+        for (int k = 0; k < charts.size(); k++) {
+            XWPFChart xwpfChart = charts.get(k);
+            XDDFTitle xddfTitletitle = xwpfChart.getTitle();
+            if (xddfTitletitle != null) {
+                XDDFTextBody body = xddfTitletitle.getBody();
+                CTTextBody xmlObject = body.getXmlObject();
+                String tt = xmlObject.toString(); //图表的标题
+                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+                try {
+                    DocumentBuilder builder = factory.newDocumentBuilder();
+                    // 解析 XML 字符串
+                    org.w3c.dom.Document document = builder.parse(new ByteArrayInputStream(tt.getBytes()));
+                    // 获取根元素 <a:r>
+                    Element root = document.getDocumentElement();
+                    // 获取包含文本的 <a:t> 元素
+                    Element aT = (Element) root.getElementsByTagName("a:t").item(0);
+                    // 获取 <a:t> 元素的文本内容 获取标题具体内容
+                    String value = aT.getTextContent();
+                    String chartTitle = "图"+(31 + i * j)+" "+i+"号厂区排放"+molecularFormula+"通量反演结果";
+                    if ((i+"-"+j).equals(value)) {
+                        drawBarChartExec(charts.get(k), series2, x2, value2, chartTitle);
+                    }
+                } catch (ParserConfigurationException e) {
+                    e.printStackTrace();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                } catch (SAXException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        try (FileOutputStream fos = new FileOutputStream(templatePath)) {
+            doc.write(fos);
+            doc.close();
+            is.close();
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    public void drawLineChart(List<GasConcentration> gasConcentrations,String fileurl,String series,String title,String molecularFormula,Integer i) {
+        List<String> collect = gasConcentrations.stream()
+                .map(gasConcentration -> gasConcentration.getTime().format(lineChartXDataDisplay))
+                .collect(Collectors.toList());
+        String[] x2 = collect.toArray(new String[collect.size()]);
+        String fieldName = "gasValue";
+        i = i+1;
+        if (i<10){
+            fieldName = fieldName + "0" + i;
+        }else {
+            fieldName = fieldName + i;
+        }
+        final String fieldTempName = fieldName;
+        Double[] n = gasConcentrations.stream().map(obj -> {
+            try {
+                Field field = obj.getClass().getDeclaredField(fieldTempName);
+                field.setAccessible(true);
+                return field.get(obj);
+            } catch (NoSuchFieldException | IllegalAccessException e) {
+                e.printStackTrace();
+                return null;
+            }
+        }).collect(Collectors.toList()).toArray(new Double[gasConcentrations.size()]);
+
+        String templatePath = fileurl;
+        XWPFDocument doc=null;
+        InputStream is = null;
+        try{
+            is = new FileInputStream(new File(templatePath));
+            doc = new XWPFDocument(is);
+        } catch (Exception e){
+            System.out.println(e);
+        }
+        String[] series2 = {"图" + (i)+" "+series};//
+
+        String title2=title;
+        //y轴
+        List<Number[]> value2 = new ArrayList<>();
+        value2.add(n);
+
+        //
+        List<XWPFChart> charts = doc.getCharts();
+        for (int j = 0; j < charts.size(); j++) {
+            XWPFChart xwpfChart = charts.get(j);
+            XDDFTitle xddfTitletitle = xwpfChart.getTitle();
+            if (xddfTitletitle != null) {
+                XDDFTextBody body = xddfTitletitle.getBody();
+                CTTextBody xmlObject = body.getXmlObject();
+                String tt = xmlObject.toString(); //图表的标题
+                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+                try {
+                    DocumentBuilder builder = factory.newDocumentBuilder();
+                    // 解析 XML 字符串
+                    org.w3c.dom.Document document = builder.parse(new ByteArrayInputStream(tt.getBytes()));
+                    // 获取根元素 <a:r>
+                    Element root = document.getDocumentElement();
+                    // 获取包含文本的 <a:t> 元素
+                    Element aT = (Element) root.getElementsByTagName("a:t").item(0);
+                    // 获取 <a:t> 元素的文本内容 获取标题具体内容
+                    String value = aT.getTextContent();
+                    if (molecularFormula.equals(value)) {
+                        drawLineChartExec(charts.get(j), series2, x2, value2, title2);
+                    }
+                } catch (ParserConfigurationException e) {
+                    e.printStackTrace();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                } catch (SAXException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        try (FileOutputStream fos = new FileOutputStream(templatePath)) {
+            doc.write(fos);
+            doc.close();
+            is.close();
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    public void drawBarChartExec(XWPFChart chart, String[] series, String[] categories,
+                                  List<Number[]> values, String chartTitle) {
+        final List<XDDFChartData> data = chart.getChartSeries();
+
+        final XDDFBarChartData line = (XDDFBarChartData) data.get(0);//这里一般获取第一个,我们这里是折线图就是XDDFLineChartData
+        line.getCategoryAxis().setTitle(chartTitle);
+        line.getValueAxes().get(0).setTitle("C2H2 Emission Rate (ug/m^2/s)");
+        final int numOfPoints = categories.length;
+
+        final String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0));
+
+        final XDDFDataSource<?> categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, 0);
+        for (int i = 0; i < values.size(); i++) {
+            final String valuesDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, i + 1, i + 1));
+            Number[] value = values.get(i);
+            final XDDFNumericalDataSource<? extends Number> valuesData = XDDFDataSourcesFactory.fromArray(value, valuesDataRange, i + 1);
+            XDDFChartData.Series ser;//图表中的系列
+            ser = line.getSeries().get(i);
+            ser.replaceData(categoriesData, valuesData);
+            CellReference cellReference = chart.setSheetTitle(series[i], 1);//修改系列标题
+            ser.setTitle(series[i], cellReference);
+        }
+        chart.plot(line);
+        chart.setTitleText("");//折线图标题
+        chart.setTitleOverlay(false);
+    }
+
+    public void drawLineChartExec(XWPFChart chart, String[] series, String[] categories,
+                               List<Number[]> values, String chartTitle) {
+        final List<XDDFChartData> data = chart.getChartSeries();
+
+        final XDDFLineChartData line = (XDDFLineChartData) data.get(0);//这里一般获取第一个,我们这里是折线图就是XDDFLineChartData
+
+        final int numOfPoints = categories.length;
+
+        //List<String> lineChartXDataDisplayDefault = Arrays.asList("00:00","01:00","02:00","03:00","04:00","05:00","06:00"
+        //        ,"07:00","08:00","09:00",
+        //        "10:00","11:00","12:00","13:00","19:00");
+        //for (int i = 0; i < numOfPoints; i++) {
+        //    if (!lineChartXDataDisplayDefault.contains(categories[i])) {
+        //        categories[i] = ""; // 设置为空字符串,隐藏原有的标签
+        //    }
+        //}
+
+        final String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0));
+
+        final XDDFDataSource<?> categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, 0);
+        for (int i = 0; i < values.size(); i++) {
+            final String valuesDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, i + 1, i + 1));
+            Number[] value = values.get(i);
+            final XDDFNumericalDataSource<? extends Number> valuesData = XDDFDataSourcesFactory.fromArray(value, valuesDataRange, i + 1);
+            XDDFChartData.Series ser;//图表中的系列
+            ser = line.getSeries().get(i);
+            ser.replaceData(categoriesData, valuesData);
+            CellReference cellReference = chart.setSheetTitle(series[i], 1);//修改系列标题
+            ser.setTitle(series[i], cellReference);
+        }
+        chart.plot(line);
+        chart.setTitleText(chartTitle);//折线图标题
+        chart.setTitleOverlay(false);
+    }
+
+    private Map<String, Object> dataMap(List<GasCategory> gasCategories){
+        LocalDateTime now = LocalDateTime.now();
+        String today = now.format(formatter);
+        String yesterday = LocalDateTime.now().plusDays(1).format(formatter);
+        //要替换的map,key为占位符,value为要被替换的值
+        Map<String, Object> map = new HashMap<>();
+        map.put("${today}", today);
+        map.put("${yesterday}", yesterday);
+        map.put("${generalradius}","10");
+        map.put("${generalradiu}","20");
+
+        List<GasWarnLog> gasWarnLogs = gasWarnLogService.listYesterday();
+        if (!CollectionUtils.isEmpty(gasWarnLogs)){
+            String warnInfo = "根据以上气体浓度变化曲线,各物种的浓度有如下特征:";
+            for (int i = 0; i < gasWarnLogs.size(); i++) {
+                LocalDateTime warnTime = gasWarnLogs.get(i).getWarnTime();
+                String time = warnTime.format(execformatter);
+                warnInfo = warnInfo + gasWarnLogs.get(i).getGasMolecularFormula()
+                        +"("+gasWarnLogs.get(i).getGasName()+")浓度在"+time+" 出现"+gasWarnLogs.get(i).getGasThresholdName()
+                        + "浓度达到:"+gasWarnLogs.get(i).getGasConcentration()+gasWarnLogs.get(i).getGasUnit() + ";   ";
+
+            }
+            map.put("${warn}",warnInfo);
+        }else {
+            map.put("${warn}","");
+        }
+        String fiveGas = "";
+        String sixGas = "";
+        for (int i = 0; i < 6; i++) {
+            String name = gasCategories.get(i).getMolecularFormula()+"("+gasCategories.get(i).getName()+")";
+            name = name + "、";
+            if (i < 5){
+                fiveGas = fiveGas + name;
+                if (i == 4){
+                    int index = fiveGas.lastIndexOf("、");
+                    fiveGas =  fiveGas.substring(0, index)+"共五种";
+                }
+            }
+            if (i < 6){
+                sixGas = sixGas + name;
+                if (i == 5){
+                    int index = sixGas.lastIndexOf("、");
+                    sixGas =  sixGas.substring(0, index)+"共六种";
+                }
+            }
+        }
+        map.put("${fiveGas}",fiveGas);
+        map.put("${sixGas}",sixGas);
+        return map;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/schedule/GasConcentrationAutoCreateKeySchedule.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/schedule/GasConcentrationAutoCreateKeySchedule.java
new file mode 100644
index 0000000..1908f22
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/schedule/GasConcentrationAutoCreateKeySchedule.java
@@ -0,0 +1,64 @@
+package com.gkhy.fourierSpecialGasMonitor.schedule;
+
+import com.alibaba.fastjson.JSON;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasConcentration;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasFlux;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UploadGasConcentrationReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UploadGasFluxReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.service.DataReceiveService;
+import org.redisson.api.RBucket;
+import org.redisson.api.RedissonClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/7 15:30
+ */
+@Component
+public class GasConcentrationAutoCreateKeySchedule {
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+    @Autowired
+    private DataReceiveService dataReceiveService;
+
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+    private static String gasConcentrationCachePrefix = "gas_concentration_cache_";
+
+    @Scheduled(cron = "0 0 0 * * ?") // 每天凌晨执行
+    @Async(value = "SocketTaskExecutor")
+    public void createRedisKey() {
+        LocalDateTime time = LocalDateTime.now();
+        String cacheName = time.format(formatter);
+        List<GasConcentration> gasConcentrations = new ArrayList<>();
+        String jsonString = JSON.toJSONString(gasConcentrations);
+        RBucket<String> bucket = redissonClient.getBucket(gasConcentrationCachePrefix+cacheName);
+        bucket.set(jsonString);
+
+        //清除前一天的缓存
+        LocalDateTime yesterday = LocalDateTime.now().minusDays(1);
+        String yesterdayCache = yesterday.format(formatter);
+        RBucket<String> yesterdayBucket = redissonClient.getBucket(gasConcentrationCachePrefix+yesterdayCache);
+        if (yesterdayBucket.isExists()) {
+            yesterdayBucket.delete();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/schedule/HeartbeatSchedule.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/schedule/HeartbeatSchedule.java
new file mode 100644
index 0000000..6bb7087
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/schedule/HeartbeatSchedule.java
@@ -0,0 +1,92 @@
+package com.gkhy.fourierSpecialGasMonitor.schedule;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.entity.DeviceExceptionLog;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasConcentration;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasFlux;
+import com.gkhy.fourierSpecialGasMonitor.enums.HeartbeatExecEnum;
+import com.gkhy.fourierSpecialGasMonitor.service.DeviceExceptionLogService;
+import com.gkhy.fourierSpecialGasMonitor.service.GasConcentrationService;
+import com.gkhy.fourierSpecialGasMonitor.service.GasFluxService;
+import com.gkhy.fourierSpecialGasMonitor.websocket.HeartbeatExcWebsocketServer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.time.LocalDateTime;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/8 10:49
+ */
+@Component
+public class HeartbeatSchedule {
+
+    @Autowired
+    private GasConcentrationService gasConcentrationService;
+
+    @Autowired
+    private GasFluxService gasFluxService;
+
+    @Autowired
+    private DeviceExceptionLogService deviceExceptionLogService;
+
+    @Autowired
+    private HeartbeatExcWebsocketServer heartbeatExcWebsocketServer;
+
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    //@Scheduled(cron = "1 * * * * *") // 每分钟执行一次
+    @Scheduled(cron = "1 * * * * ?") // 每天凌晨执行
+    @Async(value = "SocketTaskExecutor")
+    public void gasConcentrationStatus() {
+
+        GasConcentration gasConcentration = gasConcentrationService.getLastData();
+        if (gasConcentration != null){
+            LocalDateTime lastReceiveTime = gasConcentration.getDataReceivingTime().plusMinutes(1);
+            if (LocalDateTime.now().compareTo(lastReceiveTime) > 0){
+                try {
+                    heartbeatExcWebsocketServer.sendInfo(HeartbeatExecEnum.GAS_CONCENTRATION.getStatus()+"",null);
+                    logger.info(HeartbeatExecEnum.GAS_CONCENTRATION.getDesc());
+                    DeviceExceptionLog deviceExceptionLog = new DeviceExceptionLog();
+                    deviceExceptionLog.setTime(LocalDateTime.now());
+                    deviceExceptionLog.setExecDesc(HeartbeatExecEnum.GAS_CONCENTRATION.getDesc());
+                    DeviceExceptionLog save =  deviceExceptionLogService.save(deviceExceptionLog);
+                    if (save == null)
+                        throw new BusinessException(this.getClass(), ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"设备异常日志保存失败");
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    @Scheduled(cron = "0 0/30 * * * ?") // 每30分钟执行一次
+    @Async(value = "SocketTaskExecutor")
+    public void gasFluxStatus() {
+        GasFlux gasFlux = gasFluxService.getLastData();
+        if (gasFlux != null){
+            LocalDateTime lastReceiveTime = gasFlux.getDataReceivingTime().plusMinutes(30);
+            if (LocalDateTime.now().compareTo(lastReceiveTime) > 0){
+                try {
+                    heartbeatExcWebsocketServer.sendInfo(HeartbeatExecEnum.GAS_FLUX.getStatus()+"",null);
+                    logger.info(HeartbeatExecEnum.GAS_FLUX.getDesc());
+                    DeviceExceptionLog deviceExceptionLog = new DeviceExceptionLog();
+                    deviceExceptionLog.setTime(LocalDateTime.now());
+                    deviceExceptionLog.setExecDesc(HeartbeatExecEnum.GAS_FLUX.getDesc());
+                    DeviceExceptionLog save =  deviceExceptionLogService.save(deviceExceptionLog);
+                    if (save == null)
+                        throw new BusinessException(this.getClass(), ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"设备异常日志保存失败");
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/DataReceiveService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/DataReceiveService.java
new file mode 100644
index 0000000..08eb622
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/DataReceiveService.java
@@ -0,0 +1,22 @@
+package com.gkhy.fourierSpecialGasMonitor.service;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.ForeignResult;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.DeviceMonitorReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UploadGasConcentrationReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UploadGasFluxReqDTO;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/7 14:25
+ */
+public interface DataReceiveService {
+    ForeignResult uploadGasConcentration(UploadGasConcentrationReqDTO reqDto);
+
+    ForeignResult listGasCategory();
+
+    ForeignResult uploadGasFlux(UploadGasFluxReqDTO reqDto);
+
+    ForeignResult deviceMonitor(DeviceMonitorReqDTO reqDTO);
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/DeviceExceptionLogService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/DeviceExceptionLogService.java
new file mode 100644
index 0000000..7b91b30
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/DeviceExceptionLogService.java
@@ -0,0 +1,12 @@
+package com.gkhy.fourierSpecialGasMonitor.service;
+
+import com.gkhy.fourierSpecialGasMonitor.entity.DeviceExceptionLog;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/8 15:12
+ */
+public interface DeviceExceptionLogService {
+    DeviceExceptionLog save(DeviceExceptionLog log);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasCategoryService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasCategoryService.java
new file mode 100644
index 0000000..914f9f4
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasCategoryService.java
@@ -0,0 +1,27 @@
+package com.gkhy.fourierSpecialGasMonitor.service;
+
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasCategory;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindGasCategoryPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.CreateGasCategoryReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UpdateGasCategoryReqDTO;
+
+import java.util.List;
+
+public interface GasCategoryService {
+    Result createGasCategory(CreateGasCategoryReqDTO reqDto);
+
+    Result updateGasCategory(UpdateGasCategoryReqDTO reqDto);
+
+    Result findGasCategoryById(Integer id);
+
+    Result gasCategoryList();
+
+    List<GasCategory> list();
+
+    Result findGasCategoryPage(PageQuery<FindGasCategoryPageQuery> pageQuery);
+
+    GasCategory findById(Integer id);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasConcentrationService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasConcentrationService.java
new file mode 100644
index 0000000..b47ccc2
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasConcentrationService.java
@@ -0,0 +1,24 @@
+package com.gkhy.fourierSpecialGasMonitor.service;
+
+
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasConcentration;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasWarnUser;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.GasAtmospherePageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.GasPageQuery;
+import org.springframework.data.domain.Page;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+public interface GasConcentrationService{
+    GasConcentration save(GasConcentration gasConcentration);
+
+    GasConcentration getLastData();
+
+    List<GasConcentration> listDatabyTimeSlot(LocalDateTime startTime, LocalDateTime endTime);
+
+    Page<GasConcentration> listDatabyTimeSlotAndPage(PageQuery<GasPageQuery> pageQuery);
+
+    Page<GasConcentration> gasAtmospherePage(PageQuery<GasAtmospherePageQuery> pageQuery);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasFluxService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasFluxService.java
new file mode 100644
index 0000000..4863339
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasFluxService.java
@@ -0,0 +1,30 @@
+package com.gkhy.fourierSpecialGasMonitor.service;
+
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasCategory;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasConcentration;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasFlux;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.GasFluxPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.CreateGasCategoryReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UpdateGasCategoryReqDTO;
+import org.springframework.data.domain.Page;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+public interface GasFluxService {
+    GasFlux save(GasFlux gasFlux);
+
+    List<GasFlux> listTodayGasFluxData(LocalDateTime startTime, LocalDateTime time);
+
+    GasFlux getLastData();
+
+    List<GasFlux> listDatabyTimeSlotAndAreaId(LocalDateTime startTime, LocalDateTime endTime, Integer areaId);
+
+    Page<GasFlux> listDatabyTimeSlotAndPage(PageQuery<GasFluxPageQuery> pageQuery);
+
+    List<GasFlux> listYesterday();
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasThresholdService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasThresholdService.java
new file mode 100644
index 0000000..f800de4
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasThresholdService.java
@@ -0,0 +1,22 @@
+package com.gkhy.fourierSpecialGasMonitor.service;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasThreshold;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UpdateGasThresholdReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UpdateRegionReqDTO;
+
+import java.util.List;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 14:33
+ */
+public interface GasThresholdService {
+    Result gasThresholdList();
+
+    Result updateGasThreshold(UpdateGasThresholdReqDTO reqDto);
+
+    List<GasThreshold> findAll();
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasWarnLogService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasWarnLogService.java
new file mode 100644
index 0000000..7595768
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasWarnLogService.java
@@ -0,0 +1,23 @@
+package com.gkhy.fourierSpecialGasMonitor.service;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasWarnLog;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindGasWarnLogPageQuery;
+
+import java.util.List;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 16:47
+ */
+public interface GasWarnLogService {
+    Result findGasWarnLogPage(PageQuery<FindGasWarnLogPageQuery> pageQuery);
+
+    Result handleGasWarnLog(Long id);
+
+    GasWarnLog save(GasWarnLog gasWarnLog);
+
+    List<GasWarnLog> listYesterday();
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasWarnLogSmsUserService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasWarnLogSmsUserService.java
new file mode 100644
index 0000000..a809922
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasWarnLogSmsUserService.java
@@ -0,0 +1,15 @@
+package com.gkhy.fourierSpecialGasMonitor.service;
+
+import com.gkhy.fourierSpecialGasMonitor.entity.GasWarnLogSmsUser;
+
+import java.util.List;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 16:24
+ */
+public interface GasWarnLogSmsUserService {
+    List<GasWarnLogSmsUser> saveAll(List<GasWarnLogSmsUser> gasWarnLogSmsUsers);
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasWarnUserService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasWarnUserService.java
new file mode 100644
index 0000000..732b2b6
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/GasWarnUserService.java
@@ -0,0 +1,29 @@
+package com.gkhy.fourierSpecialGasMonitor.service;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasWarnUser;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindGasWarnUserPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.CreateGasWarnUserReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.DelGasWarnUserByIdReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UpdateGasWarnUserReqDTO;
+
+import java.util.List;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 14:59
+ */
+public interface GasWarnUserService {
+    Result createGasWarnUser(CreateGasWarnUserReqDTO reqDto);
+
+    Result delGasWarnUserById(DelGasWarnUserByIdReqDTO reqDto);
+
+    Result updateGasWarnUser(UpdateGasWarnUserReqDTO reqDto);
+
+    Result findGasWarnUserPage(PageQuery<FindGasWarnUserPageQuery> pageQuery);
+
+    List<GasWarnUser> findAll();
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/MonitorDailyReportService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/MonitorDailyReportService.java
new file mode 100644
index 0000000..df73f54
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/MonitorDailyReportService.java
@@ -0,0 +1,18 @@
+package com.gkhy.fourierSpecialGasMonitor.service;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.MonitorDailyReport;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindDailyReportPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindRegionPageQuery;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 15:44
+ */
+public interface MonitorDailyReportService {
+    Result findDailyReportPage(PageQuery<FindDailyReportPageQuery> pageQuery);
+
+    MonitorDailyReport save(MonitorDailyReport report);
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/MonitorDataService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/MonitorDataService.java
new file mode 100644
index 0000000..50af6cb
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/MonitorDataService.java
@@ -0,0 +1,30 @@
+package com.gkhy.fourierSpecialGasMonitor.service;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.GasAtmospherePageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.GasFluxPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.GasPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.GasAtmosphereLineChartReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.GasFluxLineChartReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.GasLineChartReqDTO;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 9:15
+ */
+public interface MonitorDataService {
+    Result gasLineChart(GasLineChartReqDTO reqDto);
+
+    Result gasPage(PageQuery<GasPageQuery> pageQuery);
+
+    Result gasFluxLineChart(GasFluxLineChartReqDTO reqDto);
+
+    Result gasFluxPage(PageQuery<GasFluxPageQuery> pageQuery);
+
+    Result gasAtmosphereLineChart(GasAtmosphereLineChartReqDTO reqDto);
+
+    Result gasAtmospherePage(PageQuery<GasAtmospherePageQuery> pageQuery);
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/RegionService.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/RegionService.java
new file mode 100644
index 0000000..c33b4ac
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/RegionService.java
@@ -0,0 +1,31 @@
+package com.gkhy.fourierSpecialGasMonitor.service;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.Region;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindRegionPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.CreateRegionReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.DelRegionByIdReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UpdateRegionReqDTO;
+
+import java.util.List;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 10:46
+ */
+public interface RegionService {
+    Result createRegion(CreateRegionReqDTO reqDto);
+
+    Result delRegionById(DelRegionByIdReqDTO reqDto);
+
+    Result findRegionById(Integer id);
+
+    Result findRegionPage(PageQuery<FindRegionPageQuery> pageQuery);
+
+    Result updateRegion(UpdateRegionReqDTO reqDto);
+
+    List<Region> findAll();
+
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/DataReceiveServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/DataReceiveServiceImpl.java
new file mode 100644
index 0000000..e7b2837
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/DataReceiveServiceImpl.java
@@ -0,0 +1,540 @@
+package com.gkhy.fourierSpecialGasMonitor.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.ForeignResult;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ForeignResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.DataReceiveException;
+import com.gkhy.fourierSpecialGasMonitor.decorator.WarningThresholdUpdateEvent;
+import com.gkhy.fourierSpecialGasMonitor.entity.*;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.DeviceMonitorReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UploadGasConcentrationReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UploadGasFluxReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.resp.GasCategoryListRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.enums.*;
+import com.gkhy.fourierSpecialGasMonitor.repository.GasConcentrationRepository;
+import com.gkhy.fourierSpecialGasMonitor.service.*;
+import com.gkhy.fourierSpecialGasMonitor.utils.SendMessageUtil;
+import com.gkhy.fourierSpecialGasMonitor.websocket.GasConcentrationExcWebsocketServer;
+import com.gkhy.fourierSpecialGasMonitor.websocket.GasConcentrationWebsocketServer;
+import com.gkhy.fourierSpecialGasMonitor.websocket.GasDeviceExcWebsocketServer;
+import com.gkhy.fourierSpecialGasMonitor.websocket.GasFluxWebsocketServer;
+import io.micrometer.core.instrument.util.StringUtils;
+import org.redisson.api.RBucket;
+import org.redisson.api.RedissonClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.PostConstruct;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.text.MessageFormat;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.stream.Collectors;
+
+import static org.apache.el.lang.ELArithmetic.isNumberType;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/7 14:25
+ */
+@Service
+public class DataReceiveServiceImpl implements DataReceiveService {
+
+    @Autowired
+    private GasConcentrationService gasConcentrationService;
+
+    @Autowired
+    private GasCategoryService gasCategoryService;
+
+    @Autowired
+    private GasThresholdService gasThresholdService;
+
+    @Autowired
+    private GasWarnLogService gasWarnLogService;
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+    @Autowired
+    private GasFluxService gasFluxService;
+
+    @Autowired
+    private SendMessageUtil sendMessageUtil;
+
+    @Autowired
+    private GasWarnLogSmsUserService gasWarnLogSmsUserService;
+
+    @Autowired
+    private GasWarnUserService gasWarnUserService;
+
+    @Autowired
+    private DeviceExceptionLogService deviceExceptionLogService;
+
+    @Autowired
+    private GasConcentrationWebsocketServer gasConcentrationWebsocketServer;
+
+    @Autowired
+    private GasFluxWebsocketServer gasFluxWebsocketServer;
+
+    private static final ReentrantLock lock = new ReentrantLock();
+
+    @Autowired
+    private GasConcentrationExcWebsocketServer gasConcentrationExcWebsocketServer;
+
+    private Map<Integer,Integer> gasExcCountMap = new HashMap<>();
+
+    private static Integer yellowWarningThreshold = 2;
+
+    private static Integer redWarningThreshold = 5;
+
+    @Value("${sms.send.enabled}")
+    private String smsSendEnabledStatus;
+
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+
+    private static String gasConcentrationCachePrefix = "gas_concentration_cache_";
+
+    private static final String warnContentFormat = "【气体监测预警提示】{0} {1}气体浓度连续超标系统判断为{2},请相关负责人及时检查处置。";
+
+    private static final DateTimeFormatter warnLogFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
+
+
+    @PostConstruct
+    public void init() {
+        List<GasCategory> gasCategories = gasCategoryService.list();
+        if (!CollectionUtils.isEmpty(gasCategories)){
+            List<GasCategory> collect = gasCategories.stream().map(gasCategory -> {
+                gasExcCountMap.put(gasCategory.getId(), 0);
+                return gasCategory;
+            }).collect(Collectors.toList());
+        }
+        logger.info("【气体异常map】init完成");
+    }
+
+    @PostConstruct
+    public void warningThresholdInit() {
+        List<GasThreshold> gasThresholds = gasThresholdService.findAll();
+        if (!CollectionUtils.isEmpty(gasThresholds)){
+            for (int i = 0; i < gasThresholds.size(); i++) {
+                if (WarningThresholdEnum.YELLOW.getCode().equals(gasThresholds.get(i).getId())){
+                    yellowWarningThreshold = gasThresholds.get(i).getThreshold();
+                }
+                if (WarningThresholdEnum.RED.getCode().equals(gasThresholds.get(i).getId())){
+                    redWarningThreshold = gasThresholds.get(i).getThreshold();
+                }
+            }
+        }
+        logger.info("【预警阈值】init完成");
+    }
+
+    @Override
+    public ForeignResult listGasCategory() {
+        Result result = gasCategoryService.gasCategoryList();
+        List<GasCategoryListRespDTO> data = (List<GasCategoryListRespDTO>) result.getData();
+        ForeignResult success = ForeignResult.success();
+        success.setData(data);
+        return success;
+    }
+
+    @Override
+    public ForeignResult uploadGasFlux(UploadGasFluxReqDTO reqDto) {
+        gasFluxParameterVerification(reqDto);
+        GasFlux gasFlux = new GasFlux();
+        BeanUtils.copyProperties(reqDto,gasFlux);
+        gasFlux.setDataReceivingTime(LocalDateTime.now());
+        GasFlux save = gasFluxService.save(gasFlux);
+        if (save == null)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"气体通量数据保存失败");
+        return ForeignResult.success();
+    }
+
+    @Override
+    public ForeignResult deviceMonitor(DeviceMonitorReqDTO reqDTO) {
+        if (reqDTO == null)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"数据为空");
+        if (CollectionUtils.isEmpty(reqDTO.getHardwareState()))
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"硬件设备状态不能为空");
+        if (reqDTO.getConState() < 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"浓度数据状态不能为空");
+        if (reqDTO.getFluxState() < 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"通量数据状态不能为空");
+        Boolean push = false;
+        List<String> descs = new ArrayList<>();
+        if (reqDTO.getHardwareState().size() > 1){
+            push = true;
+            for (int i = 0; i < reqDTO.getHardwareState().size(); i++) {
+                descs.add(HardwareStateEnum.getValue(reqDTO.getHardwareState().get(i)));
+            }
+        }
+        if (GasConcentrationStateEnum.NO_DATA_FROM_ONSITE_EQUIPMENT_FOR_5_MINUTES.getState().equals(reqDTO.getConState())){
+            push = true;
+            descs.add(GasConcentrationStateEnum.NO_DATA_FROM_ONSITE_EQUIPMENT_FOR_5_MINUTES.getDesc());
+        }
+        if (GasFluxStateEnum.INVERSION_FAILED_10_MINUTES_NO_DATA.getState().equals(reqDTO.getFluxState())){
+            push = true;
+            descs.add(GasFluxStateEnum.INVERSION_FAILED_10_MINUTES_NO_DATA.getDesc());
+        }
+        if (push == true){
+            String message = JSON.toJSONString(reqDTO);
+            try {
+                GasDeviceExcWebsocketServer.sendInfo(message,null);
+            } catch (IOException e) {
+                logger.info("【警告】设备异常提醒推送>>>>>>>>>>>>>>>>>>失败");
+            }
+            String execInfo = JSON.toJSONString(descs);
+            logger.info("【警告】设备异常,异常原因: "+ execInfo);
+            DeviceExceptionLog log = new DeviceExceptionLog();
+            log.setTime(LocalDateTime.now());
+            log.setExecDesc(execInfo);
+            DeviceExceptionLog save =  deviceExceptionLogService.save(log);
+            if (save == null)
+                logger.info("【警告】设备异常日志保存>>>>>>>>>>>>>>>>>>失败");
+        }
+        return ForeignResult.success();
+    }
+
+    private void gasFluxDataCacheAndPush(GasFlux save){
+        LocalDateTime time = LocalDateTime.now();
+        LocalDateTime startTime = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0);
+        List<GasFlux> gasFluxes =  gasFluxService.listTodayGasFluxData(startTime,time);
+        String message = "";
+        if (!CollectionUtils.isEmpty(gasFluxes)){
+            message = JSON.toJSONString(gasFluxes);
+        }
+        try {
+            gasFluxWebsocketServer.sendInfo(message,null);
+        } catch (IOException e) {
+            logger.info("【警告】气体通量数据推送>>>>>>>>>>>>>>>>>>失败");
+        }
+    }
+
+
+    @Override
+    @Transactional
+    public ForeignResult uploadGasConcentration(UploadGasConcentrationReqDTO reqDto) {
+        //gasConcentrationParameterVerification(reqDto);
+        GasConcentration gasConcentration = new GasConcentration();
+        BeanUtils.copyProperties(reqDto,gasConcentration);
+        gasConcentration.setDataReceivingTime(LocalDateTime.now());
+        GasConcentration save = gasConcentrationService.save(gasConcentration);
+        if (save == null)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"气体实时数据保存失败");
+        dataCacheAndPush(save);
+        execDataCountAndPush(reqDto);
+        return ForeignResult.success();
+    }
+
+
+    private  void execDataCountAndPush(UploadGasConcentrationReqDTO reqDto){
+        RBucket<List<GasCategory>> bucket = redissonClient.getBucket("gas_category_cache_info");
+        List<GasCategory> gasCategoryCache = bucket.get();
+        if (CollectionUtils.isEmpty(gasCategoryCache)){
+            gasCategoryCache = gasCategoryService.list();
+            if (CollectionUtils.isEmpty(gasCategoryCache)){
+                throw new DataReceiveException(this.getClass(), ForeignResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"气体对照表为空");
+            }
+            bucket.set(gasCategoryCache);
+        }
+        Map<Integer, Double> threshold = gasCategoryCache.stream().collect(Collectors.toMap(GasCategory::getId, GasCategory::getThreshold));
+        Map<Integer,GasCategory> gasCategory = gasCategoryCache.stream().collect(Collectors.toMap(GasCategory::getId,g -> g));
+        lock.lock();
+        try{
+            for (int i = 1; i <= gasCategoryCache.size(); i++) {
+                String fileNamePrefix = "gasValue";
+                String fileName = fileNamePrefix + i;
+                if (i < 10) {
+                    fileName = fileNamePrefix + "0" + i;
+                }
+                Field[] fields = reqDto.getClass().getDeclaredFields();
+                for (Field field : fields) {
+                    field.setAccessible(true);  // 设置字段可访问,即使是私有字段
+                    if (field.getName().equals(fileName)) {
+                        Double value = null;
+                        try {
+                            value = (Double) field.get(reqDto);
+                        } catch (IllegalAccessException e) {
+                            logger.info("【警告】反射获取气体浓度失败");
+                        }
+                        if (value > threshold.get(i)) {
+                            Integer integer = gasExcCountMap.get(i);
+                            Integer count= integer + 1;
+                            gasExcCountMap.put(i,count);
+                            if (yellowWarningThreshold.equals(count)) {
+                                System.out.println("超过次数: "+count);
+                                warnLogGenerateAndExecPush(WarningThresholdEnum.YELLOW.getCode(), gasCategory.get(i),value);
+                            }
+                            if (redWarningThreshold.equals(count)) {
+                                warnLogGenerateAndExecPush(WarningThresholdEnum.RED.getCode(), gasCategory.get(i),value);
+                            }
+                        } else {
+                            Integer integer = gasExcCountMap.get(i);
+                            if (integer != null) {
+                                gasExcCountMap.put(i,0);
+                            }
+                        }
+                    }
+                }
+            }
+        }finally {
+            lock.unlock();
+        }
+    }
+
+    private void warnLogGenerateAndExecPush(Integer warnThresholdEnumCode,GasCategory gasCategory,Double value){
+        if (gasCategory == null)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"该气体不存在于对照表");
+        GasWarnLog gasWarnLog = new GasWarnLog();
+        String warnThresholdName = WarningThresholdEnum.getValue(warnThresholdEnumCode);
+        LocalDateTime now = LocalDateTime.now();
+        String warnTime = now.format(warnLogFormatter);
+        String content  = MessageFormat.format(warnContentFormat,warnTime,gasCategory.getName(),warnThresholdName);
+        gasWarnLog.setGasConcentration(value);
+        gasWarnLog.setGasName(gasCategory.getName());
+        gasWarnLog.setGasUnit(gasCategory.getUnit());
+        gasWarnLog.setGasConcentrationThreshold(gasCategory.getThreshold());
+        gasWarnLog.setGasMolecularFormula(gasCategory.getMolecularFormula());
+        gasWarnLog.setContent(content);
+        gasWarnLog.setStatus(WarnHandleStatusEnum.HANDLE_NO.getStatus());
+        gasWarnLog.setWarnTime(now);
+        gasWarnLog.setGasCategoryId(gasCategory.getId());
+        gasWarnLog.setGasThresholdId(warnThresholdEnumCode);
+        gasWarnLog.setGasThresholdName(warnThresholdName);
+        GasWarnLog save = gasWarnLogService.save(gasWarnLog);
+        if (save == null)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"预警异常日志保存失败");
+        String gasConcentrationExcInfo = JSON.toJSONString(save);
+        try {
+            gasConcentrationExcWebsocketServer.sendInfo(gasConcentrationExcInfo,null);
+        } catch (IOException e) {
+            logger.info("【警告】气体浓度异常推送>>>>>>>>>>>>>>>>>>失败");
+        }
+
+        List<GasWarnUser> gasWarnUsers = gasWarnUserService.findAll();
+        if (!CollectionUtils.isEmpty(gasWarnUsers)){
+            List<String> phone = new ArrayList<>();
+            List<GasWarnLogSmsUser> gasWarnLogSmsUsers = gasWarnUsers.stream().map(gasWarnUser -> {
+                phone.add(gasWarnUser.getPhone());
+                GasWarnLogSmsUser gasWarnLogSmsUser = new GasWarnLogSmsUser();
+                BeanUtils.copyProperties(gasWarnUser, gasWarnLogSmsUser, "id");
+                gasWarnLogSmsUser.setWarnLogId(save.getId());
+                return gasWarnLogSmsUser;
+            }).collect(Collectors.toList());
+            List<GasWarnLogSmsUser> saveAll = gasWarnLogSmsUserService.saveAll(gasWarnLogSmsUsers);
+            if (saveAll == null)
+                throw new DataReceiveException(this.getClass(), ForeignResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"预警异常短信接收人保存失败");
+            Map<String, String> mesMap = new HashMap<>();
+            mesMap.put("message",warnTime+" "+gasCategory.getName());
+            mesMap.put("level",warnThresholdName);
+            //todo
+            if (!CollectionUtils.isEmpty(phone)) {
+                List<String> distinctPhone = phone.stream().distinct().collect(Collectors.toList());
+                logger.info("【气体浓度异常短信发送】-----发送内容:" + content + " 发送时间: " + now + " 接收人手机号:" + distinctPhone);
+                if (!org.springframework.util.StringUtils.isEmpty(smsSendEnabledStatus) && "true".equals(smsSendEnabledStatus)) {
+                    sendMessageUtil.sendMessageCheck(phone.toArray(new String[phone.size()]), mesMap);
+                }
+            }
+        }
+    }
+
+    private void dataCacheAndPush(GasConcentration save){
+        LocalDateTime time = LocalDateTime.now();
+        String cacheName = time.format(formatter);
+        RBucket<String> bucket = redissonClient.getBucket(gasConcentrationCachePrefix+cacheName);
+        String cache = bucket.get();
+        List<GasConcentration> gasConcentrations = JSON.parseArray(cache,GasConcentration.class);
+        if (CollectionUtils.isEmpty(gasConcentrations)){
+            gasConcentrations = new ArrayList<>();
+            gasConcentrations.add(save);
+        }else {
+            gasConcentrations.add(save);
+        }
+        String gasConcentrationsToJson = JSON.toJSONString(gasConcentrations);
+        bucket.set(gasConcentrationsToJson);
+        try {
+            gasConcentrationWebsocketServer.sendInfo(gasConcentrationsToJson,null);
+        } catch (IOException e) {
+            logger.info("【警告】气体浓度实时推送>>>>>>>>>>>>>>>>>>失败");
+        }
+    }
+
+    private void gasConcentrationParameterVerification(UploadGasConcentrationReqDTO reqDto){
+        if (reqDto == null)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"数据为空");
+        if (StringUtils.isBlank(reqDto.getEquipmentId()))
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"设备id为空");
+        if (reqDto.getTime() == null)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"扫描时间为空");
+        if (reqDto.getType() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"设备类型异常");
+        if (StringUtils.isBlank(reqDto.getLng()))
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"经度为空");
+        if (StringUtils.isBlank(reqDto.getLat()))
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"纬度为空");
+        if (StringUtils.isBlank(reqDto.getAngle()))
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"角度为空");
+        if (reqDto.getTemp() == null)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"实时温度数据为空");
+        if (reqDto.getHumidity() == null)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"实时相对湿度数据为空");
+        if (reqDto.getWindSpeed() == null)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"实时风速数据为空");
+        if (reqDto.getWindDirection() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"实时风向数据为空");
+        if (reqDto.getPressure() == null)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"实时气压数据为空");
+        if (reqDto.getGasName01() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类01编号异常");
+        if (reqDto.getGasName02() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类02编号异常");
+        if (reqDto.getGasName03() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类03编号异常");
+        if (reqDto.getGasName04() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类04编号异常");
+        if (reqDto.getGasName05() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类05编号异常");
+        if (reqDto.getGasName06() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类06编号异常");
+        if (reqDto.getGasName07() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类07编号异常");
+        if (reqDto.getGasName08() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类08编号异常");
+        if (reqDto.getGasName09() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类09编号异常");
+        if (reqDto.getGasName10() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类10编号异常");
+        if (reqDto.getGasName11() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类11编号异常");
+        if (reqDto.getGasName12() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类12编号异常");
+        if (reqDto.getGasName13() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类13编号异常");
+        if (reqDto.getGasName14() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类14编号异常");
+        if (reqDto.getGasName15() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类15编号异常");
+        if (reqDto.getGasName16() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类16编号异常");
+        if (reqDto.getGasName17() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类17编号异常");
+        if (reqDto.getGasName18() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类18编号异常");
+        if (reqDto.getGasName19() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类19编号异常");
+        if (reqDto.getGasName20() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类20编号异常");
+        if (reqDto.getGasName21() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类21编号异常");
+        if (reqDto.getGasName22() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类22编号异常");
+        if (reqDto.getGasName23() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类23编号异常");
+        if (reqDto.getGasName24() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类24编号异常");
+        if (reqDto.getGasName25() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类25编号异常");
+        if (reqDto.getGasName26() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类26编号异常");
+        if (reqDto.getGasName27() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类27编号异常");
+        if (reqDto.getGasName28() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类28编号异常");
+        if (reqDto.getGasName29() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类29编号异常");
+        if (reqDto.getGasName30() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类30编号异常");
+    }
+
+    private void gasFluxParameterVerification(UploadGasFluxReqDTO reqDto){
+        if (reqDto == null)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"数据为空");
+        if (StringUtils.isBlank(reqDto.getEquipmentId()))
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"设备id为空");
+        if (reqDto.getAreaId() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"区域id为空");
+        if (reqDto.getTime() == null)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"扫描时间为空");
+        if (reqDto.getType() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"设备类型异常");
+        if (reqDto.getWindSpeed() == null)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"实时风速数据为空");
+        if (reqDto.getWindDirection() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"实时风向数据为空");
+        if (reqDto.getGasName01() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类01编号异常");
+        if (reqDto.getGasName02() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类02编号异常");
+        if (reqDto.getGasName03() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类03编号异常");
+        if (reqDto.getGasName04() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类04编号异常");
+        if (reqDto.getGasName05() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类05编号异常");
+        if (reqDto.getGasName06() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类06编号异常");
+        if (reqDto.getGasName07() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类07编号异常");
+        if (reqDto.getGasName08() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类08编号异常");
+        if (reqDto.getGasName09() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类09编号异常");
+        if (reqDto.getGasName10() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类10编号异常");
+        if (reqDto.getGasName11() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类11编号异常");
+        if (reqDto.getGasName12() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类12编号异常");
+        if (reqDto.getGasName13() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类13编号异常");
+        if (reqDto.getGasName14() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类14编号异常");
+        if (reqDto.getGasName15() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类15编号异常");
+        if (reqDto.getGasName16() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类16编号异常");
+        if (reqDto.getGasName17() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类17编号异常");
+        if (reqDto.getGasName18() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类18编号异常");
+        if (reqDto.getGasName19() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类19编号异常");
+        if (reqDto.getGasName20() <= 0)
+            throw new DataReceiveException(this.getClass(), ForeignResultCode.PARAM_ERROR_NULL.getCode(),"气体种类20编号异常");
+    }
+
+
+    //@Async   // 异步方式
+    @EventListener   // 监听器注解
+    public void updateWarningThreshold(WarningThresholdUpdateEvent event){
+        List<GasThreshold> gasThresholds = gasThresholdService.findAll();
+        if (!CollectionUtils.isEmpty(gasThresholds)){
+            for (int i = 0; i < gasThresholds.size(); i++) {
+                if (WarningThresholdEnum.YELLOW.getCode().equals(gasThresholds.get(i).getId())){
+                    yellowWarningThreshold = gasThresholds.get(i).getThreshold();
+                }
+                if (WarningThresholdEnum.RED.getCode().equals(gasThresholds.get(i).getId())){
+                    redWarningThreshold = gasThresholds.get(i).getThreshold();
+                }
+            }
+        }
+        logger.info("【预警阈值】更新完成");
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/DeviceExceptionLogServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/DeviceExceptionLogServiceImpl.java
new file mode 100644
index 0000000..6be49cc
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/DeviceExceptionLogServiceImpl.java
@@ -0,0 +1,24 @@
+package com.gkhy.fourierSpecialGasMonitor.service.impl;
+
+import com.gkhy.fourierSpecialGasMonitor.entity.DeviceExceptionLog;
+import com.gkhy.fourierSpecialGasMonitor.repository.DeviceExceptionLogRepository;
+import com.gkhy.fourierSpecialGasMonitor.service.DeviceExceptionLogService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/8 15:12
+ */
+@Service
+public class DeviceExceptionLogServiceImpl implements DeviceExceptionLogService {
+
+    @Autowired
+    private DeviceExceptionLogRepository deviceExceptionLogRepository;
+
+    @Override
+    public DeviceExceptionLog save(DeviceExceptionLog log) {
+        return deviceExceptionLogRepository.save(log);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasCategoryServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasCategoryServiceImpl.java
new file mode 100644
index 0000000..0898d67
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasCategoryServiceImpl.java
@@ -0,0 +1,222 @@
+package com.gkhy.fourierSpecialGasMonitor.service.impl;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.User;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.enums.UserStatusEnum;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa.UserRepository;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasCategory;
+import com.gkhy.fourierSpecialGasMonitor.entity.Region;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindGasCategoryPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindRegionPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.CreateGasCategoryReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UpdateGasCategoryReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.resp.*;
+import com.gkhy.fourierSpecialGasMonitor.enums.DeleteStatusEnum;
+import com.gkhy.fourierSpecialGasMonitor.repository.GasCategoryRepository;
+import com.gkhy.fourierSpecialGasMonitor.service.GasCategoryService;
+import com.gkhy.fourierSpecialGasMonitor.utils.ThreadLocalUtil;
+import io.micrometer.core.instrument.util.StringUtils;
+import org.redisson.api.RBucket;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.stream.Collectors;
+
+@Service
+public class GasCategoryServiceImpl implements GasCategoryService {
+
+    @Autowired
+    private UserRepository userRepository;
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+    @Autowired
+    private GasCategoryRepository gasCategoryRepository;
+
+    private static ReentrantLock gasCategoryMolecularFormulaRepeatlock = new ReentrantLock();
+
+    private User getCurrentUser(){
+        Long userId = ThreadLocalUtil.get().getId();
+        User user = userRepository.findUserByIdAndStatus(userId, UserStatusEnum.STATUS_ACTIVE.getStatus());
+        if (user == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"未成功获取用户信息");
+        return user;
+    }
+
+    @Override
+    public Result createGasCategory(CreateGasCategoryReqDTO reqDto) {
+        if (reqDto == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        if (StringUtils.isBlank(reqDto.getMolecularFormula()))
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"气体分子式不能为空");
+        if (StringUtils.isBlank(reqDto.getName()))
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"气体名称不能为空");
+        if (StringUtils.isBlank(reqDto.getUnit()))
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"气体单位不能为空");
+        if (reqDto.getThreshold() == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"气体浓度阈值不能为空");
+        gasCategoryMolecularFormulaRepeatlock.lock();
+        try{
+            GasCategory byMolecularFormula = gasCategoryRepository.findByMolecularFormula(reqDto.getMolecularFormula());
+            if (byMolecularFormula != null){
+                throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"气体分子式已存在");
+            }
+            User user = getCurrentUser();
+            GasCategory gasCategory = new GasCategory();
+            BeanUtils.copyProperties(reqDto,gasCategory);
+            gasCategory.setGmtCreate(LocalDateTime.now());
+            gasCategory.setGmtModified(LocalDateTime.now());
+            gasCategory.setCreatedby(user.getRealName());
+            gasCategory.setLastmodifiedby(user.getRealName());
+            GasCategory save = gasCategoryRepository.save(gasCategory);
+            if (save == null)
+                throw new BusinessException(this.getClass(), ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(), "气体新增失败");
+        }finally {
+            gasCategoryMolecularFormulaRepeatlock.unlock();
+        }
+        //清除redis缓存
+        RBucket<List<GasCategory>> bucket = redissonClient.getBucket("gas_category_cache_info");
+        if (bucket.isExists()) {
+            bucket.delete();
+        }
+        return Result.success();
+    }
+
+    @Override
+    public Result updateGasCategory(UpdateGasCategoryReqDTO reqDto) {
+        if (reqDto == null || reqDto.getId() == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        if (StringUtils.isBlank(reqDto.getMolecularFormula()))
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"气体分子式不能为空");
+        if (StringUtils.isBlank(reqDto.getName()))
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"气体名称不能为空");
+        if (StringUtils.isBlank(reqDto.getUnit()))
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"气体单位不能为空");
+        if (reqDto.getThreshold() == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"气体浓度阈值不能为空");
+        gasCategoryMolecularFormulaRepeatlock.lock();
+        try {
+            GasCategory byMolecularFormula = gasCategoryRepository.findByMolecularFormula(reqDto.getMolecularFormula());
+            if (byMolecularFormula != null && byMolecularFormula.getId() != reqDto.getId()){
+                throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"气体分子式已存在");
+            }
+            User user = getCurrentUser();
+            Optional<GasCategory> category = gasCategoryRepository.findById(reqDto.getId());
+            if (category.isPresent()){
+                GasCategory gasCategory = category.get();
+                BeanUtils.copyProperties(reqDto,gasCategory);
+                gasCategory.setGmtModified(LocalDateTime.now());
+                gasCategory.setLastmodifiedby(user.getRealName());
+                GasCategory save = gasCategoryRepository.save(gasCategory);
+                if (save == null)
+                    throw new BusinessException(this.getClass(), ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(), "气体更新失败");
+            }
+        }finally {
+            gasCategoryMolecularFormulaRepeatlock.unlock();
+        }
+        //清除redis缓存
+        RBucket<List<GasCategory>> bucket = redissonClient.getBucket("gas_category_cache_info");
+        if (bucket.isExists()) {
+            bucket.delete();
+        }
+        return Result.success();
+    }
+
+    @Override
+    public Result findGasCategoryById(Integer id) {
+        Result success = Result.success();
+        if (id == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        Optional<GasCategory> optionalGasCategory = gasCategoryRepository.findById(id);
+        if (optionalGasCategory.isPresent()){
+            FindGasCategoryByIdRespDTO resp = new FindGasCategoryByIdRespDTO();
+            GasCategory gasCategory = optionalGasCategory.get();
+            BeanUtils.copyProperties(gasCategory,resp);
+            success.setData(resp);
+        }
+        return success;
+    }
+
+    public GasCategory findById(Integer id) {
+        if (id == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        Optional<GasCategory> optionalGasCategory = gasCategoryRepository.findById(id);
+        return optionalGasCategory.get();
+    }
+
+    @Override
+    public Result gasCategoryList() {
+        Result success = Result.success();
+        RBucket<List<GasCategory>> bucket = redissonClient.getBucket("gas_category_cache_info");
+        List<GasCategory> categories = bucket.get();
+        if (CollectionUtils.isEmpty(categories)){
+            categories = gasCategoryRepository.findAll();
+            bucket.set(categories);
+        }
+        if (!CollectionUtils.isEmpty(categories)){
+            List<GasCategoryListRespDTO> resps = categories.stream().map(categorie -> {
+                GasCategoryListRespDTO resp = new GasCategoryListRespDTO();
+                BeanUtils.copyProperties(categorie, resp);
+                return resp;
+            }).collect(Collectors.toList());
+            success.setData(resps);
+        }
+        return success;
+    }
+
+    @Override
+    public List<GasCategory> list() {
+        return gasCategoryRepository.findAll();
+    }
+
+    @Override
+    public Result findGasCategoryPage(PageQuery<FindGasCategoryPageQuery> pageQuery) {
+        if (pageQuery == null || pageQuery.getPageIndex() == null || pageQuery.getPageSize() == null){
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL,"分页参数不能为空");
+        }
+        Pageable pageable = PageRequest.of(pageQuery.getPageIndex()-1, pageQuery.getPageSize());
+        Specification<GasCategory> specification = new Specification<GasCategory>() {
+            @Override
+            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
+                Set<Predicate> predicateList = new HashSet<>();
+                FindGasCategoryPageQuery searchParams = pageQuery.getSearchParams();
+                if (searchParams != null && !StringUtils.isBlank(searchParams.getName())){
+                    predicateList.add(criteriaBuilder.like(root.get("name").as(String.class),"%"+searchParams.getName()+"%"));
+                }
+                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
+            }
+        };
+        SearchResult<List<FindGasCategoryPageRespDTO>> searchResult = new SearchResult<>();
+        searchResult.setPageIndex(pageQuery.getPageIndex());
+        searchResult.setPageSize(pageQuery.getPageSize());
+        searchResult.setSuccess();
+        Page<GasCategory> pageResult = gasCategoryRepository.findAll(specification,pageable);
+        searchResult.setTotal(pageResult.getTotalElements());
+        searchResult.setPages(pageResult.getTotalPages());
+        if (!CollectionUtils.isEmpty(pageResult.getContent())){
+            List<FindGasCategoryPageRespDTO> respDTOS = new ArrayList<>();
+            BeanUtils.copyProperties(pageResult.getContent(),respDTOS);
+            searchResult.setData(respDTOS);
+        }
+        return searchResult;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasConcentrationServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasConcentrationServiceImpl.java
new file mode 100644
index 0000000..b27996e
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasConcentrationServiceImpl.java
@@ -0,0 +1,101 @@
+package com.gkhy.fourierSpecialGasMonitor.service.impl;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasConcentration;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasWarnLog;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasWarnUser;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindGasWarnLogPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindGasWarnUserPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.GasAtmospherePageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.GasPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.resp.FindGasWarnUserPageRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.enums.DeleteStatusEnum;
+import com.gkhy.fourierSpecialGasMonitor.repository.GasConcentrationRepository;
+import com.gkhy.fourierSpecialGasMonitor.service.GasConcentrationService;
+import io.micrometer.core.instrument.util.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.criteria.*;
+import java.time.LocalDateTime;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@Service
+public class GasConcentrationServiceImpl implements GasConcentrationService {
+
+    @Autowired
+    private GasConcentrationRepository gasConcentrationRepository;
+
+    @Override
+    public GasConcentration save(GasConcentration gasConcentration) {
+        return gasConcentrationRepository.save(gasConcentration);
+    }
+
+    @Override
+    public GasConcentration getLastData() {
+        GasConcentration gasConcentration = gasConcentrationRepository.findTopByOrderByDataReceivingTimeDesc();
+        return gasConcentration;
+    }
+
+    @Override
+    public List<GasConcentration> listDatabyTimeSlot(LocalDateTime startTime, LocalDateTime endTime) {
+        if (startTime == null || endTime == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"时间区段值不能为空");
+        Specification<GasConcentration> specification = new Specification<GasConcentration>() {
+            @Override
+            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
+                Set<Predicate> predicateList = new HashSet<>();
+                predicateList.add(criteriaBuilder.between(root.get("time").as(LocalDateTime.class),startTime,endTime));
+                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
+            }
+        };
+        List<GasConcentration> gasConcentrations = gasConcentrationRepository.findAll(specification);
+        return gasConcentrations;
+    }
+
+    @Override
+    public Page<GasConcentration> listDatabyTimeSlotAndPage(PageQuery<GasPageQuery> pageQuery) {
+        Pageable pageable = PageRequest.of(pageQuery.getPageIndex()-1, pageQuery.getPageSize(), Sort.Direction.DESC, "time");
+        Specification<GasConcentration> specification = new Specification<GasConcentration>() {
+            @Override
+            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
+                Set<Predicate> predicateList = new HashSet<>();
+                GasPageQuery searchParams = pageQuery.getSearchParams();
+                if (searchParams != null && searchParams.getStartTime() != null && searchParams.getEndTime() != null){
+                    predicateList.add(criteriaBuilder.between(root.get("time").as(LocalDateTime.class),searchParams.getStartTime(),searchParams.getEndTime()));
+                }
+                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
+            }
+        };
+        Page<GasConcentration> pageResult = gasConcentrationRepository.findAll(specification,pageable);
+        return pageResult;
+    }
+
+    @Override
+    public Page<GasConcentration> gasAtmospherePage(PageQuery<GasAtmospherePageQuery> pageQuery) {
+        Pageable pageable = PageRequest.of(pageQuery.getPageIndex()-1, pageQuery.getPageSize(), Sort.Direction.DESC, "time");
+        Specification<GasConcentration> specification = new Specification<GasConcentration>() {
+            @Override
+            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
+                Set<Predicate> predicateList = new HashSet<>();
+                GasAtmospherePageQuery searchParams = pageQuery.getSearchParams();
+                if (searchParams != null && searchParams.getStartTime() != null && searchParams.getEndTime() != null){
+                    predicateList.add(criteriaBuilder.between(root.get("time").as(LocalDateTime.class),searchParams.getStartTime(),searchParams.getEndTime()));
+                }
+                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
+            }
+        };
+        Page<GasConcentration> pageResult = gasConcentrationRepository.findAll(specification,pageable);
+        return pageResult;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasFluxServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasFluxServiceImpl.java
new file mode 100644
index 0000000..0b80e0d
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasFluxServiceImpl.java
@@ -0,0 +1,123 @@
+package com.gkhy.fourierSpecialGasMonitor.service.impl;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasConcentration;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasFlux;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasWarnLog;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.GasFluxPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.GasPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.repository.GasConcentrationRepository;
+import com.gkhy.fourierSpecialGasMonitor.repository.GasFluxRepository;
+import com.gkhy.fourierSpecialGasMonitor.service.GasConcentrationService;
+import com.gkhy.fourierSpecialGasMonitor.service.GasFluxService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.criteria.*;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@Service
+public class GasFluxServiceImpl implements GasFluxService {
+
+    @Autowired
+    private GasFluxRepository gasFluxRepository;
+
+    @Override
+    public GasFlux save(GasFlux gasFlux) {
+        return gasFluxRepository.save(gasFlux);
+    }
+
+    @Override
+    public List<GasFlux> listTodayGasFluxData(LocalDateTime startTime, LocalDateTime time) {
+        Specification<GasFlux> specification = new Specification<GasFlux>() {
+            @Override
+            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
+                Set<Predicate> predicateList = new HashSet<>();
+                if (startTime != null && time != null){
+                    predicateList.add(criteriaBuilder.between(root.get("time").as(LocalDateTime.class),startTime,time));
+                }
+                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
+            }
+        };
+        List<GasFlux> gasFluxes = gasFluxRepository.findAll(specification);
+        return gasFluxes;
+    }
+
+    @Override
+    public GasFlux getLastData() {
+        return gasFluxRepository.findTopByOrderByDataReceivingTimeDesc();
+    }
+
+    @Override
+    public List<GasFlux> listDatabyTimeSlotAndAreaId(LocalDateTime startTime, LocalDateTime endTime, Integer areaId) {
+        if (startTime == null || endTime == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"时间区段值不能为空");
+        Specification<GasFlux> specification = new Specification<GasFlux>() {
+            @Override
+            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
+                Set<Predicate> predicateList = new HashSet<>();
+                predicateList.add(criteriaBuilder.between(root.get("time").as(LocalDateTime.class),startTime,endTime));
+                if (areaId != null){
+                    predicateList.add(criteriaBuilder.equal(root.get("areaId").as(Integer.class),areaId));
+                }
+                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
+            }
+        };
+        List<GasFlux> gasFluxes = gasFluxRepository.findAll(specification);
+        return gasFluxes;
+    }
+
+    @Override
+    public Page<GasFlux> listDatabyTimeSlotAndPage(PageQuery<GasFluxPageQuery> pageQuery) {
+        Pageable pageable = PageRequest.of(pageQuery.getPageIndex()-1, pageQuery.getPageSize(), Sort.Direction.DESC, "time");
+        Specification<GasFlux> specification = new Specification<GasFlux>() {
+            @Override
+            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
+                Set<Predicate> predicateList = new HashSet<>();
+                GasFluxPageQuery searchParams = pageQuery.getSearchParams();
+                if (searchParams != null && searchParams.getStartTime() != null && searchParams.getEndTime() != null){
+                    predicateList.add(criteriaBuilder.between(root.get("time").as(LocalDateTime.class),searchParams.getStartTime(),searchParams.getEndTime()));
+                }
+                if (searchParams != null && searchParams.getAreaId() != null){
+                    predicateList.add(criteriaBuilder.equal(root.get("areaId").as(Integer.class),searchParams.getAreaId()));
+                }
+                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
+            }
+        };
+        Page<GasFlux> pageResult = gasFluxRepository.findAll(specification,pageable);
+        return pageResult;
+    }
+
+    @Override
+    public List<GasFlux> listYesterday() {
+        // 获取当前时间
+        LocalDateTime now = LocalDateTime.now();
+        // 获取昨天的日期
+        LocalDateTime yesterday = now.minusDays(1);
+        // 获取昨天的0点时间(即凌晨)
+        LocalDateTime yesterdayStart = LocalDateTime.of(yesterday.toLocalDate(), LocalTime.MIN);
+        // 获取昨天的24点时间(即今天的凌晨)
+        LocalDateTime yesterdayEnd = LocalDateTime.of(yesterday.toLocalDate(), LocalTime.MAX);
+        Specification<GasFlux> specification = new Specification<GasFlux>() {
+            @Override
+            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
+                Set<Predicate> predicateList = new HashSet<>();
+                predicateList.add(criteriaBuilder.between(root.get("time").as(LocalDateTime.class),yesterdayStart,yesterdayEnd));
+                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
+            }
+        };
+        List<GasFlux> gasFluxes = gasFluxRepository.findAll(specification);
+        return gasFluxes;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasThresholdServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasThresholdServiceImpl.java
new file mode 100644
index 0000000..1df8a20
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasThresholdServiceImpl.java
@@ -0,0 +1,93 @@
+package com.gkhy.fourierSpecialGasMonitor.service.impl;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.decorator.WarningThresholdUpdateEvent;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.User;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.enums.UserStatusEnum;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa.UserRepository;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasThreshold;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UpdateGasThresholdReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UpdateRegionReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.resp.GasThresholdListRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.repository.GasThresholdRepository;
+import com.gkhy.fourierSpecialGasMonitor.service.DataReceiveService;
+import com.gkhy.fourierSpecialGasMonitor.service.GasThresholdService;
+import com.gkhy.fourierSpecialGasMonitor.utils.ThreadLocalUtil;
+import io.micrometer.core.instrument.util.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 14:33
+ */
+@Service
+public class GasThresholdServiceImpl implements GasThresholdService {
+
+
+    @Autowired
+    private GasThresholdRepository gasThresholdRepository;
+
+    @Autowired
+    private ApplicationEventPublisher applicationEventPublisher;
+
+    @Autowired
+    private UserRepository userRepository;
+
+    private User getCurrentUser(){
+        Long userId = ThreadLocalUtil.get().getId();
+        User user = userRepository.findUserByIdAndStatus(userId, UserStatusEnum.STATUS_ACTIVE.getStatus());
+        if (user == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"未成功获取用户信息");
+        return user;
+    }
+
+    @Override
+    public Result gasThresholdList() {
+        Result success = Result.success();
+        List<GasThreshold> gasThresholds = gasThresholdRepository.findAll();
+        if (!CollectionUtils.isEmpty(gasThresholds)){
+            List<GasThresholdListRespDTO> respDTOS = new ArrayList<>();
+            BeanUtils.copyProperties(gasThresholds,respDTOS);
+            success.setData(respDTOS);
+        }
+        return success;
+    }
+
+    @Override
+    public synchronized Result updateGasThreshold(UpdateGasThresholdReqDTO reqDto) {
+        User currentUser = getCurrentUser();
+        if (reqDto == null || reqDto.getId() == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        if (reqDto.getThreshold() <= 0)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"连续超过阈值点数不能小于0");
+        Optional<GasThreshold> thresholdRepositoryById = gasThresholdRepository.findById(reqDto.getId());
+        if (!thresholdRepositoryById.isPresent())
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"预警该配置不存在");
+        GasThreshold threshold = thresholdRepositoryById.get();
+        threshold.setThreshold(reqDto.getThreshold());
+        threshold.setGmtModified(LocalDateTime.now());
+        threshold.setLastmodifiedby(currentUser.getRealName());
+        GasThreshold save = gasThresholdRepository.save(threshold);
+        if (save == null)
+            throw new BusinessException(this.getClass(), ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"预警设置修改失败");
+        applicationEventPublisher.publishEvent(new WarningThresholdUpdateEvent("事件源--预警阈值发生变更"));
+        return Result.success();
+    }
+
+    @Override
+    public List<GasThreshold> findAll() {
+        return gasThresholdRepository.findAll();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasWarnLogServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasWarnLogServiceImpl.java
new file mode 100644
index 0000000..1846dd5
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasWarnLogServiceImpl.java
@@ -0,0 +1,163 @@
+package com.gkhy.fourierSpecialGasMonitor.service.impl;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.User;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.enums.UserStatusEnum;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa.UserRepository;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasWarnLog;
+import com.gkhy.fourierSpecialGasMonitor.entity.MonitorDailyReport;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindDailyReportPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindGasWarnLogPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.resp.FindDailyReportPageRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.resp.FindGasWarnLogPageRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.resp.FindGasWarnLogSmsUserPageRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.enums.WarnHandleStatusEnum;
+import com.gkhy.fourierSpecialGasMonitor.repository.GasWarnLogRepository;
+import com.gkhy.fourierSpecialGasMonitor.service.GasWarnLogService;
+import com.gkhy.fourierSpecialGasMonitor.utils.ThreadLocalUtil;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.temporal.TemporalAdjusters;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 16:47
+ */
+@Service
+public class GasWarnLogServiceImpl implements GasWarnLogService {
+
+    @Autowired
+    private GasWarnLogRepository gasWarnLogRepository;
+
+    @Autowired
+    private UserRepository userRepository;
+
+    private User getCurrentUser(){
+        Long userId = ThreadLocalUtil.get().getId();
+        User user = userRepository.findUserByIdAndStatus(userId, UserStatusEnum.STATUS_ACTIVE.getStatus());
+        if (user == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"未成功获取用户信息");
+        return user;
+    }
+
+    @Override
+    public Result findGasWarnLogPage(PageQuery<FindGasWarnLogPageQuery> pageQuery) {
+        if (pageQuery == null || pageQuery.getPageIndex() == null || pageQuery.getPageSize() == null){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL,"分页参数不能为空");
+        }
+        Pageable pageable = PageRequest.of(pageQuery.getPageIndex()-1, pageQuery.getPageSize(), Sort.Direction.DESC, "warnTime");
+        Specification<GasWarnLog> specification = new Specification<GasWarnLog>() {
+            @Override
+            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
+                Set<Predicate> predicateList = new HashSet<>();
+                FindGasWarnLogPageQuery searchParams = pageQuery.getSearchParams();
+                if (searchParams != null && searchParams.getStartTime() != null && searchParams.getEndTime() != null){
+                    predicateList.add(criteriaBuilder.between(root.get("gmtCreate").as(LocalDateTime.class),searchParams.getStartTime(),searchParams.getEndTime()));
+                }
+                if (searchParams != null && searchParams.getStatus() != null){
+                    predicateList.add(criteriaBuilder.equal(root.get("status").as(Byte.class), searchParams.getStatus()));
+                }
+                if (searchParams != null && searchParams.getGasCategoryId() != null){
+                    predicateList.add(criteriaBuilder.equal(root.get("gasCategoryId").as(Integer.class), searchParams.getGasCategoryId()));
+                }
+                if (searchParams != null && searchParams.getGasThresholdId() != null){
+                    predicateList.add(criteriaBuilder.equal(root.get("gasThresholdId").as(Long.class), searchParams.getGasThresholdId()));
+                }
+                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
+            }
+        };
+        SearchResult<List<FindGasWarnLogPageRespDTO>> searchResult = new SearchResult<>();
+        searchResult.setPageIndex(pageQuery.getPageIndex());
+        searchResult.setPageSize(pageQuery.getPageSize());
+        searchResult.setSuccess();
+        Page<GasWarnLog> pageResult = gasWarnLogRepository.findAll(specification,pageable);
+        searchResult.setTotal(pageResult.getTotalElements());
+        searchResult.setPages(pageResult.getTotalPages());
+        if (!CollectionUtils.isEmpty(pageResult.getContent())){
+            List<FindGasWarnLogPageRespDTO> respDTOS = pageResult.getContent().stream().map(gasWarnLog -> {
+                FindGasWarnLogPageRespDTO dto = new FindGasWarnLogPageRespDTO();
+                BeanUtils.copyProperties(gasWarnLog, dto);
+                if (!CollectionUtils.isEmpty(gasWarnLog.getGasWarnLogSmsUsers())) {
+                    List<FindGasWarnLogSmsUserPageRespDTO> gasWarnLogSmsUsers = new ArrayList<>();
+                    BeanUtils.copyProperties(gasWarnLog.getGasWarnLogSmsUsers(), gasWarnLogSmsUsers);
+                    dto.setGasWarnLogSmsUsers(gasWarnLogSmsUsers);
+                }
+                return dto;
+            }).collect(Collectors.toList());
+            searchResult.setData(respDTOS);
+        }
+        return searchResult;
+    }
+
+    @Override
+    public Result handleGasWarnLog(Long id) {
+        User currentUser = getCurrentUser();
+        if (id == null){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL,"参数不能为空");
+        }
+        GasWarnLog gasWarnLog = gasWarnLogRepository.findByIdAndStatus(id, WarnHandleStatusEnum.HANDLE_NO.getStatus());
+        if (gasWarnLog == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL,"预警信息不存在");
+        gasWarnLog.setHandlerId(currentUser.getId());
+        gasWarnLog.setHandlerName(currentUser.getName());
+        gasWarnLog.setHandlerRealName(currentUser.getRealName());
+        gasWarnLog.setHandlerTime(LocalDateTime.now());
+        gasWarnLog.setStatus(WarnHandleStatusEnum.HANDLE_YES.getStatus());
+        GasWarnLog save = gasWarnLogRepository.save(gasWarnLog);
+        if (save == null)
+            throw new BusinessException(this.getClass(), ResultCode.SYSTEM_ERROR_DATABASE_FAIL,"预警信息处理失败");
+        return Result.success();
+    }
+
+    @Override
+    public GasWarnLog save(GasWarnLog gasWarnLog) {
+        return gasWarnLogRepository.save(gasWarnLog);
+    }
+
+    @Override
+    public List<GasWarnLog> listYesterday() {
+        // 获取当前时间
+        LocalDateTime now = LocalDateTime.now();
+        // 获取昨天的日期
+        LocalDateTime yesterday = now.minusDays(1);
+        // 获取昨天的0点时间(即凌晨)
+        LocalDateTime yesterdayStart = LocalDateTime.of(yesterday.toLocalDate(), LocalTime.MIN);
+        // 获取昨天的24点时间(即今天的凌晨)
+        LocalDateTime yesterdayEnd = LocalDateTime.of(yesterday.toLocalDate(), LocalTime.MAX);
+        Specification<GasWarnLog> specification = new Specification<GasWarnLog>() {
+            @Override
+            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
+                Set<Predicate> predicateList = new HashSet<>();
+                predicateList.add(criteriaBuilder.between(root.get("warnTime").as(LocalDateTime.class),yesterdayStart,yesterdayEnd));
+                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
+            }
+        };
+        List<GasWarnLog> warnLogs = gasWarnLogRepository.findAll(specification);
+        return warnLogs;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasWarnLogSmsUserServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasWarnLogSmsUserServiceImpl.java
new file mode 100644
index 0000000..5d87867
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasWarnLogSmsUserServiceImpl.java
@@ -0,0 +1,26 @@
+package com.gkhy.fourierSpecialGasMonitor.service.impl;
+
+import com.gkhy.fourierSpecialGasMonitor.entity.GasWarnLogSmsUser;
+import com.gkhy.fourierSpecialGasMonitor.repository.GasWarnLogSmsUserRepository;
+import com.gkhy.fourierSpecialGasMonitor.service.GasWarnLogSmsUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 16:24
+ */
+@Service
+public class GasWarnLogSmsUserServiceImpl implements GasWarnLogSmsUserService {
+
+    @Autowired
+    private GasWarnLogSmsUserRepository gasWarnLogSmsUserRepository;
+
+    @Override
+    public List<GasWarnLogSmsUser> saveAll(List<GasWarnLogSmsUser> gasWarnLogSmsUsers) {
+        return gasWarnLogSmsUserRepository.saveAll(gasWarnLogSmsUsers);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasWarnUserServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasWarnUserServiceImpl.java
new file mode 100644
index 0000000..bc219a2
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/GasWarnUserServiceImpl.java
@@ -0,0 +1,184 @@
+package com.gkhy.fourierSpecialGasMonitor.service.impl;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.User;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.enums.UserStatusEnum;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa.UserRepository;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasCategory;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasThreshold;
+import com.gkhy.fourierSpecialGasMonitor.entity.GasWarnUser;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindGasCategoryPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindGasWarnUserPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.CreateGasWarnUserReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.DelGasWarnUserByIdReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.UpdateGasWarnUserReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.resp.FindGasCategoryPageRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.resp.FindGasWarnUserPageRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.enums.DeleteStatusEnum;
+import com.gkhy.fourierSpecialGasMonitor.repository.GasWarnUserRepository;
+import com.gkhy.fourierSpecialGasMonitor.service.GasWarnUserService;
+import com.gkhy.fourierSpecialGasMonitor.utils.ThreadLocalUtil;
+import io.micrometer.core.instrument.util.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 15:00
+ */
+@Service
+public class GasWarnUserServiceImpl implements GasWarnUserService {
+
+    @Autowired
+    private UserRepository userRepository;
+
+    @Autowired
+    private GasWarnUserRepository gasWarnUserRepository;
+
+    private static ReentrantLock gasWarnUserIdlock = new ReentrantLock();
+
+    private User getCurrentUser(){
+        Long userId = ThreadLocalUtil.get().getId();
+        User user = userRepository.findUserByIdAndStatus(userId, UserStatusEnum.STATUS_ACTIVE.getStatus());
+        if (user == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"未成功获取用户信息");
+        return user;
+    }
+
+    @Override
+    public Result createGasWarnUser(CreateGasWarnUserReqDTO reqDto) {
+        if (reqDto == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        if (StringUtils.isBlank(reqDto.getName()))
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"预警通知人员用户名不能为空");
+        if (StringUtils.isBlank(reqDto.getRealName()))
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"预警通知人员真实姓名不能为空");
+        if (StringUtils.isBlank(reqDto.getPhone()))
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"预警通知人员手机号不能为空");
+
+        gasWarnUserIdlock.lock();
+        try {
+            GasWarnUser byUserIdAndStatus = gasWarnUserRepository.findByUserIdAndStatus(reqDto.getUserId(), DeleteStatusEnum.DELECT_NO.getStatus());
+            if (byUserIdAndStatus != null)
+                throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "预警通知人员已存在");
+            GasWarnUser gasWarnUser = new GasWarnUser();
+            BeanUtils.copyProperties(reqDto, gasWarnUser);
+            gasWarnUser.setStatus(DeleteStatusEnum.DELECT_NO.getStatus());
+            gasWarnUser.setGmtModified(LocalDateTime.now());
+            gasWarnUser.setGmtCreate(LocalDateTime.now());
+            gasWarnUser.setLastmodifiedby(getCurrentUser().getRealName());
+            gasWarnUser.setCreatedby(getCurrentUser().getRealName());
+            GasWarnUser save = gasWarnUserRepository.save(gasWarnUser);
+            if (save == null)
+                throw new BusinessException(this.getClass(), ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(), "预警通知人员保存失败");
+        }finally {
+            gasWarnUserIdlock.unlock();
+        }
+        return Result.success();
+    }
+
+    @Override
+    public Result delGasWarnUserById(DelGasWarnUserByIdReqDTO reqDto) {
+        if (reqDto == null || reqDto.getId() == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        GasWarnUser gasWarnUser = gasWarnUserRepository.findByIdAndStatus(reqDto.getId(), DeleteStatusEnum.DELECT_NO.getStatus());
+        if (gasWarnUser != null){
+            gasWarnUser.setStatus(DeleteStatusEnum.DELECT_YES.getStatus());
+            gasWarnUser.setLastmodifiedby(getCurrentUser().getRealName());
+            gasWarnUser.setGmtModified(LocalDateTime.now());
+            GasWarnUser save = gasWarnUserRepository.save(gasWarnUser);
+            if (save == null)
+                throw new BusinessException(this.getClass(), ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"预警通知人员删除失败");
+        }
+        return Result.success();
+    }
+
+    @Override
+    public Result updateGasWarnUser(UpdateGasWarnUserReqDTO reqDto) {
+        if (reqDto == null || reqDto.getId() == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        if (StringUtils.isBlank(reqDto.getName()))
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"预警通知人员用户名不能为空");
+        if (StringUtils.isBlank(reqDto.getRealName()))
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"预警通知人员真实姓名不能为空");
+        if (StringUtils.isBlank(reqDto.getPhone()))
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"预警通知人员手机号不能为空");
+
+        gasWarnUserIdlock.lock();
+        try {
+            GasWarnUser gasWarnUser = gasWarnUserRepository.findByUserIdAndStatus(reqDto.getUserId(), DeleteStatusEnum.DELECT_NO.getStatus());
+            if (gasWarnUser != null && !reqDto.getUserId().equals(gasWarnUser.getUserId()))
+                throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "预警通知人员已存在");
+            BeanUtils.copyProperties(reqDto, gasWarnUser);
+            gasWarnUser.setGmtModified(LocalDateTime.now());
+            gasWarnUser.setLastmodifiedby(getCurrentUser().getRealName());
+            GasWarnUser save = gasWarnUserRepository.save(gasWarnUser);
+            if (save == null)
+                throw new BusinessException(this.getClass(), ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(), "预警通知人员更新失败");
+        }finally {
+            gasWarnUserIdlock.unlock();
+        }
+        return Result.success();
+    }
+
+    @Override
+    public Result findGasWarnUserPage(PageQuery<FindGasWarnUserPageQuery> pageQuery) {
+        if (pageQuery == null || pageQuery.getPageIndex() == null || pageQuery.getPageSize() == null){
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL,"分页参数不能为空");
+        }
+        Pageable pageable = PageRequest.of(pageQuery.getPageIndex()-1, pageQuery.getPageSize());
+        Specification<GasWarnUser> specification = new Specification<GasWarnUser>() {
+            @Override
+            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
+                Set<Predicate> predicateList = new HashSet<>();
+                FindGasWarnUserPageQuery searchParams = pageQuery.getSearchParams();
+                if (searchParams != null && !StringUtils.isBlank(searchParams.getRealName())){
+                    predicateList.add(criteriaBuilder.like(root.get("realName").as(String.class),"%"+searchParams.getRealName()+"%"));
+                }
+                predicateList.add(criteriaBuilder.equal(root.get("status").as(Byte.class), DeleteStatusEnum.DELECT_NO.getStatus()));
+                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
+            }
+        };
+        SearchResult<List<FindGasWarnUserPageRespDTO>> searchResult = new SearchResult<>();
+        searchResult.setPageIndex(pageQuery.getPageIndex());
+        searchResult.setPageSize(pageQuery.getPageSize());
+        searchResult.setSuccess();
+        Page<GasWarnUser> pageResult = gasWarnUserRepository.findAll(specification,pageable);
+        searchResult.setTotal(pageResult.getTotalElements());
+        searchResult.setPages(pageResult.getTotalPages());
+        if (!CollectionUtils.isEmpty(pageResult.getContent())){
+            List<FindGasWarnUserPageRespDTO> respDTOS = new ArrayList<>();
+            BeanUtils.copyProperties(pageResult.getContent(),respDTOS);
+            searchResult.setData(respDTOS);
+        }
+        return searchResult;
+    }
+
+    @Override
+    public List<GasWarnUser> findAll() {
+        List<GasWarnUser> gasWarnUsers = gasWarnUserRepository.findAllByStatus(DeleteStatusEnum.DELECT_NO.getStatus());
+        return gasWarnUsers;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/MonitorDailyReportServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/MonitorDailyReportServiceImpl.java
new file mode 100644
index 0000000..e369f7c
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/MonitorDailyReportServiceImpl.java
@@ -0,0 +1,85 @@
+package com.gkhy.fourierSpecialGasMonitor.service.impl;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.MonitorDailyReport;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindDailyReportPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindRegionPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.resp.FindDailyReportPageRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.repository.MonitorDailyReportRepository;
+import com.gkhy.fourierSpecialGasMonitor.service.MonitorDailyReportService;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import javax.persistence.criteria.*;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.temporal.TemporalAdjusters;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 15:44
+ */
+@Service
+public class MonitorDailyReportServiceImpl implements MonitorDailyReportService {
+
+    @Autowired
+    private MonitorDailyReportRepository monitorDailyReportRepository;
+
+    @Override
+    public Result findDailyReportPage(PageQuery<FindDailyReportPageQuery> pageQuery) {
+        if (pageQuery == null || pageQuery.getPageIndex() == null || pageQuery.getPageSize() == null){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL,"分页参数不能为空");
+        }
+        Pageable pageable = PageRequest.of(pageQuery.getPageIndex()-1, pageQuery.getPageSize(), Sort.Direction.DESC, "gmtCreate");
+        Specification<MonitorDailyReport> specification = new Specification<MonitorDailyReport>() {
+            @Override
+            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
+                Set<Predicate> predicateList = new HashSet<>();
+                FindDailyReportPageQuery searchParams = pageQuery.getSearchParams();
+                if (searchParams != null && searchParams.getYear() != null && searchParams.getMonth() != null){
+                    // 获取指定月份的第一天
+                    LocalDate firstDayOfMonth = LocalDate.of(searchParams.getYear(), searchParams.getMonth(), 1);
+                    // 获取指定月份的最后一天
+                    LocalDate lastDayOfMonth = LocalDate.of(searchParams.getYear(), searchParams.getMonth(), 1).with(TemporalAdjusters.lastDayOfMonth());
+                    predicateList.add(criteriaBuilder.between(root.get("gmtCreate").as(LocalDateTime.class),firstDayOfMonth,lastDayOfMonth));
+                }
+                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
+            }
+        };
+        SearchResult<List<FindDailyReportPageRespDTO>> searchResult = new SearchResult<>();
+        searchResult.setPageIndex(pageQuery.getPageIndex());
+        searchResult.setPageSize(pageQuery.getPageSize());
+        searchResult.setSuccess();
+        Page<MonitorDailyReport> pageResult = monitorDailyReportRepository.findAll(specification,pageable);
+        searchResult.setTotal(pageResult.getTotalElements());
+        searchResult.setPages(pageResult.getTotalPages());
+        if (!CollectionUtils.isEmpty(pageResult.getContent())){
+            List<FindDailyReportPageRespDTO> respDTOS = new ArrayList<>();
+            BeanUtils.copyProperties(pageResult.getContent(),respDTOS);
+            searchResult.setData(respDTOS);
+        }
+        return searchResult;
+    }
+
+    @Override
+    public MonitorDailyReport save(MonitorDailyReport report) {
+        return monitorDailyReportRepository.save(report);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/MonitorDataServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/MonitorDataServiceImpl.java
new file mode 100644
index 0000000..59a4821
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/MonitorDataServiceImpl.java
@@ -0,0 +1,377 @@
+package com.gkhy.fourierSpecialGasMonitor.service.impl;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.*;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.GasAtmospherePageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.GasFluxPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.GasPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.GasAtmosphereLineChartReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.GasFluxLineChartReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.GasLineChartReqDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.resp.*;
+import com.gkhy.fourierSpecialGasMonitor.service.*;
+import io.micrometer.core.instrument.util.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.lang.reflect.Field;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/10 9:16
+ */
+@Service
+public class MonitorDataServiceImpl implements MonitorDataService {
+
+    private LocalDateTime zeroTime = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0);
+
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    private LocalDateTime nowTime = LocalDateTime.now();
+
+    @Autowired
+    private GasCategoryService gasCategoryService;
+
+    @Autowired
+    private GasFluxService gasFluxService;
+
+    @Autowired
+    private RegionService regionService;
+
+    @Autowired
+    private GasConcentrationService gasConcentrationService;
+
+    @Override
+    public Result gasLineChart(GasLineChartReqDTO reqDto) {
+        Result success = Result.success();
+        if (reqDto == null || reqDto.getGasName() == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        LocalDateTime startTime = reqDto.getStartTime();
+        LocalDateTime endTime = reqDto.getEndTime();
+        if (startTime == null || endTime == null){
+            startTime = zeroTime;
+            endTime = nowTime;
+        }
+        List<GasConcentration> gasConcentrationList =  gasConcentrationService.listDatabyTimeSlot(startTime,endTime);
+        if (CollectionUtils.isEmpty(gasConcentrationList))
+            return success;
+        GasCategory gasCategory = gasCategoryService.findById(reqDto.getGasName());
+        if (gasCategory == null){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"暂无该气体实时数据");
+        }
+        String fileNamePrefix = "gasValue";
+        String fileName = fileNamePrefix + reqDto.getGasName();
+        if (reqDto.getGasName() < 10){
+            fileName = fileNamePrefix +"0"+ reqDto.getGasName();
+        }
+        String fileNameTemp = fileName;
+        List<GasLineChartRespDTO> respDTOS = gasConcentrationList.stream().map(gasConcentration -> {
+            GasLineChartRespDTO gasLineChartRespDTO = new GasLineChartRespDTO();
+            BeanUtils.copyProperties(gasCategory, gasLineChartRespDTO);
+            BeanUtils.copyProperties(gasConcentration, gasLineChartRespDTO);
+            gasLineChartRespDTO.setGasName(reqDto.getGasName());
+            Field[] fields = gasConcentration.getClass().getDeclaredFields();
+            for (Field field : fields) {
+                field.setAccessible(true);  // 设置字段可访问,即使是私有字段
+                if (field.getName().equals(fileNameTemp)) {
+                    Double value = null;
+                    try {
+                        value = (Double) field.get(gasConcentration);
+                        gasLineChartRespDTO.setGasValue(value);
+                    } catch (IllegalAccessException e) {
+                        logger.info("【警告】气体浓度折线图反射获取气体浓度失败");
+                    }
+                }
+            }
+            return gasLineChartRespDTO;
+        }).collect(Collectors.toList());
+        success.setData(respDTOS);
+        return success;
+    }
+
+    @Override
+    public Result gasPage(PageQuery<GasPageQuery> pageQuery) {
+        if (pageQuery == null || pageQuery.getPageIndex() == null || pageQuery.getPageSize() == null){
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL,"分页参数不能为空");
+        }
+        if (pageQuery == null || pageQuery.getSearchParams() == null || pageQuery.getSearchParams().getGasName() == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        GasPageQuery searchParams = pageQuery.getSearchParams();
+        Integer gasName = searchParams.getGasName();
+        LocalDateTime startTime = searchParams.getStartTime();
+        LocalDateTime endTime = searchParams.getEndTime();
+        if (startTime == null || endTime == null){
+            searchParams.setStartTime(zeroTime);
+            searchParams.setEndTime(nowTime);
+        }
+
+        SearchResult<List<GasPageRespDTO>> searchResult = new SearchResult<>();
+        searchResult.setPageIndex(pageQuery.getPageIndex());
+        searchResult.setPageSize(pageQuery.getPageSize());
+        searchResult.setSuccess();
+        Page<GasConcentration> pageResult =  gasConcentrationService.listDatabyTimeSlotAndPage(pageQuery);
+        if (CollectionUtils.isEmpty(pageResult.getContent()))
+            return searchResult;
+        searchResult.setTotal(pageResult.getTotalElements());
+        searchResult.setPages(pageResult.getTotalPages());
+        GasCategory gasCategory = gasCategoryService.findById(gasName);
+        if (gasCategory == null){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"暂无该气体实时数据");
+        }
+        String fileNamePrefix = "gasValue";
+        String fileName = fileNamePrefix + gasName;
+        if (gasName < 10){
+            fileName = fileNamePrefix +"0"+ gasName;
+        }
+        String fileNameTemp = fileName;
+        List<GasPageRespDTO> respDTOS = pageResult.getContent().stream().map(gasConcentration -> {
+            GasPageRespDTO gasLineChartRespDTO = new GasPageRespDTO();
+            BeanUtils.copyProperties(gasCategory, gasLineChartRespDTO);
+            BeanUtils.copyProperties(gasConcentration, gasLineChartRespDTO);
+            gasLineChartRespDTO.setGasName(gasName);
+            Field[] fields = gasConcentration.getClass().getDeclaredFields();
+            for (Field field : fields) {
+                field.setAccessible(true);  // 设置字段可访问,即使是私有字段
+                if (field.getName().equals(fileNameTemp)) {
+                    Double value = null;
+                    try {
+                        value = (Double) field.get(gasConcentration);
+                        gasLineChartRespDTO.setGasValue(value);
+                    } catch (IllegalAccessException e) {
+                        logger.info("【警告】气体浓度分页-反射获取气体浓度失败");
+                    }
+                }
+            }
+            return gasLineChartRespDTO;
+        }).collect(Collectors.toList());
+        searchResult.setData(respDTOS);
+        return searchResult;
+    }
+
+    @Override
+    public Result gasFluxLineChart(GasFluxLineChartReqDTO reqDto) {
+        Result success = Result.success();
+        if (reqDto == null || reqDto.getGasName() == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        LocalDateTime startTime = reqDto.getStartTime();
+        LocalDateTime endTime = reqDto.getEndTime();
+        if (startTime == null || endTime == null){
+            startTime = zeroTime;
+            endTime = nowTime;
+        }
+        List<GasFlux> gasFluxes =  gasFluxService.listDatabyTimeSlotAndAreaId(startTime,endTime,reqDto.getAreaId());
+        if (CollectionUtils.isEmpty(gasFluxes))
+            return success;
+        GasCategory gasCategory = gasCategoryService.findById(reqDto.getGasName());
+        if (gasCategory == null){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"暂无该气体通量数据");
+        }
+
+        List<Region> regions = regionService.findAll();
+        if (CollectionUtils.isEmpty(regions)){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"无法获取区域信息");
+        }
+        Map<Integer, Region> regionMap = regions.stream().collect(Collectors.toMap(Region::getId, r -> r));
+        String fileNamePrefix = "gasValue";
+        String fileName = fileNamePrefix + reqDto.getGasName();
+        if (reqDto.getGasName() < 10){
+            fileName = fileNamePrefix +"0"+ reqDto.getGasName();
+        }
+        String fileNameTemp = fileName;
+        List<GasFluxLineChartRespDTO> respDTOS = gasFluxes.stream().map(gasFlux -> {
+            GasFluxLineChartRespDTO gasFluxLineChartRespDTO = new GasFluxLineChartRespDTO();
+            BeanUtils.copyProperties(gasCategory, gasFluxLineChartRespDTO);
+            BeanUtils.copyProperties(gasFlux, gasFluxLineChartRespDTO);
+            if (regionMap.get(gasFlux.getAreaId()) != null){
+                Region region = regionMap.get(gasFlux.getAreaId());
+                BeanUtils.copyProperties(region,gasFluxLineChartRespDTO,"name");
+                gasFluxLineChartRespDTO.setRegionName(region.getName());
+            }
+            gasFluxLineChartRespDTO.setGasName(reqDto.getGasName());
+            Field[] fields = gasFlux.getClass().getDeclaredFields();
+            for (Field field : fields) {
+                field.setAccessible(true);  // 设置字段可访问,即使是私有字段
+                if (field.getName().equals(fileNameTemp)) {
+                    Double value = null;
+                    try {
+                        value = (Double) field.get(gasFlux);
+                        gasFluxLineChartRespDTO.setGasValue(value);
+                    } catch (IllegalAccessException e) {
+                        logger.info("【警告】气体通量折线图反射获取气体浓度失败");
+                    }
+                }
+            }
+            return gasFluxLineChartRespDTO;
+        }).collect(Collectors.toList());
+        success.setData(respDTOS);
+        return success;
+    }
+
+    @Override
+    public Result gasFluxPage(PageQuery<GasFluxPageQuery> pageQuery) {
+        if (pageQuery == null || pageQuery.getPageIndex() == null || pageQuery.getPageSize() == null){
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL,"分页参数不能为空");
+        }
+        if (pageQuery == null || pageQuery.getSearchParams() == null || pageQuery.getSearchParams().getGasName() == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        GasFluxPageQuery searchParams = pageQuery.getSearchParams();
+        Integer gasName = searchParams.getGasName();
+        LocalDateTime startTime = searchParams.getStartTime();
+        LocalDateTime endTime = searchParams.getEndTime();
+        if (startTime == null || endTime == null){
+            searchParams.setStartTime(zeroTime);
+            searchParams.setEndTime(nowTime);
+        }
+        SearchResult<List<GasFluxPageRespDTO>> searchResult = new SearchResult<>();
+        searchResult.setPageIndex(pageQuery.getPageIndex());
+        searchResult.setPageSize(pageQuery.getPageSize());
+        searchResult.setSuccess();
+        Page<GasFlux> pageResult =  gasFluxService.listDatabyTimeSlotAndPage(pageQuery);
+        if (CollectionUtils.isEmpty(pageResult.getContent()))
+            return searchResult;
+        searchResult.setTotal(pageResult.getTotalElements());
+        searchResult.setPages(pageResult.getTotalPages());
+        GasCategory gasCategory = gasCategoryService.findById(gasName);
+        if (gasCategory == null){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"暂无该气体实时数据");
+        }
+        List<Region> regions = regionService.findAll();
+        if (CollectionUtils.isEmpty(regions)){
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"无法获取区域信息");
+        }
+        Map<Integer, Region> regionMap = regions.stream().collect(Collectors.toMap(Region::getId, r -> r));
+        String fileNamePrefix = "gasValue";
+        String fileName = fileNamePrefix + gasName;
+        if (gasName < 10){
+            fileName = fileNamePrefix +"0"+ gasName;
+        }
+        String fileNameTemp = fileName;
+        List<GasFluxPageRespDTO> respDTOS = pageResult.getContent().stream().map(gasFlux -> {
+            GasFluxPageRespDTO gasFluxPageRespDTO = new GasFluxPageRespDTO();
+            BeanUtils.copyProperties(gasCategory, gasFluxPageRespDTO);
+            BeanUtils.copyProperties(gasFlux, gasFluxPageRespDTO);
+            if (regionMap.get(gasFlux.getAreaId()) != null){
+                Region region = regionMap.get(gasFlux.getAreaId());
+                BeanUtils.copyProperties(region,gasFluxPageRespDTO,"name");
+                gasFluxPageRespDTO.setRegionName(region.getName());
+            }
+            gasFluxPageRespDTO.setGasName(pageQuery.getSearchParams().getGasName());
+            Field[] fields = gasFlux.getClass().getDeclaredFields();
+            for (Field field : fields) {
+                field.setAccessible(true);  // 设置字段可访问,即使是私有字段
+                if (field.getName().equals(fileNameTemp)) {
+                    Double value = null;
+                    try {
+                        value = (Double) field.get(gasFlux);
+                        gasFluxPageRespDTO.setGasValue(value);
+                    } catch (IllegalAccessException e) {
+                        logger.info("【警告】气体通量分页数据-反射获取气体浓度失败");
+                    }
+                }
+            }
+            return gasFluxPageRespDTO;
+        }).collect(Collectors.toList());
+        searchResult.setData(respDTOS);
+        return searchResult;
+    }
+
+    @Override
+    public Result gasAtmosphereLineChart(GasAtmosphereLineChartReqDTO reqDto) {
+        Result success = Result.success();
+        if (reqDto == null || StringUtils.isEmpty(reqDto.getAtmosphere()))
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        LocalDateTime startTime = reqDto.getStartTime();
+        LocalDateTime endTime = reqDto.getEndTime();
+        if (startTime == null || endTime == null){
+            startTime = zeroTime;
+            endTime = nowTime;
+        }
+        List<GasConcentration> gasConcentrations =  gasConcentrationService.listDatabyTimeSlot(startTime,endTime);
+        if (CollectionUtils.isEmpty(gasConcentrations))
+            return success;
+        List<GasAtmosphereLineChartRespDTO> respDTOS = gasConcentrations.stream().map(gasConcentration -> {
+            GasAtmosphereLineChartRespDTO gasAtmosphereLineChartRespDTO = new GasAtmosphereLineChartRespDTO();
+            gasAtmosphereLineChartRespDTO.setTime(gasConcentration.getTime());
+            Field[] fields = gasConcentration.getClass().getDeclaredFields();
+            for (Field field : fields) {
+                field.setAccessible(true);  // 设置字段可访问,即使是私有字段
+                if (field.getName().equals(reqDto.getAtmosphere())) {
+                    Double value = null;
+                    try {
+                        value = (Double) field.get(gasConcentration);
+                        gasAtmosphereLineChartRespDTO.setValue(value);
+                    } catch (IllegalAccessException e) {
+                        logger.info("【警告】气象折线图反射获取气体浓度失败");
+                    }
+                }
+            }
+            return gasAtmosphereLineChartRespDTO;
+        }).collect(Collectors.toList());
+        success.setData(respDTOS);
+        return success;
+    }
+
+
+    @Override
+    public Result gasAtmospherePage(PageQuery<GasAtmospherePageQuery> pageQuery) {
+        if (pageQuery == null || pageQuery.getPageIndex() == null || pageQuery.getPageSize() == null){
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL,"分页参数不能为空");
+        }
+        if (pageQuery == null || pageQuery.getSearchParams() == null || StringUtils.isEmpty(pageQuery.getSearchParams().getAtmosphere()))
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        GasAtmospherePageQuery searchParams = pageQuery.getSearchParams();
+        String atmosphere = searchParams.getAtmosphere();
+        LocalDateTime startTime = searchParams.getStartTime();
+        LocalDateTime endTime = searchParams.getEndTime();
+        if (startTime == null || endTime == null){
+            searchParams.setStartTime(zeroTime);
+            searchParams.setEndTime(nowTime);
+        }
+
+        SearchResult<List<GasAtmospherePageRespDTO>> searchResult = new SearchResult<>();
+        searchResult.setPageIndex(pageQuery.getPageIndex());
+        searchResult.setPageSize(pageQuery.getPageSize());
+        searchResult.setSuccess();
+        Page<GasConcentration> pageResult =  gasConcentrationService.gasAtmospherePage(pageQuery);
+        if (CollectionUtils.isEmpty(pageResult.getContent()))
+            return searchResult;
+        searchResult.setTotal(pageResult.getTotalElements());
+        searchResult.setPages(pageResult.getTotalPages());
+
+        List<GasAtmospherePageRespDTO> respDTOS = pageResult.getContent().stream().map(gasConcentration -> {
+            GasAtmospherePageRespDTO gasAtmospherePageRespDTO = new GasAtmospherePageRespDTO();
+            gasAtmospherePageRespDTO.setTime(gasConcentration.getTime());
+            Field[] fields = gasConcentration.getClass().getDeclaredFields();
+            for (Field field : fields) {
+                field.setAccessible(true);  // 设置字段可访问,即使是私有字段
+                if (field.getName().equals(atmosphere)) {
+                    Double value = null;
+                    try {
+                        value = (Double) field.get(gasConcentration);
+                        gasAtmospherePageRespDTO.setValue(value);
+                    } catch (IllegalAccessException e) {
+                        logger.info("【警告】气象折线图反射获取气体浓度失败");
+                    }
+                }
+            }
+            return gasAtmospherePageRespDTO;
+        }).collect(Collectors.toList());
+        searchResult.setData(respDTOS);
+        return searchResult;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/RegionServiceImpl.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/RegionServiceImpl.java
new file mode 100644
index 0000000..8678626
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/RegionServiceImpl.java
@@ -0,0 +1,234 @@
+package com.gkhy.fourierSpecialGasMonitor.service.impl;
+
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
+import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult;
+import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
+import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException;
+import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.User;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.enums.UserStatusEnum;
+import com.gkhy.fourierSpecialGasMonitor.domain.account.repository.jpa.UserRepository;
+import com.gkhy.fourierSpecialGasMonitor.entity.Region;
+import com.gkhy.fourierSpecialGasMonitor.entity.RegionLngLat;
+import com.gkhy.fourierSpecialGasMonitor.entity.query.FindRegionPageQuery;
+import com.gkhy.fourierSpecialGasMonitor.entity.req.*;
+import com.gkhy.fourierSpecialGasMonitor.entity.resp.FindRegionByIdRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.resp.FindRegionLngLatPageRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.entity.resp.FindRegionPageRespDTO;
+import com.gkhy.fourierSpecialGasMonitor.enums.DeleteStatusEnum;
+import com.gkhy.fourierSpecialGasMonitor.repository.RegionLngLatRepository;
+import com.gkhy.fourierSpecialGasMonitor.repository.RegionRepository;
+import com.gkhy.fourierSpecialGasMonitor.service.RegionService;
+import com.gkhy.fourierSpecialGasMonitor.utils.ThreadLocalUtil;
+import io.micrometer.core.instrument.util.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import javax.persistence.criteria.*;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.stream.Collectors;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/8/9 10:46
+ */
+@Service
+public class RegionServiceImpl implements RegionService {
+
+    @Autowired
+    private UserRepository userRepository;
+
+    @Autowired
+    private RegionRepository regionRepository;
+
+    @Autowired
+    private RegionLngLatRepository regionLngLatRepository;
+
+    private static final ReentrantLock regionNamelock = new ReentrantLock();
+
+    private User getCurrentUser(){
+        Long userId = ThreadLocalUtil.get().getId();
+        User user = userRepository.findUserByIdAndStatus(userId, UserStatusEnum.STATUS_ACTIVE.getStatus());
+        if (user == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"未成功获取用户信息");
+        return user;
+    }
+
+    @Override
+    public Result createRegion(CreateRegionReqDTO reqDto) {
+        User currentUser = getCurrentUser();
+        if (reqDto == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        if (StringUtils.isBlank(reqDto.getName()))
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"区域名称为空");
+        if (StringUtils.isBlank(reqDto.getColor()))
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"区域颜色不能为空");
+        if (CollectionUtils.isEmpty(reqDto.getRegionLngLats()) || reqDto.getRegionLngLats().size() < 3)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"经纬度数据不能为空或个数少于3");
+        regionNamelock.lock();
+        try {
+            Region regionold = findByNameAndStatus(reqDto.getName());
+            if (regionold != null)
+                throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"区域名称已存在");
+            Region region = new Region();
+            BeanUtils.copyProperties(reqDto,region);
+            region.setCreatedby(currentUser.getRealName());
+            region.setLastmodifiedby(currentUser.getRealName());
+            region.setStatus(DeleteStatusEnum.DELECT_NO.getStatus());
+            region.setGmtCreate(LocalDateTime.now());
+            region.setGmtModified(LocalDateTime.now());
+            Region save = regionRepository.save(region);
+            if (save == null)
+                throw new BusinessException(this.getClass(), ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"区域保存失败");
+            List<CreateRegionLngLatReqDTO> regionLngLats = reqDto.getRegionLngLats();
+            List<RegionLngLat> collect = regionLngLats.stream().map(regionLngLat -> {
+                RegionLngLat lngLat = new RegionLngLat();
+                BeanUtils.copyProperties(regionLngLat, lngLat);
+                lngLat.setRegionId(save.getId());
+                return lngLat;
+            }).collect(Collectors.toList());
+            List<RegionLngLat> lats = regionLngLatRepository.saveAll(collect);
+            if (CollectionUtils.isEmpty(lats))
+                throw new BusinessException(this.getClass(), ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"区域相关经纬度保存失败");
+        }finally {
+            regionNamelock.unlock();
+        }
+
+        return Result.success();
+    }
+
+    @Override
+    public Result delRegionById(DelRegionByIdReqDTO reqDto) {
+        User currentUser = getCurrentUser();
+        if (reqDto == null || reqDto.getId() == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        Region region = regionRepository.findByIdAndStatus(reqDto.getId(), DeleteStatusEnum.DELECT_NO.getStatus());
+        if (region == null){
+            return Result.success();
+        }
+        region.setStatus(DeleteStatusEnum.DELECT_YES.getStatus());
+        region.setLastmodifiedby(currentUser.getRealName());
+        region.setGmtModified(LocalDateTime.now());
+        Region save = regionRepository.save(region);
+        if (save == null)
+            throw new BusinessException(this.getClass(), ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"区域删除失败");
+        return Result.success();
+    }
+
+    @Override
+    public Result findRegionById(Integer id) {
+        Result success = Result.success();
+        if (id == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        Region region = regionRepository.findByIdAndStatus(id, DeleteStatusEnum.DELECT_NO.getStatus());
+        if (region != null){
+            List<RegionLngLat> regionLngLats = region.getRegionLngLats();
+            if (!CollectionUtils.isEmpty(regionLngLats)){
+                List<FindRegionByIdRespDTO> respDTOS = new ArrayList<>();
+                BeanUtils.copyProperties(regionLngLats,respDTOS);
+                success.setData(respDTOS);
+            }
+        }
+        return success;
+    }
+
+    @Override
+    public Result findRegionPage(PageQuery<FindRegionPageQuery> pageQuery) {
+        if (pageQuery == null || pageQuery.getPageIndex() == null || pageQuery.getPageSize() == null){
+            throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL,"分页参数不能为空");
+        }
+        Pageable pageable = PageRequest.of(pageQuery.getPageIndex()-1, pageQuery.getPageSize());
+        Specification<Region> specification = new Specification<Region>() {
+            @Override
+            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
+                Set<Predicate> predicateList = new HashSet<>();
+                FindRegionPageQuery searchParams = pageQuery.getSearchParams();
+                if (searchParams != null && !StringUtils.isBlank(searchParams.getName())){
+                    predicateList.add(criteriaBuilder.like(root.get("name").as(String.class),"%"+searchParams.getName()+"%"));
+                }
+                predicateList.add(criteriaBuilder.equal(root.get("deleteStatus").as(Byte.class), DeleteStatusEnum.DELECT_NO.getStatus()));
+                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
+            }
+        };
+        SearchResult<List<FindRegionPageRespDTO>> searchResult = new SearchResult<>();
+        searchResult.setPageIndex(pageQuery.getPageIndex());
+        searchResult.setPageSize(pageQuery.getPageSize());
+        searchResult.setSuccess();
+        Page<Region> pageResult = regionRepository.findAll(specification,pageable);
+        searchResult.setTotal(pageResult.getTotalElements());
+        searchResult.setPages(pageResult.getTotalPages());
+        if (!CollectionUtils.isEmpty(pageResult.getContent())){
+            List<FindRegionPageRespDTO> dtos = pageResult.getContent().stream().map(region -> {
+                FindRegionPageRespDTO dto = new FindRegionPageRespDTO();
+                BeanUtils.copyProperties(region, dto);
+                List<FindRegionLngLatPageRespDTO> regionLngLatPageRespDTOS = new ArrayList<>();
+                BeanUtils.copyProperties(region.getRegionLngLats(), regionLngLatPageRespDTOS);
+                dto.setRegionLngLats(regionLngLatPageRespDTOS);
+                return dto;
+            }).collect(Collectors.toList());
+            searchResult.setData(dtos);
+        }
+        return searchResult;
+    }
+
+    @Override
+    @Transactional
+    public Result updateRegion(UpdateRegionReqDTO reqDto) {
+        User currentUser = getCurrentUser();
+        if (reqDto == null)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"参数不能为空");
+        if (StringUtils.isBlank(reqDto.getName()))
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"区域名称为空");
+        if (StringUtils.isBlank(reqDto.getColor()))
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"区域颜色不能为空");
+        if (CollectionUtils.isEmpty(reqDto.getRegionLngLats()) || reqDto.getRegionLngLats().size() < 3)
+            throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(),"经纬度数据不能为空或个数少于3");
+        regionNamelock.lock();
+        try {
+            Region regionold = findByNameAndStatus(reqDto.getName());
+            if (regionold != null && !regionold.getId().equals(reqDto.getId()))
+                throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL.getCode(), "区域名称已存在");
+            regionold.setName(reqDto.getName());
+            regionold.setColor(reqDto.getColor());
+            regionold.setLastmodifiedby(currentUser.getRealName());
+            regionold.setGmtModified(LocalDateTime.now());
+            regionLngLatRepository.deleteAllByRegionId(reqDto.getId());
+            List<UpdateRegionLngLatReqDTO> regionLngLats = reqDto.getRegionLngLats();
+            List<RegionLngLat> collect = regionLngLats.stream().map(regionLngLat -> {
+                RegionLngLat lngLat = new RegionLngLat();
+                BeanUtils.copyProperties(regionLngLat, lngLat);
+                lngLat.setRegionId(reqDto.getId());
+                return lngLat;
+            }).collect(Collectors.toList());
+            List<RegionLngLat> lats = regionLngLatRepository.saveAll(collect);
+            if (CollectionUtils.isEmpty(lats))
+                throw new BusinessException(this.getClass(), ResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(), "区域相关经纬度保存失败");
+        }finally {
+            regionNamelock.unlock();
+        }
+        return Result.success();
+    }
+
+    @Override
+    public List<Region> findAll() {
+        List<Region> regions = regionRepository.findAllByStatus(DeleteStatusEnum.DELECT_NO.getStatus());
+        return regions;
+    }
+
+    private Region findByNameAndStatus(String name){
+        return regionRepository.findByNameAndStatus(name, DeleteStatusEnum.DELECT_NO.getStatus());
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/utils/SendMessageUtil.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/utils/SendMessageUtil.java
new file mode 100644
index 0000000..9099176
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/utils/SendMessageUtil.java
@@ -0,0 +1,49 @@
+package com.gkhy.fourierSpecialGasMonitor.utils;
+
+import com.qiniu.common.QiniuException;
+import com.qiniu.http.Response;
+import com.qiniu.sms.SmsManager;
+import com.qiniu.util.Auth;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+@Component
+public class SendMessageUtil {
+
+    private static final Logger log = LoggerFactory.getLogger(SendMessageUtil.class);
+
+    @Value("${qiniuymes.accesskey}")
+    private String accesskey;
+
+    @Value("${qiniuymes.secretkey}")
+    private String secretkey;
+
+    @Value("${qiniuymes.templateid}")
+    private String templateid;
+ 
+    /**
+     * 发送短信提示
+     */
+    @Async("SocketTaskExecutor")
+    public Boolean sendMessageCheck(String[] phone, Map<String, String> map){
+        Auth auth = Auth.create(accesskey, secretkey);
+        SmsManager smsManager = new SmsManager(auth);
+        try {
+            Response resp = smsManager.sendMessage(templateid, phone , map);
+            if(resp.statusCode == 200){
+                return true;
+            }else {
+                log.info("短信发送状态码非200:【"+resp.statusCode+"】");
+                return false;
+            }
+        } catch (QiniuException e) {
+            log.info("发生短信异常 =======================" ,e);
+        }
+        return false;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/utils/ThreadLocalUtil.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/utils/ThreadLocalUtil.java
new file mode 100644
index 0000000..b06ca5f
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/utils/ThreadLocalUtil.java
@@ -0,0 +1,28 @@
+package com.gkhy.fourierSpecialGasMonitor.utils;
+
+import com.gkhy.fourierSpecialGasMonitor.domain.account.entity.User;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/7/11 13:38
+ */
+public class ThreadLocalUtil {
+
+    public final static ThreadLocal<User> USER_THREAD_LOCAL = new ThreadLocal<>();
+
+    //存入线程中
+    public static void set(User user){
+        USER_THREAD_LOCAL.set(user);
+    }
+
+    //从线程中获取
+    public static User get(){
+        return  USER_THREAD_LOCAL.get();
+    }
+
+    //将存入的数据移除
+    public static void clear(){
+        USER_THREAD_LOCAL.remove();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/GasConcentrationExcWebsocketServer.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/GasConcentrationExcWebsocketServer.java
new file mode 100644
index 0000000..6a52921
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/GasConcentrationExcWebsocketServer.java
@@ -0,0 +1,172 @@
+package com.gkhy.fourierSpecialGasMonitor.websocket;
+
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import io.micrometer.core.instrument.util.StringUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.websocket.*;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Slf4j
+@ServerEndpoint("/gas/exc/{userId}")
+@Component
+public class GasConcentrationExcWebsocketServer {
+
+    /**
+     * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的
+     */
+    private static int onlineCount = 0;
+
+    /**
+     * concurrent 包的线程安全Set,用来存放每个客户端对应的 myWebSocket对象
+     * 根据userId来获取对应的 WebSocket
+     */
+    private static ConcurrentHashMap<String, GasConcentrationExcWebsocketServer> webSocketMap = new ConcurrentHashMap<>();
+
+    /**
+     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
+     */
+    private Session session;
+
+    /**
+     * 接收 sid
+     */
+    private String userId = "";
+
+
+    /**
+     * 连接建立成功调用的方法
+     *
+     * @param session
+     * @param userId
+     */
+    @OnOpen
+    public void onOpen(Session session, @PathParam("userId") String userId) {
+        this.session = session;
+        this.userId = userId;
+
+        webSocketMap.put(userId, this);
+        log.info("webSocketMap -> " + JSON.toJSONString(webSocketMap));
+
+        addOnlineCount(); // 在线数 +1
+        log.info("【气体浓度异常】有新窗口开始监听:" + userId + ",当前在线人数为" + getOnlineCount());
+
+        try {
+            sendMessage(JSON.toJSONString("【气体浓度异常】连接成功"));
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new RuntimeException("【气体浓度异常】websocket IO异常!!!!");
+        }
+
+    }
+
+    /**
+     * 关闭连接
+     */
+
+    @OnClose
+    public void onClose() {
+        if (webSocketMap.get(this.userId) != null) {
+            webSocketMap.remove(this.userId);
+            subOnlineCount(); // 人数 -1
+            log.info("【气体浓度异常】有一连接关闭,当前在线人数为:" + getOnlineCount());
+        }
+    }
+
+    /**
+     * 收到客户端消息后调用的方法
+     *
+     * @param message 客户端发送过来的消息
+     * @param session
+     */
+    @OnMessage
+    public void onMessage(String message, Session session) {
+        log.info("收到来自窗口" + userId + "的信息:" + message);
+
+        if (StringUtils.isNotBlank(message)) {
+            try {
+                // 解析发送的报文
+                JSONObject jsonObject = JSON.parseObject(message);
+                // 追加发送人(防窜改)
+                jsonObject.put("fromUserId", this.userId);
+                String toUserId = jsonObject.getString("toUserId");
+                // 传送给对应 toUserId 用户的 WebSocket
+                if (StringUtils.isNotBlank(toUserId) && webSocketMap.containsKey(toUserId)) {
+                    webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString());
+                } else {
+                    log.info("请求的userId:" + toUserId + "不在该服务器上"); // 否则不在这个服务器上,发送到 MySQL 或者 Redis
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+    }
+
+    /**
+     * @param session
+     * @param error
+     */
+    @OnError
+    public void onError(Session session, Throwable error) {
+        log.error("用户错误:" + this.userId + ",原因:" + error.getMessage());
+        error.printStackTrace();
+    }
+
+    /**
+     * 实现服务器主动推送
+     *
+     * @param message
+     * @throws IOException
+     */
+    public void sendMessage(String message) throws IOException {
+        this.session.getBasicRemote().sendText(message);
+    }
+
+    /**
+     * 群发自定义消息
+     *
+     * @param message
+     * @param userId
+     * @throws IOException
+     */
+    public static void sendInfo(String message, @PathParam("userId") String userId) throws IOException {
+
+        // 遍历集合,可设置为推送给指定sid,为 null 时发送给所有人
+        Iterator entrys = webSocketMap.entrySet().iterator();
+        while (entrys.hasNext()) {
+            Map.Entry entry = (Map.Entry) entrys.next();
+
+            if (userId == null) {
+                webSocketMap.get(entry.getKey()).sendMessage(message);
+                log.info("【气体浓度异常】发送消息到:" + entry.getKey() + ",消息:" + message);
+            } else if (entry.getKey().equals(userId)) {
+                webSocketMap.get(entry.getKey()).sendMessage(message);
+                log.info("【气体浓度异常】发送消息到:" + entry.getKey() + ",消息:" + message);
+            }
+
+        }
+
+
+    }
+
+    private static synchronized int getOnlineCount() {
+        return onlineCount;
+    }
+
+    private static synchronized void addOnlineCount() {
+        GasConcentrationExcWebsocketServer.onlineCount++;
+    }
+
+    private static synchronized void subOnlineCount() {
+        GasConcentrationExcWebsocketServer.onlineCount--;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/GasConcentrationWebsocketServer.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/GasConcentrationWebsocketServer.java
new file mode 100644
index 0000000..cb7acd8
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/GasConcentrationWebsocketServer.java
@@ -0,0 +1,171 @@
+package com.gkhy.fourierSpecialGasMonitor.websocket;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import io.micrometer.core.instrument.util.StringUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.websocket.*;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Slf4j
+@ServerEndpoint("/gas/{userId}")
+@Component
+public class GasConcentrationWebsocketServer {
+
+    /**
+     * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的
+     */
+    private static int onlineCount = 0;
+
+    /**
+     * concurrent 包的线程安全Set,用来存放每个客户端对应的 myWebSocket对象
+     * 根据userId来获取对应的 WebSocket
+     */
+    private static ConcurrentHashMap<String, GasConcentrationWebsocketServer> webSocketMap = new ConcurrentHashMap<>();
+
+    /**
+     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
+     */
+    private Session session;
+
+    /**
+     * 接收 sid
+     */
+    private String userId = "";
+
+
+    /**
+     * 连接建立成功调用的方法
+     *
+     * @param session
+     * @param userId
+     */
+    @OnOpen
+    public void onOpen(Session session, @PathParam("userId") String userId) {
+        this.session = session;
+        this.userId = userId;
+
+        webSocketMap.put(userId, this);
+        log.info("webSocketMap -> " + JSON.toJSONString(webSocketMap));
+
+        addOnlineCount(); // 在线数 +1
+        log.info("【气体浓度实时推送】有新窗口开始监听:" + userId + ",当前在线人数为" + getOnlineCount());
+
+        try {
+            sendMessage(JSON.toJSONString("【气体浓度实时推送】连接成功"));
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new RuntimeException("【气体浓度实时推送】websocket IO异常!!!!");
+        }
+
+    }
+
+    /**
+     * 关闭连接
+     */
+
+    @OnClose
+    public void onClose() {
+        if (webSocketMap.get(this.userId) != null) {
+            webSocketMap.remove(this.userId);
+            subOnlineCount(); // 人数 -1
+            log.info("【气体浓度实时推送】有一连接关闭,当前在线人数为:" + getOnlineCount());
+        }
+    }
+
+    /**
+     * 收到客户端消息后调用的方法
+     *
+     * @param message 客户端发送过来的消息
+     * @param session
+     */
+    @OnMessage
+    public void onMessage(String message, Session session) {
+        log.info("收到来自窗口" + userId + "的信息:" + message);
+
+        if (StringUtils.isNotBlank(message)) {
+            try {
+                // 解析发送的报文
+                JSONObject jsonObject = JSON.parseObject(message);
+                // 追加发送人(防窜改)
+                jsonObject.put("fromUserId", this.userId);
+                String toUserId = jsonObject.getString("toUserId");
+                // 传送给对应 toUserId 用户的 WebSocket
+                if (StringUtils.isNotBlank(toUserId) && webSocketMap.containsKey(toUserId)) {
+                    webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString());
+                } else {
+                    log.info("请求的userId:" + toUserId + "不在该服务器上"); // 否则不在这个服务器上,发送到 MySQL 或者 Redis
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+    }
+
+    /**
+     * @param session
+     * @param error
+     */
+    @OnError
+    public void onError(Session session, Throwable error) {
+        log.error("用户错误:" + this.userId + ",原因:" + error.getMessage());
+        error.printStackTrace();
+    }
+
+    /**
+     * 实现服务器主动推送
+     *
+     * @param message
+     * @throws IOException
+     */
+    public void sendMessage(String message) throws IOException {
+        this.session.getBasicRemote().sendText(message);
+    }
+
+    /**
+     * 群发自定义消息
+     *
+     * @param message
+     * @param userId
+     * @throws IOException
+     */
+    public static void sendInfo(String message, @PathParam("userId") String userId) throws IOException {
+
+        // 遍历集合,可设置为推送给指定sid,为 null 时发送给所有人
+        Iterator entrys = webSocketMap.entrySet().iterator();
+        while (entrys.hasNext()) {
+            Map.Entry entry = (Map.Entry) entrys.next();
+
+            if (userId == null) {
+                webSocketMap.get(entry.getKey()).sendMessage(message);
+                log.info("【气体浓度实时推送】发送消息到:" + entry.getKey() + ",消息:" + message);
+            } else if (entry.getKey().equals(userId)) {
+                webSocketMap.get(entry.getKey()).sendMessage(message);
+                log.info("【气体浓度实时推送】发送消息到:" + entry.getKey() + ",消息:" + message);
+            }
+
+        }
+
+
+    }
+
+    private static synchronized int getOnlineCount() {
+        return onlineCount;
+    }
+
+    private static synchronized void addOnlineCount() {
+        GasConcentrationWebsocketServer.onlineCount++;
+    }
+
+    private static synchronized void subOnlineCount() {
+        GasConcentrationWebsocketServer.onlineCount--;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/GasDeviceExcWebsocketServer.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/GasDeviceExcWebsocketServer.java
new file mode 100644
index 0000000..9f0050c
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/GasDeviceExcWebsocketServer.java
@@ -0,0 +1,171 @@
+package com.gkhy.fourierSpecialGasMonitor.websocket;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import io.micrometer.core.instrument.util.StringUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.websocket.*;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Slf4j
+@ServerEndpoint("/gas/device/exc/{userId}")
+@Component
+public class GasDeviceExcWebsocketServer {
+
+    /**
+     * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的
+     */
+    private static int onlineCount = 0;
+
+    /**
+     * concurrent 包的线程安全Set,用来存放每个客户端对应的 myWebSocket对象
+     * 根据userId来获取对应的 WebSocket
+     */
+    private static ConcurrentHashMap<String, GasDeviceExcWebsocketServer> webSocketMap = new ConcurrentHashMap<>();
+
+    /**
+     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
+     */
+    private Session session;
+
+    /**
+     * 接收 sid
+     */
+    private String userId = "";
+
+
+    /**
+     * 连接建立成功调用的方法
+     *
+     * @param session
+     * @param userId
+     */
+    @OnOpen
+    public void onOpen(Session session, @PathParam("userId") String userId) {
+        this.session = session;
+        this.userId = userId;
+
+        webSocketMap.put(userId, this);
+        log.info("webSocketMap -> " + JSON.toJSONString(webSocketMap));
+
+        addOnlineCount(); // 在线数 +1
+        log.info("【气体设备状态异常】有新窗口开始监听:" + userId + ",当前在线人数为" + getOnlineCount());
+
+        try {
+            sendMessage(JSON.toJSONString("【气体设备状态异常】连接成功"));
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new RuntimeException("【气体设备状态异常】websocket IO异常!!!!");
+        }
+
+    }
+
+    /**
+     * 关闭连接
+     */
+
+    @OnClose
+    public void onClose() {
+        if (webSocketMap.get(this.userId) != null) {
+            webSocketMap.remove(this.userId);
+            subOnlineCount(); // 人数 -1
+            log.info("【气体设备状态异常】有一连接关闭,当前在线人数为:" + getOnlineCount());
+        }
+    }
+
+    /**
+     * 收到客户端消息后调用的方法
+     *
+     * @param message 客户端发送过来的消息
+     * @param session
+     */
+    @OnMessage
+    public void onMessage(String message, Session session) {
+        log.info("收到来自窗口" + userId + "的信息:" + message);
+
+        if (StringUtils.isNotBlank(message)) {
+            try {
+                // 解析发送的报文
+                JSONObject jsonObject = JSON.parseObject(message);
+                // 追加发送人(防窜改)
+                jsonObject.put("fromUserId", this.userId);
+                String toUserId = jsonObject.getString("toUserId");
+                // 传送给对应 toUserId 用户的 WebSocket
+                if (StringUtils.isNotBlank(toUserId) && webSocketMap.containsKey(toUserId)) {
+                    webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString());
+                } else {
+                    log.info("请求的userId:" + toUserId + "不在该服务器上"); // 否则不在这个服务器上,发送到 MySQL 或者 Redis
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+    }
+
+    /**
+     * @param session
+     * @param error
+     */
+    @OnError
+    public void onError(Session session, Throwable error) {
+        log.error("用户错误:" + this.userId + ",原因:" + error.getMessage());
+        error.printStackTrace();
+    }
+
+    /**
+     * 实现服务器主动推送
+     *
+     * @param message
+     * @throws IOException
+     */
+    public void sendMessage(String message) throws IOException {
+        this.session.getBasicRemote().sendText(message);
+    }
+
+    /**
+     * 群发自定义消息
+     *
+     * @param message
+     * @param userId
+     * @throws IOException
+     */
+    public static void sendInfo(String message, @PathParam("userId") String userId) throws IOException {
+
+        // 遍历集合,可设置为推送给指定sid,为 null 时发送给所有人
+        Iterator entrys = webSocketMap.entrySet().iterator();
+        while (entrys.hasNext()) {
+            Map.Entry entry = (Map.Entry) entrys.next();
+
+            if (userId == null) {
+                webSocketMap.get(entry.getKey()).sendMessage(message);
+                log.info("【气体设备状态异常】发送消息到:" + entry.getKey() + ",消息:" + message);
+            } else if (entry.getKey().equals(userId)) {
+                webSocketMap.get(entry.getKey()).sendMessage(message);
+                log.info("【气体设备状态异常】发送消息到:" + entry.getKey() + ",消息:" + message);
+            }
+
+        }
+
+
+    }
+
+    private static synchronized int getOnlineCount() {
+        return onlineCount;
+    }
+
+    private static synchronized void addOnlineCount() {
+        GasDeviceExcWebsocketServer.onlineCount++;
+    }
+
+    private static synchronized void subOnlineCount() {
+        GasDeviceExcWebsocketServer.onlineCount--;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/GasFluxWebsocketServer.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/GasFluxWebsocketServer.java
new file mode 100644
index 0000000..0671a9f
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/GasFluxWebsocketServer.java
@@ -0,0 +1,171 @@
+package com.gkhy.fourierSpecialGasMonitor.websocket;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import io.micrometer.core.instrument.util.StringUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.websocket.*;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Slf4j
+@ServerEndpoint("/gas/flux/{userId}")
+@Component
+public class GasFluxWebsocketServer {
+
+    /**
+     * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的
+     */
+    private static int onlineCount = 0;
+
+    /**
+     * concurrent 包的线程安全Set,用来存放每个客户端对应的 myWebSocket对象
+     * 根据userId来获取对应的 WebSocket
+     */
+    private static ConcurrentHashMap<String, GasFluxWebsocketServer> webSocketMap = new ConcurrentHashMap<>();
+
+    /**
+     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
+     */
+    private Session session;
+
+    /**
+     * 接收 sid
+     */
+    private String userId = "";
+
+
+    /**
+     * 连接建立成功调用的方法
+     *
+     * @param session
+     * @param userId
+     */
+    @OnOpen
+    public void onOpen(Session session, @PathParam("userId") String userId) {
+        this.session = session;
+        this.userId = userId;
+
+        webSocketMap.put(userId, this);
+        log.info("webSocketMap -> " + JSON.toJSONString(webSocketMap));
+
+        addOnlineCount(); // 在线数 +1
+        log.info("【气体通量实时推送】有新窗口开始监听:" + userId + ",当前在线人数为" + getOnlineCount());
+
+        try {
+            sendMessage(JSON.toJSONString("【气体通量实时推送】连接成功"));
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new RuntimeException("【气体通量实时推送】websocket IO异常!!!!");
+        }
+
+    }
+
+    /**
+     * 关闭连接
+     */
+
+    @OnClose
+    public void onClose() {
+        if (webSocketMap.get(this.userId) != null) {
+            webSocketMap.remove(this.userId);
+            subOnlineCount(); // 人数 -1
+            log.info("【气体通量实时推送】有一连接关闭,当前在线人数为:" + getOnlineCount());
+        }
+    }
+
+    /**
+     * 收到客户端消息后调用的方法
+     *
+     * @param message 客户端发送过来的消息
+     * @param session
+     */
+    @OnMessage
+    public void onMessage(String message, Session session) {
+        log.info("收到来自窗口" + userId + "的信息:" + message);
+
+        if (StringUtils.isNotBlank(message)) {
+            try {
+                // 解析发送的报文
+                JSONObject jsonObject = JSON.parseObject(message);
+                // 追加发送人(防窜改)
+                jsonObject.put("fromUserId", this.userId);
+                String toUserId = jsonObject.getString("toUserId");
+                // 传送给对应 toUserId 用户的 WebSocket
+                if (StringUtils.isNotBlank(toUserId) && webSocketMap.containsKey(toUserId)) {
+                    webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString());
+                } else {
+                    log.info("请求的userId:" + toUserId + "不在该服务器上"); // 否则不在这个服务器上,发送到 MySQL 或者 Redis
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+    }
+
+    /**
+     * @param session
+     * @param error
+     */
+    @OnError
+    public void onError(Session session, Throwable error) {
+        log.error("用户错误:" + this.userId + ",原因:" + error.getMessage());
+        error.printStackTrace();
+    }
+
+    /**
+     * 实现服务器主动推送
+     *
+     * @param message
+     * @throws IOException
+     */
+    public void sendMessage(String message) throws IOException {
+        this.session.getBasicRemote().sendText(message);
+    }
+
+    /**
+     * 群发自定义消息
+     *
+     * @param message
+     * @param userId
+     * @throws IOException
+     */
+    public static void sendInfo(String message, @PathParam("userId") String userId) throws IOException {
+
+        // 遍历集合,可设置为推送给指定sid,为 null 时发送给所有人
+        Iterator entrys = webSocketMap.entrySet().iterator();
+        while (entrys.hasNext()) {
+            Map.Entry entry = (Map.Entry) entrys.next();
+
+            if (userId == null) {
+                webSocketMap.get(entry.getKey()).sendMessage(message);
+                log.info("【气体通量实时推送】发送消息到:" + entry.getKey() + ",消息:" + message);
+            } else if (entry.getKey().equals(userId)) {
+                webSocketMap.get(entry.getKey()).sendMessage(message);
+                log.info("【气体通量实时推送】发送消息到:" + entry.getKey() + ",消息:" + message);
+            }
+
+        }
+
+
+    }
+
+    private static synchronized int getOnlineCount() {
+        return onlineCount;
+    }
+
+    private static synchronized void addOnlineCount() {
+        GasFluxWebsocketServer.onlineCount++;
+    }
+
+    private static synchronized void subOnlineCount() {
+        GasFluxWebsocketServer.onlineCount--;
+    }
+}
diff --git a/src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/HeartbeatExcWebsocketServer.java b/src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/HeartbeatExcWebsocketServer.java
new file mode 100644
index 0000000..abda9b4
--- /dev/null
+++ b/src/main/java/com/gkhy/fourierSpecialGasMonitor/websocket/HeartbeatExcWebsocketServer.java
@@ -0,0 +1,171 @@
+package com.gkhy.fourierSpecialGasMonitor.websocket;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import io.micrometer.core.instrument.util.StringUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.websocket.*;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Slf4j
+@ServerEndpoint("/gas/heartbeat/{userId}")
+@Component
+public class HeartbeatExcWebsocketServer {
+
+    /**
+     * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的
+     */
+    private static int onlineCount = 0;
+
+    /**
+     * concurrent 包的线程安全Set,用来存放每个客户端对应的 myWebSocket对象
+     * 根据userId来获取对应的 WebSocket
+     */
+    private static ConcurrentHashMap<String, HeartbeatExcWebsocketServer> webSocketMap = new ConcurrentHashMap<>();
+
+    /**
+     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
+     */
+    private Session session;
+
+    /**
+     * 接收 sid
+     */
+    private String userId = "";
+
+
+    /**
+     * 连接建立成功调用的方法
+     *
+     * @param session
+     * @param userId
+     */
+    @OnOpen
+    public void onOpen(Session session, @PathParam("userId") String userId) {
+        this.session = session;
+        this.userId = userId;
+
+        webSocketMap.put(userId, this);
+        log.info("webSocketMap -> " + JSON.toJSONString(webSocketMap));
+
+        addOnlineCount(); // 在线数 +1
+        log.info("【气体通量实时推送】有新窗口开始监听:" + userId + ",当前在线人数为" + getOnlineCount());
+
+        try {
+            sendMessage(JSON.toJSONString("【气体通量实时推送】连接成功"));
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new RuntimeException("【气体通量实时推送】websocket IO异常!!!!");
+        }
+
+    }
+
+    /**
+     * 关闭连接
+     */
+
+    @OnClose
+    public void onClose() {
+        if (webSocketMap.get(this.userId) != null) {
+            webSocketMap.remove(this.userId);
+            subOnlineCount(); // 人数 -1
+            log.info("【气体通量实时推送】有一连接关闭,当前在线人数为:" + getOnlineCount());
+        }
+    }
+
+    /**
+     * 收到客户端消息后调用的方法
+     *
+     * @param message 客户端发送过来的消息
+     * @param session
+     */
+    @OnMessage
+    public void onMessage(String message, Session session) {
+        log.info("收到来自窗口" + userId + "的信息:" + message);
+
+        if (StringUtils.isNotBlank(message)) {
+            try {
+                // 解析发送的报文
+                JSONObject jsonObject = JSON.parseObject(message);
+                // 追加发送人(防窜改)
+                jsonObject.put("fromUserId", this.userId);
+                String toUserId = jsonObject.getString("toUserId");
+                // 传送给对应 toUserId 用户的 WebSocket
+                if (StringUtils.isNotBlank(toUserId) && webSocketMap.containsKey(toUserId)) {
+                    webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString());
+                } else {
+                    log.info("请求的userId:" + toUserId + "不在该服务器上"); // 否则不在这个服务器上,发送到 MySQL 或者 Redis
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+    }
+
+    /**
+     * @param session
+     * @param error
+     */
+    @OnError
+    public void onError(Session session, Throwable error) {
+        log.error("用户错误:" + this.userId + ",原因:" + error.getMessage());
+        error.printStackTrace();
+    }
+
+    /**
+     * 实现服务器主动推送
+     *
+     * @param message
+     * @throws IOException
+     */
+    public void sendMessage(String message) throws IOException {
+        this.session.getBasicRemote().sendText(message);
+    }
+
+    /**
+     * 群发自定义消息
+     *
+     * @param message
+     * @param userId
+     * @throws IOException
+     */
+    public static void sendInfo(String message, @PathParam("userId") String userId) throws IOException {
+
+        // 遍历集合,可设置为推送给指定sid,为 null 时发送给所有人
+        Iterator entrys = webSocketMap.entrySet().iterator();
+        while (entrys.hasNext()) {
+            Map.Entry entry = (Map.Entry) entrys.next();
+
+            if (userId == null) {
+                webSocketMap.get(entry.getKey()).sendMessage(message);
+                log.info("【气体通量实时推送】发送消息到:" + entry.getKey() + ",消息:" + message);
+            } else if (entry.getKey().equals(userId)) {
+                webSocketMap.get(entry.getKey()).sendMessage(message);
+                log.info("【气体通量实时推送】发送消息到:" + entry.getKey() + ",消息:" + message);
+            }
+
+        }
+
+
+    }
+
+    private static synchronized int getOnlineCount() {
+        return onlineCount;
+    }
+
+    private static synchronized void addOnlineCount() {
+        HeartbeatExcWebsocketServer.onlineCount++;
+    }
+
+    private static synchronized void subOnlineCount() {
+        HeartbeatExcWebsocketServer.onlineCount--;
+    }
+}
diff --git a/src/main/resources/config/application-dev.yaml b/src/main/resources/config/application-dev.yaml
new file mode 100644
index 0000000..1ae602b
--- /dev/null
+++ b/src/main/resources/config/application-dev.yaml
@@ -0,0 +1,119 @@
+server:
+  port: 9091
+
+spring:
+  #    enable-logging: false
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    url: jdbc:mysql://192.168.0.52:3306/fourier_specialgas_monitor.dev?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&useAffectedRows=true
+    username: gkhy_dev_team
+    password: Sjscn783fsDsa21
+    master:
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      url: jdbc:mysql://192.168.0.52:3306/fourier_specialgas_monitor.dev?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&useAffectedRows=true
+      username: gkhy_dev_team
+      password: Sjscn783fsDsa21
+      type: com.alibaba.druid.pool.DruidDataSource
+  jpa:
+    hibernate:
+      ddl-auto: none
+#      ddl-auto: update #自动更新
+    show-sql: false  #日志中显示sql语句
+
+  redis:
+#    host: 192.168.0.52
+#    port: 6371
+#    password: SEF98uvs98dUAUEF90Udssa      # Redis 服务器密码,默认为空。生产中,一定要设置 Redis 密码!
+#    database: 0           # Redis 数据库号,默认为 0
+#    timeout: 5000        # Redis 连接超时时间,单位:毫秒。
+    redisson:
+      file: classpath:config/redisson-dev.yml
+    lettuce:
+      pool:
+        # 最大连接数
+        max-active: 8
+        min-active: 3
+        # 最大阻塞等待时间(负数表示没限制)
+        max-wait: -1
+        # 最小空闲
+        min-idle: 3
+        # 最大空闲
+        max-idle: 8
+  jackson:
+    default-property-inclusion: non_null
+    date-format: yyyy-MM-dd HH:mm:ss
+    time-zone: GMT+8
+  servlet:
+    multipart:
+      enabled: true
+      max-file-size: 20MB
+      max-request-size: 200MB
+  #不要在控制台输出Spring Data Redis - Could not safely identify store assignment for repository 日志
+  data:
+    redis:
+      repositories:
+        enabled: false
+
+system:
+  deployMode: standalone  #单机部署
+#  deployMode: cluster  #集群部署
+  enableCors: true  #跨域设置
+  token: #token 配置项
+    header: tk
+    expiration: 7200
+    refreshExpiration: 14400
+    loginUserHeader: uid
+    externalAccessHeader: Access-Token
+    externalAccessKey: HG0f40036fe7420230808150035407
+
+#windous测试
+reportfile:
+  path:
+    #基础路径
+    dcPath: E:\file\fourier\test\
+    urlRootPath: /uploadtest/
+
+#windous测试
+file:
+  path:
+    #基础路径
+    dcPath: E:\file\gkhy\test\
+    urlRootPath: /uploadtest/
+    module:
+      #用户模块
+      accountPath: /account/user/
+
+#linux测试
+#file:
+#  path:
+#    #基础路径
+#    dcPath: /home/gkhy/upload/laboratoryRiskManage/
+#    urlRootPath: /upload/
+#    module:
+#      #用户模块
+#      accountPath: /account/user/
+
+#线程池配置
+threadPool:
+  corePoolSize: 20
+  maxPoolSize: 20
+  queueCapacity: 10000
+  scheduling:
+    #控制线程是否执行 true:执行;false:不执行
+    enabled: true
+#    enabled: false
+
+# 七牛云相关信息
+qiniuymes:
+  accesskey: 5YprpjY0BJiyjII2VqlHed7UhBEvvkPZicbwd8Kl
+  secretkey: m3gGQNQ9cLmVBBZwPXZ5-Wzr0duzyAPPmJUx4_ay
+  templateid: 1689091213799469056
+
+#测试环境 短信功能关闭,只在控制台上打印日志
+sms:
+  send:
+    enabled: false
+
+
+
diff --git a/src/main/resources/config/application-online-uat.yaml b/src/main/resources/config/application-online-uat.yaml
new file mode 100644
index 0000000..865402b
--- /dev/null
+++ b/src/main/resources/config/application-online-uat.yaml
@@ -0,0 +1,96 @@
+erver:
+  port: 16070
+
+spring:
+  #    enable-logging: false
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    url: jdbc:mysql://121.239.169.30:33306/laboratory_risk_manage.uat?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&useAffectedRows=true
+    username: root
+    password: e7be93ef5413e5ed
+    master:
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      url: jdbc:mysql://121.239.169.30:33306/laboratory_risk_manage.uat?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&useAffectedRows=true
+      username: root
+      password: e7be93ef5413e5ed
+      type: com.alibaba.druid.pool.DruidDataSource
+  jpa: 
+    hibernate: 
+      ddl-auto: none
+#      ddl-auto: update #自动更新
+    show-sql: true  #日志中显示sql语句
+
+  redis:
+#    host: 192.168.0.52
+#    port: 6371
+#    password: SEF98uvs98dUAUEF90Udssa      # Redis 服务器密码,默认为空。生产中,一定要设置 Redis 密码!
+#    database: 0           # Redis 数据库号,默认为 0
+#    timeout: 5000        # Redis 连接超时时间,单位:毫秒。
+    redisson:
+      file: classpath:config/redisson-online-uat.yml
+    lettuce:
+      pool:
+        # 最大连接数
+        max-active: 8
+        min-active: 3
+        # 最大阻塞等待时间(负数表示没限制)
+        max-wait: -1
+        # 最小空闲
+        min-idle: 3
+        # 最大空闲
+        max-idle: 8
+  jackson:
+    default-property-inclusion: non_null
+    date-format: yyyy-MM-dd HH:mm:ss
+    time-zone: GMT+8
+  #不要在控制台输出Spring Data Redis - Could not safely identify store assignment for repository 日志
+  data:
+    redis:
+      repositories:
+        enabled: false
+
+
+system:
+  deployMode: standalone  #单机部署
+#  deployMode: cluster  #集群部署
+  enableCors: true  #跨域设置
+  token: #token 配置项
+    header: tk
+    expiration: 7200
+    refreshExpiration: 14400
+    loginUserHeader: uid
+    externalAccessHeader: Access-Token
+    externalAccessKey: HG0f40036fe7420230808150035407
+
+file:
+    path:
+      #基础路径
+      dcPath: /home/upload/laboratoryRiskManage/
+      urlRootPath: /upload/
+      module:
+        #用户模块
+        accountPath: /account/user/
+
+#线程池配置
+threadPool:
+  corePoolSize: 20
+  maxPoolSize: 20
+  queueCapacity: 10000
+  scheduling:
+    #控制线程是否执行 true:执行;false:不执行
+    enabled: true
+#    enabled: false
+
+# 七牛云相关信息
+qiniuymes:
+  accesskey: 5YprpjY0BJiyjII2VqlHed7UhBEvvkPZicbwd8Kl
+  secretkey: m3gGQNQ9cLmVBBZwPXZ5-Wzr0duzyAPPmJUx4_ay
+  templateid: 1689091213799469056
+
+#测试环境 短信功能关闭,只在控制台上打印日志
+sms:
+  send:
+    enabled: true
+
+
diff --git a/src/main/resources/config/application.yaml b/src/main/resources/config/application.yaml
new file mode 100644
index 0000000..6065d42
--- /dev/null
+++ b/src/main/resources/config/application.yaml
@@ -0,0 +1,6 @@
+spring:
+  application:
+    name: fourierSpecialGasMonitor
+  profiles:
+    active: dev
+#    active: online-uat
diff --git a/src/main/resources/config/redisson-dev.yml b/src/main/resources/config/redisson-dev.yml
new file mode 100644
index 0000000..2772d7b
--- /dev/null
+++ b/src/main/resources/config/redisson-dev.yml
@@ -0,0 +1,42 @@
+singleServerConfig:
+  #  连接空闲超时,单位:毫秒
+  idleConnectionTimeout: 100000
+  #  连接超时,单位:毫秒
+  connectTimeout: 10000
+  #  命令等待超时,单位:毫秒
+  timeout: 3000
+  #  命令失败重试次数
+  retryAttempts: 3
+  #  命令重试发送时间间隔,单位:毫秒
+  retryInterval: 1500
+  #  密码
+  password: root
+  #  单个连接最大订阅数量
+  subscriptionsPerConnection: 5
+  #  客户端名称
+#  clientName: null
+  #  节点地址
+  address: redis://127.0.0.1:6379
+#  #  发布和订阅连接的最小空闲连接数
+#  subscriptionConnectionMinimumIdleSize: 1
+#  #  发布和订阅连接池大小
+#  subscriptionConnectionPoolSize: 50
+  #  最小空闲连接数
+  connectionMinimumIdleSize: 4
+  #  连接池大小
+  connectionPoolSize: 8
+  #  redis数据库编号
+  database: 0
+  #  DNS监测时间间隔,单位:毫秒
+  dnsMonitoringInterval: 5000
+#  线程池数量
+threads: 8
+#  Netty线程池数量
+nettyThreads: 4
+#  编码
+codec:
+  class: "org.redisson.codec.JsonJacksonCodec"
+#  传输模式
+transportMode: "NIO"
+#  配置看门狗的默认超时时间为30s,这里改为10s
+lockWatchdogTimeout: 10000
\ No newline at end of file
diff --git a/src/main/resources/config/redisson-online-uat.yml b/src/main/resources/config/redisson-online-uat.yml
new file mode 100644
index 0000000..c071833
--- /dev/null
+++ b/src/main/resources/config/redisson-online-uat.yml
@@ -0,0 +1,42 @@
+singleServerConfig:
+  #  连接空闲超时,单位:毫秒
+  idleConnectionTimeout: 100000
+  #  连接超时,单位:毫秒
+  connectTimeout: 10000
+  #  命令等待超时,单位:毫秒
+  timeout: 3000
+  #  命令失败重试次数
+  retryAttempts: 3
+  #  命令重试发送时间间隔,单位:毫秒
+  retryInterval: 1500
+  #  密码
+  password: akj78avauba789a
+  #  单个连接最大订阅数量
+  subscriptionsPerConnection: 5
+  #  客户端名称
+#  clientName: null
+  #  节点地址
+  address: redis://127.0.0.1:6379
+#  #  发布和订阅连接的最小空闲连接数
+#  subscriptionConnectionMinimumIdleSize: 1
+#  #  发布和订阅连接池大小
+#  subscriptionConnectionPoolSize: 50
+  #  最小空闲连接数
+  connectionMinimumIdleSize: 4
+  #  连接池大小
+  connectionPoolSize: 8
+  #  redis数据库编号
+  database: 0
+  #  DNS监测时间间隔,单位:毫秒
+  dnsMonitoringInterval: 5000
+#  线程池数量
+threads: 8
+#  Netty线程池数量
+nettyThreads: 4
+#  编码
+codec:
+  class: "org.redisson.codec.JsonJacksonCodec"
+#  传输模式
+transportMode: "NIO"
+#  配置看门狗的默认超时时间为30s,这里改为10s
+lockWatchdogTimeout: 10000
\ No newline at end of file
diff --git a/src/main/resources/template/dailyReportTemplate.docx b/src/main/resources/template/dailyReportTemplate.docx
new file mode 100644
index 0000000..bffd0c4
--- /dev/null
+++ b/src/main/resources/template/dailyReportTemplate.docx
Binary files differ

--
Gitblit v1.9.2