From f8dfb4f52d4c1b22fa447b5262d99858dd66bc5a Mon Sep 17 00:00:00 2001 From: GoblinsWang <806586736@qq.com> Date: Thu, 23 Mar 2023 11:26:57 +0800 Subject: [PATCH] first commit --- .gitignore | 35 + README.md | 9 + doc/face.PDM | 9554 +++++++++++++++++ doc/face.pdb | 9530 ++++++++++++++++ doc/数据库变更字段-2020-01-07.sql | 7 + docker-compose.yml | 57 + docker-compose1.yml | 77 + face-common/pom.xml | 126 + .../com/dkha/common/CommonApplication.java | 19 + .../java/com/dkha/common/consul/BaseLock.java | 71 + .../java/com/dkha/common/consul/CheckTtl.java | 89 + .../java/com/dkha/common/consul/Lock.java | 84 + .../com/dkha/common/enums/ApiUrlEnum.java | 42 + .../common/enums/BoardAndLodgingEnums.java | 19 + .../dkha/common/enums/CompanyCheckEnums.java | 22 + .../common/enums/CompanyMessageEnums.java | 19 + .../common/enums/ContractFileStausEnums.java | 18 + .../common/enums/ContractStatusEnums.java | 19 + .../com/dkha/common/enums/ContractType.java | 18 + .../com/dkha/common/enums/ContralEnums.java | 44 + .../com/dkha/common/enums/DictTypeEnums.java | 42 + .../dkha/common/enums/EmployeeChannel.java | 39 + .../java/com/dkha/common/enums/ErrEnum.java | 35 + .../common/enums/ExpiryTimeTypeEnums.java | 22 + .../dkha/common/enums/IndustryTypeEnum.java | 30 + .../dkha/common/enums/IsOnWorkingEnums.java | 14 + .../com/dkha/common/enums/IsPoorEnums.java | 13 + .../dkha/common/enums/LaborMessageEnms.java | 20 + .../java/com/dkha/common/enums/MsgEnums.java | 34 + .../com/dkha/common/enums/OpinionEnums.java | 22 + .../common/enums/PlatformDictTypeEnum.java | 23 + .../dkha/common/enums/PlatformTypeEnum.java | 21 + .../com/dkha/common/enums/ProjectType.java | 19 + .../java/com/dkha/common/enums/SEXEnums.java | 30 + .../com/dkha/common/enums/SocketEnum.java | 28 + .../com/dkha/common/enums/TaskStatuEnum.java | 29 + .../com/dkha/common/enums/TaskStatusEnum.java | 23 + .../enums/TrainingAssessmentStatus.java | 15 + .../java/com/dkha/common/enums/YNEnums.java | 20 + .../com/dkha/common/enums/YNNumberEnum.java | 20 + .../common/exception/AuthorityException.java | 27 + .../exception/DkAuthorityException.java | 27 + .../dkha/common/exception/DkException.java | 78 + .../common/exception/EmployeeException.java | 25 + .../com/dkha/common/fileupload/MinioUtil.java | 391 + .../java/com/dkha/common/http/ConfigBean.java | 25 + .../java/com/dkha/common/http/HttpUtil.java | 175 + .../com/dkha/common/jwt/JwtConstantEnum.java | 22 + .../java/com/dkha/common/jwt/JwtHelper.java | 97 + .../dkha/common/kaptcha/KaptchaConfig.java | 39 + .../com/dkha/common/modules/vo/ApiVO.java | 34 + .../com/dkha/common/modules/vo/ReturnVO.java | 150 + .../vo/camera/AssociationPeopleVO.java | 32 + .../modules/vo/camera/BayOnetCameraVO.java | 48 + .../modules/vo/camera/CameraInfoVO.java | 27 + .../modules/vo/camera/PeopleComparableVO.java | 44 + .../common/modules/vo/camera/PeopleVO.java | 35 + .../vo/control/ControlTaskVedioVO.java | 42 + .../common/modules/vo/control/ControlVO.java | 43 + .../modules/vo/control/TaskControlVO.java | 84 + .../modules/vo/control/VideoControlVo.java | 48 + .../com/dkha/common/modules/vo/cut/CutVo.java | 24 + .../common/modules/vo/dto/FaceLibraryVO.java | 39 + .../common/modules/vo/dto/ImageListVO.java | 35 + .../dkha/common/modules/vo/dto/ImageVO.java | 50 + .../common/modules/vo/face/AlarmReturnVO.java | 72 + .../common/modules/vo/face/ApiAlarmVO.java | 50 + .../vo/face/ApiFaceOneSearchFaceVO.java | 29 + .../vo/face/ApiFaceOneSearchReturnFaceVO.java | 32 + .../vo/face/ApiFaceSearGroupReturnVO.java | 30 + .../modules/vo/face/ApiFaceSearchFaceVO.java | 32 + .../modules/vo/face/ApiFaceSearchFacesVO.java | 35 + .../vo/face/ApiFaceSearchReturnVO.java | 30 + .../modules/vo/face/ApiFaceSearchVO.java | 36 + .../common/modules/vo/face/ApiFaceVO.java | 40 + .../modules/vo/face/ApiSearchFaceRectVO.java | 29 + .../common/modules/vo/face/ComparisonVO.java | 34 + .../common/modules/vo/face/ControlTaskVO.java | 46 + .../common/modules/vo/face/EsReturnVO.java | 34 + .../common/modules/vo/face/FaceBayonetVO.java | 46 + .../common/modules/vo/face/FaceLibraryVO.java | 39 + .../common/modules/vo/face/FaceTrackVO.java | 46 + .../common/modules/vo/face/FeatureVO.java | 31 + .../modules/vo/face/GovShortBaseEntity.java | 44 + .../modules/vo/face/HitConditionVO.java | 41 + .../common/modules/vo/face/ImageListVO.java | 35 + .../common/modules/vo/face/ImageReturnVO.java | 50 + .../dkha/common/modules/vo/face/ImageVO.java | 50 + .../dkha/common/modules/vo/face/ImagesVO.java | 65 + .../modules/vo/face/PagePortraitVO.java | 31 + .../dkha/common/modules/vo/face/PageVO.java | 44 + .../modules/vo/facelib/CompareListVO.java | 33 + .../modules/vo/facelib/CompareRequestVo.java | 21 + .../vo/facelib/CompareResultDetailVo.java | 19 + .../vo/facelib/CompareResultSubVo.java | 22 + .../modules/vo/facelib/CompareResultVo.java | 19 + .../modules/vo/facelib/FaceDeleteVO.java | 32 + .../vo/facelib/FaceLibaryReturnVO.java | 34 + .../modules/vo/facelib/FaceLibaryVO.java | 34 + .../modules/vo/facelib/FileImageVo.java | 19 + .../modules/vo/facelib/OneToOneResultVo.java | 22 + .../modules/vo/facelib/OnecompareOneVO.java | 34 + .../vo/facelib/PersonalInformationVO.java | 37 + .../modules/vo/libary/FaceLibraryVO.java | 39 + .../common/modules/vo/libary/LibaryVO.java | 31 + .../modules/vo/position/FScoreCompVO.java | 14 + .../modules/vo/position/FaceCompareVO.java | 36 + .../common/modules/vo/position/FaceVO.java | 40 + .../modules/vo/position/GroupInfoVO.java | 21 + .../modules/vo/position/GroupPositionVO.java | 37 + .../modules/vo/position/GroupRelation.java | 26 + .../common/modules/vo/position/GroupVO.java | 36 + .../common/modules/vo/position/Imginfo.java | 17 + .../modules/vo/position/PortraitListVo.java | 28 + .../modules/vo/position/PositionVO.java | 38 + .../common/modules/vo/search/FaceCheckVO.java | 34 + .../modules/vo/search/FaceCompareVO.java | 33 + .../modules/vo/search/FaceSearchVO.java | 37 + .../modules/vo/search/SearchFutureVo.java | 21 + .../modules/vo/search/SearchPortraitVo.java | 42 + .../modules/vo/search/SearchRequestVo.java | 39 + .../modules/vo/search/SearchResultVo.java | 34 + .../modules/vo/upload/ImageUploadResult.java | 24 + .../vo/warning/BayoneReturnListVO.java | 37 + .../modules/vo/warning/BayonetReturnVO.java | 37 + .../modules/vo/warning/BgImageSize.java | 27 + .../common/modules/vo/warning/CameraVO.java | 62 + .../modules/vo/warning/CameraWarningVO.java | 27 + .../modules/vo/warning/FScoreCompVO.java | 14 + .../modules/vo/warning/GroupInfoVO.java | 21 + .../modules/vo/warning/GroupRelation.java | 25 + .../common/modules/vo/warning/GroupVO.java | 19 + .../common/modules/vo/warning/HeadVo.java | 18 + .../common/modules/vo/warning/Imginfo.java | 17 + .../dkha/common/modules/vo/warning/P5sVO.java | 19 + .../common/modules/vo/warning/PositionVo.java | 17 + .../common/modules/vo/warning/RectVO.java | 16 + .../vo/warning/WarningBayonetReturnVO.java | 35 + .../modules/vo/warning/WarningPageVO.java | 69 + .../common/modules/vo/warning/WarningVO.java | 54 + .../dkha/common/mybatis/CodeGenerator.java | 178 + .../java/com/dkha/common/page/PageParam.java | 101 + .../dkha/common/pool/EmployeeThreadPool.java | 25 + .../main/java/com/dkha/common/pwd/MD5.java | 70 + .../main/java/com/dkha/common/pwd/SHA1.java | 47 + .../com/dkha/common/redis/RedisConfig.java | 41 + .../java/com/dkha/common/redis/RedisKeys.java | 67 + .../com/dkha/common/redis/RedisUtils.java | 144 + .../redis/serializer/JsonRedisSerializer.java | 53 + .../com/dkha/common/result/CommonResult.java | 145 + .../dkha/common/signature/SignatureUtil.java | 144 + .../dkha/common/systemcode/SystemCode.java | 148 + .../dkha/common/util/Base64ImageUtils.java | 444 + .../com/dkha/common/util/ContextUtil.java | 33 + .../java/com/dkha/common/util/DateUtils.java | 1221 +++ .../java/com/dkha/common/util/EnumUtil.java | 186 + .../java/com/dkha/common/util/ExcelUtils.java | 403 + .../dkha/common/util/HttpContextUtils.java | 78 + .../java/com/dkha/common/util/IdCardUtil.java | 427 + .../java/com/dkha/common/util/IntUUID.java | 40 + .../java/com/dkha/common/util/IpUtils.java | 61 + .../java/com/dkha/common/util/JsonUtil.java | 226 + .../java/com/dkha/common/util/NameUtil.java | 98 + .../java/com/dkha/common/util/ShieldUtil.java | 56 + .../common/util/SpringBeanFactoryUtils.java | 28 + .../dkha/common/util/SpringContextUtils.java | 55 + .../java/com/dkha/common/util/TimeUtil.java | 101 + .../java/com/dkha/common/util/UUIDBits.java | 43 + .../java/com/dkha/common/util/UrlUtil.java | 109 + .../com/dkha/common/util/UtilValidate.java | 144 + .../dkha/common/util/excel/ExcelField.java | 59 + .../dkha/common/util/excel/ImportExcel.java | 343 + .../dkha/common/util/excel/Reflections.java | 299 + face-server/Dockerfile | 8 + face-server/pom.xml | 194 + .../dkha/server/FaceServerApplication.java | 50 + .../annotation/NoRepeatSubmitAnnotation.java | 29 + .../server/aspect/RepeatSubmitAspect.java | 93 + .../dkha/server/aspect/portraitThread.java | 41 + .../common/config/InitStartDateConfig.java | 32 + .../server/common/config/SwaggerConfig.java | 64 + .../common/exception/DkExceptionHandler.java | 69 + .../common/handler/MyMetaObjectHandler.java | 43 + .../server/controllers/CameraController.java | 227 + .../server/controllers/CompareController.java | 62 + .../controllers/ControlTaskController.java | 263 + .../server/controllers/FaceController.java | 113 + .../server/controllers/FileController.java | 73 + .../dkha/server/controllers/IndexContral.java | 144 + .../controllers/ResourcesController.java | 369 + .../server/controllers/SearchController.java | 70 + .../server/controllers/TrackController.java | 286 + .../server/controllers/WarningController.java | 705 ++ .../mappers/ControlBayonetMidMapper.java | 39 + .../mappers/ControlLibraryMidMapper.java | 25 + .../server/mappers/ControlTaskMapper.java | 46 + .../dkha/server/mappers/FaceCameraDao.java | 48 + .../dkha/server/mappers/FaceCameraMapper.java | 18 + .../server/mappers/FaceLibraryMapper.java | 35 + .../dkha/server/mappers/FaceTrackMapper.java | 64 + .../dkha/server/mappers/PortraitMapper.java | 79 + .../mappers/WarningInformationMapper.java | 18 + .../modules/entities/ControlBayonetMid.java | 62 + .../modules/entities/ControlLibraryMid.java | 61 + .../server/modules/entities/ControlTask.java | 121 + .../modules/entities/FaceCameraEntity.java | 171 + .../server/modules/entities/FaceLibrary.java | 69 + .../modules/entities/FaceTrackEntity.java | 84 + .../server/modules/entities/Portrait.java | 88 + .../modules/entities/WarningInformation.java | 73 + .../entities/faceCamera/FaceCameraExcel.java | 60 + .../entities/faceCamera/FaceCameraInfo.java | 130 + .../entities/faceCamera/FaceCameraList.java | 92 + .../entities/faceCamera/InsertFaceCamera.java | 102 + .../server/schedule/CheckCameraTimer.java | 68 + .../server/services/FaceCameraService.java | 129 + .../server/services/FaceTrackService.java | 68 + .../dkha/server/services/ICompareService.java | 35 + .../services/IControlBayonetMidService.java | 59 + .../services/IControlLibraryMidService.java | 19 + .../server/services/IControlTaskService.java | 54 + .../server/services/IFaceCameraService.java | 16 + .../server/services/IFaceLibraryService.java | 52 + .../dkha/server/services/IFileService.java | 36 + .../server/services/IPortraitService.java | 89 + .../services/IWarningInformationService.java | 16 + .../services/impl/CompareServiceImpl.java | 203 + .../impl/ControlBayonetMidServiceImpl.java | 72 + .../impl/ControlLibraryMidServiceImpl.java | 27 + .../services/impl/ControlTaskServiceImpl.java | 734 ++ .../services/impl/FaceCameraServiceImpl.java | 478 + .../services/impl/FaceLibraryServiceImpl.java | 179 + .../services/impl/FaceTrackServiceImpl.java | 93 + .../server/services/impl/FileServiceImpl.java | 191 + .../services/impl/PortraitServiceImpl.java | 700 ++ .../server/services/impl/TrackTaskImpl.java | 276 + .../impl/WarningInformationServiceImpl.java | 20 + .../system/common/annotation/DataFilter.java | 42 + .../common/annotation/LogOperation.java | 24 + .../common/aspect/DataFilterAspect.java | 113 + .../common/aspect/LogOperationAspect.java | 110 + .../common/config/MybatisPlusConfig.java | 46 + .../system/common/constant/Constant.java | 189 + .../system/common/convert/DateConverter.java | 79 + .../server/system/common/dao/BaseDao.java | 21 + .../system/common/entity/BaseEntity.java | 45 + .../system/common/entity/CommonEntity.java | 32 + .../system/common/exception/ErrorCode.java | 73 + .../common/exception/ExceptionUtils.java | 53 + .../system/common/exception/RenException.java | 75 + .../common/exception/RenExceptionHandler.java | 94 + .../interceptor/DataFilterInterceptor.java | 91 + .../system/common/interceptor/DataScope.java | 36 + .../server/system/common/page/PageData.java | 43 + .../system/common/service/BaseService.java | 115 + .../system/common/service/CrudService.java | 37 + .../common/service/impl/BaseServiceImpl.java | 257 + .../common/service/impl/CrudServiceImpl.java | 80 + .../system/common/utils/ConvertUtils.java | 63 + .../server/system/common/utils/DateUtils.java | 182 + .../system/common/utils/ExcelUtils.java | 77 + .../system/common/utils/HttpContextUtils.java | 78 + .../server/system/common/utils/IpUtils.java | 63 + .../system/common/utils/MessageUtils.java | 34 + .../server/system/common/utils/Result.java | 98 + .../server/system/common/utils/TreeNode.java | 59 + .../server/system/common/utils/TreeUtils.java | 83 + .../system/common/validator/AssertUtils.java | 96 + .../common/validator/ValidatorUtils.java | 57 + .../common/validator/group/AddGroup.java | 19 + .../common/validator/group/AliyunGroup.java | 17 + .../common/validator/group/DefaultGroup.java | 19 + .../common/validator/group/FastDFSGroup.java | 17 + .../system/common/validator/group/Group.java | 22 + .../common/validator/group/LocalGroup.java | 17 + .../common/validator/group/QcloudGroup.java | 17 + .../common/validator/group/QiniuGroup.java | 17 + .../common/validator/group/TreeNode.java | 59 + .../common/validator/group/UpdateGroup.java | 19 + .../server/system/common/xss/SqlFilter.java | 50 + .../server/system/common/xss/XssFilter.java | 37 + .../xss/XssHttpServletRequestWrapper.java | 147 + .../server/system/common/xss/XssUtils.java | 78 + .../log/controller/SysLogErrorController.java | 74 + .../log/controller/SysLogLoginController.java | 80 + .../controller/SysLogOperationController.java | 75 + .../modules/log/dao/SysLogErrorDao.java | 24 + .../modules/log/dao/SysLogLoginDao.java | 24 + .../modules/log/dao/SysLogOperationDao.java | 24 + .../modules/log/dto/SysLogErrorDTO.java | 46 + .../modules/log/dto/SysLogLoginDTO.java | 50 + .../modules/log/dto/SysLogOperationDTO.java | 62 + .../modules/log/entity/SysLogErrorEntity.java | 53 + .../modules/log/entity/SysLogLoginEntity.java | 49 + .../log/entity/SysLogOperationEntity.java | 64 + .../modules/log/enums/LoginOperationEnum.java | 36 + .../modules/log/enums/LoginStatusEnum.java | 40 + .../log/enums/OperationStatusEnum.java | 36 + .../modules/log/excel/SysLogErrorExcel.java | 37 + .../modules/log/excel/SysLogLoginExcel.java | 37 + .../log/excel/SysLogOperationExcel.java | 45 + .../log/service/SysLogErrorService.java | 35 + .../log/service/SysLogLoginService.java | 33 + .../log/service/SysLogOperationService.java | 33 + .../service/impl/SysLogErrorServiceImpl.java | 64 + .../service/impl/SysLogLoginServiceImpl.java | 71 + .../impl/SysLogOperationServiceImpl.java | 69 + .../modules/security/config/FilterConfig.java | 49 + .../modules/security/config/ShiroConfig.java | 103 + .../modules/security/config/WebMvcConfig.java | 89 + .../security/controller/LoginController.java | 166 + .../system/modules/security/dto/LoginDTO.java | 44 + .../modules/security/oauth2/Oauth2Filter.java | 114 + .../modules/security/oauth2/Oauth2Realm.java | 92 + .../modules/security/oauth2/Oauth2Token.java | 34 + .../security/oauth2/TokenGenerator.java | 53 + .../modules/security/password/BCrypt.java | 662 ++ .../password/BCryptPasswordEncoder.java | 82 + .../security/password/PasswordEncoder.java | 30 + .../security/password/PasswordUtils.java | 58 + .../security/service/CaptchaService.java | 32 + .../security/service/ShiroService.java | 43 + .../security/service/SysUserTokenService.java | 35 + .../service/impl/CaptchaServiceImpl.java | 95 + .../service/impl/ShiroServiceImpl.java | 73 + .../service/impl/SysUserTokenServiceImpl.java | 90 + .../modules/security/user/SecurityUser.java | 59 + .../modules/security/user/UserDetail.java | 41 + .../sys/controller/SysDeptController.java | 98 + .../sys/controller/SysDictDataController.java | 120 + .../sys/controller/SysDictTypeController.java | 119 + .../sys/controller/SysMenuController.java | 138 + .../sys/controller/SysParamsController.java | 126 + .../sys/controller/SysRegionController.java | 137 + .../sys/controller/SysRoleController.java | 133 + .../sys/controller/SysUserController.java | 165 + .../sys/controller/SystemController.java | 61 + .../system/modules/sys/dao/SysDeptDao.java | 41 + .../modules/sys/dao/SysDictDataDao.java | 31 + .../modules/sys/dao/SysDictTypeDao.java | 23 + .../modules/sys/dao/SysLanguageDao.java | 26 + .../system/modules/sys/dao/SysMenuDao.java | 62 + .../system/modules/sys/dao/SysParamsDao.java | 46 + .../system/modules/sys/dao/SysRegionDao.java | 47 + .../system/modules/sys/dao/SysRoleDao.java | 24 + .../modules/sys/dao/SysRoleDataScopeDao.java | 41 + .../modules/sys/dao/SysRoleMenuDao.java | 41 + .../modules/sys/dao/SysRoleUserDao.java | 45 + .../system/modules/sys/dao/SysUserDao.java | 40 + .../modules/sys/dao/SysUserTokenDao.java | 29 + .../system/modules/sys/dto/PasswordDTO.java | 37 + .../system/modules/sys/dto/SysDeptDTO.java | 111 + .../system/modules/sys/dto/SysDictDTO.java | 56 + .../modules/sys/dto/SysDictDataDTO.java | 66 + .../modules/sys/dto/SysDictTypeDTO.java | 63 + .../system/modules/sys/dto/SysMenuDTO.java | 157 + .../system/modules/sys/dto/SysParamsDTO.java | 60 + .../system/modules/sys/dto/SysRegionDTO.java | 63 + .../system/modules/sys/dto/SysRoleDTO.java | 59 + .../system/modules/sys/dto/SysUserDTO.java | 93 + .../system/modules/sys/dto/SystemDTO.java | 48 + .../system/modules/sys/dto/region/Region.java | 36 + .../modules/sys/dto/region/RegionCity.java | 30 + .../sys/dto/region/RegionProvince.java | 30 + .../system/modules/sys/entity/DictData.java | 16 + .../system/modules/sys/entity/DictType.java | 19 + .../modules/sys/entity/SysDeptEntity.java | 52 + .../modules/sys/entity/SysDictDataEntity.java | 60 + .../modules/sys/entity/SysDictEntity.java | 59 + .../modules/sys/entity/SysDictTypeEntity.java | 48 + .../modules/sys/entity/SysLanguageEntity.java | 39 + .../modules/sys/entity/SysMenuEntity.java | 76 + .../modules/sys/entity/SysParamsEntity.java | 59 + .../modules/sys/entity/SysRegionEntity.java | 77 + .../sys/entity/SysRoleDataScopeEntity.java | 37 + .../modules/sys/entity/SysRoleEntity.java | 54 + .../modules/sys/entity/SysRoleMenuEntity.java | 36 + .../modules/sys/entity/SysRoleUserEntity.java | 37 + .../modules/sys/entity/SysUserEntity.java | 86 + .../sys/entity/SysUserTokenEntity.java | 54 + .../modules/sys/enums/MenuTypeEnum.java | 36 + .../modules/sys/enums/RegionLeafEnum.java | 29 + .../modules/sys/enums/RegionLevelEnum.java | 30 + .../modules/sys/enums/RegionTopEnum.java | 18 + .../modules/sys/enums/SuperAdminEnum.java | 30 + .../modules/sys/enums/UserStatusEnum.java | 30 + .../modules/sys/excel/SysParamsExcel.java | 29 + .../modules/sys/excel/SysUserExcel.java | 43 + .../modules/sys/redis/SysParamsRedis.java | 45 + .../modules/sys/service/SysDeptService.java | 40 + .../sys/service/SysDictDataService.java | 27 + .../sys/service/SysDictTypeService.java | 37 + .../sys/service/SysLanguageService.java | 39 + .../modules/sys/service/SysMenuService.java | 53 + .../modules/sys/service/SysParamsService.java | 61 + .../modules/sys/service/SysRegionService.java | 55 + .../sys/service/SysRoleDataScopeService.java | 42 + .../sys/service/SysRoleMenuService.java | 48 + .../modules/sys/service/SysRoleService.java | 41 + .../sys/service/SysRoleUserService.java | 49 + .../modules/sys/service/SysUserService.java | 53 + .../sys/service/impl/SysDeptServiceImpl.java | 162 + .../service/impl/SysDictDataServiceImpl.java | 80 + .../service/impl/SysDictTypeServiceImpl.java | 111 + .../service/impl/SysLanguageServiceImpl.java | 47 + .../sys/service/impl/SysMenuServiceImpl.java | 122 + .../service/impl/SysParamsServiceImpl.java | 142 + .../service/impl/SysRegionServiceImpl.java | 237 + .../impl/SysRoleDataScopeServiceImpl.java | 62 + .../service/impl/SysRoleMenuServiceImpl.java | 69 + .../sys/service/impl/SysRoleServiceImpl.java | 135 + .../service/impl/SysRoleUserServiceImpl.java | 65 + .../sys/service/impl/SysUserServiceImpl.java | 152 + .../com/dkha/server/util/FileToBase64.java | 68 + .../com/dkha/server/util/RequestUtil.java | 29 + .../src/main/resources/application-dev.yml | 137 + .../src/main/resources/application-prod.yml | 137 + .../src/main/resources/application-test.yml | 137 + .../src/main/resources/application.yml | 4 + face-server/src/main/resources/banner.txt | 23 + .../main/resources/i18n/messages.properties | 35 + .../resources/i18n/messages_en_US.properties | 35 + .../resources/i18n/messages_zh_CN.properties | 38 + .../resources/i18n/messages_zh_TW.properties | 35 + .../main/resources/i18n/validation.properties | 89 + .../i18n/validation_en_US.properties | 90 + .../i18n/validation_zh_CN.properties | 89 + .../i18n/validation_zh_TW.properties | 90 + .../src/main/resources/logback-spring.xml | 60 + .../mapper/ControlBayonetMidMapper.xml | 35 + .../mapper/ControlLibraryMidMapper.xml | 16 + .../mybatis/mapper/ControlTaskMapper.xml | 114 + .../mybatis/mapper/FaceCameraDao.xml | 85 + .../mybatis/mapper/FaceCameraMapper.xml | 5 + .../mybatis/mapper/FaceLibraryMapper.xml | 26 + .../mybatis/mapper/FaceTrackMapper.xml | 171 + .../mybatis/mapper/PortraitMapper.xml | 156 + .../mapper/WarningInformationMapper.xml | 5 + .../mybatis/mapper/log/SysLogErrorDao.xml | 6 + .../mybatis/mapper/log/SysLogLoginDao.xml | 6 + .../mybatis/mapper/log/SysLogOperationDao.xml | 6 + .../mybatis/mapper/sys/SysDeptDao.xml | 32 + .../mybatis/mapper/sys/SysDictDataDao.xml | 11 + .../mybatis/mapper/sys/SysDictTypeDao.xml | 10 + .../mybatis/mapper/sys/SysLanguageDao.xml | 19 + .../mybatis/mapper/sys/SysMenuDao.xml | 54 + .../mybatis/mapper/sys/SysParamsDao.xml | 23 + .../mybatis/mapper/sys/SysRegionDao.xml | 43 + .../mybatis/mapper/sys/SysRoleDao.xml | 7 + .../mapper/sys/SysRoleDataScopeDao.xml | 22 + .../mybatis/mapper/sys/SysRoleMenuDao.xml | 20 + .../mybatis/mapper/sys/SysRoleUserDao.xml | 24 + .../mybatis/mapper/sys/SysUserDao.xml | 43 + .../mybatis/mapper/sys/SysUserTokenDao.xml | 17 + .../main/resources/mybatis/mybatis.cfg.xml | 10 + .../src/main/resources/摄像头导入模板.xls | Bin 0 -> 39936 bytes face-snapShot/pom.xml | 69 + .../java/com/dkha/face/FaceSnapShotMain.java | 25 + .../com/dkha/face/contral/FaceSnapContal.java | 60 + .../com/dkha/face/modules/ReceiveSnapVO.java | 482 + .../java/com/dkha/face/modules/RecevieVO.java | 28 + .../src/main/resources/application.yml | 2 + face-task/pom.xml | 109 + .../main/java/com/dkha/task/FaceTaskMain.java | 62 + .../java/com/dkha/task/comm/TimerData.java | 38 + .../dkha/task/config/MyMetaObjectHandler.java | 42 + .../com/dkha/task/config/WebSocketConfig.java | 19 + .../com/dkha/task/contral/TestContral.java | 61 + .../com/dkha/task/contral/TimerContral.java | 273 + .../java/com/dkha/task/modual/BaseDao.java | 21 + .../dkha/task/modual/SysUserTokenEntity.java | 54 + .../task/modual/entity/ControlBayonetMid.java | 62 + .../dkha/task/modual/entity/FaceCamera.java | 107 + .../task/modual/entity/FaceTrackEntity.java | 84 + .../mapper/ControlBayonetMidMapper.java | 36 + .../task/modual/mapper/FaceTrackMapper.java | 41 + .../task/modual/mapper/SysUserTokenDao.java | 30 + .../com/dkha/task/modual/vo/BayonetVO.java | 30 + .../com/dkha/task/modual/vo/FaceTrackVO.java | 46 + .../com/dkha/task/modual/vo/ReturnVO.java | 162 + .../com/dkha/task/service/ApiDeelService.java | 34 + .../dkha/task/service/FaceTrackService.java | 44 + .../service/IControlBayonetMidService.java | 57 + .../dkha/task/service/WebSocketContral.java | 174 + .../task/service/impl/ApiDeelServiceImpl.java | 302 + .../task/service/impl/AsyncServiceImpl.java | 190 + .../impl/ControlBayonetMidServiceImpl.java | 67 + .../service/impl/FaceTrackServiceImpl.java | 71 + .../dkha/task/util/PeopleComparableUitl.java | 43 + .../src/main/resources/application-dev.yml | 108 + .../src/main/resources/application-prod.yml | 108 + .../src/main/resources/application-test.yml | 108 + face-task/src/main/resources/application.yml | 4 + .../src/main/resources/logback-spring.xml | 59 + .../mapper/ControlBayonetMidMapper.xml | 33 + .../mybatis/mapper/FaceTrackMapper.xml | 84 + .../mybatis/mapper/sys/SysUserTokenDao.xml | 15 + .../main/resources/mybatis/mybatis.cfg.xml | 10 + .../main/resources/static/images/Ink_Note.ico | Bin 0 -> 30139 bytes .../src/main/resources/static/images/a64.ico | Bin 0 -> 16958 bytes .../src/main/resources/static/images/bg.png | Bin 0 -> 1587 bytes .../main/resources/static/images/bg_blue.png | Bin 0 -> 1587 bytes .../main/resources/static/images/bg_green.png | Bin 0 -> 1584 bytes .../main/resources/static/images/bg_red.png | Bin 0 -> 1579 bytes .../main/resources/static/images/deskicon.ico | Bin 0 -> 16958 bytes .../main/resources/static/images/favicon.ico | Bin 0 -> 2862 bytes .../src/main/resources/static/images/jt.png | Bin 0 -> 441 bytes .../main/resources/static/images/pulse.ico | Bin 0 -> 353118 bytes .../resources/static/images/ringtones.ico | Bin 0 -> 51881 bytes .../main/resources/static/images/settings.ico | Bin 0 -> 67664 bytes .../src/main/resources/static/index.html | 76 + .../src/main/resources/static/index1.html | 57 + .../src/main/resources/static/index2.html | 196 + .../src/main/resources/static/index4.html | 216 + .../src/main/resources/static/indexline.html | 44 + .../src/main/resources/static/indexmove.html | 66 + .../src/main/resources/static/js/baidu.js | 1 + .../src/main/resources/static/js/jiemi.js | 89 + .../src/main/resources/static/js/jiemi2.js | 90 + .../resources/static/js/jquery-1.6.2.min.js | 18 + .../static/js/jquery-3.2.1.slim.min.js | 4 + face-task/src/main/resources/static/js/yj.js | 136 + face-task/src/main/resources/static/map.html | 222 + .../src/main/resources/static/mp3/song.mp3 | 0 pom.xml | 245 + 525 files changed, 56959 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 doc/face.PDM create mode 100644 doc/face.pdb create mode 100644 doc/数据库变更字段-2020-01-07.sql create mode 100644 docker-compose.yml create mode 100644 docker-compose1.yml create mode 100644 face-common/pom.xml create mode 100644 face-common/src/main/java/com/dkha/common/CommonApplication.java create mode 100644 face-common/src/main/java/com/dkha/common/consul/BaseLock.java create mode 100644 face-common/src/main/java/com/dkha/common/consul/CheckTtl.java create mode 100644 face-common/src/main/java/com/dkha/common/consul/Lock.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/ApiUrlEnum.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/BoardAndLodgingEnums.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/CompanyCheckEnums.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/CompanyMessageEnums.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/ContractFileStausEnums.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/ContractStatusEnums.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/ContractType.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/ContralEnums.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/DictTypeEnums.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/EmployeeChannel.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/ErrEnum.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/ExpiryTimeTypeEnums.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/IndustryTypeEnum.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/IsOnWorkingEnums.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/IsPoorEnums.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/LaborMessageEnms.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/MsgEnums.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/OpinionEnums.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/PlatformDictTypeEnum.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/PlatformTypeEnum.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/ProjectType.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/SEXEnums.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/SocketEnum.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/TaskStatuEnum.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/TaskStatusEnum.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/TrainingAssessmentStatus.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/YNEnums.java create mode 100644 face-common/src/main/java/com/dkha/common/enums/YNNumberEnum.java create mode 100644 face-common/src/main/java/com/dkha/common/exception/AuthorityException.java create mode 100644 face-common/src/main/java/com/dkha/common/exception/DkAuthorityException.java create mode 100644 face-common/src/main/java/com/dkha/common/exception/DkException.java create mode 100644 face-common/src/main/java/com/dkha/common/exception/EmployeeException.java create mode 100644 face-common/src/main/java/com/dkha/common/fileupload/MinioUtil.java create mode 100644 face-common/src/main/java/com/dkha/common/http/ConfigBean.java create mode 100644 face-common/src/main/java/com/dkha/common/http/HttpUtil.java create mode 100644 face-common/src/main/java/com/dkha/common/jwt/JwtConstantEnum.java create mode 100644 face-common/src/main/java/com/dkha/common/jwt/JwtHelper.java create mode 100644 face-common/src/main/java/com/dkha/common/kaptcha/KaptchaConfig.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/ApiVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/ReturnVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/camera/AssociationPeopleVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/camera/BayOnetCameraVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/camera/CameraInfoVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/camera/PeopleComparableVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/camera/PeopleVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/control/ControlTaskVedioVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/control/ControlVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/control/TaskControlVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/control/VideoControlVo.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/cut/CutVo.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/dto/FaceLibraryVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/dto/ImageListVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/dto/ImageVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/AlarmReturnVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/ApiAlarmVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceOneSearchFaceVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceOneSearchReturnFaceVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearGroupReturnVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearchFaceVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearchFacesVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearchReturnVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearchVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/ApiSearchFaceRectVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/ComparisonVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/ControlTaskVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/EsReturnVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/FaceBayonetVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/FaceLibraryVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/FaceTrackVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/FeatureVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/GovShortBaseEntity.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/HitConditionVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/ImageListVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/ImageReturnVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/ImageVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/ImagesVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/PagePortraitVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/face/PageVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareListVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareRequestVo.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareResultDetailVo.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareResultSubVo.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareResultVo.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/facelib/FaceDeleteVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/facelib/FaceLibaryReturnVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/facelib/FaceLibaryVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/facelib/FileImageVo.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/facelib/OneToOneResultVo.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/facelib/OnecompareOneVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/facelib/PersonalInformationVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/libary/FaceLibraryVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/libary/LibaryVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/position/FScoreCompVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/position/FaceCompareVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/position/FaceVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/position/GroupInfoVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/position/GroupPositionVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/position/GroupRelation.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/position/GroupVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/position/Imginfo.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/position/PortraitListVo.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/position/PositionVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/search/FaceCheckVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/search/FaceCompareVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/search/FaceSearchVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/search/SearchFutureVo.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/search/SearchPortraitVo.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/search/SearchRequestVo.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/search/SearchResultVo.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/upload/ImageUploadResult.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/warning/BayoneReturnListVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/warning/BayonetReturnVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/warning/BgImageSize.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/warning/CameraVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/warning/CameraWarningVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/warning/FScoreCompVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/warning/GroupInfoVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/warning/GroupRelation.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/warning/GroupVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/warning/HeadVo.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/warning/Imginfo.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/warning/P5sVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/warning/PositionVo.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/warning/RectVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/warning/WarningBayonetReturnVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/warning/WarningPageVO.java create mode 100644 face-common/src/main/java/com/dkha/common/modules/vo/warning/WarningVO.java create mode 100644 face-common/src/main/java/com/dkha/common/mybatis/CodeGenerator.java create mode 100644 face-common/src/main/java/com/dkha/common/page/PageParam.java create mode 100644 face-common/src/main/java/com/dkha/common/pool/EmployeeThreadPool.java create mode 100644 face-common/src/main/java/com/dkha/common/pwd/MD5.java create mode 100644 face-common/src/main/java/com/dkha/common/pwd/SHA1.java create mode 100644 face-common/src/main/java/com/dkha/common/redis/RedisConfig.java create mode 100644 face-common/src/main/java/com/dkha/common/redis/RedisKeys.java create mode 100644 face-common/src/main/java/com/dkha/common/redis/RedisUtils.java create mode 100644 face-common/src/main/java/com/dkha/common/redis/serializer/JsonRedisSerializer.java create mode 100644 face-common/src/main/java/com/dkha/common/result/CommonResult.java create mode 100644 face-common/src/main/java/com/dkha/common/signature/SignatureUtil.java create mode 100644 face-common/src/main/java/com/dkha/common/systemcode/SystemCode.java create mode 100644 face-common/src/main/java/com/dkha/common/util/Base64ImageUtils.java create mode 100644 face-common/src/main/java/com/dkha/common/util/ContextUtil.java create mode 100644 face-common/src/main/java/com/dkha/common/util/DateUtils.java create mode 100644 face-common/src/main/java/com/dkha/common/util/EnumUtil.java create mode 100644 face-common/src/main/java/com/dkha/common/util/ExcelUtils.java create mode 100644 face-common/src/main/java/com/dkha/common/util/HttpContextUtils.java create mode 100644 face-common/src/main/java/com/dkha/common/util/IdCardUtil.java create mode 100644 face-common/src/main/java/com/dkha/common/util/IntUUID.java create mode 100644 face-common/src/main/java/com/dkha/common/util/IpUtils.java create mode 100644 face-common/src/main/java/com/dkha/common/util/JsonUtil.java create mode 100644 face-common/src/main/java/com/dkha/common/util/NameUtil.java create mode 100644 face-common/src/main/java/com/dkha/common/util/ShieldUtil.java create mode 100644 face-common/src/main/java/com/dkha/common/util/SpringBeanFactoryUtils.java create mode 100644 face-common/src/main/java/com/dkha/common/util/SpringContextUtils.java create mode 100644 face-common/src/main/java/com/dkha/common/util/TimeUtil.java create mode 100644 face-common/src/main/java/com/dkha/common/util/UUIDBits.java create mode 100644 face-common/src/main/java/com/dkha/common/util/UrlUtil.java create mode 100644 face-common/src/main/java/com/dkha/common/util/UtilValidate.java create mode 100644 face-common/src/main/java/com/dkha/common/util/excel/ExcelField.java create mode 100644 face-common/src/main/java/com/dkha/common/util/excel/ImportExcel.java create mode 100644 face-common/src/main/java/com/dkha/common/util/excel/Reflections.java create mode 100644 face-server/Dockerfile create mode 100644 face-server/pom.xml create mode 100644 face-server/src/main/java/com/dkha/server/FaceServerApplication.java create mode 100644 face-server/src/main/java/com/dkha/server/annotation/NoRepeatSubmitAnnotation.java create mode 100644 face-server/src/main/java/com/dkha/server/aspect/RepeatSubmitAspect.java create mode 100644 face-server/src/main/java/com/dkha/server/aspect/portraitThread.java create mode 100644 face-server/src/main/java/com/dkha/server/common/config/InitStartDateConfig.java create mode 100644 face-server/src/main/java/com/dkha/server/common/config/SwaggerConfig.java create mode 100644 face-server/src/main/java/com/dkha/server/common/exception/DkExceptionHandler.java create mode 100644 face-server/src/main/java/com/dkha/server/common/handler/MyMetaObjectHandler.java create mode 100644 face-server/src/main/java/com/dkha/server/controllers/CameraController.java create mode 100644 face-server/src/main/java/com/dkha/server/controllers/CompareController.java create mode 100644 face-server/src/main/java/com/dkha/server/controllers/ControlTaskController.java create mode 100644 face-server/src/main/java/com/dkha/server/controllers/FaceController.java create mode 100644 face-server/src/main/java/com/dkha/server/controllers/FileController.java create mode 100644 face-server/src/main/java/com/dkha/server/controllers/IndexContral.java create mode 100644 face-server/src/main/java/com/dkha/server/controllers/ResourcesController.java create mode 100644 face-server/src/main/java/com/dkha/server/controllers/SearchController.java create mode 100644 face-server/src/main/java/com/dkha/server/controllers/TrackController.java create mode 100644 face-server/src/main/java/com/dkha/server/controllers/WarningController.java create mode 100644 face-server/src/main/java/com/dkha/server/mappers/ControlBayonetMidMapper.java create mode 100644 face-server/src/main/java/com/dkha/server/mappers/ControlLibraryMidMapper.java create mode 100644 face-server/src/main/java/com/dkha/server/mappers/ControlTaskMapper.java create mode 100644 face-server/src/main/java/com/dkha/server/mappers/FaceCameraDao.java create mode 100644 face-server/src/main/java/com/dkha/server/mappers/FaceCameraMapper.java create mode 100644 face-server/src/main/java/com/dkha/server/mappers/FaceLibraryMapper.java create mode 100644 face-server/src/main/java/com/dkha/server/mappers/FaceTrackMapper.java create mode 100644 face-server/src/main/java/com/dkha/server/mappers/PortraitMapper.java create mode 100644 face-server/src/main/java/com/dkha/server/mappers/WarningInformationMapper.java create mode 100644 face-server/src/main/java/com/dkha/server/modules/entities/ControlBayonetMid.java create mode 100644 face-server/src/main/java/com/dkha/server/modules/entities/ControlLibraryMid.java create mode 100644 face-server/src/main/java/com/dkha/server/modules/entities/ControlTask.java create mode 100644 face-server/src/main/java/com/dkha/server/modules/entities/FaceCameraEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/modules/entities/FaceLibrary.java create mode 100644 face-server/src/main/java/com/dkha/server/modules/entities/FaceTrackEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/modules/entities/Portrait.java create mode 100644 face-server/src/main/java/com/dkha/server/modules/entities/WarningInformation.java create mode 100644 face-server/src/main/java/com/dkha/server/modules/entities/faceCamera/FaceCameraExcel.java create mode 100644 face-server/src/main/java/com/dkha/server/modules/entities/faceCamera/FaceCameraInfo.java create mode 100644 face-server/src/main/java/com/dkha/server/modules/entities/faceCamera/FaceCameraList.java create mode 100644 face-server/src/main/java/com/dkha/server/modules/entities/faceCamera/InsertFaceCamera.java create mode 100644 face-server/src/main/java/com/dkha/server/schedule/CheckCameraTimer.java create mode 100644 face-server/src/main/java/com/dkha/server/services/FaceCameraService.java create mode 100644 face-server/src/main/java/com/dkha/server/services/FaceTrackService.java create mode 100644 face-server/src/main/java/com/dkha/server/services/ICompareService.java create mode 100644 face-server/src/main/java/com/dkha/server/services/IControlBayonetMidService.java create mode 100644 face-server/src/main/java/com/dkha/server/services/IControlLibraryMidService.java create mode 100644 face-server/src/main/java/com/dkha/server/services/IControlTaskService.java create mode 100644 face-server/src/main/java/com/dkha/server/services/IFaceCameraService.java create mode 100644 face-server/src/main/java/com/dkha/server/services/IFaceLibraryService.java create mode 100644 face-server/src/main/java/com/dkha/server/services/IFileService.java create mode 100644 face-server/src/main/java/com/dkha/server/services/IPortraitService.java create mode 100644 face-server/src/main/java/com/dkha/server/services/IWarningInformationService.java create mode 100644 face-server/src/main/java/com/dkha/server/services/impl/CompareServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/services/impl/ControlBayonetMidServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/services/impl/ControlLibraryMidServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/services/impl/ControlTaskServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/services/impl/FaceCameraServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/services/impl/FaceLibraryServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/services/impl/FaceTrackServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/services/impl/FileServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/services/impl/PortraitServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/services/impl/TrackTaskImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/services/impl/WarningInformationServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/annotation/DataFilter.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/annotation/LogOperation.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/aspect/DataFilterAspect.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/aspect/LogOperationAspect.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/config/MybatisPlusConfig.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/constant/Constant.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/convert/DateConverter.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/dao/BaseDao.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/entity/BaseEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/entity/CommonEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/exception/ErrorCode.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/exception/ExceptionUtils.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/exception/RenException.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/exception/RenExceptionHandler.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/interceptor/DataFilterInterceptor.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/interceptor/DataScope.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/page/PageData.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/service/BaseService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/service/CrudService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/service/impl/BaseServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/service/impl/CrudServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/utils/ConvertUtils.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/utils/DateUtils.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/utils/ExcelUtils.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/utils/HttpContextUtils.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/utils/IpUtils.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/utils/MessageUtils.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/utils/Result.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/utils/TreeNode.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/utils/TreeUtils.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/validator/AssertUtils.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/validator/ValidatorUtils.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/validator/group/AddGroup.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/validator/group/AliyunGroup.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/validator/group/DefaultGroup.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/validator/group/FastDFSGroup.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/validator/group/Group.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/validator/group/LocalGroup.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/validator/group/QcloudGroup.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/validator/group/QiniuGroup.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/validator/group/TreeNode.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/validator/group/UpdateGroup.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/xss/SqlFilter.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/xss/XssFilter.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/xss/XssHttpServletRequestWrapper.java create mode 100644 face-server/src/main/java/com/dkha/server/system/common/xss/XssUtils.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/controller/SysLogErrorController.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/controller/SysLogLoginController.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/controller/SysLogOperationController.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/dao/SysLogErrorDao.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/dao/SysLogLoginDao.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/dao/SysLogOperationDao.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/dto/SysLogErrorDTO.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/dto/SysLogLoginDTO.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/dto/SysLogOperationDTO.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/entity/SysLogErrorEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/entity/SysLogLoginEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/entity/SysLogOperationEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/enums/LoginOperationEnum.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/enums/LoginStatusEnum.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/enums/OperationStatusEnum.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/excel/SysLogErrorExcel.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/excel/SysLogLoginExcel.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/excel/SysLogOperationExcel.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/service/SysLogErrorService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/service/SysLogLoginService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/service/SysLogOperationService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/service/impl/SysLogErrorServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/service/impl/SysLogLoginServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/log/service/impl/SysLogOperationServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/config/FilterConfig.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/config/ShiroConfig.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/config/WebMvcConfig.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/controller/LoginController.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/dto/LoginDTO.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/oauth2/Oauth2Filter.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/oauth2/Oauth2Realm.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/oauth2/Oauth2Token.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/oauth2/TokenGenerator.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/password/BCrypt.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/password/BCryptPasswordEncoder.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/password/PasswordEncoder.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/password/PasswordUtils.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/service/CaptchaService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/service/ShiroService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/service/SysUserTokenService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/service/impl/CaptchaServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/service/impl/ShiroServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/service/impl/SysUserTokenServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/user/SecurityUser.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/security/user/UserDetail.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysDeptController.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysDictDataController.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysDictTypeController.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysMenuController.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysParamsController.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysRegionController.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysRoleController.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysUserController.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SystemController.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysDeptDao.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysDictDataDao.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysDictTypeDao.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysLanguageDao.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysMenuDao.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysParamsDao.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRegionDao.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRoleDao.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRoleDataScopeDao.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRoleMenuDao.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRoleUserDao.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysUserDao.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysUserTokenDao.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dto/PasswordDTO.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysDeptDTO.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysDictDTO.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysDictDataDTO.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysDictTypeDTO.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysMenuDTO.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysParamsDTO.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysRegionDTO.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysRoleDTO.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysUserDTO.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SystemDTO.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dto/region/Region.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dto/region/RegionCity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/dto/region/RegionProvince.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/entity/DictData.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/entity/DictType.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysDeptEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysDictDataEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysDictEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysDictTypeEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysLanguageEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysMenuEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysParamsEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRegionEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRoleDataScopeEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRoleEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRoleMenuEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRoleUserEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysUserEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysUserTokenEntity.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/enums/MenuTypeEnum.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/enums/RegionLeafEnum.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/enums/RegionLevelEnum.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/enums/RegionTopEnum.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/enums/SuperAdminEnum.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/enums/UserStatusEnum.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/excel/SysParamsExcel.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/excel/SysUserExcel.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/redis/SysParamsRedis.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysDeptService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysDictDataService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysDictTypeService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysLanguageService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysMenuService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysParamsService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRegionService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRoleDataScopeService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRoleMenuService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRoleService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRoleUserService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysUserService.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysDeptServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysDictDataServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysDictTypeServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysLanguageServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysMenuServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysParamsServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRegionServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRoleDataScopeServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRoleMenuServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRoleServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRoleUserServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysUserServiceImpl.java create mode 100644 face-server/src/main/java/com/dkha/server/util/FileToBase64.java create mode 100644 face-server/src/main/java/com/dkha/server/util/RequestUtil.java create mode 100644 face-server/src/main/resources/application-dev.yml create mode 100644 face-server/src/main/resources/application-prod.yml create mode 100644 face-server/src/main/resources/application-test.yml create mode 100644 face-server/src/main/resources/application.yml create mode 100644 face-server/src/main/resources/banner.txt create mode 100644 face-server/src/main/resources/i18n/messages.properties create mode 100644 face-server/src/main/resources/i18n/messages_en_US.properties create mode 100644 face-server/src/main/resources/i18n/messages_zh_CN.properties create mode 100644 face-server/src/main/resources/i18n/messages_zh_TW.properties create mode 100644 face-server/src/main/resources/i18n/validation.properties create mode 100644 face-server/src/main/resources/i18n/validation_en_US.properties create mode 100644 face-server/src/main/resources/i18n/validation_zh_CN.properties create mode 100644 face-server/src/main/resources/i18n/validation_zh_TW.properties create mode 100644 face-server/src/main/resources/logback-spring.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/ControlBayonetMidMapper.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/ControlLibraryMidMapper.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/ControlTaskMapper.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/FaceCameraDao.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/FaceCameraMapper.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/FaceLibraryMapper.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/FaceTrackMapper.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/PortraitMapper.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/WarningInformationMapper.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/log/SysLogErrorDao.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/log/SysLogLoginDao.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/log/SysLogOperationDao.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/sys/SysDeptDao.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/sys/SysDictDataDao.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/sys/SysDictTypeDao.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/sys/SysLanguageDao.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/sys/SysMenuDao.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/sys/SysParamsDao.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/sys/SysRegionDao.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/sys/SysRoleDao.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/sys/SysRoleDataScopeDao.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/sys/SysRoleMenuDao.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/sys/SysRoleUserDao.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/sys/SysUserDao.xml create mode 100644 face-server/src/main/resources/mybatis/mapper/sys/SysUserTokenDao.xml create mode 100644 face-server/src/main/resources/mybatis/mybatis.cfg.xml create mode 100644 face-server/src/main/resources/摄像头导入模板.xls create mode 100644 face-snapShot/pom.xml create mode 100644 face-snapShot/src/main/java/com/dkha/face/FaceSnapShotMain.java create mode 100644 face-snapShot/src/main/java/com/dkha/face/contral/FaceSnapContal.java create mode 100644 face-snapShot/src/main/java/com/dkha/face/modules/ReceiveSnapVO.java create mode 100644 face-snapShot/src/main/java/com/dkha/face/modules/RecevieVO.java create mode 100644 face-snapShot/src/main/resources/application.yml create mode 100644 face-task/pom.xml create mode 100644 face-task/src/main/java/com/dkha/task/FaceTaskMain.java create mode 100644 face-task/src/main/java/com/dkha/task/comm/TimerData.java create mode 100644 face-task/src/main/java/com/dkha/task/config/MyMetaObjectHandler.java create mode 100644 face-task/src/main/java/com/dkha/task/config/WebSocketConfig.java create mode 100644 face-task/src/main/java/com/dkha/task/contral/TestContral.java create mode 100644 face-task/src/main/java/com/dkha/task/contral/TimerContral.java create mode 100644 face-task/src/main/java/com/dkha/task/modual/BaseDao.java create mode 100644 face-task/src/main/java/com/dkha/task/modual/SysUserTokenEntity.java create mode 100644 face-task/src/main/java/com/dkha/task/modual/entity/ControlBayonetMid.java create mode 100644 face-task/src/main/java/com/dkha/task/modual/entity/FaceCamera.java create mode 100644 face-task/src/main/java/com/dkha/task/modual/entity/FaceTrackEntity.java create mode 100644 face-task/src/main/java/com/dkha/task/modual/mapper/ControlBayonetMidMapper.java create mode 100644 face-task/src/main/java/com/dkha/task/modual/mapper/FaceTrackMapper.java create mode 100644 face-task/src/main/java/com/dkha/task/modual/mapper/SysUserTokenDao.java create mode 100644 face-task/src/main/java/com/dkha/task/modual/vo/BayonetVO.java create mode 100644 face-task/src/main/java/com/dkha/task/modual/vo/FaceTrackVO.java create mode 100644 face-task/src/main/java/com/dkha/task/modual/vo/ReturnVO.java create mode 100644 face-task/src/main/java/com/dkha/task/service/ApiDeelService.java create mode 100644 face-task/src/main/java/com/dkha/task/service/FaceTrackService.java create mode 100644 face-task/src/main/java/com/dkha/task/service/IControlBayonetMidService.java create mode 100644 face-task/src/main/java/com/dkha/task/service/WebSocketContral.java create mode 100644 face-task/src/main/java/com/dkha/task/service/impl/ApiDeelServiceImpl.java create mode 100644 face-task/src/main/java/com/dkha/task/service/impl/AsyncServiceImpl.java create mode 100644 face-task/src/main/java/com/dkha/task/service/impl/ControlBayonetMidServiceImpl.java create mode 100644 face-task/src/main/java/com/dkha/task/service/impl/FaceTrackServiceImpl.java create mode 100644 face-task/src/main/java/com/dkha/task/util/PeopleComparableUitl.java create mode 100644 face-task/src/main/resources/application-dev.yml create mode 100644 face-task/src/main/resources/application-prod.yml create mode 100644 face-task/src/main/resources/application-test.yml create mode 100644 face-task/src/main/resources/application.yml create mode 100644 face-task/src/main/resources/logback-spring.xml create mode 100644 face-task/src/main/resources/mybatis/mapper/ControlBayonetMidMapper.xml create mode 100644 face-task/src/main/resources/mybatis/mapper/FaceTrackMapper.xml create mode 100644 face-task/src/main/resources/mybatis/mapper/sys/SysUserTokenDao.xml create mode 100644 face-task/src/main/resources/mybatis/mybatis.cfg.xml create mode 100644 face-task/src/main/resources/static/images/Ink_Note.ico create mode 100644 face-task/src/main/resources/static/images/a64.ico create mode 100644 face-task/src/main/resources/static/images/bg.png create mode 100644 face-task/src/main/resources/static/images/bg_blue.png create mode 100644 face-task/src/main/resources/static/images/bg_green.png create mode 100644 face-task/src/main/resources/static/images/bg_red.png create mode 100644 face-task/src/main/resources/static/images/deskicon.ico create mode 100644 face-task/src/main/resources/static/images/favicon.ico create mode 100644 face-task/src/main/resources/static/images/jt.png create mode 100644 face-task/src/main/resources/static/images/pulse.ico create mode 100644 face-task/src/main/resources/static/images/ringtones.ico create mode 100644 face-task/src/main/resources/static/images/settings.ico create mode 100644 face-task/src/main/resources/static/index.html create mode 100644 face-task/src/main/resources/static/index1.html create mode 100644 face-task/src/main/resources/static/index2.html create mode 100644 face-task/src/main/resources/static/index4.html create mode 100644 face-task/src/main/resources/static/indexline.html create mode 100644 face-task/src/main/resources/static/indexmove.html create mode 100644 face-task/src/main/resources/static/js/baidu.js create mode 100644 face-task/src/main/resources/static/js/jiemi.js create mode 100644 face-task/src/main/resources/static/js/jiemi2.js create mode 100644 face-task/src/main/resources/static/js/jquery-1.6.2.min.js create mode 100644 face-task/src/main/resources/static/js/jquery-3.2.1.slim.min.js create mode 100644 face-task/src/main/resources/static/js/yj.js create mode 100644 face-task/src/main/resources/static/map.html create mode 100644 face-task/src/main/resources/static/mp3/song.mp3 create mode 100644 pom.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0a0dceb --- /dev/null +++ b/.gitignore @@ -0,0 +1,35 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/** +!**/src/test/** +.yml +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ + +### VS Code ### +.vscode/ +face-common/src/test/ +face-server/src/test/resources/ + +/.idea/workspace.xml +/.idea/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..1ef26ad --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# 不不不不v +``` +mvn install +``` + +#的点点滴滴 +``` +mvn clean +``` diff --git a/doc/face.PDM b/doc/face.PDM new file mode 100644 index 0000000..9ed3861 --- /dev/null +++ b/doc/face.PDM @@ -0,0 +1,9554 @@ + + + + + + + + + +90F6E7F8-C9CE-45FA-A6FC-EFEE42BCE6C6 +PhysicalDataModel_1 +PhysicalDataModel_1 +1573436673 +Mhb +1575889044 +Mhb +[FolderOptions] + +[FolderOptions\Physical Objects] +GenerationCheckModel=Yes +GenerationPath= +GenerationOptions= +GenerationTasks= +GenerationTargets= +GenerationSelections= +RevPkey=Yes +RevFkey=Yes +RevAkey=Yes +RevCheck=Yes +RevIndx=Yes +RevOpts=Yes +RevViewAsTabl=No +RevViewOpts=Yes +RevSystAsTabl=Yes +RevTablPerm=No +RevViewPerm=No +RevProcPerm=No +RevDbpkPerm=No +RevSqncPerm=No +RevAdtPerm=No +RevUserPriv=No +RevUserOpts=No +RevGrpePriv=No +RevRolePriv=No +RevDtbsOpts=Yes +RevDtbsPerm=No +RevViewIndx=Yes +RevJidxOpts=Yes +RevStats=No +RevTspcPerm=No +RevCaseSensitive=No +GenTrgrStdMsg=Yes +GenTrgrMsgTab= +GenTrgrMsgNo= +GenTrgrMsgTxt= +TrgrPreserve=No +TrgrIns=Yes +TrgrUpd=Yes +TrgrDel=Yes +TrgrC2Ins=Yes +TrgrC2Upd=Yes +TrgrC3=Yes +TrgrC4=Yes +TrgrC5=Yes +TrgrC6=Yes +TrgrC7=Yes +TrgrC8=Yes +TrgrC9=Yes +TrgrC10=Yes +TrgrC11=Yes +TrgrC1=Yes +TrgrC12Ins=Yes +TrgrC12Upd=Yes +TrgrC13=Yes +UpdateTableStatistics=Yes +UpdateColumnStatistics=Yes + +[FolderOptions\Physical Objects\Database Generation] +GenScriptName=face.sql +GenScriptName0= +GenScriptName1= +GenScriptName2= +GenScriptName3= +GenScriptName4= +GenScriptName5= +GenScriptName6= +GenScriptName7= +GenScriptName8= +GenScriptName9= +GenPathName=C:\Users\Mhb\Desktop\face\ +GenSingleFile=Yes +GenODBC=No +GenCheckModel=Yes +GenScriptPrev=Yes +GenArchiveModel=No +GenUseSync=No +GenSyncChoice=0 +GenSyncArch= +GenSyncRmg=0 + +[FolderOptions\Physical Objects\Database Generation\Format] +GenScriptTitle=No +GenScriptNamLabl=No +GenScriptQDtbs=No +GenScriptQOwnr=No +GenScriptCase=0 +GenScriptEncoding=UTF8 +GenScriptNAcct=No +IdentifierDelimiter=" + +[FolderOptions\Physical Objects\Database Generation\Database] +Create=Yes +Open=Yes +Close=Yes +Drop=Yes +Permission=No + +[FolderOptions\Physical Objects\Database Generation\Database\Create] +Physical Options=Yes +Header=Yes +Footer=Yes + +[FolderOptions\Physical Objects\Database Generation\Tablespace] +Create=Yes +Drop=Yes +Comment=Yes +Permission=No + +[FolderOptions\Physical Objects\Database Generation\Tablespace\Create] +Header=Yes +Footer=Yes + +[FolderOptions\Physical Objects\Database Generation\Storage] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\User] +Create=Yes +Drop=Yes +Comment=Yes +Privilege=No + +[FolderOptions\Physical Objects\Database Generation\User\Create] +Physical Options=No + +[FolderOptions\Physical Objects\Database Generation\Group] +Create=Yes +Drop=Yes +Comment=Yes +Privilege=No + +[FolderOptions\Physical Objects\Database Generation\Role] +Create=Yes +Drop=Yes +Privilege=No + +[FolderOptions\Physical Objects\Database Generation\UserDefinedDataType] +Create=Yes +Comment=Yes +Drop=Yes + +[FolderOptions\Physical Objects\Database Generation\UserDefinedDataType\Create] +Default value=Yes +Check=Yes + +[FolderOptions\Physical Objects\Database Generation\AbstractDataType] +Create=Yes +Header=Yes +Footer=Yes +Drop=Yes +Comment=Yes +Install JAVA class=Yes +Remove JAVA class=Yes +Permission=No + +[FolderOptions\Physical Objects\Database Generation\Rule] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\Default] +Create=Yes +Comment=Yes +Drop=Yes + +[FolderOptions\Physical Objects\Database Generation\Sequence] +Create=Yes +Drop=Yes +Comment=Yes +Permission=No + +[FolderOptions\Physical Objects\Database Generation\Table&&Column] + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Table] +Create=Yes +Drop=Yes +Comment=Yes +Permission=No + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Table\Create] +Check=Yes +Physical Options=Yes +Header=Yes +Footer=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Table\Create\Check] +Constraint declaration=No + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Column] +User datatype=No +Default value=Yes +Check=Yes +Physical Options=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Column\Check] +Constraint declaration=No + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Key] + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Key\Primary key] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Key\Primary key\Create] +Constraint declaration=No +Physical Options=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Key\Alternate key] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Key\Alternate key\Create] +Constraint declaration=No +Physical Options=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Foreign key] +Create=No +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Foreign key\Create] +Constraint declaration=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Index] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Index\Create] +Constraint declaration=Yes +Physical Options=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Index\Filter] +Primary key=No +Foreign key=No +Alternate key=No +Cluster=Yes +Other=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Trigger] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Trigger\Filter] +For insert=Yes +For update=Yes +For delete=Yes +For other=Yes + +[FolderOptions\Physical Objects\Database Generation\View] +Create=Yes +Drop=Yes +Comment=Yes +Permission=No + +[FolderOptions\Physical Objects\Database Generation\View\Create] +Force Column list=No +Physical Options=Yes +Header=Yes +Footer=Yes + +[FolderOptions\Physical Objects\Database Generation\View\ViewColumn] +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\View\ViewIndex] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\View\ViewIndex\Create] +Physical Options=Yes + +[FolderOptions\Physical Objects\Database Generation\View\ViewIndex\Filter] +Cluster=Yes +Other=Yes + +[FolderOptions\Physical Objects\Database Generation\View\Trigger] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\View\Trigger\Filter] +For insert=Yes +For update=Yes +For delete=Yes +For other=Yes + +[FolderOptions\Physical Objects\Database Generation\DBMSTrigger] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\Synonym] +Create=Yes +Drop=Yes + +[FolderOptions\Physical Objects\Database Generation\Synonym\Filter] +Table=Yes +View=Yes +Proc=Yes +Synonym=Yes +Database Package=Yes +Sequence=Yes + +[FolderOptions\Physical Objects\Database Generation\JoinIndex] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\JoinIndex\Create] +Physical Options=Yes +Header=Yes +Footer=Yes + +[FolderOptions\Physical Objects\Database Generation\Procedure] +Create=Yes +Drop=Yes +Comment=Yes +Permission=No + +[FolderOptions\Physical Objects\Database Generation\Procedure\Create] +Header=Yes +Footer=Yes + +[FolderOptions\Physical Objects\Database Generation\DatabasePackage] +Create=Yes +Drop=Yes +Permission=No + +[FolderOptions\Physical Objects\Database Generation\WebService] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\Dimension] +Create=Yes +Drop=Yes + +[FolderOptions\Physical Objects\Database Generation\Synchronization] +GenBackupTabl=1 +GenKeepBackTabl=1 +GenTmpTablDrop=No +GenKeepTablOpts=No + +[FolderOptions\Physical Objects\Test Data] +GenDataPathName= +GenDataSinglefile=Yes +GenDataScriptName=testdata +GenDataScriptName0= +GenDataScriptName1= +GenDataScriptName2= +GenDataScriptName3= +GenDataScriptName4= +GenDataScriptName5= +GenDataScriptName6= +GenDataScriptName7= +GenDataScriptName8= +GenDataScriptName9= +GenDataOdbc=0 +GenDataDelOld=No +GenDataTitle=Yes +GenDataDefNumRows=20 +GenDataCommit=0 +GenDataPacket=0 +GenDataOwner=Yes +GenDataProfNumb= +GenDataProfChar= +GenDataProfDate= +GenDataCSVSeparator=, +GenDataFileFormat=CSV +GenDataUseWizard=No + +[FolderOptions\Pdm] +IndxIQName=%COLUMN%_%INDEXTYPE% +IndxPK=Yes +IndxFK=Yes +IndxAK=Yes +IndxPKName=%TABLE%_PK +IndxFKName=%REFR%_FK +IndxAKName=%AKEY%_AK +IndxPreserve=No +IndxThreshold=0 +IndxStats=No +RefrPreserve=No +JidxPreserve=No +RbldMultiFact=Yes +RbldMultiDim=Yes +RbldMultiJidx=Yes +CubePreserve=No +TablStProcPreserve=No +ProcDepPreserve=Yes +TrgrDepPreserve=Yes +CubeScriptPath= +CubeScriptCase=0 +CubeScriptEncoding=ANSI +CubeScriptNacct=No +CubeScriptHeader=No +CubeScriptExt=csv +CubeScriptExt0=txt +CubeScriptExt1= +CubeScriptExt2= +CubeScriptSep=, +CubeScriptDeli=" +EstimationYears=0 +DfltDomnName=D_%.U:VALUE% +DfltColnName=D_%.U:VALUE% +DfltReuse=Yes +DfltDrop=Yes + +[FolderOptions\CheckModel] + +[FolderOptions\CheckModel\Package] + +[FolderOptions\CheckModel\Package\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\CheckPackageMissTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\DefaultCheckPackageMissTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\CircularReference] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\ConstraintName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\CnstMaxLen] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\CircularDependency] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\ShortcutUniqCode] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Table] + +[FolderOptions\CheckModel\Table\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\UniqIndex] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\MaxLen - NAME] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\EmptyColl - COLNCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\EmptyColl - INDXCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\EmptyColl - KEYCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\SerialColumnNumber] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\EmptyCollYesYes] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\TableIndexes] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\Mapping] +CheckSeverity=No +FixRequested=Yes +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\MappingSFMap] +CheckSeverity=No +FixRequested=Yes +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\EmptyColl - PERMCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Table\CheckTablePartitionKey] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\CheckTableStartDate] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\CheckTableRefNoLifecycle] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\CheckTableSourceMapping] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\CheckTablePartialColumnMapping] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\CheckTableKeyColumnMapping] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\CheckTableNotOnLifecycleTablespace] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\MYSQL50_Table_Table_storage_type] +CheckSeverity=No +FixRequested=Yes +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column] + +[FolderOptions\CheckModel\Table.Column\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\DomainDivergence] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\ColumnMandatory] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\CheckNumParam] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\CheckPrecSupLng] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\CheckUndefDttp] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\FkeyDttpDivergence] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\FkeyCheckDivergence] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\ColnSqncNoKey] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\ColnSqncDttp] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\SerialColumnFK] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\ColumnCompExpr] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\CheckColumnOneToOneMapping] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\CheckColumnDataTypeMapping] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\CheckColumnNoMapping] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\CheckDttpIncompatibleFormat] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\MYSQL50_Column_Auto_increment_key] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\MYSQL50_Column_Datatype_attributes] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index] + +[FolderOptions\CheckModel\Table.Index\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\EmptyColl - CIDXCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\UndefIndexType] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\IndexColumnCount] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\IQIndxHNGUniq] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\CheckIncludeColl - Tabl] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\MYSQL50_Index_Fulltext_indexes_validity] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key] + +[FolderOptions\CheckModel\Table.Key\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\EmptyColl - COLNCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\CheckIncludeColl - Tabl] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\MultiKeySqnc] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Trigger] + +[FolderOptions\CheckModel\Table.Trigger\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Trigger\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Trigger\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Trigger\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Trigger\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Trigger\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Trigger\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Trigger\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Join Index] + +[FolderOptions\CheckModel\Join Index\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Join Index\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Join Index\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Join Index\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Join Index\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Join Index\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Join Index\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View] + +[FolderOptions\CheckModel\View\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View\EmptyColl - PERMCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\View.View Index] + +[FolderOptions\CheckModel\View.View Index\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\EmptyColl - CIDXCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\IndexColumnCount] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\CheckIncludeColl - Tabl] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference] + +[FolderOptions\CheckModel\Reference\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\Reflexive] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\EmptyColl - RFJNCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\IncompleteJoin] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\JoinOrder] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View Reference] + +[FolderOptions\CheckModel\View Reference\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View Reference\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View Reference\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View Reference\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View Reference\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View Reference\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View Reference\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View Reference\EmptyColl - VRFJNCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain] + +[FolderOptions\CheckModel\Domain\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\CheckNumParam] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\CheckPrecSupLng] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\CheckUndefDttp] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\CheckDttpIncompatibleFormat] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default] + +[FolderOptions\CheckModel\Default\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default\DfltValeEmpty] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default\DfltSameVale] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\User] + +[FolderOptions\CheckModel\User\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\User\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\User\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\User\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\User\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\User\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\User\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\User\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\User\UniquePassword] +CheckSeverity=No +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Group] + +[FolderOptions\CheckModel\Group\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Group\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Group\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Group\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Group\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Group\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Group\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Group\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Group\EmptyColl - USERCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Group\UniquePassword] +CheckSeverity=No +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Role] + +[FolderOptions\CheckModel\Role\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Role\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Role\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Role\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Role\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Role\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Role\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Role\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Role\EmptyColl - USERCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure] + +[FolderOptions\CheckModel\Procedure\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure\ProcBodyEmpty] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure\EmptyColl - PERMCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\DBMS Trigger] + +[FolderOptions\CheckModel\DBMS Trigger\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\DBMS Trigger\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\DBMS Trigger\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\DBMS Trigger\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\DBMS Trigger\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\DBMS Trigger\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\DBMS Trigger\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\DBMS Trigger\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\DBMS Trigger\DbmsTriggerEvent] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source] + +[FolderOptions\CheckModel\Data Source\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source\EmptyColl - MODLSRC] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source\DtscTargets] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source\CheckDataSourceModels] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Horizontal Partitioning] + +[FolderOptions\CheckModel\Horizontal Partitioning\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Horizontal Partitioning\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Horizontal Partitioning\EmptyColl - PARTCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Horizontal Partitioning\TargetTables] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Vertical Partitioning] + +[FolderOptions\CheckModel\Vertical Partitioning\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Vertical Partitioning\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Vertical Partitioning\EmptyColl - PARTCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Vertical Partitioning\TargetTables] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table Collapsing] + +[FolderOptions\CheckModel\Table Collapsing\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table Collapsing\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table Collapsing\EmptyColl - TargetTable] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table Collapsing\TargetTables] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact] + +[FolderOptions\CheckModel\Fact\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\EmptyColl - MEASCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\Mapping] +CheckSeverity=No +FixRequested=Yes +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\MappingSFMap] +CheckSeverity=No +FixRequested=Yes +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\EmptyColl - ALLOLINKCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\CubeDupAssociation] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension] + +[FolderOptions\CheckModel\Dimension\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\EmptyColl - DATTRCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\EmptyColl - HIERCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\DimnDupHierarchy] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\DimnDefHierarchy] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\Mapping] +CheckSeverity=No +FixRequested=Yes +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\MappingSFMap] +CheckSeverity=No +FixRequested=Yes +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\SerialColumnNumber] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Association] + +[FolderOptions\CheckModel\Association\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Association\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Association\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Association\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Association\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Association\EmptyColl - Hierarchy] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Attribute] + +[FolderOptions\CheckModel\Dimension.Attribute\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Attribute\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Attribute\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Attribute\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Attribute\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Attribute\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Attribute\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact.Measure] + +[FolderOptions\CheckModel\Fact.Measure\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact.Measure\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact.Measure\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact.Measure\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact.Measure\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact.Measure\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact.Measure\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Hierarchy] + +[FolderOptions\CheckModel\Dimension.Hierarchy\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Hierarchy\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Hierarchy\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Hierarchy\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Hierarchy\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Hierarchy\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Hierarchy\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Hierarchy\EmptyColl - DATTRCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym] + +[FolderOptions\CheckModel\Synonym\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym\MaxLen - NAME] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym\EmptyColl - BASEOBJ] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type] + +[FolderOptions\CheckModel\Abstract Data Type\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type\AdtInstantiable] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type\AdtAbstractUsed] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure] + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\AdtProcUniqName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\UniqueDefinition] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\ReturnDataType] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package] + +[FolderOptions\CheckModel\Database Package\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\MaxLen - NAME] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\EmptyColl - PROCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\EmptyColl - CURCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Database Package\EmptyColl - VARCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Database Package\EmptyColl - TYPCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Database Package\EmptyColl - EXCCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Database Package.Database Package Procedure] + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\UniqueDefinition] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\EmptyColl - PARM] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\ReturnDataType] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Sequence] + +[FolderOptions\CheckModel\Sequence\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Sequence\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Sequence\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Sequence\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Sequence\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Sequence\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Sequence\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Sequence\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor] + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\UniqueDefinition] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\ReturnDataType] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\EmptyColl - PARM] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Database Package.Database Package Variable] + +[FolderOptions\CheckModel\Database Package.Database Package Variable\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Variable\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Variable\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Variable\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Variable\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Variable\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Variable\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Variable\CheckUndefDttp] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Type] + +[FolderOptions\CheckModel\Database Package.Database Package Type\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Type\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Type\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Type\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Type\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Type\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Type\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Type\UniqueDefinition] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Exception] + +[FolderOptions\CheckModel\Database Package.Database Package Exception\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Exception\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Exception\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Exception\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Exception\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Exception\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Exception\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Tablespace] + +[FolderOptions\CheckModel\Tablespace\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Tablespace\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Tablespace\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Tablespace\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Tablespace\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Tablespace\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Tablespace\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Tablespace\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Tablespace\IsObjectUsed] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Storage] + +[FolderOptions\CheckModel\Storage\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Storage\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Storage\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Storage\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Storage\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Storage\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Storage\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Storage\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Storage\IsObjectUsed] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database] + +[FolderOptions\CheckModel\Database\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database\IsObjectUsed] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service] + +[FolderOptions\CheckModel\Web Service\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service.Web Operation] + +[FolderOptions\CheckModel\Web Service.Web Operation\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service.Web Operation\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service.Web Operation\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service.Web Operation\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service.Web Operation\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service.Web Operation\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service.Web Operation\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service.Web Operation\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle] + +[FolderOptions\CheckModel\Lifecycle\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle\CheckLifecyclePhase] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle\CheckLifecycleRetention] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle\CheckPartitionRange] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase] + +[FolderOptions\CheckModel\Lifecycle.Phase\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckPhaseTbspace] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckPhaseIQTbspace] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckPhaseDuplicateTbspace] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckPhaseTbspaceCurrency] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckPhaseRetention] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckPhaseIdlePeriod] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckPhaseDataSource] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckPhaseExternalOnFirst] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Replication] + +[FolderOptions\CheckModel\Replication\PartialReplication] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Business Rule] + +[FolderOptions\CheckModel\Business Rule\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Business Rule\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Business Rule\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Business Rule\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Business Rule\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Business Rule\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Business Rule\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Business Rule\EmptyColl - OBJCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Object] + +[FolderOptions\CheckModel\Extended Object\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Object\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Object\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Object\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Object\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Object\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Object\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Link] + +[FolderOptions\CheckModel\Extended Link\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Link\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Link\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Link\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Link\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Link\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Link\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\File] + +[FolderOptions\CheckModel\File\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\File\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\File\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\File\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\File\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\File\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\File\CheckPathExists] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Format] + +[FolderOptions\CheckModel\Data Format\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Format\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Format\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Format\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Format\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Format\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Format\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Format\CheckDataFormatNullExpression] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes +[ModelOptions] + +[ModelOptions\Physical Objects] +CaseSensitive=No +DisplayName=Yes +EnableTrans=No +UseTerm=No +EnableRequirements=No +EnableFullShortcut=Yes +DefaultDttp= +IgnoreOwner=No +RebuildTrigger=Yes +RefrUnique=No +RefrAutoMigrate=Yes +RefrMigrateReuse=Yes +RefrMigrateDomain=Yes +RefrMigrateCheck=Yes +RefrMigrateRule=Yes +RefrMigrateExtd=No +RefrMigrDefaultLink=No +RefrDfltImpl=D +RefrPrgtColn=No +RefrMigrateToEnd=No +RebuildTriggerDep=No +ColnFKName=%.3:PARENT%_%COLUMN% +ColnFKNameUse=No +DomnCopyDttp=Yes +DomnCopyChck=No +DomnCopyRule=No +DomnCopyMand=No +DomnCopyExtd=No +DomnCopyProf=No +Notation=0 +DomnDefaultMandatory=No +ColnDefaultMandatory=No +TablDefaultOwner= +ViewDefaultOwner= +TrgrDefaultOwnerTabl= +TrgrDefaultOwnerView= +IdxDefaultOwnerTabl= +IdxDefaultOwnerView= +JdxDefaultOwner= +DBPackDefaultOwner= +SeqDefaultOwner= +ProcDefaultOwner= +DBMSTrgrDefaultOwner= +Currency=USD +RefrDeleteConstraint=1 +RefrUpdateConstraint=1 +RefrParentMandatory=No +RefrParentChangeAllow=Yes +RefrCheckOnCommit=No + +[ModelOptions\Physical Objects\NamingOptionsTemplates] + +[ModelOptions\Physical Objects\ClssNamingOptions] + +[ModelOptions\Physical Objects\ClssNamingOptions\PDMPCKG] + +[ModelOptions\Physical Objects\ClssNamingOptions\PDMPCKG\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\PDMPCKG\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\PDMDOMN] + +[ModelOptions\Physical Objects\ClssNamingOptions\PDMDOMN\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\PDMDOMN\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\TABL] + +[ModelOptions\Physical Objects\ClssNamingOptions\TABL\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\TABL\Code] +Template= +MaxLen=64 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\COLN] + +[ModelOptions\Physical Objects\ClssNamingOptions\COLN\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\COLN\Code] +Template= +MaxLen=64 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\INDX] + +[ModelOptions\Physical Objects\ClssNamingOptions\INDX\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\INDX\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\REFR] + +[ModelOptions\Physical Objects\ClssNamingOptions\REFR\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\REFR\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\VREF] + +[ModelOptions\Physical Objects\ClssNamingOptions\VREF\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\VREF\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\VIEW] + +[ModelOptions\Physical Objects\ClssNamingOptions\VIEW\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\VIEW\Code] +Template= +MaxLen=64 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\VIEWC] + +[ModelOptions\Physical Objects\ClssNamingOptions\VIEWC\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\VIEWC\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\WEBSERV] + +[ModelOptions\Physical Objects\ClssNamingOptions\WEBSERV\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\WEBSERV\Code] +Template= +MaxLen=254 +Case=M +ValidChar='a'-'z','A'-'Z','0'-'9',"/-_.!~*'()" +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\WEBOP] + +[ModelOptions\Physical Objects\ClssNamingOptions\WEBOP\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\WEBOP\Code] +Template= +MaxLen=254 +Case=M +ValidChar='a'-'z','A'-'Z','0'-'9',"/-_.!~*'()" +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\WPARAM] + +[ModelOptions\Physical Objects\ClssNamingOptions\WPARAM\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\WPARAM\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\FACT] + +[ModelOptions\Physical Objects\ClssNamingOptions\FACT\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\FACT\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\DIMN] + +[ModelOptions\Physical Objects\ClssNamingOptions\DIMN\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\DIMN\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\MEAS] + +[ModelOptions\Physical Objects\ClssNamingOptions\MEAS\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\MEAS\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\DATTR] + +[ModelOptions\Physical Objects\ClssNamingOptions\DATTR\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\DATTR\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\FILO] + +[ModelOptions\Physical Objects\ClssNamingOptions\FILO\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\FILO\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\FRMEOBJ] + +[ModelOptions\Physical Objects\ClssNamingOptions\FRMEOBJ\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\FRMEOBJ\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\FRMELNK] + +[ModelOptions\Physical Objects\ClssNamingOptions\FRMELNK\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\FRMELNK\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\DefaultClass] + +[ModelOptions\Physical Objects\ClssNamingOptions\DefaultClass\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\DefaultClass\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Connection] + +[ModelOptions\Pdm] + +[ModelOptions\Generate] + +[ModelOptions\Generate\Xsm] +GenRootElement=Yes +GenComplexType=No +GenAttribute=Yes +CheckModel=Yes +SaveLinks=Yes +ORMapping=No +NameToCode=No + +[ModelOptions\Generate\Pdm] +RRMapping=No + +[ModelOptions\Generate\Cdm] +CheckModel=Yes +SaveLinks=Yes +NameToCode=No +Notation=2 + +[ModelOptions\Generate\Oom] +CheckModel=Yes +SaveLinks=Yes +ORMapping=No +NameToCode=Yes +ClassPrefix= + +[ModelOptions\Generate\Ldm] +CheckModel=Yes +SaveLinks=Yes +NameToCode=No + +[ModelOptions\Default Opts] + +[ModelOptions\Default Opts\TABL] +PhysOpts= + +[ModelOptions\Default Opts\COLN] +PhysOpts= + +[ModelOptions\Default Opts\INDX] +PhysOpts= + +[ModelOptions\Default Opts\AKEY] +PhysOpts= + +[ModelOptions\Default Opts\PKEY] +PhysOpts= + +[ModelOptions\Default Opts\STOR] +PhysOpts= + +[ModelOptions\Default Opts\TSPC] +PhysOpts= + +[ModelOptions\Default Opts\SQNC] +PhysOpts= + +[ModelOptions\Default Opts\DTBS] +PhysOpts= + +[ModelOptions\Default Opts\USER] +PhysOpts= + +[ModelOptions\Default Opts\JIDX] +PhysOpts= + + +9E1F518A-7D51-4939-BAD2-58F09FDE6A85 +MySQL 5.0 +MYSQL50 +1573436673 +Mhb +1573436673 +Mhb + +F4F16ECD-F2F1-4006-AF6F-638D5C65F35E +4BA9F647-DAB1-11D1-9944-006097355D9B + + + + +AC53207B-2EBA-4AC0-96E5-909C17A10072 +PhysicalDiagram_1 +PhysicalDiagram_1 +1573436673 +Mhb +1575889044 +Mhb +[DisplayPreferences] + +[DisplayPreferences\PDM] + +[DisplayPreferences\General] +Adjust to text=Yes +Snap Grid=No +Constrain Labels=Yes +Display Grid=No +Show Page Delimiter=Yes +Show Links intersections=Yes +Activate automatic link routing=Yes +Grid size=0 +Graphic unit=2 +Window color=255, 255, 255 +Background image= +Background mode=8 +Watermark image= +Watermark mode=8 +Show watermark on screen=No +Gradient mode=0 +Gradient end color=255, 255, 255 +Show Swimlane=No +SwimlaneVert=Yes +TreeVert=No +CompDark=0 + +[DisplayPreferences\Object] +Show Icon=No +Mode=2 +Trunc Length=40 +Word Length=40 +Word Text=!"#$%&')*+,-./:;=>?@\]^_`|}~ +Shortcut IntIcon=Yes +Shortcut IntLoct=Yes +Shortcut IntFullPath=No +Shortcut IntLastPackage=Yes +Shortcut ExtIcon=Yes +Shortcut ExtLoct=No +Shortcut ExtFullPath=No +Shortcut ExtLastPackage=Yes +Shortcut ExtIncludeModl=Yes +EObjShowStrn=Yes +ExtendedObject.Comment=No +ExtendedObject.IconPicture=No +ExtendedObject.TextStyle=No +ExtendedObject_SymbolLayout=<Form>[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="&lt;&lt;" Suffix="&gt;&gt;" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Object Name" Attribute="DisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF] <Separator Name="Separator" />[CRLF] <StandardAttribute Name="Comment" Attribute="Comment" Prefix="" Suffix="" Alignment="LEFT" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Icon" Attribute="IconPicture" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF] <StandardAttribute Name="Force top align" Attribute="TextStyle" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF]</Form> +ELnkShowStrn=Yes +ELnkShowName=Yes +ExtendedLink_SymbolLayout=<Form>[CRLF] <Form Name="Center" >[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="&lt;&lt;" Suffix="&gt;&gt;" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] </Form>[CRLF] <Form Name="Source" >[CRLF] </Form>[CRLF] <Form Name="Destination" >[CRLF] </Form>[CRLF]</Form> +FileObject.Stereotype=No +FileObject.DisplayName=Yes +FileObject.LocationOrName=No +FileObject.IconPicture=No +FileObject.TextStyle=No +FileObject.IconMode=Yes +FileObject_SymbolLayout=<Form>[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="&lt;&lt;" Suffix="&gt;&gt;" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <ExclusiveChoice Name="Exclusive Choice" Mandatory="Yes" Display="HorizontalRadios" >[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Location" Attribute="LocationOrName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] </ExclusiveChoice>[CRLF] <StandardAttribute Name="Icon" Attribute="IconPicture" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF] <StandardAttribute Name="Force top align" Attribute="TextStyle" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF]</Form> +Package.Stereotype=Yes +Package.Comment=No +Package.IconPicture=No +Package.TextStyle=No +Package_SymbolLayout=<Form>[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="&lt;&lt;" Suffix="&gt;&gt;" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF] <Separator Name="Separator" />[CRLF] <StandardAttribute Name="Comment" Attribute="Comment" Prefix="" Suffix="" Alignment="LEFT" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Icon" Attribute="IconPicture" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF] <StandardAttribute Name="Force top align" Attribute="TextStyle" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF]</Form> +Display Model Version=Yes +Table.Stereotype=Yes +Table.DisplayName=Yes +Table.OwnerDisplayName=No +Table.Columns=Yes +Table.Columns._Filter="All Columns" PDMCOLNALL +Table.Columns._Columns=Stereotype DataType KeyIndicator +Table.Columns._Limit=-5 +Table.Keys=No +Table.Keys._Columns=Stereotype Indicator +Table.Indexes=No +Table.Indexes._Columns=Stereotype +Table.Triggers=No +Table.Triggers._Columns=Stereotype +Table.Comment=No +Table.IconPicture=No +Table.TextStyle=No +Table_SymbolLayout=<Form>[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="&lt;&lt;" Suffix="&gt;&gt;" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <ExclusiveChoice Name="Exclusive Choice" Mandatory="Yes" Display="HorizontalRadios" >[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Owner and Name" Attribute="OwnerDisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] </ExclusiveChoice>[CRLF] <Separator Name="Separator" />[CRLF] <StandardCollection Name="Columns" Collection="Columns" Columns="Stereotype No\r\nDisplayName Yes\r\nDataType No\r\nSymbolDataType No &quot;Domain or Data type&quot;\r\nDomain No\r\nKeyIndicator No\r\nIndexIndicator No\r\nNullStatus No" Filters="&quot;All Columns&quot; PDMCOLNALL &quot;&quot;\r\n&quot;PK Columns&quot; PDMCOLNPK &quot;\&quot;PRIM \&quot;TRUE\&quot; TRUE\&quot;&quot;\r\n&quot;Key Columns&quot; PDMCOLNKEY &quot;\&quot;KEYS \&quot;TRUE\&quot; TRUE\&quot;&quot;" HasLimit="Yes" HideEmpty="No" Caption="" Mandatory="No" />[CRLF] <StandardCollection Name="Keys" Collection="Keys" Columns="Stereotype No\r\nDisplayName Yes\r\nIndicator No" HasLimit="No" HideEmpty="No" Caption="" Mandatory="No" />[CRLF] <StandardCollection Name="Indexes" Collection="Indexes" Columns="Stereotype No\r\nDisplayName Yes\r\nIndicator No" HasLimit="No" HideEmpty="No" Caption="" Mandatory="No" />[CRLF] <StandardCollection Name="Triggers" Collection="Triggers" Columns="Stereotype No\r\nDisplayName Yes" HasLimit="No" HideEmpty="No" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Comment" Attribute="Comment" Prefix="" Suffix="" Alignment="LEFT" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Icon" Attribute="IconPicture" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF] <StandardAttribute Name="Force top align" Attribute="TextStyle" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF]</Form> +View.Stereotype=Yes +View.DisplayName=Yes +View.OwnerDisplayName=No +View.Columns=Yes +View.Columns._Columns=DisplayName +View.Columns._Limit=-5 +View.TemporaryVTables=Yes +View.Indexes=No +View.Comment=No +View.IconPicture=No +View.TextStyle=No +View_SymbolLayout=<Form>[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="&lt;&lt;" Suffix="&gt;&gt;" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <ExclusiveChoice Name="Exclusive Choice" Mandatory="Yes" Display="HorizontalRadios" >[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Owner and Name" Attribute="OwnerDisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] </ExclusiveChoice>[CRLF] <Separator Name="Separator" />[CRLF] <StandardCollection Name="Columns" Collection="Columns" Columns="DisplayName No\r\nExpression No\r\nDataType No\r\nSymbolDataType No &quot;Domain or Data type&quot;\r\nIndexIndicator No" HasLimit="Yes" HideEmpty="No" Caption="" Mandatory="No" />[CRLF] <StandardCollection Name="Tables" Collection="TemporaryVTables" Columns="Name Yes" HasLimit="No" HideEmpty="No" Caption="" Mandatory="No" />[CRLF] <StandardCollection Name="Indexes" Collection="Indexes" Columns="DisplayName Yes" HasLimit="No" HideEmpty="No" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Comment" Attribute="Comment" Prefix="" Suffix="" Alignment="LEFT" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Icon" Attribute="IconPicture" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF] <StandardAttribute Name="Force top align" Attribute="TextStyle" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF]</Form> +Procedure.Stereotype=No +Procedure.DisplayName=Yes +Procedure.OwnerDisplayName=No +Procedure.Comment=No +Procedure.IconPicture=No +Procedure.TextStyle=No +Procedure_SymbolLayout=<Form>[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="&lt;&lt;" Suffix="&gt;&gt;" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <ExclusiveChoice Name="Exclusive Choice" Mandatory="Yes" Display="HorizontalRadios" >[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Owner and Name" Attribute="OwnerDisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] </ExclusiveChoice>[CRLF] <Separator Name="Separator" />[CRLF] <StandardAttribute Name="Comment" Attribute="Comment" Prefix="" Suffix="" Alignment="LEFT" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Icon" Attribute="IconPicture" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF] <StandardAttribute Name="Force top align" Attribute="TextStyle" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF]</Form> +Reference.Cardinality=No +Reference.ImplementationType=No +Reference.ChildRole=Yes +Reference.Stereotype=Yes +Reference.DisplayName=No +Reference.ForeignKeyConstraintName=No +Reference.JoinExpression=No +Reference.Integrity=No +Reference.ParentRole=Yes +Reference_SymbolLayout=<Form>[CRLF] <Form Name="Source" >[CRLF] <StandardAttribute Name="Cardinality" Attribute="Cardinality" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Implementation" Attribute="ImplementationType" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Child Role" Attribute="ChildRole" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] </Form>[CRLF] <Form Name="Center" >[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="&lt;&lt;" Suffix="&gt;&gt;" Caption="" Mandatory="No" />[CRLF] <ExclusiveChoice Name="Exclusive Choice" Mandatory="No" Display="HorizontalRadios" >[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Cons&amp;traint Name" Attribute="ForeignKeyConstraintName" Prefix="" Suffix="" Caption="Cons&amp;traint Name" Mandatory="No" />[CRLF] <StandardAttribute Name="Join" Attribute="JoinExpression" Prefix="" Suffix="" Caption="Join" Mandatory="No" />[CRLF] </ExclusiveChoice>[CRLF] <StandardAttribute Name="Referential integrity" Attribute="Integrity" Prefix="" Suffix="" Caption="Referential integrity" Mandatory="No" />[CRLF] </Form>[CRLF] <Form Name="Destination" >[CRLF] <StandardAttribute Name="Parent Role" Attribute="ParentRole" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] </Form>[CRLF]</Form> +ViewReference.ChildRole=Yes +ViewReference.Stereotype=Yes +ViewReference.DisplayName=No +ViewReference.JoinExpression=No +ViewReference.ParentRole=Yes +ViewReference_SymbolLayout=<Form>[CRLF] <Form Name="Source" >[CRLF] <StandardAttribute Name="Child Role" Attribute="ChildRole" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] </Form>[CRLF] <Form Name="Center" >[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="&lt;&lt;" Suffix="&gt;&gt;" Caption="" Mandatory="No" />[CRLF] <ExclusiveChoice Name="Exclusive Choice" Mandatory="No" Display="HorizontalRadios" >[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Join Expression" Attribute="JoinExpression" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] </ExclusiveChoice>[CRLF] </Form>[CRLF] <Form Name="Destination" >[CRLF] <StandardAttribute Name="Parent Role" Attribute="ParentRole" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] </Form>[CRLF]</Form> + +[DisplayPreferences\Symbol] + +[DisplayPreferences\Symbol\FRMEOBJ] +STRNFont=新宋体,8,N +STRNFont color=0, 0, 0 +DISPNAMEFont=新宋体,8,N +DISPNAMEFont color=0, 0, 0 +LABLFont=新宋体,8,N +LABLFont color=0, 0, 0 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Width=6000 +Height=2000 +Brush color=255 255 255 +Fill Color=Yes +Brush style=6 +Brush bitmap mode=12 +Brush gradient mode=64 +Brush gradient color=192 192 192 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 255 128 128 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\FRMELNK] +CENTERFont=新宋体,8,N +CENTERFont color=0, 0, 0 +Line style=1 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Brush color=255 255 255 +Fill Color=Yes +Brush style=1 +Brush bitmap mode=12 +Brush gradient mode=0 +Brush gradient color=118 118 118 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 128 128 255 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\FILO] +OBJSTRNFont=新宋体,8,N +OBJSTRNFont color=0, 0, 0 +DISPNAMEFont=新宋体,8,N +DISPNAMEFont color=0, 0, 0 +LCNMFont=新宋体,8,N +LCNMFont color=0, 0, 0 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Width=4800 +Height=3600 +Brush color=255 255 255 +Fill Color=Yes +Brush style=1 +Brush bitmap mode=12 +Brush gradient mode=0 +Brush gradient color=118 118 118 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 0 0 255 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\PDMPCKG] +STRNFont=新宋体,8,N +STRNFont color=0, 0, 0 +DISPNAMEFont=新宋体,8,N +DISPNAMEFont color=0, 0, 0 +LABLFont=新宋体,8,N +LABLFont color=0, 0, 0 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Width=4800 +Height=4000 +Brush color=255 255 192 +Fill Color=Yes +Brush style=6 +Brush bitmap mode=12 +Brush gradient mode=65 +Brush gradient color=255 255 255 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 178 178 178 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\TABL] +STRNFont=新宋体,8,N +STRNFont color=0, 0, 0 +DISPNAMEFont=新宋体,8,N +DISPNAMEFont color=0, 0, 0 +OWNRDISPNAMEFont=新宋体,8,N +OWNRDISPNAMEFont color=0, 0, 0 +ColumnsFont=新宋体,8,N +ColumnsFont color=0, 0, 0 +TablePkColumnsFont=新宋体,8,U +TablePkColumnsFont color=0, 0, 0 +TableFkColumnsFont=新宋体,8,N +TableFkColumnsFont color=0, 0, 0 +KeysFont=新宋体,8,N +KeysFont color=0, 0, 0 +IndexesFont=新宋体,8,N +IndexesFont color=0, 0, 0 +TriggersFont=新宋体,8,N +TriggersFont color=0, 0, 0 +LABLFont=新宋体,8,N +LABLFont color=0, 0, 0 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Width=4800 +Height=4000 +Brush color=178 214 252 +Fill Color=Yes +Brush style=6 +Brush bitmap mode=12 +Brush gradient mode=65 +Brush gradient color=255 255 255 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 0 128 192 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\VIEW] +STRNFont=新宋体,8,N +STRNFont color=0, 0, 0 +DISPNAMEFont=新宋体,8,N +DISPNAMEFont color=0, 0, 0 +OWNRDISPNAMEFont=新宋体,8,N +OWNRDISPNAMEFont color=0, 0, 0 +ColumnsFont=新宋体,8,N +ColumnsFont color=0, 0, 0 +TablePkColumnsFont=新宋体,8,U +TablePkColumnsFont color=0, 0, 0 +TableFkColumnsFont=新宋体,8,N +TableFkColumnsFont color=0, 0, 0 +TemporaryVTablesFont=新宋体,8,N +TemporaryVTablesFont color=0, 0, 0 +IndexesFont=新宋体,8,N +IndexesFont color=0, 0, 0 +LABLFont=新宋体,8,N +LABLFont color=0, 0, 0 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Width=4800 +Height=4000 +Brush color=208 208 255 +Fill Color=Yes +Brush style=6 +Brush bitmap mode=12 +Brush gradient mode=65 +Brush gradient color=255 255 255 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 128 128 192 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\PROC] +STRNFont=新宋体,8,N +STRNFont color=0, 0, 0 +DISPNAMEFont=新宋体,8,N +DISPNAMEFont color=0, 0, 0 +OWNRDISPNAMEFont=新宋体,8,N +OWNRDISPNAMEFont color=0, 0, 0 +LABLFont=新宋体,8,N +LABLFont color=0, 0, 0 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Width=4000 +Height=1000 +Brush color=255 255 192 +Fill Color=Yes +Brush style=6 +Brush bitmap mode=12 +Brush gradient mode=65 +Brush gradient color=255 255 255 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 128 108 0 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\REFR] +SOURCEFont=新宋体,8,N +SOURCEFont color=0, 0, 0 +CENTERFont=新宋体,8,N +CENTERFont color=0, 0, 0 +DESTINATIONFont=新宋体,8,N +DESTINATIONFont color=0, 0, 0 +Line style=1 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Brush color=255 255 255 +Fill Color=Yes +Brush style=1 +Brush bitmap mode=12 +Brush gradient mode=0 +Brush gradient color=118 118 118 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 0 128 192 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\VREF] +SOURCEFont=新宋体,8,N +SOURCEFont color=0, 0, 0 +CENTERFont=新宋体,8,N +CENTERFont color=0, 0, 0 +DESTINATIONFont=新宋体,8,N +DESTINATIONFont color=0, 0, 0 +Line style=1 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Brush color=255 255 255 +Fill Color=Yes +Brush style=1 +Brush bitmap mode=12 +Brush gradient mode=0 +Brush gradient color=118 118 118 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 128 128 192 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\USRDEPD] +OBJXSTRFont=新宋体,8,N +OBJXSTRFont color=0, 0, 0 +Line style=1 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Brush color=255 255 255 +Fill Color=Yes +Brush style=1 +Brush bitmap mode=12 +Brush gradient mode=0 +Brush gradient color=118 118 118 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=2 0 128 128 255 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\Free Symbol] +Free TextFont=新宋体,8,N +Free TextFont color=0, 0, 0 +Line style=0 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Brush color=255 255 255 +Fill Color=Yes +Brush style=1 +Brush bitmap mode=12 +Brush gradient mode=0 +Brush gradient color=118 118 118 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 0 0 255 +Shadow color=192 192 192 +Shadow=0 +(8268, 11693) +((315,354), (433,354)) +1 +15 + + +1573443498 +1578289481 +((-21587,-55647), (-14146,-33693)) +((-21187,-55247),(-14771,-55247),(-14771,-34093)) +1 +1 +12615680 +12632256 +CENTER 0 新宋体,8,N +SOURCE 0 新宋体,8,N +DESTINATION 0 新宋体,8,N +4 + + + + + + + + + + + +1575624441 +1575855293 +((7952,-65177), (9202,-37779)) +((8577,-64777),(8577,-38179)) +1 +1 +12615680 +12632256 +CENTER 0 新宋体,8,N +SOURCE 0 新宋体,8,N +DESTINATION 0 新宋体,8,N + + + + + + + + + + + +1575624473 +1575855293 +((-42707,-69189), (1113,-48816)) +((713,-68789),(-42082,-68789),(-42082,-49216)) +1 +1 +12615680 +12632256 +CENTER 0 新宋体,8,N +SOURCE 0 新宋体,8,N +DESTINATION 0 新宋体,8,N + + + + + + + + + + + +1575624521 +1575855289 +((663,-51761), (8002,-37779)) +((1063,-51361),(7377,-51361),(7377,-38179)) +1 +1 +12615680 +12632256 +CENTER 0 新宋体,8,N +SOURCE 0 新宋体,8,N +DESTINATION 0 新宋体,8,N + + + + + + + + + + + +1575624526 +1575855289 +((-12582,-47749), (-11332,-33693)) +((-11957,-47349),(-11957,-34093)) +1 +1 +12615680 +12632256 +CENTER 0 新宋体,8,N +SOURCE 0 新宋体,8,N +DESTINATION 0 新宋体,8,N + + + + + + + + + + + +1573436700 +1575889010 +-1 +((-45485,-49216), (-25299,-21394)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1573436823 +1575889010 +-1 +((-20969,-34093), (-8507,-25245)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1573439850 +1575889010 +-1 +((5372,-38179), (20150,-22731)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1573442367 +1575889010 +-1 +((24745,-63550), (40683,-50578)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1573442751 +1578289481 +-1 +((-34421,-66256), (-21187,-51634)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575624135 +1575889010 +-1 +((-12557,-55373), (1063,-47349)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575624135 +1575889010 +-1 +((713,-72801), (14333,-64777)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-27388,1549), (-14927,10396)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((2370,-7000), (15603,-1452)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((1597,14221), (14830,23068)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((3144,2373), (15991,10395)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-27774,28543), (-14541,39864)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-43235,13395), (-31162,23067)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-43235,-9474), (-31162,-1452)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-11541,29367), (920,39864)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((441,-17196), (12514,-12473)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-43235,1549), (-30388,10396)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-28162,13395), (-16089,23067)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-28162,-9474), (-16089,-1452)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-13859,-18022), (-2557,-12474)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-43235,-18022), (-31547,-12474)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-28547,-18022), (-16859,-12474)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-13089,13395), (-1401,23067)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-43235,26067), (-30774,39863)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-13089,-7824), (-628,-1452)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889030 +-1 +((-13023,996), (-176,10668)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889107 +-1 +((2682,31182), (14755,40029)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + + + + + + + + +E4E8B02A-08FE-4D41-AF69-E356B1ADF6B2 +face_camera +face_camera +1573436700 +Mhb +1578554809 +Mhb +摄像头表 + + + +1A74B7DC-03CD-46A8-9D38-526940D52CD8 +id_face_camera +id_face_camera +1573437457 +Mhb +1575861037 +Mhb +id +bigint(32) +32 +1 + + +384744B7-F06F-40CB-A217-BCD81E187B4D +camera_name +camera_name +1573437457 +Mhb +1576823629 +Mhb +摄像头名称 +varchar(255) +255 + + +D398DC39-3975-4E5C-AFCB-B4870E6867BD +camera_region_firstlevel +camera_region_firstlevel +1573437457 +Mhb +1576056977 +Mhb +摄像头层级区域-码值 +varchar(255) +255 + + +8265813D-F22C-4B2A-8668-EC46030D361D +camera_region_firstlevel_back_up +camera_region_firstlevel_back_up +1576138474 +Mhb +1576138611 +Mhb +摄像头层级区域冗余字段 +varchar(255) +255 + + +CBF48334-B876-4E7B-B5B7-4922E38A0BB0 +camera_region +camera_region +1576056922 +Mhb +1576056958 +Mhb +摄像头区域码值 +varchar(255) +255 + + +66813EBD-4D00-4948-96A8-AD6F18182008 +camera_region_back_up +camera_region_back_up +1576138474 +Mhb +1576138611 +Mhb +摄像头区域冗余字段 +varchar(255) +255 + + +6D7BAD6F-A7C7-46CE-AF9E-A1A2300C4FB9 +camera_address +camera_address +1573437457 +Mhb +1575623722 +Mhb +摄像头详细地址 +varchar(255) +255 + + +1C9BD8BB-D20F-4EDD-AF7D-AA524E4AA53D +version +version +1576057036 +Mhb +1576057072 +Mhb +摄像头型号 +varchar(255) +255 + + +989C9D47-6682-4B62-B172-9475E9C0B6C4 +id_brand +id_brand +1578289236 +Administrator +1578554809 +Mhb +品牌码值 +varchar(32) +32 + + +91ABA7B4-8D6E-43F3-A440-7966180127DE +camerat_longitude +camerat_longitude +1573437457 +Mhb +1575623722 +Mhb +摄像头经度 +varchar(100) +100 + + +45726891-DFB9-4C33-802C-31C7E4C372C1 +camera_latitude +camera_latitude +1573437457 +Mhb +1575623722 +Mhb +摄像头纬度 +varchar(100) +100 + + +03444A9A-5758-4AA6-8C02-AA113BF10DD9 +camerat_locationtype_id +camerat_locationtype_id +1573437457 +Mhb +1576221873 +Mhb +位置类型-码值 +varchar(255) +255 + + +A6D640CB-2885-4D12-9FC5-236C63BB3CC1 +camerat_locationtype_id_back_up +camerat_locationtype_id_back_up +1576138474 +Mhb +1576138611 +Mhb +位置类型冗余字段 +varchar(255) +255 + + +4E38BE4F-977D-4D5B-8FEE-16E641F97C19 +public_security_code +public_security_code +1573437457 +Mhb +1573526258 +Mhb +公安机关代码 +varchar(100) +100 + + +C5934BE0-2B22-4488-9410-FCE8423A6E20 +public_security_name +public_security_name +1573437457 +Mhb +1573438883 +Mhb +公安机关名称 +varchar(255) +255 + + +7094AFAC-2FA0-4783-A862-99DDB5B624A0 +construction_unit +construction_unit +1573437457 +Mhb +1573438883 +Mhb +建设单位 +varchar(255) +255 + + +C7947C59-4EFB-4528-BBB6-214C88FB5309 +management_unit +management_unit +1573437457 +Mhb +1573438883 +Mhb +管理单位 +varchar(255) +255 + + +69B2FAEE-4476-455F-BF07-89C2BED473F9 +management_personnel +management_personnel +1573437457 +Mhb +1573438883 +Mhb +管理人员 +varchar(50) +50 + + +8819B1EE-0F95-45F4-8591-7685675B1D44 +contact_number +contact_number +1573437457 +Mhb +1573438883 +Mhb +联系电话 +varchar(11) +11 + + +F367BFD2-DCCE-4242-88B5-4B1910E407D4 +ip +ip +1575623219 +Mhb +1575623722 +Mhb +IP +varchar(255) +255 + + +1A671B8A-EB99-4E1B-839E-8675BE7BFCC1 +port +port +1578554711 +Mhb +1578554809 +Mhb +端口 +varchar(32) +32 + + +83CF2C7D-0013-42AC-A67C-B5D2F2C3BB49 +user_name +user_name +1575623219 +Mhb +1575623722 +Mhb +用户名 +varchar(255) +255 + + +595009F9-3B8F-481C-BF37-70DB18595BB3 +passwd +passwd +1575623219 +Mhb +1575623722 +Mhb +密码 +varchar(32) +32 + + +39AC6D85-2A82-457B-973B-833C5A1F0EC9 +brand +brand +1575623219 +Mhb +1575623722 +Mhb +品牌 +varchar(50) +50 + + +4E4CD6FD-D3F2-4592-B5AC-C01FFE56CFAB +rtsp_url +rtsp_url +1575623219 +Mhb +1575623722 +Mhb +rtsp地址 +varchar(255) +255 + + +EB1C71EB-1038-4A3C-B14D-40A723A36408 +remarks +remarks +1573439050 +Mhb +1573439206 +Mhb +备注信息 +text + + +D3FB0AE4-6D5D-4412-848F-3AFE58312B7C +status +status +1573439050 +Mhb +1573439206 +Mhb +是否运行 Y启动 N未启动 +varchar(1) +1 + + +C38B226A-DFA0-439D-A188-04AC3905CFD5 +is_valid +is_valid +1573437457 +Mhb +1573438883 +Mhb +是否有效 Y有效 N无效 +varchar(1) +1 + + +0082D9B3-EC08-4C51-83F2-B99379EBB7C9 +create_time +create_time +1573437457 +Mhb +1573438883 +Mhb +创建时间 +datetime + + +8F5CCA05-CAA0-48B9-A8C2-5765F3B9BB5D +update_time +update_time +1573437457 +Mhb +1573438883 +Mhb +更新时间 +datetime + + +6A8C4EC6-8859-4E65-830E-8B9B2F4E6FC8 +create_by +create_by +1573437457 +Mhb +1573438883 +Mhb +创建人 +varchar(32) +32 + + +7705E005-354A-44C3-9C45-A9811253A948 +update_by +update_by +1573437457 +Mhb +1573438883 +Mhb +更新人 +varchar(32) +32 + + + + +762D34E1-D0BB-43E1-A3AA-B29DC3FB0816 +Key_1 +Key_1 +1573437457 +Mhb +1573438883 +Mhb + + + + + + + + + + +2C890490-554A-40C9-9E52-B764B6D77A67 +face_library +face_library +1573436823 +Mhb +1575624380 +Mhb +库表 + + + +E50A7606-639A-41C9-A8C7-D813FD9CC77C +id_factory +id_factory +1573439238 +Mhb +1575861050 +Mhb +id +bigint(32) +32 +1 + + +3672C199-FB8A-4E09-946A-23EE9ECACDB2 +factory_name +factory_name +1573439238 +Mhb +1573439727 +Mhb +库名称 +varchar(255) +255 + + +E562845F-7E6A-46B1-92AC-747E1E4394B5 +factory_type +factory_type +1573439238 +Mhb +1573439727 +Mhb +库类型-码值 +varchar(2) +2 + + +0502AE24-8A23-46D8-A92D-83ECC1579FD3 +remarks +remarks +1573439739 +Mhb +1573439777 +Mhb +备注信息 +varchar(255) +255 + + +0FE75B86-45F9-478D-82A7-3FAC77CAF204 +is_valid +is_valid +1573439238 +Mhb +1573439727 +Mhb +是否有效 Y有效 N无效 +varchar(1) +1 + + +DC672B5F-F72F-4110-AFC4-D2D973FBB219 +create_time +create_time +1573439238 +Mhb +1573443221 +Mhb +创建时间 +datetime + + +97EEED5B-7EC2-4739-A85A-537C38104297 +create_by +create_by +1573439238 +Mhb +1573439727 +Mhb +创建人 +varchar(32) +32 + + +73909D78-E9F6-47DF-B26D-19B65FF40D25 +update_time +update_time +1573439238 +Mhb +1573439727 +Mhb +更新时间 +datetime + + +162BC533-0B3F-4229-A8FB-445CADC70BD2 +update_by +update_by +1573439238 +Mhb +1573439727 +Mhb +更新人 +varchar(32) +32 + + + + +2F8CA6A0-DB4A-4939-B94D-3DA2D510FEA6 +Key_1 +Key_1 +1573439777 +Mhb +1573439781 +Mhb + + + + + + + + + + +046778F8-B0CE-4309-B625-34BC7C78EB20 +control_task +control_task +1573439850 +Mhb +1573442319 +Mhb +布控任务 + + + +0DED6519-44BC-492F-88FE-7549FE6274FA +id_control_task +id_control_task +1573439850 +Mhb +1575861062 +Mhb +id +bigint(32) +32 +1 + + +09DF71A8-0F01-4C8B-9BEB-282DBE292E4D +task_name +task_name +1573439923 +Mhb +1573441288 +Mhb +任务名称 +varchar(255) +255 + + +4267CDB1-57BF-4047-8FF4-4A253E88D42F +control_object +control_object +1573439923 +Mhb +1573441288 +Mhb +布控对象(id 人像库id 或者上传图片id) +varchar(32) +32 + + +AAD04542-7F80-4602-A5C4-91583100AD93 +disposal_type +disposal_type +1573439923 +Mhb +1575869626 +Mhb +处置类型-码值 +varchar(3) +3 + + +E5016236-E62E-4B22-8EA4-C171BAF146AC +control_type +control_type +1573439923 +Mhb +1573441288 +Mhb +布控类型-码值 +varchar(1) +1 + + +2D7F6B74-2424-4DA1-9370-CD058112378B +control_start_time +control_start_time +1573439923 +Mhb +1573441288 +Mhb +布控开始时间 +datetime + + +7939CB58-6F61-4D70-B891-AEDD57BDC26A +control_end_time +control_end_time +1573439923 +Mhb +1573441288 +Mhb +布控结束时间 +datetime + + +9E6E0F90-0714-4293-8EA8-435775748148 +control_region +control_region +1573439923 +Mhb +1573441288 +Mhb +布控区域 +varchar(255) +255 + + +B327871B-E72C-4096-9D98-5C24D4623304 +control_threshold +control_threshold +1573439923 +Mhb +1573441288 +Mhb +布控阈值 +double + + +534C211F-0A48-413B-B80D-FA3866D5B1A3 +control_status +control_status +1573442211 +Mhb +1573442319 +Mhb +布控状态-码值 +varchar(1) +1 + + +EB469329-2721-4847-A969-DD7DE9797B33 +receive +receive +1573439923 +Mhb +1573441288 +Mhb +接收人员(人员id逗号隔开) +text + + +C5AC5EB0-57B0-44B3-8B8A-9EB82FDC184B +remarks +remarks +1573439923 +Mhb +1573441288 +Mhb +备注信息 +text + + +4537FE59-BD10-484A-B134-D13FCC05FF7E +is_valid +is_valid +1573439923 +Mhb +1573441288 +Mhb +是否有效 Y有效 N无效 +varchar(1) +1 + + +6573FCC6-D476-485A-836B-AF3F0422F496 +create_time +create_time +1573439923 +Mhb +1573441288 +Mhb +创建时间 +datetime + + +02537A17-3D66-43BB-ACB7-5ECA206DCEBF +update_time +update_time +1573439923 +Mhb +1573441288 +Mhb +更新时间 +datetime + + +13C83835-9669-4A2D-990E-5B52BF8292DA +create_by +create_by +1573439923 +Mhb +1573441288 +Mhb +创建人 +varchar(32) +32 + + +1355E161-2F24-40AA-BA97-F8D0F31487D7 +update_by +update_by +1573439923 +Mhb +1573441288 +Mhb +更新人 +varchar(32) +32 + + + + +AF085F36-0775-4494-9850-05B5E0CA9613 +Key_1 +Key_1 +1573441293 +Mhb +1573441306 +Mhb + + + + + + + + + + +AA9FB273-75E3-4361-B7B4-C0ABE3C749B1 +warning_information +warning_information +1573442367 +Mhb +1573520775 +Mhb +预警信息 + + + +7D229B27-8F0D-47C7-987D-E3A25E771027 +id_warning_information +id_warning_information +1573442367 +Mhb +1573451149 +Mhb +id +varchar(32) +32 +1 + + +A02A7C65-D407-48ED-85BB-480DD3C996C3 +receive_json +receive_json +1573442367 +Mhb +1573451149 +Mhb +接收参数 +text + + +BC7C9C5D-4899-4B5A-B1D9-DE65F4DDCFD2 +id_control_task +id_control_task +1573450400 +Mhb +1573451149 +Mhb +布控任务id +varchar(32) +32 + + +E72CEEE7-3FB8-442C-945D-D1F0CD137744 +id_portrait +id_portrait +1573450400 +Mhb +1573451149 +Mhb +人像id/图片id +varchar(32) +32 + + +634A26AF-66D0-4672-B9E7-C077A27162B8 +type +type +1573451188 +Mhb +1573451339 +Mhb +预警类型-码值 +varchar(2) +2 + + +52184851-1D99-4EF5-A7BB-82588F3C6C3D +id_face_bayonet +id_face_bayonet +1573451188 +Mhb +1573451339 +Mhb +卡口id +varchar(32) +32 + + +394727A5-BAD4-4426-AEA4-26591CD012C1 +score +score +1573451373 +Mhb +1573451549 +Mhb +比对分数 +double + + +8EC3BB7B-DC88-4DC0-BA90-7AF08ABF5268 +process_result_type +process_result_type +1573468005 +Mhb +1573520775 +Mhb +处理结果类型(1盘查 2抓捕) +varchar(1) +1 + + +61F63A0F-1EFD-4C52-A385-0A267F9477D4 +process_result +process_result +1573520652 +Mhb +1573520775 +Mhb +处理结果 +text + + +949990AF-72E6-4261-ABCB-A04CFD66D1E8 +is_valid +is_valid +1573450400 +Mhb +1573451149 +Mhb +是否有效 Y有效 N无效 +varchar(1) +1 + + +B23168D4-E0F1-4FCE-ADDA-CD54A3DCCF70 +create_time +create_time +1573450400 +Mhb +1573451149 +Mhb +创建时间 +datetime + + +66E8BF37-727F-43CE-8900-4D261F0C3F7F +create_by +create_by +1573450400 +Mhb +1573451149 +Mhb +创建人 +varchar(32) +32 + + +74E4673F-D850-4EB1-955D-AF904D020BA5 +update_time +update_time +1573450400 +Mhb +1573451149 +Mhb +更新时间 +datetime + + +F5F2FB5C-01F8-4873-8270-5ED3BE93481B +update_by +update_by +1573450400 +Mhb +1573451149 +Mhb +更新人 +varchar(32) +32 + + + + +5A10E169-5FF8-42EC-95B4-42FE6B61CB1A +Key_1 +Key_1 +1573450400 +Mhb +1573451149 +Mhb + + + + + + + + + + +8382D296-44E4-4718-9E54-9500D18479C9 +portrait +portrait +1573442751 +Mhb +1575623995 +Mhb +人像表 + + + +6E5F59AA-78E7-4CD0-9436-D81385D49C8F +id_portrait +id_portrait +1573442751 +Mhb +1575861079 +Mhb +人像id +bigint(32) +32 +1 + + +D6A0563F-E2B6-4199-B5EC-87789059C286 +id_factory +id_factory +1573442751 +Mhb +1575861079 +Mhb +库id +bigint(32) +32 + + +246D0D42-0BCE-4EEB-B7DC-DDC75B9E63A8 +url +url +1573442751 +Mhb +1573443337 +Mhb +图片url +text + + +00BB5BFB-C463-416C-A47C-11EFFA6CB12B +background_url +background_url +1573442751 +Mhb +1573443337 +Mhb +背景图url +text + + +8B57855B-52F5-4FA1-A99C-B219A1D6F806 +name +name +1573442751 +Mhb +1573443337 +Mhb +姓名 +varchar(100) +100 + + +2CD02889-7317-4B2A-8D25-3F46FD21D29F +sex +sex +1573442751 +Mhb +1573443337 +Mhb +性别 +varchar(10) +10 + + +00BFA5BD-13B9-49C0-A743-CB839016ACA2 +birth_date +birth_date +1573442751 +Mhb +1573443337 +Mhb +出生日期 +datetime + + +80B1951F-A3A5-473E-95AA-313E0A520757 +id_card +id_card +1573442751 +Mhb +1573443337 +Mhb +身份证 +varchar(18) +18 + + +E04FA0CB-5D37-4756-89C6-30CE730BD24E +face_rect +face_rect +1575623921 +Mhb +1575623995 +Mhb +人脸坐标位置 +varchar(255) +255 + + +FD26970C-19B7-4CC3-BA7D-8EBAC463094F +faceIds +faceIds +1573466044 +Mhb +1573466138 +Mhb +人脸入库id +varchar(32) +32 + + +8C74B033-4170-4642-902C-C1DB5DFEA24B +featId +featId +1573466044 +Mhb +1573466138 +Mhb +人脸特征id +varchar(32) +32 + + +19D66449-97F7-4CFE-985B-77EE5ED73732 +is_valid +is_valid +1573442751 +Mhb +1573443337 +Mhb +是否有效 Y有效 N无效 +varchar(1) +1 + + +C9245E6B-7A77-4D87-BEF5-59611569D824 +create_time +create_time +1573442751 +Mhb +1573443337 +Mhb +创建时间 +datetime + + +3E0B9B58-0075-492D-B898-48DF118D925F +create_by +create_by +1573442751 +Mhb +1573443337 +Mhb +创建人 +varchar(32) +32 + + +289075BD-55C6-4503-B805-6F9465A6A4CA +update_time +update_time +1573442751 +Mhb +1573443337 +Mhb +更新时间 +datetime + + +85D672D5-A474-4F91-AC38-85E43C5BF950 +update_by +update_by +1573442751 +Mhb +1573443337 +Mhb +更新人 +varchar(32) +32 + + + + +1B2E506C-1CE2-4D22-A491-70460B046196 +Key_1 +Key_1 +1573442751 +Mhb +1573443337 +Mhb + + + + + + + + + + +FA56C67F-89DF-4FDB-AD24-0C0F36CAAFD9 +control_library_mid +control_library_mid +1574155051 +Mhb +1575624573 +Mhb +布控和库中间表 + + + +1EC6F044-24DB-4F69-9E7B-F30E69CF08D3 +id +id +1574155051 +Mhb +1575861095 +Mhb +id +bigint(32) +32 +1 + + +910BBD12-1A6C-4AA3-9FC3-F277F3136D46 +id_control_task +id_control_task +1575624521 +Mhb +1575861095 +Mhb +布控id +bigint(32) +32 + + +BD86C361-D857-4CC1-8745-0B13C8AC9F94 +id_factory +id_factory +1575624526 +Mhb +1575861095 +Mhb +库id +bigint(32) +32 + + +B9640E36-69D5-4A37-8512-46DE02EDDBCB +is_valid +is_valid +1574155051 +Mhb +1575624135 +Mhb +是否有效 Y有效 N无效 +varchar(1) +1 + + +94F3622A-81D2-4B70-8220-9C1D1672986D +create_time +create_time +1574155051 +Mhb +1575624135 +Mhb +创建时间 +datetime + + +DF4654D3-08FE-4235-9BF4-B02F5966DC09 +update_time +update_time +1574155051 +Mhb +1575624135 +Mhb +更新时间 +datetime + + +3B2469E3-1D56-421A-A89B-34F021D019FF +update_by +update_by +1574233842 +Mhb +1575624135 +Mhb +更新人 +varchar(32) +32 + + +4A4FF023-FB25-49A4-A7F8-AD2D94656D07 +create_by +create_by +1574233842 +Mhb +1575624135 +Mhb +创建人 +varchar(32) +32 + + + + +55ACAA83-F906-4C3A-A16A-4D013F1C2AE1 +Key_1 +Key_1 +1574218130 +Mhb +1575624135 +Mhb + + + + + + + + + + +9F049A00-E53A-4773-8A56-5E2168F92FE8 +sys_dept +sys_dept +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '部门管理' ROW_FORMAT = Dynamic + + + +99E4E099-4E6F-4B2C-B760-B6255751F6DE +id +id +1575627715 +Mhb +1575860857 +Mhb +id +bigint(32) +32 +1 + + +4BE52A70-17B3-4C49-A3FF-7C2190407AF2 +pid +pid +1575627715 +Mhb +1575860857 +Mhb +上级ID +NULL +bigint(32) +32 + + +48505E3B-44DF-4C1A-8CB0-EDDFD785F2B0 +pids +pids +1575627715 +Mhb +1575627719 +Mhb +varchar(500) +500 + + +E557AB7A-B66B-4B92-9017-61A076CA99D1 +name +name +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +2E751D61-1EAF-4399-9E0B-A76AB0CFA95D +sort +sort +1575627715 +Mhb +1575627719 +Mhb +排序 +NULL +int(10) +10 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +F79AEE39-9FAA-42AE-9CD5-9770F8EB80B6 +creator +creator +1575627715 +Mhb +1575860857 +Mhb +创建者 +NULL +bigint(32) +32 + + +F3AECF63-6325-4851-AC87-7D810369A7E4 +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + +61EED6A4-E252-438B-8702-F6F0F35186F5 +updater +updater +1575627715 +Mhb +1575860857 +Mhb +更新者 +NULL +bigint(32) +32 + + +87D7DA60-8C6C-44CE-9A81-4EFAA9DDB090 +update_date +update_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +096A16B9-7840-44A8-A450-F127ED1354C7 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +6D2EA011-6633-4D84-8E55-F854B11B33A8 +idx_pid +idx_pid +1575627715 +Mhb +1575627719 +Mhb +idx_pid + + + + + +D5AD0430-B8A3-4098-911C-C5853ADF4EAB +idx_sort +idx_sort +1575627715 +Mhb +1575627719 +Mhb +idx_sort + + + + + + + + + + +6C21474D-6E31-43C8-B630-FF1841F63FB2 +sys_dict_data +sys_dict_data +1575888977 +Mhb +1575888983 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '字典数据' ROW_FORMAT = Dynamic + + + +3F58B53B-D90D-4EAC-8885-98F92D97393E +id +id +1575888977 +Mhb +1575889099 +Mhb +id +bigint(32) +32 +1 + + +93F777B3-FB31-46E2-8C86-6514649A432A +dict_type_id +dict_type_id +1575888977 +Mhb +1575889099 +Mhb +字典类型ID +bigint(32) +32 +1 + + +3151FD0B-26AD-4B8C-BFDE-13150FD6E023 +dict_label +dict_label +1575888977 +Mhb +1575888983 +Mhb +varchar(255) +255 + + +E4A7FC9F-ED7F-4186-8CC7-F7496BD0DD77 +dict_value +dict_value +1575888977 +Mhb +1575888983 +Mhb +varchar(255) +255 + + +5DB469B0-7D4C-430A-A53C-DA82C022FFEC +remark +remark +1575888977 +Mhb +1575888983 +Mhb +varchar(255) +255 + + +2D38FDAB-0E2C-4D4C-AFB3-F84D2E934A6C +sort +sort +1575888977 +Mhb +1575888983 +Mhb +排序 +NULL +int(10) +10 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +DF1449A4-FC37-4DE1-BC58-F4646FC8BB5D +creator +creator +1575888977 +Mhb +1575889099 +Mhb +创建者 +NULL +bigint(32) +32 + + +8B787594-FB81-4C1B-B99D-08DCDB73483F +create_date +create_date +1575888977 +Mhb +1575888983 +Mhb +datetime + + +EF9F74EB-2F54-4000-8731-6FD54AF49EF8 +updater +updater +1575888977 +Mhb +1575889099 +Mhb +更新者 +NULL +bigint(32) +32 + + +930A19BC-C7DE-4CF0-9F7E-FB94A3D89FA8 +update_date +update_date +1575888977 +Mhb +1575888983 +Mhb +datetime + + + + +5D39F44E-C97C-4EDD-BE40-4A4D7CB68122 +Key_1 +Key_1 +1575888977 +Mhb +1575888983 +Mhb + + + + + +90898574-3825-42BD-99F4-01E40443531C +uk_dict_type_value +uk_dict_type_value +1575888977 +Mhb +1575888983 +Mhb +uk_dict_type_value +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,57={D1C795B8-8F7B-4AA7-A240-85C5B737C543},ExtUnique,4=true + + + + + + + + +9CB71773-7DE1-468F-9994-C6506B2B92C0 +idx_sort +idx_sort +1575888977 +Mhb +1575888983 +Mhb +idx_sort + + + + + + + + + + +1B482A57-1B23-4C5B-B955-1F982B1CEE49 +sys_dict_type +sys_dict_type +1575889007 +Mhb +1575889009 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '字典类型' ROW_FORMAT = Dynamic + + + +03B9DD8A-7F6D-47AE-88CD-719B3AFCD594 +id +id +1575889007 +Mhb +1575889066 +Mhb +id +bigint(32) +32 +1 + + +2C10EEC8-6DCC-4FE6-9C23-6572618DBE9E +dict_type +dict_type +1575889007 +Mhb +1575889009 +Mhb +varchar(100) +100 + + +B66550FC-E390-4D36-B904-3859D3F5AAF3 +dict_name +dict_name +1575889007 +Mhb +1575889009 +Mhb +varchar(255) +255 + + +73083542-E05D-4318-9777-E598401547E7 +remark +remark +1575889007 +Mhb +1575889009 +Mhb +varchar(255) +255 + + +9ABD4C19-01FE-4127-928A-3BE7B235293F +sort +sort +1575889007 +Mhb +1575889009 +Mhb +排序 +NULL +int(10) +10 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +6DAB2997-81D1-4DC7-97F4-57466F24CBB5 +creator +creator +1575889007 +Mhb +1575889066 +Mhb +创建者 +NULL +bigint(32) +32 + + +D840C92A-3AF7-4CC3-B7CA-AE9F92D8A4E1 +create_date +create_date +1575889007 +Mhb +1575889009 +Mhb +datetime + + +D0B20B56-B091-446D-AA83-9684CDEF6813 +updater +updater +1575889007 +Mhb +1575889066 +Mhb +更新者 +NULL +bigint(32) +32 + + +E78BE102-69B2-402F-AB56-910A2441C163 +update_date +update_date +1575889007 +Mhb +1575889009 +Mhb +datetime + + + + +80F0AA09-704F-451E-8243-04BF2B5733C7 +Key_1 +Key_1 +1575889007 +Mhb +1575889009 +Mhb + + + + + +B58F7149-042A-4F02-9A69-2604E62EADC9 +dict_type +dict_type +1575889007 +Mhb +1575889009 +Mhb +dict_type +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,57={D1C795B8-8F7B-4AA7-A240-85C5B737C543},ExtUnique,4=true + + + + + + + + + + + + +2F2FC176-0502-4464-9A63-2165384CE8F5 +sys_language +sys_language +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '国际化' ROW_FORMAT = Dynamic + + + +78DDD97F-01BC-4D07-8CE0-E295DC43D77B +table_name +table_name +1575627715 +Mhb +1575627719 +Mhb +varchar(32) +32 +1 + + +D96A0DF7-ABA7-4FB6-AD40-59B28C71CC05 +table_id +table_id +1575627715 +Mhb +1575862019 +Mhb +表主键 +bigint(32) +32 +1 + + +D0B719E8-3DDB-42A8-B636-AB6EA90854B4 +field_name +field_name +1575627715 +Mhb +1575627719 +Mhb +varchar(32) +32 +1 + + +6C611C25-9B68-4151-B3EA-14E5C6EF6BBD +field_value +field_value +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +9956297C-35B9-4975-912F-BBAB29C6F9F7 +language +language +1575627715 +Mhb +1575627719 +Mhb +varchar(10) +10 +1 + + + + +5E3CB867-43BC-49D0-B831-BF008A66B898 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + + + + +66CEE822-E213-45DC-9CC8-861DA9D6683A +idx_table_id +idx_table_id +1575627715 +Mhb +1575627719 +Mhb +idx_table_id + + + + + + + + + + +26AF1720-5B40-4B53-A9B3-190C99952181 +sys_log_error +sys_log_error +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '异常日志' ROW_FORMAT = Dynamic + + + +427B735A-94B7-4144-92C2-378A5F21AD49 +id +id +1575627715 +Mhb +1575860814 +Mhb +id +bigint(32) +32 +1 + + +2ABCD2A4-A863-4F1C-B4ED-B3C7EE7FBFA2 +request_uri +request_uri +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +10F4427C-4911-4ADC-9C5A-710B71FE3266 +request_method +request_method +1575627715 +Mhb +1575627719 +Mhb +varchar(20) +20 + + +AB3897EC-DC22-409A-A868-96C77CFF050D +request_params +request_params +1575627715 +Mhb +1575627719 +Mhb +text + + +76F89572-6BFB-4E3A-8522-12C1F53021EF +user_agent +user_agent +1575627715 +Mhb +1575627719 +Mhb +varchar(500) +500 + + +99D318E1-F035-4B93-90B1-BB54F2E2D882 +ip +ip +1575627715 +Mhb +1575627719 +Mhb +varchar(32) +32 + + +1B032144-9B70-4081-8CE3-9C8731992202 +error_info +error_info +1575627715 +Mhb +1575627719 +Mhb +text + + +A55433CF-E4B0-41DC-B4B5-DACE31429871 +creator +creator +1575627715 +Mhb +1575860814 +Mhb +创建者 +NULL +bigint(32) +32 + + +5EF35C60-4A2E-41D4-AFCF-7DFBB2C1317E +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +D9768FFE-44A1-444B-B960-7016280070C8 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +D940DBD9-88FC-4583-B353-90A58DE455A4 +idx_create_date +idx_create_date +1575627715 +Mhb +1575627719 +Mhb +idx_create_date + + + + + + + + + + +2380061C-D4F6-42E6-ADED-E19B797BD5DA +sys_log_login +sys_log_login +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '登录日志' ROW_FORMAT = Dynamic + + + +EA11F126-1895-4FB7-BD1D-F44A5B6DEE84 +id +id +1575627715 +Mhb +1575860871 +Mhb +id +bigint(32) +32 +1 + + +C9E783D8-C255-40CA-B614-9BCE7D35723A +operation +operation +1575627715 +Mhb +1575627719 +Mhb +用户操作 0:用户登录 1:用户退出 +NULL +tinyint(3) +3 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +C75D2E3C-21DC-481F-8402-1663098427DB +status +status +1575627715 +Mhb +1575627719 +Mhb +状态 0:失败 1:成功 2:账号已锁定 +tinyint(3) +3 +1 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +09ABAA4F-775A-4F0D-A149-C7AEE703E52E +user_agent +user_agent +1575627715 +Mhb +1575627719 +Mhb +varchar(500) +500 + + +084B3DB4-F6AF-446E-A110-C93489BBD3A2 +ip +ip +1575627715 +Mhb +1575627719 +Mhb +varchar(32) +32 + + +1AE4EFD0-4C2B-49CE-B308-32DF99EB5F8B +creator_name +creator_name +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +19AD544E-4425-4A9A-99CB-3530E09707E0 +creator +creator +1575627715 +Mhb +1575860871 +Mhb +创建者 +NULL +bigint(32) +32 + + +3D94AB21-5C3B-49E9-A686-CB195FC3D48B +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +70F8B6B9-567B-431D-BF46-AF2EEFF96D50 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +D5414B25-50A6-484B-A165-1E7C61D91724 +idx_status +idx_status +1575627715 +Mhb +1575627719 +Mhb +idx_status + + + + + +C9A69DDE-0FE3-4896-8CD1-456C003F7339 +idx_create_date +idx_create_date +1575627715 +Mhb +1575627719 +Mhb +idx_create_date + + + + + + + + + + +93F1EDF9-F27B-4EDC-B9B4-FB91DA648BE9 +sys_log_operation +sys_log_operation +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '操作日志' ROW_FORMAT = Dynamic + + + +57BE3274-2F38-424A-AE05-401BD923AF4E +id +id +1575627715 +Mhb +1575860286 +Mhb +id +bigint(32) +32 +1 + + +F9439ED2-128A-4A62-A4C6-1CD9E8A1F778 +operation +operation +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +4AE3E94D-E164-4817-84C6-53B2C887CCBA +request_uri +request_uri +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +C063592C-2467-4956-BA4C-A01FE1EF63AB +request_method +request_method +1575627715 +Mhb +1575627719 +Mhb +varchar(20) +20 + + +D46DDBBC-37D4-4054-B9E2-E8CFCCF63628 +request_params +request_params +1575627715 +Mhb +1575627719 +Mhb +text + + +0BB4AF57-D74F-4E52-A7B8-8B6FFE56FF22 +request_time +request_time +1575627715 +Mhb +1575627719 +Mhb +请求时长(毫秒) +int(10) +10 +1 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +762654F5-C9CA-4088-B406-3E779C72F13F +user_agent +user_agent +1575627715 +Mhb +1575627719 +Mhb +varchar(500) +500 + + +9599B8EF-AA8D-4912-9170-6C438594D234 +ip +ip +1575627715 +Mhb +1575627719 +Mhb +varchar(32) +32 + + +1ABE28F8-9CE4-4931-8BC8-C0754FCE22A5 +status +status +1575627715 +Mhb +1575627719 +Mhb +状态 0:失败 1:成功 +tinyint(3) +3 +1 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +B33D74E0-A229-4BD2-8D7F-EF986D931F5A +creator_name +creator_name +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +5EB6EAD6-8DE2-4403-BB8C-EBE24D46423A +creator +creator +1575627715 +Mhb +1575861976 +Mhb +创建者 +NULL +bigint(32) +32 + + +E6846B72-224B-4F7C-8066-094332A29A7E +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +DAE48F36-6C99-431C-B1A5-AAB1AAE20946 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +29FACFD7-CFC0-4770-AAC6-4FCFC8B70788 +idx_create_date +idx_create_date +1575627715 +Mhb +1575627719 +Mhb +idx_create_date + + + + + + + + + + +D611436E-27EF-46E2-B787-A289354824D7 +sys_mail_log +sys_mail_log +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '邮件发送记录' ROW_FORMAT = Dynamic + + + +ABE063DC-EE35-4992-8602-0729AA5A4EE4 +id +id +1575627715 +Mhb +1575860698 +Mhb +id +bigint(32) +32 +1 + + +95A5DDA5-6531-411D-9B28-41E282A1EEAA +template_id +template_id +1575627715 +Mhb +1575860698 +Mhb +邮件模板ID +bigint(32) +32 +1 + + +328CAE6E-C72C-488D-BB2B-B18460B7365E +mail_from +mail_from +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +67C576A8-49C6-486E-83B6-91800959B07B +mail_to +mail_to +1575627715 +Mhb +1575627719 +Mhb +varchar(400) +400 + + +60897F65-122D-47B7-B300-503E7750ECE7 +mail_cc +mail_cc +1575627715 +Mhb +1575627719 +Mhb +varchar(400) +400 + + +43D64500-A658-49C5-8CB8-8E964866B6D9 +subject +subject +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +464AC206-FFB7-4710-84CF-D5D38FAE4013 +content +content +1575627715 +Mhb +1575627719 +Mhb +text + + +EECFB0B6-0CEC-46E7-910B-906B8C115627 +status +status +1575627715 +Mhb +1575627719 +Mhb +发送状态 0:失败 1:成功 +NULL +tinyint(3) +3 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +E0C60476-7866-486F-B1FB-35A7AE051AE1 +creator +creator +1575627715 +Mhb +1575860698 +Mhb +创建者 +NULL +bigint(32) +32 + + +AB589EBD-BFDE-4677-961B-AD4A2A3976C1 +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +31286D33-2B76-4256-9731-9957E37CB6B1 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +EBA018CA-2321-4052-9706-2728E609E3B2 +idx_create_date +idx_create_date +1575627715 +Mhb +1575627719 +Mhb +idx_create_date + + + + + + + + + + +41C79146-5F02-4466-8EAE-6545338C0E42 +sys_mail_template +sys_mail_template +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '邮件模板' ROW_FORMAT = Dynamic + + + +4AC1F548-A110-4CF9-A19C-FF297749E235 +id +id +1575627715 +Mhb +1575860890 +Mhb +id +bigint(32) +32 +1 + + +55839EA1-7458-4D99-93FB-FAFF0D650906 +name +name +1575627715 +Mhb +1575627719 +Mhb +varchar(100) +100 + + +CEC616F2-411E-4012-9C5B-2179DA0FA6A6 +subject +subject +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +D3A5CCEC-D582-459C-9190-56878BA2DD8E +content +content +1575627715 +Mhb +1575627719 +Mhb +text + + +6E388731-7056-4E8A-A08E-F00D4B7F47AD +creator +creator +1575627715 +Mhb +1575860890 +Mhb +创建者 +NULL +bigint(32) +32 + + +0F59C1ED-BEEF-4611-85E1-D2B734C5583F +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + +F2E738E9-9BBE-45D9-ACB7-E7A3AE56F5FD +updater +updater +1575627715 +Mhb +1575860890 +Mhb +更新者 +NULL +bigint(32) +32 + + +E4BFD487-5EC6-4F23-8885-9934F2A00EC9 +update_date +update_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +8100DA95-F266-4AF5-B531-71AD03A90E5A +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +2255D6F0-6E19-4583-B0C3-BD34751BA401 +idx_create_date +idx_create_date +1575627715 +Mhb +1575627719 +Mhb +idx_create_date + + + + + + + + + + +3E050872-07DB-4891-8B01-C645FFF85D21 +sys_menu +sys_menu +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '菜单管理' ROW_FORMAT = Dynamic + + + +AC622DFC-3480-4008-AA3B-ED26881CAA93 +id +id +1575627715 +Mhb +1575860304 +Mhb +id +bigint(32) +32 +1 + + +121D5699-F67F-44C2-B491-56E17DED4FC0 +pid +pid +1575627715 +Mhb +1575860304 +Mhb +上级ID,一级菜单为0 +NULL +bigint(32) +32 + + +E59D2DA4-07CC-41B9-B33D-FF16AD57CACE +url +url +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +A4C9A30E-D00C-4A80-96EA-2CF74AAF5B0D +permissions +permissions +1575627715 +Mhb +1575627719 +Mhb +varchar(500) +500 + + +32789A89-C7ED-4623-85BC-537ACDE4DF2B +type +type +1575627715 +Mhb +1575627719 +Mhb +类型 0:菜单 1:按钮 +NULL +tinyint(3) +3 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +E6E567C8-B599-4841-A620-77026A9B4827 +icon +icon +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +68A5D78C-F9BD-404A-940F-BA09BE1CFE3F +sort +sort +1575627715 +Mhb +1575627719 +Mhb +排序 +NULL +int(11) +11 + + +226EFB13-B697-4DDF-887C-56F752A85710 +creator +creator +1575627715 +Mhb +1575861967 +Mhb +创建者 +NULL +bigint(32) +32 + + +329E62AF-DDC4-4E21-A3B3-6E969F96AB8F +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + +6BBD80F0-3679-4D2A-A9ED-6A2D2F988207 +updater +updater +1575627715 +Mhb +1575861967 +Mhb +更新者 +NULL +bigint(32) +32 + + +0FAAA683-7E5B-44C3-8EF1-363648D2C9F0 +update_date +update_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +72DE01D1-7B49-4B02-96BA-AC3D77A12A0F +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +58671D8B-FD69-476C-91FE-1B8F88832F5B +idx_pid +idx_pid +1575627715 +Mhb +1575627719 +Mhb +idx_pid + + + + + +A2834894-2D59-49BA-9A6F-CEE0FDEC17D9 +idx_sort +idx_sort +1575627715 +Mhb +1575627719 +Mhb +idx_sort + + + + + + + + + + +2D3D9596-404B-4E5F-BD8C-B9898F1DE56E +sys_oss +sys_oss +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '文件上传' ROW_FORMAT = Dynamic + + + +55F388A8-4FFE-4B7D-B6A3-A0AFF8CE2118 +id +id +1575627715 +Mhb +1575860953 +Mhb +id +bigint(32) +32 +1 + + +3F7EF8E5-628C-497D-BC3D-048448E34C5D +url +url +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +621C8AAC-7EB0-4384-9A7D-6287812F4596 +creator +creator +1575627715 +Mhb +1575860953 +Mhb +创建者 +NULL +bigint(32) +32 + + +FBEE4055-4887-423A-9063-F8160125EAAF +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +27A68632-900D-4778-95C5-26407BDF357C +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +61BC7698-640F-4D46-88CE-F4B3923A9C3C +idx_create_date +idx_create_date +1575627715 +Mhb +1575627719 +Mhb +idx_create_date + + + + + + + + + + +247AB0AE-CAAB-48E3-B2D3-B45E68C4ED75 +sys_params +sys_params +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '参数管理' ROW_FORMAT = Dynamic + + + +4B7C9891-5565-4E89-8418-0FE0F1CE220B +id +id +1575627715 +Mhb +1575860834 +Mhb +id +bigint(32) +32 +1 + + +15BA8EA1-CBC2-4EF2-AC5C-1939E8F09AC4 +param_code +param_code +1575627715 +Mhb +1575627719 +Mhb +varchar(32) +32 + + +945860B6-D134-485F-BBC7-8EA4C5888909 +param_value +param_value +1575627715 +Mhb +1575627719 +Mhb +varchar(2000) +2000 + + +43A17513-08B0-49F5-9958-33ACC001CCD9 +param_type +param_type +1575627715 +Mhb +1575627719 +Mhb +类型 0:系统参数 1:非系统参数 +1 +tinyint(3) +3 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +EADAF023-9C8F-4D8F-B023-21CB79E2DF5C +remark +remark +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +F476E89E-24F5-4E79-9199-CB942188B8EE +creator +creator +1575627715 +Mhb +1575860834 +Mhb +创建者 +NULL +bigint(32) +32 + + +CC0B4F24-1E2F-4E43-9F25-3EB2F12D3006 +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + +700805FD-B6CE-48C7-BD7D-E078FD1B07D9 +updater +updater +1575627715 +Mhb +1575860834 +Mhb +更新者 +NULL +bigint(32) +32 + + +3A416029-C771-4755-BA16-8C12B9F49104 +update_date +update_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +036A6EAF-1D71-4181-825A-661F31502F2C +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +CFC7D93C-A23D-44EE-A0D9-D927FB3B81E9 +uk_param_code +uk_param_code +1575627715 +Mhb +1575627719 +Mhb +uk_param_code +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,57={D1C795B8-8F7B-4AA7-A240-85C5B737C543},ExtUnique,4=true + + + + + + + +DA4BEFAB-FA06-4EC5-AB46-01EA8D270A71 +idx_create_date +idx_create_date +1575627715 +Mhb +1575627719 +Mhb +idx_create_date + + + + + + + + + + +C6F2E10E-0E90-40BA-8D4D-E8A536A47F96 +sys_region +sys_region +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '行政区域' ROW_FORMAT = Dynamic + + + +59C04A52-F0C9-4D2D-A15C-3BE998F23827 +id +id +1575627715 +Mhb +1575860771 +Mhb +id +bigint(32) +32 +1 + + +CB875F9A-9177-4C90-9DBE-A1A968A99112 +pid +pid +1575627715 +Mhb +1575860771 +Mhb +上级ID,一级为0 +NULL +bigint(32) +32 + + +0BD08184-57DC-4FFC-9804-AA6E0E98DAAC +name +name +1575627715 +Mhb +1575627719 +Mhb +varchar(100) +100 + + +CEC11AB1-EFAF-49C6-B078-634636169DC7 +tree_level +tree_level +1575627715 +Mhb +1575627719 +Mhb +层级 +NULL +tinyint(4) +4 + + +A85210C8-E455-4543-A02C-8BED32173C54 +leaf +leaf +1575627715 +Mhb +1575627719 +Mhb +是否叶子节点 0:否 1:是 +NULL +tinyint(4) +4 + + +C1659EAD-78EF-4A41-B341-70CB2788736A +sort +sort +1575627715 +Mhb +1575860771 +Mhb +排序 +NULL +bigint(32) +32 + + +BF8751E2-188C-43ED-AB7E-1D5C74ADD389 +creator +creator +1575627715 +Mhb +1575860771 +Mhb +创建者 +NULL +bigint(32) +32 + + +46641AC0-B8B5-4456-8E8F-CCFE754B4FCA +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + +C6502EC0-3C01-4136-A21C-3117586F66F6 +updater +updater +1575627715 +Mhb +1575860771 +Mhb +更新者 +NULL +bigint(32) +32 + + +1C6A4C0E-8256-4589-85ED-FB3733D2CAA6 +update_date +update_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +42CB078D-2C48-4779-B869-95C7F69625B8 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + + + + + + +40CDA285-E748-4E22-8242-BCA72ABFAA08 +sys_role +sys_role +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色管理' ROW_FORMAT = Dynamic + + + +217A7AFC-2DF7-4CD4-B670-DEB6EC6717AC +id +id +1575627715 +Mhb +1575860914 +Mhb +id +bigint(32) +32 +1 + + +49464548-E018-4B1D-8F56-E27574445729 +name +name +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +FF95C973-C099-4353-8E51-A2C5416FDF5C +remark +remark +1575627715 +Mhb +1575627719 +Mhb +varchar(100) +100 + + +D1B90730-E941-4704-85A0-66299AF57221 +dept_id +dept_id +1575627715 +Mhb +1575860914 +Mhb +部门ID +NULL +bigint(32) +32 + + +D5D89783-B6F3-4A31-A668-C71B74B77792 +creator +creator +1575627715 +Mhb +1575860914 +Mhb +创建者 +NULL +bigint(32) +32 + + +CCA11AB6-8EDD-4CCF-9B5E-CDE87157A613 +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + +794E5CC5-2A01-40F6-8F62-78960848E8AB +updater +updater +1575627715 +Mhb +1575860914 +Mhb +更新者 +NULL +bigint(32) +32 + + +F56062C6-409C-4BE3-8B95-6E0187F17462 +update_date +update_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +A2D679AB-19B6-41BC-B4F6-00EE9110FA05 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +9F1A53FB-7A5D-4C6B-A4C4-6847631E1868 +idx_dept_id +idx_dept_id +1575627715 +Mhb +1575627719 +Mhb +idx_dept_id + + + + + + + + + + +EE744184-1867-4539-A0CA-5B9647487C4C +sys_role_data_scope +sys_role_data_scope +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色数据权限' ROW_FORMAT = Dynamic + + + +F612EA36-9962-4961-8B1F-D6E7AFB1FE7D +id +id +1575627715 +Mhb +1575860976 +Mhb +id +bigint(32) +32 +1 + + +B0FE92E4-8688-44AE-8728-658DAE7B477D +role_id +role_id +1575627715 +Mhb +1575860976 +Mhb +角色ID +NULL +bigint(32) +32 + + +68D23DAA-CDB2-4212-BF57-4BA2FF021529 +dept_id +dept_id +1575627715 +Mhb +1575860976 +Mhb +部门ID +NULL +bigint(32) +32 + + +366667E3-52D2-4823-8230-11D143D6C883 +creator +creator +1575627715 +Mhb +1575860976 +Mhb +创建者 +NULL +bigint(32) +32 + + +8005ADE8-FA90-4633-AB9A-CFC21D91EAE8 +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +BEA5FBF9-456B-4437-BDE3-3CFD7FB3954B +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +FD62465C-9456-4A6F-AAB2-C29B169C3344 +idx_role_id +idx_role_id +1575627715 +Mhb +1575627719 +Mhb +idx_role_id + + + + + + + + + + +3164016F-45D2-412C-A8D1-DB0AC2CB04D1 +sys_role_menu +sys_role_menu +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色菜单关系' ROW_FORMAT = Dynamic + + + +0D7BBAAD-CB81-4B93-A98A-B94C035C66ED +id +id +1575627715 +Mhb +1575861025 +Mhb +id +bigint(32) +32 +1 + + +81CB727A-67E0-4023-A0C2-41EB54321B42 +role_id +role_id +1575627715 +Mhb +1575861025 +Mhb +角色ID +NULL +bigint(32) +32 + + +A62A0E48-4B28-422E-BF48-8206EA8D53BA +menu_id +menu_id +1575627715 +Mhb +1575861025 +Mhb +菜单ID +NULL +bigint(32) +32 + + +DD8F097F-BAD8-46EF-A728-88CA938AA639 +creator +creator +1575627715 +Mhb +1575861025 +Mhb +创建者 +NULL +bigint(32) +32 + + +20920ECA-25EC-4AB6-819A-25BBD630EE33 +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +C981CFC7-2EA0-485D-8042-CEC356DEFDC6 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +D617E5AB-0AE8-4CF7-AC2C-99CCA00411B7 +idx_role_id +idx_role_id +1575627715 +Mhb +1575627719 +Mhb +idx_role_id + + + + + +CAF344D3-D95F-4A84-9A74-80CFFE2EFF59 +idx_menu_id +idx_menu_id +1575627715 +Mhb +1575627719 +Mhb +idx_menu_id + + + + + + + + + + +24E81675-4E7F-4319-B703-D9A562AEFDE0 +sys_role_user +sys_role_user +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色用户关系' ROW_FORMAT = Dynamic + + + +CE22484B-6B1C-43AA-9F30-0F4222DFE1AD +id +id +1575627715 +Mhb +1575861003 +Mhb +id +bigint(32) +32 +1 + + +03690EDB-90EC-43DE-BD43-30106141C83A +role_id +role_id +1575627715 +Mhb +1575861003 +Mhb +角色ID +NULL +bigint(32) +32 + + +33DAD906-AFEF-479D-9489-2037BF10FD9D +user_id +user_id +1575627715 +Mhb +1575861003 +Mhb +用户ID +NULL +bigint(32) +32 + + +C4173478-19A5-4AB4-8312-416FAA249B94 +creator +creator +1575627715 +Mhb +1575861003 +Mhb +创建者 +NULL +bigint(32) +32 + + +BACEFE68-8CD4-4272-970C-BE8E0AB3F7D4 +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +4F317FA2-C006-4810-BF2F-F7B2B567781E +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +BFF9419B-032A-43F6-8018-939EB5213CED +idx_role_id +idx_role_id +1575627715 +Mhb +1575627719 +Mhb +idx_role_id + + + + + +C335C619-CA22-4755-AC44-D641CDEDD48E +idx_user_id +idx_user_id +1575627715 +Mhb +1575627719 +Mhb +idx_user_id + + + + + + + + + + +1AC9C4B2-5D19-4B26-897A-7C1BFFF63F7E +sys_sms +sys_sms +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '短信' ROW_FORMAT = Dynamic + + + +8A21AD7C-3E3A-4D72-8C33-A1897740B2DE +id +id +1575627715 +Mhb +1575860802 +Mhb +id +bigint(32) +32 +1 + + +F40FDC7D-594A-43DE-AA2B-6A6BBBFFF0FC +platform +platform +1575627715 +Mhb +1575627719 +Mhb +平台类型 +tinyint(3) +3 +1 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +CA8E0C8F-1007-4319-A741-9C0FD7222604 +mobile +mobile +1575627715 +Mhb +1575627719 +Mhb +varchar(20) +20 + + +EBD36F17-DF4D-4931-94B2-AA918BB9A02E +params_1 +params_1 +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +9AC68093-4163-44FB-90AE-87FF682A83E0 +params_2 +params_2 +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +2BC8A341-B440-405E-8E4C-F763DE32EB55 +params_3 +params_3 +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +0E652889-5821-49C6-8CEF-6AD64478A51F +params_4 +params_4 +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +FAD4C6E1-B25D-4CDF-8B05-ED34BC5DFCFB +status +status +1575627715 +Mhb +1575627719 +Mhb +发送状态 0:失败 1:成功 +NULL +tinyint(3) +3 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +6FED6DC6-7149-4FF6-9A48-5B13393ABE01 +creator +creator +1575627715 +Mhb +1575860802 +Mhb +创建者 +NULL +bigint(32) +32 + + +F5F72AEA-3888-4C18-8C64-45B6A47E6837 +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +95D56D87-1198-41B3-B9BC-F9681E991376 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +C3DE5639-6BC6-4873-9FD0-78564AB27A8A +idx_create_date +idx_create_date +1575627715 +Mhb +1575627719 +Mhb +idx_create_date + + + + + + + + + + +A58A7698-071B-44D7-AF80-D6D8921DC48A +sys_user +sys_user +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统用户' ROW_FORMAT = Dynamic + + + +AC7A4615-459F-4A48-9E68-B2577EF93BC3 +id +id +1575627715 +Mhb +1575860277 +Mhb +id +bigint(32) +32 +1 + + +17B53829-6D56-4598-AEA9-C06EF2834D97 +username +username +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +D41C3FBE-0992-421B-9CC8-BE1BC090AFF0 +password +password +1575627715 +Mhb +1575627719 +Mhb +varchar(100) +100 + + +DEF24AE2-AB2E-4CC4-82C0-F587CDB86208 +real_name +real_name +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +924123F1-3B59-4FAF-9741-9AD042E80606 +head_url +head_url +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +1043B155-5ACF-4001-A70A-E558AAB616A8 +gender +gender +1575627715 +Mhb +1575627719 +Mhb +性别 0:男 1:女 2:保密 +NULL +tinyint(3) +3 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +A239B1A1-AE14-4A3B-86B2-9D2F7FF9CED4 +email +email +1575627715 +Mhb +1575627719 +Mhb +varchar(100) +100 + + +6888AE0F-E133-4488-A7B5-B6E03C50C19A +mobile +mobile +1575627715 +Mhb +1575627719 +Mhb +varchar(100) +100 + + +BC22BBFB-68A5-45BC-8261-B81E89C11205 +dept_id +dept_id +1575627715 +Mhb +1575861998 +Mhb +部门ID +NULL +bigint(32) +32 + + +F617DEF0-53F7-4C81-A0B1-4EEB84BDA889 +super_admin +super_admin +1575627715 +Mhb +1575627719 +Mhb +超级管理员 0:否 1:是 +NULL +tinyint(3) +3 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +7F7E5A58-921F-4D62-A615-B8EC20A1874B +status +status +1575627715 +Mhb +1575627719 +Mhb +状态 0:停用 1:正常 +NULL +tinyint(4) +4 + + +DC4FD58A-5646-4686-976C-CB87E91E6E6A +creator +creator +1575627715 +Mhb +1575861998 +Mhb +创建者 +NULL +bigint(32) +32 + + +22BB5FCF-209F-4F41-8879-ACB787BC7C1C +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + +D2B92E58-1E65-4EC0-806C-44C1C0C4A049 +updater +updater +1575627715 +Mhb +1575861998 +Mhb +更新者 +NULL +bigint(32) +32 + + +04970014-4F19-485C-BCE5-669B1E00AD21 +update_date +update_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +00D374D0-EF55-46C9-9576-B3D9C36F8845 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +A897E52A-0D35-424C-AAD8-5C3DBC88A2F9 +uk_username +uk_username +1575627715 +Mhb +1575627719 +Mhb +uk_username +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,57={D1C795B8-8F7B-4AA7-A240-85C5B737C543},ExtUnique,4=true + + + + + + + +5002034A-4E71-4BBA-8AD4-822583E53791 +idx_create_date +idx_create_date +1575627715 +Mhb +1575627719 +Mhb +idx_create_date + + + + + + + + + + +A8C9390D-ACFD-4884-A2BB-81FC7E963F06 +sys_user_token +sys_user_token +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统用户Token' ROW_FORMAT = Dynamic + + + +83E02F1F-1C82-48A6-82DA-CD4EFA9D14A4 +id +id +1575627715 +Mhb +1575860928 +Mhb +id +bigint(32) +32 +1 + + +E3AF756A-1C01-4B12-B129-7314509AEC9C +user_id +user_id +1575627715 +Mhb +1575860928 +Mhb +用户id +bigint(32) +32 +1 + + +92C51463-0DAD-4A4C-9884-671003A7C354 +token +token +1575627715 +Mhb +1575627719 +Mhb +varchar(100) +100 + + +A6EE45F6-AF53-4F3B-A4BC-2F316E1BC5DF +expire_date +expire_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + +2B4C27F5-FE17-4EE6-86A4-31D4B5657C56 +update_date +update_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + +277CECC7-4653-4C4B-854C-9BAAC9A846A4 +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +341ADA0F-3333-469F-B49B-56DDB0BBF8F7 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +789407F0-85D0-4339-9B16-6BF7AEDB7132 +user_id +user_id +1575627715 +Mhb +1575627719 +Mhb +user_id +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,57={D1C795B8-8F7B-4AA7-A240-85C5B737C543},ExtUnique,4=true + + + + + + + +4F9F2EFA-373A-45C9-99C4-91005B5A0669 +token +token +1575627715 +Mhb +1575627719 +Mhb +token +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,57={D1C795B8-8F7B-4AA7-A240-85C5B737C543},ExtUnique,4=true + + + + + + + + + + + + +34248566-81C1-440F-A2DC-310D27B597C2 +control_bayonet_mid +control_bayonet_mid +1574155394 +Mhb +1575624501 +Mhb +布控和摄像头中间表 + + + +BE8962A9-0BF5-4D70-B0B8-49386D8FA61D +id +id +1574155394 +Mhb +1575861116 +Mhb +id +bigint(32) +32 +1 + + +9A3EF00D-C9FE-4624-9DE9-24D52CCCA692 +id_control_task +id_control_task +1575624441 +Mhb +1575861116 +Mhb +id布控id +bigint(32) +32 + + +CBB59FA0-0E7A-485E-AA38-D2A266CA557F +id_face_camera +id_face_camera +1575624473 +Mhb +1575861116 +Mhb +摄像头id +bigint(32) +32 + + +BE8A507C-3BC6-4C32-9C51-8DA1BC1DCDB8 +is_valid +is_valid +1574155394 +Mhb +1575624135 +Mhb +是否有效 Y有效 N无效 +varchar(1) +1 + + +C034A691-DA39-4D27-857F-E1F4322623B1 +create_time +create_time +1574155394 +Mhb +1575624135 +Mhb +创建时间 +datetime + + +7DECBF16-045C-476F-B97F-5691E8724BA0 +update_time +update_time +1574155394 +Mhb +1575624135 +Mhb +更新时间 +datetime + + +602EA424-77B9-436E-B861-D9D13DA52FE9 +create_by +create_by +1574233787 +Mhb +1575624135 +Mhb +创建人 +varchar(32) +32 + + +86FF23B8-EDCB-439F-8DAC-8494EEB4308D +update_by +update_by +1574233787 +Mhb +1575624135 +Mhb +更新人 +varchar(32) +32 + + + + +D831BF3F-A19F-498D-80DE-E27A5E90CDDA +Key_1 +Key_1 +1574218123 +Mhb +1575624135 +Mhb + + + + + + + + + + + + +CA640E14-FD6F-4E42-855B-0A8CC8CED08F +Reference_1 +Reference_1 +1573443498 +Mhb +1573443498 +Mhb +0..* +1 +1 + + + + + + + + + + + +B97457BA-0E2B-4AB8-BD73-C1B917CDBB52 +1573443498 +Mhb +1573443498 +Mhb + + + + + + + + + + +EAC66D9E-DEDF-48C7-938A-FC51012212AE +Reference_2 +Reference_2 +1575624441 +Mhb +1575624441 +Mhb +0..* +1 +1 + + + + + + + + + + + +C4454DC3-3B36-4F7B-8C84-9206DA6A8034 +1575624441 +Mhb +1575624441 +Mhb + + + + + + + + + + +776ACDFD-7BEC-44C7-B8E0-2CDCF4AA96D6 +Reference_3 +Reference_3 +1575624473 +Mhb +1575624473 +Mhb +0..* +1 +1 + + + + + + + + + + + +FC20B0EB-6A62-44D9-A605-55B0FDC144A8 +1575624473 +Mhb +1575624473 +Mhb + + + + + + + + + + +969DEED2-95A2-4879-953C-903E5078A5A5 +Reference_4 +Reference_4 +1575624521 +Mhb +1575624521 +Mhb +0..* +1 +1 + + + + + + + + + + + +296E410E-E215-4872-B62D-359A9E7406E5 +1575624521 +Mhb +1575624521 +Mhb + + + + + + + + + + +FD5A8738-CF6F-4899-820D-A34ED667AEB6 +Reference_5 +Reference_5 +1575624526 +Mhb +1575624526 +Mhb +0..* +1 +1 + + + + + + + + + + + +7D51A18B-4561-48AA-86E7-9C48C377C5A0 +1575624526 +Mhb +1575624526 +Mhb + + + + + + + + + + + + +232A460E-291D-4EE1-AAE3-1613C9E99263 +PUBLIC +PUBLIC +1573436672 +Mhb +1573436672 +Mhb + + + + +09B937B0-C216-4794-9D7E-4ECE097A3E2E +MySQL 5.0 +MYSQL50 +1573436673 +Mhb +1573436673 +Mhb +file:///%_DBMS%/mysql50.xdb +F4F16ECD-F2F1-4006-AF6F-638D5C65F35E +4BA9F647-DAB1-11D1-9944-006097355D9B +1276524678 + + + + + + + + + + \ No newline at end of file diff --git a/doc/face.pdb b/doc/face.pdb new file mode 100644 index 0000000..81b99e9 --- /dev/null +++ b/doc/face.pdb @@ -0,0 +1,9530 @@ + + + + + + + + + +90F6E7F8-C9CE-45FA-A6FC-EFEE42BCE6C6 +PhysicalDataModel_1 +PhysicalDataModel_1 +1573436673 +Mhb +1575889044 +Mhb +[FolderOptions] + +[FolderOptions\Physical Objects] +GenerationCheckModel=Yes +GenerationPath= +GenerationOptions= +GenerationTasks= +GenerationTargets= +GenerationSelections= +RevPkey=Yes +RevFkey=Yes +RevAkey=Yes +RevCheck=Yes +RevIndx=Yes +RevOpts=Yes +RevViewAsTabl=No +RevViewOpts=Yes +RevSystAsTabl=Yes +RevTablPerm=No +RevViewPerm=No +RevProcPerm=No +RevDbpkPerm=No +RevSqncPerm=No +RevAdtPerm=No +RevUserPriv=No +RevUserOpts=No +RevGrpePriv=No +RevRolePriv=No +RevDtbsOpts=Yes +RevDtbsPerm=No +RevViewIndx=Yes +RevJidxOpts=Yes +RevStats=No +RevTspcPerm=No +RevCaseSensitive=No +GenTrgrStdMsg=Yes +GenTrgrMsgTab= +GenTrgrMsgNo= +GenTrgrMsgTxt= +TrgrPreserve=No +TrgrIns=Yes +TrgrUpd=Yes +TrgrDel=Yes +TrgrC2Ins=Yes +TrgrC2Upd=Yes +TrgrC3=Yes +TrgrC4=Yes +TrgrC5=Yes +TrgrC6=Yes +TrgrC7=Yes +TrgrC8=Yes +TrgrC9=Yes +TrgrC10=Yes +TrgrC11=Yes +TrgrC1=Yes +TrgrC12Ins=Yes +TrgrC12Upd=Yes +TrgrC13=Yes +UpdateTableStatistics=Yes +UpdateColumnStatistics=Yes + +[FolderOptions\Physical Objects\Database Generation] +GenScriptName=face.sql +GenScriptName0= +GenScriptName1= +GenScriptName2= +GenScriptName3= +GenScriptName4= +GenScriptName5= +GenScriptName6= +GenScriptName7= +GenScriptName8= +GenScriptName9= +GenPathName=C:\Users\Mhb\Desktop\face\ +GenSingleFile=Yes +GenODBC=No +GenCheckModel=Yes +GenScriptPrev=Yes +GenArchiveModel=No +GenUseSync=No +GenSyncChoice=0 +GenSyncArch= +GenSyncRmg=0 + +[FolderOptions\Physical Objects\Database Generation\Format] +GenScriptTitle=No +GenScriptNamLabl=No +GenScriptQDtbs=No +GenScriptQOwnr=No +GenScriptCase=0 +GenScriptEncoding=UTF8 +GenScriptNAcct=No +IdentifierDelimiter=" + +[FolderOptions\Physical Objects\Database Generation\Database] +Create=Yes +Open=Yes +Close=Yes +Drop=Yes +Permission=No + +[FolderOptions\Physical Objects\Database Generation\Database\Create] +Physical Options=Yes +Header=Yes +Footer=Yes + +[FolderOptions\Physical Objects\Database Generation\Tablespace] +Create=Yes +Drop=Yes +Comment=Yes +Permission=No + +[FolderOptions\Physical Objects\Database Generation\Tablespace\Create] +Header=Yes +Footer=Yes + +[FolderOptions\Physical Objects\Database Generation\Storage] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\User] +Create=Yes +Drop=Yes +Comment=Yes +Privilege=No + +[FolderOptions\Physical Objects\Database Generation\User\Create] +Physical Options=No + +[FolderOptions\Physical Objects\Database Generation\Group] +Create=Yes +Drop=Yes +Comment=Yes +Privilege=No + +[FolderOptions\Physical Objects\Database Generation\Role] +Create=Yes +Drop=Yes +Privilege=No + +[FolderOptions\Physical Objects\Database Generation\UserDefinedDataType] +Create=Yes +Comment=Yes +Drop=Yes + +[FolderOptions\Physical Objects\Database Generation\UserDefinedDataType\Create] +Default value=Yes +Check=Yes + +[FolderOptions\Physical Objects\Database Generation\AbstractDataType] +Create=Yes +Header=Yes +Footer=Yes +Drop=Yes +Comment=Yes +Install JAVA class=Yes +Remove JAVA class=Yes +Permission=No + +[FolderOptions\Physical Objects\Database Generation\Rule] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\Default] +Create=Yes +Comment=Yes +Drop=Yes + +[FolderOptions\Physical Objects\Database Generation\Sequence] +Create=Yes +Drop=Yes +Comment=Yes +Permission=No + +[FolderOptions\Physical Objects\Database Generation\Table&&Column] + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Table] +Create=Yes +Drop=Yes +Comment=Yes +Permission=No + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Table\Create] +Check=Yes +Physical Options=Yes +Header=Yes +Footer=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Table\Create\Check] +Constraint declaration=No + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Column] +User datatype=No +Default value=Yes +Check=Yes +Physical Options=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Column\Check] +Constraint declaration=No + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Key] + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Key\Primary key] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Key\Primary key\Create] +Constraint declaration=No +Physical Options=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Key\Alternate key] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Key\Alternate key\Create] +Constraint declaration=No +Physical Options=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Foreign key] +Create=No +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Foreign key\Create] +Constraint declaration=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Index] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Index\Create] +Constraint declaration=Yes +Physical Options=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Index\Filter] +Primary key=No +Foreign key=No +Alternate key=No +Cluster=Yes +Other=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Trigger] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\Table&&Column\Trigger\Filter] +For insert=Yes +For update=Yes +For delete=Yes +For other=Yes + +[FolderOptions\Physical Objects\Database Generation\View] +Create=Yes +Drop=Yes +Comment=Yes +Permission=No + +[FolderOptions\Physical Objects\Database Generation\View\Create] +Force Column list=No +Physical Options=Yes +Header=Yes +Footer=Yes + +[FolderOptions\Physical Objects\Database Generation\View\ViewColumn] +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\View\ViewIndex] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\View\ViewIndex\Create] +Physical Options=Yes + +[FolderOptions\Physical Objects\Database Generation\View\ViewIndex\Filter] +Cluster=Yes +Other=Yes + +[FolderOptions\Physical Objects\Database Generation\View\Trigger] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\View\Trigger\Filter] +For insert=Yes +For update=Yes +For delete=Yes +For other=Yes + +[FolderOptions\Physical Objects\Database Generation\DBMSTrigger] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\Synonym] +Create=Yes +Drop=Yes + +[FolderOptions\Physical Objects\Database Generation\Synonym\Filter] +Table=Yes +View=Yes +Proc=Yes +Synonym=Yes +Database Package=Yes +Sequence=Yes + +[FolderOptions\Physical Objects\Database Generation\JoinIndex] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\JoinIndex\Create] +Physical Options=Yes +Header=Yes +Footer=Yes + +[FolderOptions\Physical Objects\Database Generation\Procedure] +Create=Yes +Drop=Yes +Comment=Yes +Permission=No + +[FolderOptions\Physical Objects\Database Generation\Procedure\Create] +Header=Yes +Footer=Yes + +[FolderOptions\Physical Objects\Database Generation\DatabasePackage] +Create=Yes +Drop=Yes +Permission=No + +[FolderOptions\Physical Objects\Database Generation\WebService] +Create=Yes +Drop=Yes +Comment=Yes + +[FolderOptions\Physical Objects\Database Generation\Dimension] +Create=Yes +Drop=Yes + +[FolderOptions\Physical Objects\Database Generation\Synchronization] +GenBackupTabl=1 +GenKeepBackTabl=1 +GenTmpTablDrop=No +GenKeepTablOpts=No + +[FolderOptions\Physical Objects\Test Data] +GenDataPathName= +GenDataSinglefile=Yes +GenDataScriptName=testdata +GenDataScriptName0= +GenDataScriptName1= +GenDataScriptName2= +GenDataScriptName3= +GenDataScriptName4= +GenDataScriptName5= +GenDataScriptName6= +GenDataScriptName7= +GenDataScriptName8= +GenDataScriptName9= +GenDataOdbc=0 +GenDataDelOld=No +GenDataTitle=Yes +GenDataDefNumRows=20 +GenDataCommit=0 +GenDataPacket=0 +GenDataOwner=Yes +GenDataProfNumb= +GenDataProfChar= +GenDataProfDate= +GenDataCSVSeparator=, +GenDataFileFormat=CSV +GenDataUseWizard=No + +[FolderOptions\Pdm] +IndxIQName=%COLUMN%_%INDEXTYPE% +IndxPK=Yes +IndxFK=Yes +IndxAK=Yes +IndxPKName=%TABLE%_PK +IndxFKName=%REFR%_FK +IndxAKName=%AKEY%_AK +IndxPreserve=No +IndxThreshold=0 +IndxStats=No +RefrPreserve=No +JidxPreserve=No +RbldMultiFact=Yes +RbldMultiDim=Yes +RbldMultiJidx=Yes +CubePreserve=No +TablStProcPreserve=No +ProcDepPreserve=Yes +TrgrDepPreserve=Yes +CubeScriptPath= +CubeScriptCase=0 +CubeScriptEncoding=ANSI +CubeScriptNacct=No +CubeScriptHeader=No +CubeScriptExt=csv +CubeScriptExt0=txt +CubeScriptExt1= +CubeScriptExt2= +CubeScriptSep=, +CubeScriptDeli=" +EstimationYears=0 +DfltDomnName=D_%.U:VALUE% +DfltColnName=D_%.U:VALUE% +DfltReuse=Yes +DfltDrop=Yes + +[FolderOptions\CheckModel] + +[FolderOptions\CheckModel\Package] + +[FolderOptions\CheckModel\Package\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\CheckPackageMissTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\DefaultCheckPackageMissTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\CircularReference] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\ConstraintName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\CnstMaxLen] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\CircularDependency] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Package\ShortcutUniqCode] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Table] + +[FolderOptions\CheckModel\Table\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\UniqIndex] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\MaxLen - NAME] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\EmptyColl - COLNCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\EmptyColl - INDXCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\EmptyColl - KEYCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\SerialColumnNumber] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\EmptyCollYesYes] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\TableIndexes] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\Mapping] +CheckSeverity=No +FixRequested=Yes +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\MappingSFMap] +CheckSeverity=No +FixRequested=Yes +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\EmptyColl - PERMCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Table\CheckTablePartitionKey] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\CheckTableStartDate] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\CheckTableRefNoLifecycle] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\CheckTableSourceMapping] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\CheckTablePartialColumnMapping] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\CheckTableKeyColumnMapping] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\CheckTableNotOnLifecycleTablespace] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table\MYSQL50_Table_Table_storage_type] +CheckSeverity=No +FixRequested=Yes +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column] + +[FolderOptions\CheckModel\Table.Column\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\DomainDivergence] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\ColumnMandatory] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\CheckNumParam] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\CheckPrecSupLng] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\CheckUndefDttp] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\FkeyDttpDivergence] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\FkeyCheckDivergence] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\ColnSqncNoKey] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\ColnSqncDttp] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\SerialColumnFK] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\ColumnCompExpr] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\CheckColumnOneToOneMapping] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\CheckColumnDataTypeMapping] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\CheckColumnNoMapping] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\CheckDttpIncompatibleFormat] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\MYSQL50_Column_Auto_increment_key] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Column\MYSQL50_Column_Datatype_attributes] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index] + +[FolderOptions\CheckModel\Table.Index\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\EmptyColl - CIDXCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\UndefIndexType] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\IndexColumnCount] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\IQIndxHNGUniq] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\CheckIncludeColl - Tabl] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Index\MYSQL50_Index_Fulltext_indexes_validity] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key] + +[FolderOptions\CheckModel\Table.Key\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\EmptyColl - COLNCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\CheckIncludeColl - Tabl] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Key\MultiKeySqnc] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Trigger] + +[FolderOptions\CheckModel\Table.Trigger\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Trigger\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Trigger\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Trigger\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Trigger\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Trigger\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Trigger\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table.Trigger\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Join Index] + +[FolderOptions\CheckModel\Join Index\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Join Index\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Join Index\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Join Index\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Join Index\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Join Index\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Join Index\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View] + +[FolderOptions\CheckModel\View\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View\EmptyColl - PERMCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\View.View Index] + +[FolderOptions\CheckModel\View.View Index\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\EmptyColl - CIDXCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\IndexColumnCount] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View.View Index\CheckIncludeColl - Tabl] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference] + +[FolderOptions\CheckModel\Reference\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\Reflexive] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\EmptyColl - RFJNCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\IncompleteJoin] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Reference\JoinOrder] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View Reference] + +[FolderOptions\CheckModel\View Reference\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View Reference\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View Reference\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View Reference\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View Reference\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View Reference\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View Reference\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\View Reference\EmptyColl - VRFJNCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain] + +[FolderOptions\CheckModel\Domain\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\CheckNumParam] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\CheckPrecSupLng] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\CheckUndefDttp] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Domain\CheckDttpIncompatibleFormat] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default] + +[FolderOptions\CheckModel\Default\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default\DfltValeEmpty] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Default\DfltSameVale] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\User] + +[FolderOptions\CheckModel\User\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\User\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\User\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\User\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\User\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\User\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\User\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\User\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\User\UniquePassword] +CheckSeverity=No +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Group] + +[FolderOptions\CheckModel\Group\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Group\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Group\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Group\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Group\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Group\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Group\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Group\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Group\EmptyColl - USERCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Group\UniquePassword] +CheckSeverity=No +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Role] + +[FolderOptions\CheckModel\Role\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Role\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Role\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Role\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Role\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Role\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Role\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Role\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Role\EmptyColl - USERCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure] + +[FolderOptions\CheckModel\Procedure\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure\ProcBodyEmpty] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Procedure\EmptyColl - PERMCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\DBMS Trigger] + +[FolderOptions\CheckModel\DBMS Trigger\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\DBMS Trigger\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\DBMS Trigger\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\DBMS Trigger\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\DBMS Trigger\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\DBMS Trigger\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\DBMS Trigger\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\DBMS Trigger\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\DBMS Trigger\DbmsTriggerEvent] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source] + +[FolderOptions\CheckModel\Data Source\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source\EmptyColl - MODLSRC] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source\DtscTargets] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Source\CheckDataSourceModels] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Horizontal Partitioning] + +[FolderOptions\CheckModel\Horizontal Partitioning\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Horizontal Partitioning\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Horizontal Partitioning\EmptyColl - PARTCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Horizontal Partitioning\TargetTables] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Vertical Partitioning] + +[FolderOptions\CheckModel\Vertical Partitioning\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Vertical Partitioning\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Vertical Partitioning\EmptyColl - PARTCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Vertical Partitioning\TargetTables] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table Collapsing] + +[FolderOptions\CheckModel\Table Collapsing\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table Collapsing\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table Collapsing\EmptyColl - TargetTable] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Table Collapsing\TargetTables] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact] + +[FolderOptions\CheckModel\Fact\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\EmptyColl - MEASCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\Mapping] +CheckSeverity=No +FixRequested=Yes +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\MappingSFMap] +CheckSeverity=No +FixRequested=Yes +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\EmptyColl - ALLOLINKCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact\CubeDupAssociation] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension] + +[FolderOptions\CheckModel\Dimension\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\EmptyColl - DATTRCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\EmptyColl - HIERCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\DimnDupHierarchy] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\DimnDefHierarchy] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\Mapping] +CheckSeverity=No +FixRequested=Yes +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\MappingSFMap] +CheckSeverity=No +FixRequested=Yes +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension\SerialColumnNumber] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Association] + +[FolderOptions\CheckModel\Association\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Association\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Association\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Association\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Association\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Association\EmptyColl - Hierarchy] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Attribute] + +[FolderOptions\CheckModel\Dimension.Attribute\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Attribute\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Attribute\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Attribute\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Attribute\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Attribute\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Attribute\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact.Measure] + +[FolderOptions\CheckModel\Fact.Measure\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact.Measure\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact.Measure\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact.Measure\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact.Measure\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact.Measure\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Fact.Measure\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Hierarchy] + +[FolderOptions\CheckModel\Dimension.Hierarchy\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Hierarchy\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Hierarchy\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Hierarchy\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Hierarchy\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Hierarchy\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Hierarchy\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Dimension.Hierarchy\EmptyColl - DATTRCOL] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym] + +[FolderOptions\CheckModel\Synonym\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym\MaxLen - NAME] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Synonym\EmptyColl - BASEOBJ] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type] + +[FolderOptions\CheckModel\Abstract Data Type\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type\AdtInstantiable] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type\AdtAbstractUsed] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure] + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\AdtProcUniqName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\UniqueDefinition] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Abstract Data Type.Abstract Data Type Procedure\ReturnDataType] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package] + +[FolderOptions\CheckModel\Database Package\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\MaxLen - NAME] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\EmptyColl - PROCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package\EmptyColl - CURCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Database Package\EmptyColl - VARCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Database Package\EmptyColl - TYPCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Database Package\EmptyColl - EXCCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Database Package.Database Package Procedure] + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\UniqueDefinition] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\EmptyColl - PARM] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Database Package.Database Package Procedure\ReturnDataType] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Sequence] + +[FolderOptions\CheckModel\Sequence\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Sequence\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Sequence\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Sequence\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Sequence\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Sequence\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Sequence\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Sequence\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor] + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\UniqueDefinition] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\ReturnDataType] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Cursor\EmptyColl - PARM] +CheckSeverity=Yes +FixRequested=No +CheckRequested=No + +[FolderOptions\CheckModel\Database Package.Database Package Variable] + +[FolderOptions\CheckModel\Database Package.Database Package Variable\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Variable\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Variable\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Variable\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Variable\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Variable\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Variable\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Variable\CheckUndefDttp] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Type] + +[FolderOptions\CheckModel\Database Package.Database Package Type\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Type\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Type\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Type\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Type\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Type\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Type\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Type\UniqueDefinition] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Exception] + +[FolderOptions\CheckModel\Database Package.Database Package Exception\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Exception\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Exception\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Exception\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Exception\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Exception\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database Package.Database Package Exception\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Tablespace] + +[FolderOptions\CheckModel\Tablespace\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Tablespace\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Tablespace\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Tablespace\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Tablespace\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Tablespace\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Tablespace\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Tablespace\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Tablespace\IsObjectUsed] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Storage] + +[FolderOptions\CheckModel\Storage\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Storage\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Storage\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Storage\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Storage\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Storage\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Storage\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Storage\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Storage\IsObjectUsed] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database] + +[FolderOptions\CheckModel\Database\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Database\IsObjectUsed] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service] + +[FolderOptions\CheckModel\Web Service\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service.Web Operation] + +[FolderOptions\CheckModel\Web Service.Web Operation\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service.Web Operation\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service.Web Operation\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service.Web Operation\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service.Web Operation\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service.Web Operation\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service.Web Operation\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Web Service.Web Operation\MaxLen - CODE] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle] + +[FolderOptions\CheckModel\Lifecycle\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle\CheckLifecyclePhase] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle\CheckLifecycleRetention] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle\CheckPartitionRange] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase] + +[FolderOptions\CheckModel\Lifecycle.Phase\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckPhaseTbspace] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckPhaseIQTbspace] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckPhaseDuplicateTbspace] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckPhaseTbspaceCurrency] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckPhaseRetention] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckPhaseIdlePeriod] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckPhaseDataSource] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Lifecycle.Phase\CheckPhaseExternalOnFirst] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Replication] + +[FolderOptions\CheckModel\Replication\PartialReplication] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Business Rule] + +[FolderOptions\CheckModel\Business Rule\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Business Rule\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Business Rule\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Business Rule\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Business Rule\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Business Rule\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Business Rule\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Business Rule\EmptyColl - OBJCOL] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Object] + +[FolderOptions\CheckModel\Extended Object\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Object\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Object\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Object\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Object\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Object\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Object\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Link] + +[FolderOptions\CheckModel\Extended Link\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Link\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Link\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Link\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Link\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Link\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Extended Link\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\File] + +[FolderOptions\CheckModel\File\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\File\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\File\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\File\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\File\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\File\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\File\CheckPathExists] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Format] + +[FolderOptions\CheckModel\Data Format\CheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Format\CheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Format\DefaultCheckUseOnlyTerms] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Format\DefaultCheckUseTermBySynonym] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Format\NotApprovedTerms] +CheckSeverity=Yes +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Format\UniqueName] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Format\UniqueCode] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes + +[FolderOptions\CheckModel\Data Format\CheckDataFormatNullExpression] +CheckSeverity=No +FixRequested=No +CheckRequested=Yes +[ModelOptions] + +[ModelOptions\Physical Objects] +CaseSensitive=No +DisplayName=Yes +EnableTrans=No +UseTerm=No +EnableRequirements=No +EnableFullShortcut=Yes +DefaultDttp= +IgnoreOwner=No +RebuildTrigger=Yes +RefrUnique=No +RefrAutoMigrate=Yes +RefrMigrateReuse=Yes +RefrMigrateDomain=Yes +RefrMigrateCheck=Yes +RefrMigrateRule=Yes +RefrMigrateExtd=No +RefrMigrDefaultLink=No +RefrDfltImpl=D +RefrPrgtColn=No +RefrMigrateToEnd=No +RebuildTriggerDep=No +ColnFKName=%.3:PARENT%_%COLUMN% +ColnFKNameUse=No +DomnCopyDttp=Yes +DomnCopyChck=No +DomnCopyRule=No +DomnCopyMand=No +DomnCopyExtd=No +DomnCopyProf=No +Notation=0 +DomnDefaultMandatory=No +ColnDefaultMandatory=No +TablDefaultOwner= +ViewDefaultOwner= +TrgrDefaultOwnerTabl= +TrgrDefaultOwnerView= +IdxDefaultOwnerTabl= +IdxDefaultOwnerView= +JdxDefaultOwner= +DBPackDefaultOwner= +SeqDefaultOwner= +ProcDefaultOwner= +DBMSTrgrDefaultOwner= +Currency=USD +RefrDeleteConstraint=1 +RefrUpdateConstraint=1 +RefrParentMandatory=No +RefrParentChangeAllow=Yes +RefrCheckOnCommit=No + +[ModelOptions\Physical Objects\NamingOptionsTemplates] + +[ModelOptions\Physical Objects\ClssNamingOptions] + +[ModelOptions\Physical Objects\ClssNamingOptions\PDMPCKG] + +[ModelOptions\Physical Objects\ClssNamingOptions\PDMPCKG\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\PDMPCKG\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\PDMDOMN] + +[ModelOptions\Physical Objects\ClssNamingOptions\PDMDOMN\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\PDMDOMN\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\TABL] + +[ModelOptions\Physical Objects\ClssNamingOptions\TABL\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\TABL\Code] +Template= +MaxLen=64 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\COLN] + +[ModelOptions\Physical Objects\ClssNamingOptions\COLN\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\COLN\Code] +Template= +MaxLen=64 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\INDX] + +[ModelOptions\Physical Objects\ClssNamingOptions\INDX\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\INDX\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\REFR] + +[ModelOptions\Physical Objects\ClssNamingOptions\REFR\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\REFR\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\VREF] + +[ModelOptions\Physical Objects\ClssNamingOptions\VREF\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\VREF\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\VIEW] + +[ModelOptions\Physical Objects\ClssNamingOptions\VIEW\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\VIEW\Code] +Template= +MaxLen=64 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\VIEWC] + +[ModelOptions\Physical Objects\ClssNamingOptions\VIEWC\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\VIEWC\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\WEBSERV] + +[ModelOptions\Physical Objects\ClssNamingOptions\WEBSERV\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\WEBSERV\Code] +Template= +MaxLen=254 +Case=M +ValidChar='a'-'z','A'-'Z','0'-'9',"/-_.!~*'()" +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\WEBOP] + +[ModelOptions\Physical Objects\ClssNamingOptions\WEBOP\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\WEBOP\Code] +Template= +MaxLen=254 +Case=M +ValidChar='a'-'z','A'-'Z','0'-'9',"/-_.!~*'()" +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\WPARAM] + +[ModelOptions\Physical Objects\ClssNamingOptions\WPARAM\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\WPARAM\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\FACT] + +[ModelOptions\Physical Objects\ClssNamingOptions\FACT\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\FACT\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\DIMN] + +[ModelOptions\Physical Objects\ClssNamingOptions\DIMN\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\DIMN\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\MEAS] + +[ModelOptions\Physical Objects\ClssNamingOptions\MEAS\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\MEAS\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\DATTR] + +[ModelOptions\Physical Objects\ClssNamingOptions\DATTR\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\DATTR\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\FILO] + +[ModelOptions\Physical Objects\ClssNamingOptions\FILO\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\FILO\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\FRMEOBJ] + +[ModelOptions\Physical Objects\ClssNamingOptions\FRMEOBJ\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\FRMEOBJ\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\FRMELNK] + +[ModelOptions\Physical Objects\ClssNamingOptions\FRMELNK\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\FRMELNK\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\DefaultClass] + +[ModelOptions\Physical Objects\ClssNamingOptions\DefaultClass\Name] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Physical Objects\ClssNamingOptions\DefaultClass\Code] +Template= +MaxLen=254 +Case=M +ValidChar= +InvldChar= +AllValid=Yes +NoAccent=No +DefaultChar= +Script= +ConvTable= +ConvTablePath=%_HOME%\Resource Files\Conversion Tables + +[ModelOptions\Connection] + +[ModelOptions\Pdm] + +[ModelOptions\Generate] + +[ModelOptions\Generate\Xsm] +GenRootElement=Yes +GenComplexType=No +GenAttribute=Yes +CheckModel=Yes +SaveLinks=Yes +ORMapping=No +NameToCode=No + +[ModelOptions\Generate\Pdm] +RRMapping=No + +[ModelOptions\Generate\Cdm] +CheckModel=Yes +SaveLinks=Yes +NameToCode=No +Notation=2 + +[ModelOptions\Generate\Oom] +CheckModel=Yes +SaveLinks=Yes +ORMapping=No +NameToCode=Yes +ClassPrefix= + +[ModelOptions\Generate\Ldm] +CheckModel=Yes +SaveLinks=Yes +NameToCode=No + +[ModelOptions\Default Opts] + +[ModelOptions\Default Opts\TABL] +PhysOpts= + +[ModelOptions\Default Opts\COLN] +PhysOpts= + +[ModelOptions\Default Opts\INDX] +PhysOpts= + +[ModelOptions\Default Opts\AKEY] +PhysOpts= + +[ModelOptions\Default Opts\PKEY] +PhysOpts= + +[ModelOptions\Default Opts\STOR] +PhysOpts= + +[ModelOptions\Default Opts\TSPC] +PhysOpts= + +[ModelOptions\Default Opts\SQNC] +PhysOpts= + +[ModelOptions\Default Opts\DTBS] +PhysOpts= + +[ModelOptions\Default Opts\USER] +PhysOpts= + +[ModelOptions\Default Opts\JIDX] +PhysOpts= + + +9E1F518A-7D51-4939-BAD2-58F09FDE6A85 +MySQL 5.0 +MYSQL50 +1573436673 +Mhb +1573436673 +Mhb + +F4F16ECD-F2F1-4006-AF6F-638D5C65F35E +4BA9F647-DAB1-11D1-9944-006097355D9B + + + + +AC53207B-2EBA-4AC0-96E5-909C17A10072 +PhysicalDiagram_1 +PhysicalDiagram_1 +1573436673 +Mhb +1575889044 +Mhb +[DisplayPreferences] + +[DisplayPreferences\PDM] + +[DisplayPreferences\General] +Adjust to text=Yes +Snap Grid=No +Constrain Labels=Yes +Display Grid=No +Show Page Delimiter=Yes +Show Links intersections=Yes +Activate automatic link routing=Yes +Grid size=0 +Graphic unit=2 +Window color=255, 255, 255 +Background image= +Background mode=8 +Watermark image= +Watermark mode=8 +Show watermark on screen=No +Gradient mode=0 +Gradient end color=255, 255, 255 +Show Swimlane=No +SwimlaneVert=Yes +TreeVert=No +CompDark=0 + +[DisplayPreferences\Object] +Show Icon=No +Mode=2 +Trunc Length=40 +Word Length=40 +Word Text=!"#$%&')*+,-./:;=>?@\]^_`|}~ +Shortcut IntIcon=Yes +Shortcut IntLoct=Yes +Shortcut IntFullPath=No +Shortcut IntLastPackage=Yes +Shortcut ExtIcon=Yes +Shortcut ExtLoct=No +Shortcut ExtFullPath=No +Shortcut ExtLastPackage=Yes +Shortcut ExtIncludeModl=Yes +EObjShowStrn=Yes +ExtendedObject.Comment=No +ExtendedObject.IconPicture=No +ExtendedObject.TextStyle=No +ExtendedObject_SymbolLayout=<Form>[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="&lt;&lt;" Suffix="&gt;&gt;" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Object Name" Attribute="DisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF] <Separator Name="Separator" />[CRLF] <StandardAttribute Name="Comment" Attribute="Comment" Prefix="" Suffix="" Alignment="LEFT" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Icon" Attribute="IconPicture" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF] <StandardAttribute Name="Force top align" Attribute="TextStyle" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF]</Form> +ELnkShowStrn=Yes +ELnkShowName=Yes +ExtendedLink_SymbolLayout=<Form>[CRLF] <Form Name="Center" >[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="&lt;&lt;" Suffix="&gt;&gt;" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] </Form>[CRLF] <Form Name="Source" >[CRLF] </Form>[CRLF] <Form Name="Destination" >[CRLF] </Form>[CRLF]</Form> +FileObject.Stereotype=No +FileObject.DisplayName=Yes +FileObject.LocationOrName=No +FileObject.IconPicture=No +FileObject.TextStyle=No +FileObject.IconMode=Yes +FileObject_SymbolLayout=<Form>[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="&lt;&lt;" Suffix="&gt;&gt;" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <ExclusiveChoice Name="Exclusive Choice" Mandatory="Yes" Display="HorizontalRadios" >[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Location" Attribute="LocationOrName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] </ExclusiveChoice>[CRLF] <StandardAttribute Name="Icon" Attribute="IconPicture" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF] <StandardAttribute Name="Force top align" Attribute="TextStyle" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF]</Form> +Package.Stereotype=Yes +Package.Comment=No +Package.IconPicture=No +Package.TextStyle=No +Package_SymbolLayout=<Form>[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="&lt;&lt;" Suffix="&gt;&gt;" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF] <Separator Name="Separator" />[CRLF] <StandardAttribute Name="Comment" Attribute="Comment" Prefix="" Suffix="" Alignment="LEFT" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Icon" Attribute="IconPicture" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF] <StandardAttribute Name="Force top align" Attribute="TextStyle" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF]</Form> +Display Model Version=Yes +Table.Stereotype=Yes +Table.DisplayName=Yes +Table.OwnerDisplayName=No +Table.Columns=Yes +Table.Columns._Filter="All Columns" PDMCOLNALL +Table.Columns._Columns=Stereotype DataType KeyIndicator +Table.Columns._Limit=-5 +Table.Keys=No +Table.Keys._Columns=Stereotype Indicator +Table.Indexes=No +Table.Indexes._Columns=Stereotype +Table.Triggers=No +Table.Triggers._Columns=Stereotype +Table.Comment=No +Table.IconPicture=No +Table.TextStyle=No +Table_SymbolLayout=<Form>[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="&lt;&lt;" Suffix="&gt;&gt;" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <ExclusiveChoice Name="Exclusive Choice" Mandatory="Yes" Display="HorizontalRadios" >[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Owner and Name" Attribute="OwnerDisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] </ExclusiveChoice>[CRLF] <Separator Name="Separator" />[CRLF] <StandardCollection Name="Columns" Collection="Columns" Columns="Stereotype No\r\nDisplayName Yes\r\nDataType No\r\nSymbolDataType No &quot;Domain or Data type&quot;\r\nDomain No\r\nKeyIndicator No\r\nIndexIndicator No\r\nNullStatus No" Filters="&quot;All Columns&quot; PDMCOLNALL &quot;&quot;\r\n&quot;PK Columns&quot; PDMCOLNPK &quot;\&quot;PRIM \&quot;TRUE\&quot; TRUE\&quot;&quot;\r\n&quot;Key Columns&quot; PDMCOLNKEY &quot;\&quot;KEYS \&quot;TRUE\&quot; TRUE\&quot;&quot;" HasLimit="Yes" HideEmpty="No" Caption="" Mandatory="No" />[CRLF] <StandardCollection Name="Keys" Collection="Keys" Columns="Stereotype No\r\nDisplayName Yes\r\nIndicator No" HasLimit="No" HideEmpty="No" Caption="" Mandatory="No" />[CRLF] <StandardCollection Name="Indexes" Collection="Indexes" Columns="Stereotype No\r\nDisplayName Yes\r\nIndicator No" HasLimit="No" HideEmpty="No" Caption="" Mandatory="No" />[CRLF] <StandardCollection Name="Triggers" Collection="Triggers" Columns="Stereotype No\r\nDisplayName Yes" HasLimit="No" HideEmpty="No" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Comment" Attribute="Comment" Prefix="" Suffix="" Alignment="LEFT" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Icon" Attribute="IconPicture" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF] <StandardAttribute Name="Force top align" Attribute="TextStyle" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF]</Form> +View.Stereotype=Yes +View.DisplayName=Yes +View.OwnerDisplayName=No +View.Columns=Yes +View.Columns._Columns=DisplayName +View.Columns._Limit=-5 +View.TemporaryVTables=Yes +View.Indexes=No +View.Comment=No +View.IconPicture=No +View.TextStyle=No +View_SymbolLayout=<Form>[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="&lt;&lt;" Suffix="&gt;&gt;" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <ExclusiveChoice Name="Exclusive Choice" Mandatory="Yes" Display="HorizontalRadios" >[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Owner and Name" Attribute="OwnerDisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] </ExclusiveChoice>[CRLF] <Separator Name="Separator" />[CRLF] <StandardCollection Name="Columns" Collection="Columns" Columns="DisplayName No\r\nExpression No\r\nDataType No\r\nSymbolDataType No &quot;Domain or Data type&quot;\r\nIndexIndicator No" HasLimit="Yes" HideEmpty="No" Caption="" Mandatory="No" />[CRLF] <StandardCollection Name="Tables" Collection="TemporaryVTables" Columns="Name Yes" HasLimit="No" HideEmpty="No" Caption="" Mandatory="No" />[CRLF] <StandardCollection Name="Indexes" Collection="Indexes" Columns="DisplayName Yes" HasLimit="No" HideEmpty="No" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Comment" Attribute="Comment" Prefix="" Suffix="" Alignment="LEFT" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Icon" Attribute="IconPicture" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF] <StandardAttribute Name="Force top align" Attribute="TextStyle" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF]</Form> +Procedure.Stereotype=No +Procedure.DisplayName=Yes +Procedure.OwnerDisplayName=No +Procedure.Comment=No +Procedure.IconPicture=No +Procedure.TextStyle=No +Procedure_SymbolLayout=<Form>[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="&lt;&lt;" Suffix="&gt;&gt;" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <ExclusiveChoice Name="Exclusive Choice" Mandatory="Yes" Display="HorizontalRadios" >[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Owner and Name" Attribute="OwnerDisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] </ExclusiveChoice>[CRLF] <Separator Name="Separator" />[CRLF] <StandardAttribute Name="Comment" Attribute="Comment" Prefix="" Suffix="" Alignment="LEFT" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Icon" Attribute="IconPicture" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF] <StandardAttribute Name="Force top align" Attribute="TextStyle" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF]</Form> +Reference.Cardinality=No +Reference.ImplementationType=No +Reference.ChildRole=Yes +Reference.Stereotype=Yes +Reference.DisplayName=No +Reference.ForeignKeyConstraintName=No +Reference.JoinExpression=No +Reference.Integrity=No +Reference.ParentRole=Yes +Reference_SymbolLayout=<Form>[CRLF] <Form Name="Source" >[CRLF] <StandardAttribute Name="Cardinality" Attribute="Cardinality" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Implementation" Attribute="ImplementationType" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Child Role" Attribute="ChildRole" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] </Form>[CRLF] <Form Name="Center" >[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="&lt;&lt;" Suffix="&gt;&gt;" Caption="" Mandatory="No" />[CRLF] <ExclusiveChoice Name="Exclusive Choice" Mandatory="No" Display="HorizontalRadios" >[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Cons&amp;traint Name" Attribute="ForeignKeyConstraintName" Prefix="" Suffix="" Caption="Cons&amp;traint Name" Mandatory="No" />[CRLF] <StandardAttribute Name="Join" Attribute="JoinExpression" Prefix="" Suffix="" Caption="Join" Mandatory="No" />[CRLF] </ExclusiveChoice>[CRLF] <StandardAttribute Name="Referential integrity" Attribute="Integrity" Prefix="" Suffix="" Caption="Referential integrity" Mandatory="No" />[CRLF] </Form>[CRLF] <Form Name="Destination" >[CRLF] <StandardAttribute Name="Parent Role" Attribute="ParentRole" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] </Form>[CRLF]</Form> +ViewReference.ChildRole=Yes +ViewReference.Stereotype=Yes +ViewReference.DisplayName=No +ViewReference.JoinExpression=No +ViewReference.ParentRole=Yes +ViewReference_SymbolLayout=<Form>[CRLF] <Form Name="Source" >[CRLF] <StandardAttribute Name="Child Role" Attribute="ChildRole" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] </Form>[CRLF] <Form Name="Center" >[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="&lt;&lt;" Suffix="&gt;&gt;" Caption="" Mandatory="No" />[CRLF] <ExclusiveChoice Name="Exclusive Choice" Mandatory="No" Display="HorizontalRadios" >[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Join Expression" Attribute="JoinExpression" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] </ExclusiveChoice>[CRLF] </Form>[CRLF] <Form Name="Destination" >[CRLF] <StandardAttribute Name="Parent Role" Attribute="ParentRole" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] </Form>[CRLF]</Form> + +[DisplayPreferences\Symbol] + +[DisplayPreferences\Symbol\FRMEOBJ] +STRNFont=新宋体,8,N +STRNFont color=0, 0, 0 +DISPNAMEFont=新宋体,8,N +DISPNAMEFont color=0, 0, 0 +LABLFont=新宋体,8,N +LABLFont color=0, 0, 0 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Width=6000 +Height=2000 +Brush color=255 255 255 +Fill Color=Yes +Brush style=6 +Brush bitmap mode=12 +Brush gradient mode=64 +Brush gradient color=192 192 192 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 255 128 128 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\FRMELNK] +CENTERFont=新宋体,8,N +CENTERFont color=0, 0, 0 +Line style=1 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Brush color=255 255 255 +Fill Color=Yes +Brush style=1 +Brush bitmap mode=12 +Brush gradient mode=0 +Brush gradient color=118 118 118 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 128 128 255 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\FILO] +OBJSTRNFont=新宋体,8,N +OBJSTRNFont color=0, 0, 0 +DISPNAMEFont=新宋体,8,N +DISPNAMEFont color=0, 0, 0 +LCNMFont=新宋体,8,N +LCNMFont color=0, 0, 0 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Width=4800 +Height=3600 +Brush color=255 255 255 +Fill Color=Yes +Brush style=1 +Brush bitmap mode=12 +Brush gradient mode=0 +Brush gradient color=118 118 118 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 0 0 255 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\PDMPCKG] +STRNFont=新宋体,8,N +STRNFont color=0, 0, 0 +DISPNAMEFont=新宋体,8,N +DISPNAMEFont color=0, 0, 0 +LABLFont=新宋体,8,N +LABLFont color=0, 0, 0 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Width=4800 +Height=4000 +Brush color=255 255 192 +Fill Color=Yes +Brush style=6 +Brush bitmap mode=12 +Brush gradient mode=65 +Brush gradient color=255 255 255 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 178 178 178 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\TABL] +STRNFont=新宋体,8,N +STRNFont color=0, 0, 0 +DISPNAMEFont=新宋体,8,N +DISPNAMEFont color=0, 0, 0 +OWNRDISPNAMEFont=新宋体,8,N +OWNRDISPNAMEFont color=0, 0, 0 +ColumnsFont=新宋体,8,N +ColumnsFont color=0, 0, 0 +TablePkColumnsFont=新宋体,8,U +TablePkColumnsFont color=0, 0, 0 +TableFkColumnsFont=新宋体,8,N +TableFkColumnsFont color=0, 0, 0 +KeysFont=新宋体,8,N +KeysFont color=0, 0, 0 +IndexesFont=新宋体,8,N +IndexesFont color=0, 0, 0 +TriggersFont=新宋体,8,N +TriggersFont color=0, 0, 0 +LABLFont=新宋体,8,N +LABLFont color=0, 0, 0 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Width=4800 +Height=4000 +Brush color=178 214 252 +Fill Color=Yes +Brush style=6 +Brush bitmap mode=12 +Brush gradient mode=65 +Brush gradient color=255 255 255 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 0 128 192 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\VIEW] +STRNFont=新宋体,8,N +STRNFont color=0, 0, 0 +DISPNAMEFont=新宋体,8,N +DISPNAMEFont color=0, 0, 0 +OWNRDISPNAMEFont=新宋体,8,N +OWNRDISPNAMEFont color=0, 0, 0 +ColumnsFont=新宋体,8,N +ColumnsFont color=0, 0, 0 +TablePkColumnsFont=新宋体,8,U +TablePkColumnsFont color=0, 0, 0 +TableFkColumnsFont=新宋体,8,N +TableFkColumnsFont color=0, 0, 0 +TemporaryVTablesFont=新宋体,8,N +TemporaryVTablesFont color=0, 0, 0 +IndexesFont=新宋体,8,N +IndexesFont color=0, 0, 0 +LABLFont=新宋体,8,N +LABLFont color=0, 0, 0 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Width=4800 +Height=4000 +Brush color=208 208 255 +Fill Color=Yes +Brush style=6 +Brush bitmap mode=12 +Brush gradient mode=65 +Brush gradient color=255 255 255 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 128 128 192 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\PROC] +STRNFont=新宋体,8,N +STRNFont color=0, 0, 0 +DISPNAMEFont=新宋体,8,N +DISPNAMEFont color=0, 0, 0 +OWNRDISPNAMEFont=新宋体,8,N +OWNRDISPNAMEFont color=0, 0, 0 +LABLFont=新宋体,8,N +LABLFont color=0, 0, 0 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Width=4000 +Height=1000 +Brush color=255 255 192 +Fill Color=Yes +Brush style=6 +Brush bitmap mode=12 +Brush gradient mode=65 +Brush gradient color=255 255 255 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 128 108 0 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\REFR] +SOURCEFont=新宋体,8,N +SOURCEFont color=0, 0, 0 +CENTERFont=新宋体,8,N +CENTERFont color=0, 0, 0 +DESTINATIONFont=新宋体,8,N +DESTINATIONFont color=0, 0, 0 +Line style=1 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Brush color=255 255 255 +Fill Color=Yes +Brush style=1 +Brush bitmap mode=12 +Brush gradient mode=0 +Brush gradient color=118 118 118 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 0 128 192 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\VREF] +SOURCEFont=新宋体,8,N +SOURCEFont color=0, 0, 0 +CENTERFont=新宋体,8,N +CENTERFont color=0, 0, 0 +DESTINATIONFont=新宋体,8,N +DESTINATIONFont color=0, 0, 0 +Line style=1 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Brush color=255 255 255 +Fill Color=Yes +Brush style=1 +Brush bitmap mode=12 +Brush gradient mode=0 +Brush gradient color=118 118 118 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 128 128 192 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\USRDEPD] +OBJXSTRFont=新宋体,8,N +OBJXSTRFont color=0, 0, 0 +Line style=1 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Brush color=255 255 255 +Fill Color=Yes +Brush style=1 +Brush bitmap mode=12 +Brush gradient mode=0 +Brush gradient color=118 118 118 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=2 0 128 128 255 +Shadow color=192 192 192 +Shadow=0 + +[DisplayPreferences\Symbol\Free Symbol] +Free TextFont=新宋体,8,N +Free TextFont color=0, 0, 0 +Line style=0 +AutoAdjustToText=Yes +Keep aspect=No +Keep center=No +Keep size=No +Brush color=255 255 255 +Fill Color=Yes +Brush style=1 +Brush bitmap mode=12 +Brush gradient mode=0 +Brush gradient color=118 118 118 +Brush background image= +Custom shape= +Custom text mode=0 +Pen=1 0 0 0 255 +Shadow color=192 192 192 +Shadow=0 +(8268, 11693) +((315,354), (433,354)) +1 +15 + + +1573443498 +1575855296 +((-21737,-53172), (-14146,-33693)) +((-21337,-52772),(-14771,-52772),(-14771,-34093)) +1 +1 +12615680 +12632256 +CENTER 0 新宋体,8,N +SOURCE 0 新宋体,8,N +DESTINATION 0 新宋体,8,N +4 + + + + + + + + + + + +1575624441 +1575855293 +((7952,-65177), (9202,-37779)) +((8577,-64777),(8577,-38179)) +1 +1 +12615680 +12632256 +CENTER 0 新宋体,8,N +SOURCE 0 新宋体,8,N +DESTINATION 0 新宋体,8,N + + + + + + + + + + + +1575624473 +1575855293 +((-42707,-69189), (1113,-47991)) +((713,-68789),(-42082,-68789),(-42082,-48391)) +1 +1 +12615680 +12632256 +CENTER 0 新宋体,8,N +SOURCE 0 新宋体,8,N +DESTINATION 0 新宋体,8,N + + + + + + + + + + + +1575624521 +1575855289 +((663,-51761), (8002,-37779)) +((1063,-51361),(7377,-51361),(7377,-38179)) +1 +1 +12615680 +12632256 +CENTER 0 新宋体,8,N +SOURCE 0 新宋体,8,N +DESTINATION 0 新宋体,8,N + + + + + + + + + + + +1575624526 +1575855289 +((-12582,-47749), (-11332,-33693)) +((-11957,-47349),(-11957,-34093)) +1 +1 +12615680 +12632256 +CENTER 0 新宋体,8,N +SOURCE 0 新宋体,8,N +DESTINATION 0 新宋体,8,N + + + + + + + + + + + +1573436700 +1575889010 +-1 +((-45485,-48391), (-25299,-22219)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1573436823 +1575889010 +-1 +((-20969,-34093), (-8507,-25245)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1573439850 +1575889010 +-1 +((5372,-38179), (20150,-22731)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1573442367 +1575889010 +-1 +((24745,-63550), (40683,-50578)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1573442751 +1575889010 +-1 +((-34571,-63781), (-21337,-49159)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575624135 +1575889010 +-1 +((-12557,-55373), (1063,-47349)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575624135 +1575889010 +-1 +((713,-72801), (14333,-64777)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-27388,1549), (-14927,10396)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((2370,-7000), (15603,-1452)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((1597,14221), (14830,23068)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((3144,2373), (15991,10395)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-27774,28543), (-14541,39864)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-43235,13395), (-31162,23067)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-43235,-9474), (-31162,-1452)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-11541,29367), (920,39864)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((441,-17196), (12514,-12473)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-43235,1549), (-30388,10396)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-28162,13395), (-16089,23067)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-28162,-9474), (-16089,-1452)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-13859,-18022), (-2557,-12474)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-43235,-18022), (-31547,-12474)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-28547,-18022), (-16859,-12474)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-13089,13395), (-1401,23067)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-43235,26067), (-30774,39863)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889010 +-1 +((-13089,-7824), (-628,-1452)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889030 +-1 +((-13023,996), (-176,10668)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + +1575889107 +-1 +((2682,31182), (14755,40029)) +12615680 +16570034 +12632256 +STRN 0 新宋体,8,N +DISPNAME 0 新宋体,8,N +OWNRDISPNAME 0 新宋体,8,N +Columns 0 新宋体,8,N +TablePkColumns 0 新宋体,8,U +TableFkColumns 0 新宋体,8,N +Keys 0 新宋体,8,N +Indexes 0 新宋体,8,N +Triggers 0 新宋体,8,N +LABL 0 新宋体,8,N +6 +65 +16777215 + + + + + + + + + + + + +E4E8B02A-08FE-4D41-AF69-E356B1ADF6B2 +face_camera +face_camera +1573436700 +Mhb +1576138611 +Mhb +摄像头表 + + + +1A74B7DC-03CD-46A8-9D38-526940D52CD8 +id_face_camera +id_face_camera +1573437457 +Mhb +1575861037 +Mhb +id +bigint(32) +32 +1 + + +384744B7-F06F-40CB-A217-BCD81E187B4D +camera_name +camera_name +1573437457 +Mhb +1576823629 +Mhb +摄像头名称 +varchar(255) +255 + + +D398DC39-3975-4E5C-AFCB-B4870E6867BD +camera_region_firstlevel +camera_region_firstlevel +1573437457 +Mhb +1576056977 +Mhb +摄像头层级区域-码值 +varchar(255) +255 + + +8265813D-F22C-4B2A-8668-EC46030D361D +camera_region_firstlevel_back_up +camera_region_firstlevel_back_up +1576138474 +Mhb +1576138611 +Mhb +摄像头层级区域冗余字段 +varchar(255) +255 + + +CBF48334-B876-4E7B-B5B7-4922E38A0BB0 +camera_region +camera_region +1576056922 +Mhb +1576056958 +Mhb +摄像头区域码值 +varchar(255) +255 + + +66813EBD-4D00-4948-96A8-AD6F18182008 +camera_region_back_up +camera_region_back_up +1576138474 +Mhb +1576138611 +Mhb +摄像头区域冗余字段 +varchar(255) +255 + + +6D7BAD6F-A7C7-46CE-AF9E-A1A2300C4FB9 +camera_address +camera_address +1573437457 +Mhb +1575623722 +Mhb +摄像头详细地址 +varchar(255) +255 + + +1C9BD8BB-D20F-4EDD-AF7D-AA524E4AA53D +version +version +1576057036 +Mhb +1576057072 +Mhb +摄像头型号 +varchar(255) +255 + + +91ABA7B4-8D6E-43F3-A440-7966180127DE +camerat_longitude +camerat_longitude +1573437457 +Mhb +1575623722 +Mhb +摄像头经度 +varchar(100) +100 + + +45726891-DFB9-4C33-802C-31C7E4C372C1 +camera_latitude +camera_latitude +1573437457 +Mhb +1575623722 +Mhb +摄像头纬度 +varchar(100) +100 + + +03444A9A-5758-4AA6-8C02-AA113BF10DD9 +camerat_locationtype_id +camerat_locationtype_id +1573437457 +Mhb +1576221873 +Mhb +位置类型-码值 +varchar(255) +255 + + +A6D640CB-2885-4D12-9FC5-236C63BB3CC1 +camerat_locationtype_id_back_up +camerat_locationtype_id_back_up +1576138474 +Mhb +1576138611 +Mhb +位置类型冗余字段 +varchar(255) +255 + + +4E38BE4F-977D-4D5B-8FEE-16E641F97C19 +public_security_code +public_security_code +1573437457 +Mhb +1573526258 +Mhb +公安机关代码 +varchar(100) +100 + + +C5934BE0-2B22-4488-9410-FCE8423A6E20 +public_security_name +public_security_name +1573437457 +Mhb +1573438883 +Mhb +公安机关名称 +varchar(255) +255 + + +7094AFAC-2FA0-4783-A862-99DDB5B624A0 +construction_unit +construction_unit +1573437457 +Mhb +1573438883 +Mhb +建设单位 +varchar(255) +255 + + +C7947C59-4EFB-4528-BBB6-214C88FB5309 +management_unit +management_unit +1573437457 +Mhb +1573438883 +Mhb +管理单位 +varchar(255) +255 + + +69B2FAEE-4476-455F-BF07-89C2BED473F9 +management_personnel +management_personnel +1573437457 +Mhb +1573438883 +Mhb +管理人员 +varchar(50) +50 + + +8819B1EE-0F95-45F4-8591-7685675B1D44 +contact_number +contact_number +1573437457 +Mhb +1573438883 +Mhb +联系电话 +varchar(11) +11 + + +F367BFD2-DCCE-4242-88B5-4B1910E407D4 +ip +ip +1575623219 +Mhb +1575623722 +Mhb +IP +varchar(255) +255 + + +83CF2C7D-0013-42AC-A67C-B5D2F2C3BB49 +user_name +user_name +1575623219 +Mhb +1575623722 +Mhb +用户名 +varchar(255) +255 + + +595009F9-3B8F-481C-BF37-70DB18595BB3 +passwd +passwd +1575623219 +Mhb +1575623722 +Mhb +密码 +varchar(32) +32 + + +39AC6D85-2A82-457B-973B-833C5A1F0EC9 +brand +brand +1575623219 +Mhb +1575623722 +Mhb +品牌 +varchar(50) +50 + + +4E4CD6FD-D3F2-4592-B5AC-C01FFE56CFAB +rtsp_url +rtsp_url +1575623219 +Mhb +1575623722 +Mhb +rtsp地址 +varchar(255) +255 + + +EB1C71EB-1038-4A3C-B14D-40A723A36408 +remarks +remarks +1573439050 +Mhb +1573439206 +Mhb +备注信息 +text + + +D3FB0AE4-6D5D-4412-848F-3AFE58312B7C +status +status +1573439050 +Mhb +1573439206 +Mhb +是否运行 Y启动 N未启动 +varchar(1) +1 + + +C38B226A-DFA0-439D-A188-04AC3905CFD5 +is_valid +is_valid +1573437457 +Mhb +1573438883 +Mhb +是否有效 Y有效 N无效 +varchar(1) +1 + + +0082D9B3-EC08-4C51-83F2-B99379EBB7C9 +create_time +create_time +1573437457 +Mhb +1573438883 +Mhb +创建时间 +datetime + + +8F5CCA05-CAA0-48B9-A8C2-5765F3B9BB5D +update_time +update_time +1573437457 +Mhb +1573438883 +Mhb +更新时间 +datetime + + +6A8C4EC6-8859-4E65-830E-8B9B2F4E6FC8 +create_by +create_by +1573437457 +Mhb +1573438883 +Mhb +创建人 +varchar(32) +32 + + +7705E005-354A-44C3-9C45-A9811253A948 +update_by +update_by +1573437457 +Mhb +1573438883 +Mhb +更新人 +varchar(32) +32 + + + + +762D34E1-D0BB-43E1-A3AA-B29DC3FB0816 +Key_1 +Key_1 +1573437457 +Mhb +1573438883 +Mhb + + + + + + + + + + +2C890490-554A-40C9-9E52-B764B6D77A67 +face_library +face_library +1573436823 +Mhb +1575624380 +Mhb +库表 + + + +E50A7606-639A-41C9-A8C7-D813FD9CC77C +id_factory +id_factory +1573439238 +Mhb +1575861050 +Mhb +id +bigint(32) +32 +1 + + +3672C199-FB8A-4E09-946A-23EE9ECACDB2 +factory_name +factory_name +1573439238 +Mhb +1573439727 +Mhb +库名称 +varchar(255) +255 + + +E562845F-7E6A-46B1-92AC-747E1E4394B5 +factory_type +factory_type +1573439238 +Mhb +1573439727 +Mhb +库类型-码值 +varchar(2) +2 + + +0502AE24-8A23-46D8-A92D-83ECC1579FD3 +remarks +remarks +1573439739 +Mhb +1573439777 +Mhb +备注信息 +varchar(255) +255 + + +0FE75B86-45F9-478D-82A7-3FAC77CAF204 +is_valid +is_valid +1573439238 +Mhb +1573439727 +Mhb +是否有效 Y有效 N无效 +varchar(1) +1 + + +DC672B5F-F72F-4110-AFC4-D2D973FBB219 +create_time +create_time +1573439238 +Mhb +1573443221 +Mhb +创建时间 +datetime + + +97EEED5B-7EC2-4739-A85A-537C38104297 +create_by +create_by +1573439238 +Mhb +1573439727 +Mhb +创建人 +varchar(32) +32 + + +73909D78-E9F6-47DF-B26D-19B65FF40D25 +update_time +update_time +1573439238 +Mhb +1573439727 +Mhb +更新时间 +datetime + + +162BC533-0B3F-4229-A8FB-445CADC70BD2 +update_by +update_by +1573439238 +Mhb +1573439727 +Mhb +更新人 +varchar(32) +32 + + + + +2F8CA6A0-DB4A-4939-B94D-3DA2D510FEA6 +Key_1 +Key_1 +1573439777 +Mhb +1573439781 +Mhb + + + + + + + + + + +046778F8-B0CE-4309-B625-34BC7C78EB20 +control_task +control_task +1573439850 +Mhb +1573442319 +Mhb +布控任务 + + + +0DED6519-44BC-492F-88FE-7549FE6274FA +id_control_task +id_control_task +1573439850 +Mhb +1575861062 +Mhb +id +bigint(32) +32 +1 + + +09DF71A8-0F01-4C8B-9BEB-282DBE292E4D +task_name +task_name +1573439923 +Mhb +1573441288 +Mhb +任务名称 +varchar(255) +255 + + +4267CDB1-57BF-4047-8FF4-4A253E88D42F +control_object +control_object +1573439923 +Mhb +1573441288 +Mhb +布控对象(id 人像库id 或者上传图片id) +varchar(32) +32 + + +AAD04542-7F80-4602-A5C4-91583100AD93 +disposal_type +disposal_type +1573439923 +Mhb +1575869626 +Mhb +处置类型-码值 +varchar(3) +3 + + +E5016236-E62E-4B22-8EA4-C171BAF146AC +control_type +control_type +1573439923 +Mhb +1573441288 +Mhb +布控类型-码值 +varchar(1) +1 + + +2D7F6B74-2424-4DA1-9370-CD058112378B +control_start_time +control_start_time +1573439923 +Mhb +1573441288 +Mhb +布控开始时间 +datetime + + +7939CB58-6F61-4D70-B891-AEDD57BDC26A +control_end_time +control_end_time +1573439923 +Mhb +1573441288 +Mhb +布控结束时间 +datetime + + +9E6E0F90-0714-4293-8EA8-435775748148 +control_region +control_region +1573439923 +Mhb +1573441288 +Mhb +布控区域 +varchar(255) +255 + + +B327871B-E72C-4096-9D98-5C24D4623304 +control_threshold +control_threshold +1573439923 +Mhb +1573441288 +Mhb +布控阈值 +double + + +534C211F-0A48-413B-B80D-FA3866D5B1A3 +control_status +control_status +1573442211 +Mhb +1573442319 +Mhb +布控状态-码值 +varchar(1) +1 + + +EB469329-2721-4847-A969-DD7DE9797B33 +receive +receive +1573439923 +Mhb +1573441288 +Mhb +接收人员(人员id逗号隔开) +text + + +C5AC5EB0-57B0-44B3-8B8A-9EB82FDC184B +remarks +remarks +1573439923 +Mhb +1573441288 +Mhb +备注信息 +text + + +4537FE59-BD10-484A-B134-D13FCC05FF7E +is_valid +is_valid +1573439923 +Mhb +1573441288 +Mhb +是否有效 Y有效 N无效 +varchar(1) +1 + + +6573FCC6-D476-485A-836B-AF3F0422F496 +create_time +create_time +1573439923 +Mhb +1573441288 +Mhb +创建时间 +datetime + + +02537A17-3D66-43BB-ACB7-5ECA206DCEBF +update_time +update_time +1573439923 +Mhb +1573441288 +Mhb +更新时间 +datetime + + +13C83835-9669-4A2D-990E-5B52BF8292DA +create_by +create_by +1573439923 +Mhb +1573441288 +Mhb +创建人 +varchar(32) +32 + + +1355E161-2F24-40AA-BA97-F8D0F31487D7 +update_by +update_by +1573439923 +Mhb +1573441288 +Mhb +更新人 +varchar(32) +32 + + + + +AF085F36-0775-4494-9850-05B5E0CA9613 +Key_1 +Key_1 +1573441293 +Mhb +1573441306 +Mhb + + + + + + + + + + +AA9FB273-75E3-4361-B7B4-C0ABE3C749B1 +warning_information +warning_information +1573442367 +Mhb +1573520775 +Mhb +预警信息 + + + +7D229B27-8F0D-47C7-987D-E3A25E771027 +id_warning_information +id_warning_information +1573442367 +Mhb +1573451149 +Mhb +id +varchar(32) +32 +1 + + +A02A7C65-D407-48ED-85BB-480DD3C996C3 +receive_json +receive_json +1573442367 +Mhb +1573451149 +Mhb +接收参数 +text + + +BC7C9C5D-4899-4B5A-B1D9-DE65F4DDCFD2 +id_control_task +id_control_task +1573450400 +Mhb +1573451149 +Mhb +布控任务id +varchar(32) +32 + + +E72CEEE7-3FB8-442C-945D-D1F0CD137744 +id_portrait +id_portrait +1573450400 +Mhb +1573451149 +Mhb +人像id/图片id +varchar(32) +32 + + +634A26AF-66D0-4672-B9E7-C077A27162B8 +type +type +1573451188 +Mhb +1573451339 +Mhb +预警类型-码值 +varchar(2) +2 + + +52184851-1D99-4EF5-A7BB-82588F3C6C3D +id_face_bayonet +id_face_bayonet +1573451188 +Mhb +1573451339 +Mhb +卡口id +varchar(32) +32 + + +394727A5-BAD4-4426-AEA4-26591CD012C1 +score +score +1573451373 +Mhb +1573451549 +Mhb +比对分数 +double + + +8EC3BB7B-DC88-4DC0-BA90-7AF08ABF5268 +process_result_type +process_result_type +1573468005 +Mhb +1573520775 +Mhb +处理结果类型(1盘查 2抓捕) +varchar(1) +1 + + +61F63A0F-1EFD-4C52-A385-0A267F9477D4 +process_result +process_result +1573520652 +Mhb +1573520775 +Mhb +处理结果 +text + + +949990AF-72E6-4261-ABCB-A04CFD66D1E8 +is_valid +is_valid +1573450400 +Mhb +1573451149 +Mhb +是否有效 Y有效 N无效 +varchar(1) +1 + + +B23168D4-E0F1-4FCE-ADDA-CD54A3DCCF70 +create_time +create_time +1573450400 +Mhb +1573451149 +Mhb +创建时间 +datetime + + +66E8BF37-727F-43CE-8900-4D261F0C3F7F +create_by +create_by +1573450400 +Mhb +1573451149 +Mhb +创建人 +varchar(32) +32 + + +74E4673F-D850-4EB1-955D-AF904D020BA5 +update_time +update_time +1573450400 +Mhb +1573451149 +Mhb +更新时间 +datetime + + +F5F2FB5C-01F8-4873-8270-5ED3BE93481B +update_by +update_by +1573450400 +Mhb +1573451149 +Mhb +更新人 +varchar(32) +32 + + + + +5A10E169-5FF8-42EC-95B4-42FE6B61CB1A +Key_1 +Key_1 +1573450400 +Mhb +1573451149 +Mhb + + + + + + + + + + +8382D296-44E4-4718-9E54-9500D18479C9 +portrait +portrait +1573442751 +Mhb +1575623995 +Mhb +人像表 + + + +6E5F59AA-78E7-4CD0-9436-D81385D49C8F +id_portrait +id_portrait +1573442751 +Mhb +1575861079 +Mhb +人像id +bigint(32) +32 +1 + + +D6A0563F-E2B6-4199-B5EC-87789059C286 +id_factory +id_factory +1573442751 +Mhb +1575861079 +Mhb +库id +bigint(32) +32 + + +246D0D42-0BCE-4EEB-B7DC-DDC75B9E63A8 +url +url +1573442751 +Mhb +1573443337 +Mhb +图片url +text + + +00BB5BFB-C463-416C-A47C-11EFFA6CB12B +background_url +background_url +1573442751 +Mhb +1573443337 +Mhb +背景图url +text + + +8B57855B-52F5-4FA1-A99C-B219A1D6F806 +name +name +1573442751 +Mhb +1573443337 +Mhb +姓名 +varchar(100) +100 + + +2CD02889-7317-4B2A-8D25-3F46FD21D29F +sex +sex +1573442751 +Mhb +1573443337 +Mhb +性别 +varchar(10) +10 + + +00BFA5BD-13B9-49C0-A743-CB839016ACA2 +birth_date +birth_date +1573442751 +Mhb +1573443337 +Mhb +出生日期 +datetime + + +80B1951F-A3A5-473E-95AA-313E0A520757 +id_card +id_card +1573442751 +Mhb +1573443337 +Mhb +身份证 +varchar(18) +18 + + +E04FA0CB-5D37-4756-89C6-30CE730BD24E +face_rect +face_rect +1575623921 +Mhb +1575623995 +Mhb +人脸坐标位置 +varchar(255) +255 + + +FD26970C-19B7-4CC3-BA7D-8EBAC463094F +faceIds +faceIds +1573466044 +Mhb +1573466138 +Mhb +人脸入库id +varchar(32) +32 + + +8C74B033-4170-4642-902C-C1DB5DFEA24B +featId +featId +1573466044 +Mhb +1573466138 +Mhb +人脸特征id +varchar(32) +32 + + +19D66449-97F7-4CFE-985B-77EE5ED73732 +is_valid +is_valid +1573442751 +Mhb +1573443337 +Mhb +是否有效 Y有效 N无效 +varchar(1) +1 + + +C9245E6B-7A77-4D87-BEF5-59611569D824 +create_time +create_time +1573442751 +Mhb +1573443337 +Mhb +创建时间 +datetime + + +3E0B9B58-0075-492D-B898-48DF118D925F +create_by +create_by +1573442751 +Mhb +1573443337 +Mhb +创建人 +varchar(32) +32 + + +289075BD-55C6-4503-B805-6F9465A6A4CA +update_time +update_time +1573442751 +Mhb +1573443337 +Mhb +更新时间 +datetime + + +85D672D5-A474-4F91-AC38-85E43C5BF950 +update_by +update_by +1573442751 +Mhb +1573443337 +Mhb +更新人 +varchar(32) +32 + + + + +1B2E506C-1CE2-4D22-A491-70460B046196 +Key_1 +Key_1 +1573442751 +Mhb +1573443337 +Mhb + + + + + + + + + + +FA56C67F-89DF-4FDB-AD24-0C0F36CAAFD9 +control_library_mid +control_library_mid +1574155051 +Mhb +1575624573 +Mhb +布控和库中间表 + + + +1EC6F044-24DB-4F69-9E7B-F30E69CF08D3 +id +id +1574155051 +Mhb +1575861095 +Mhb +id +bigint(32) +32 +1 + + +910BBD12-1A6C-4AA3-9FC3-F277F3136D46 +id_control_task +id_control_task +1575624521 +Mhb +1575861095 +Mhb +布控id +bigint(32) +32 + + +BD86C361-D857-4CC1-8745-0B13C8AC9F94 +id_factory +id_factory +1575624526 +Mhb +1575861095 +Mhb +库id +bigint(32) +32 + + +B9640E36-69D5-4A37-8512-46DE02EDDBCB +is_valid +is_valid +1574155051 +Mhb +1575624135 +Mhb +是否有效 Y有效 N无效 +varchar(1) +1 + + +94F3622A-81D2-4B70-8220-9C1D1672986D +create_time +create_time +1574155051 +Mhb +1575624135 +Mhb +创建时间 +datetime + + +DF4654D3-08FE-4235-9BF4-B02F5966DC09 +update_time +update_time +1574155051 +Mhb +1575624135 +Mhb +更新时间 +datetime + + +3B2469E3-1D56-421A-A89B-34F021D019FF +update_by +update_by +1574233842 +Mhb +1575624135 +Mhb +更新人 +varchar(32) +32 + + +4A4FF023-FB25-49A4-A7F8-AD2D94656D07 +create_by +create_by +1574233842 +Mhb +1575624135 +Mhb +创建人 +varchar(32) +32 + + + + +55ACAA83-F906-4C3A-A16A-4D013F1C2AE1 +Key_1 +Key_1 +1574218130 +Mhb +1575624135 +Mhb + + + + + + + + + + +9F049A00-E53A-4773-8A56-5E2168F92FE8 +sys_dept +sys_dept +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '部门管理' ROW_FORMAT = Dynamic + + + +99E4E099-4E6F-4B2C-B760-B6255751F6DE +id +id +1575627715 +Mhb +1575860857 +Mhb +id +bigint(32) +32 +1 + + +4BE52A70-17B3-4C49-A3FF-7C2190407AF2 +pid +pid +1575627715 +Mhb +1575860857 +Mhb +上级ID +NULL +bigint(32) +32 + + +48505E3B-44DF-4C1A-8CB0-EDDFD785F2B0 +pids +pids +1575627715 +Mhb +1575627719 +Mhb +varchar(500) +500 + + +E557AB7A-B66B-4B92-9017-61A076CA99D1 +name +name +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +2E751D61-1EAF-4399-9E0B-A76AB0CFA95D +sort +sort +1575627715 +Mhb +1575627719 +Mhb +排序 +NULL +int(10) +10 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +F79AEE39-9FAA-42AE-9CD5-9770F8EB80B6 +creator +creator +1575627715 +Mhb +1575860857 +Mhb +创建者 +NULL +bigint(32) +32 + + +F3AECF63-6325-4851-AC87-7D810369A7E4 +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + +61EED6A4-E252-438B-8702-F6F0F35186F5 +updater +updater +1575627715 +Mhb +1575860857 +Mhb +更新者 +NULL +bigint(32) +32 + + +87D7DA60-8C6C-44CE-9A81-4EFAA9DDB090 +update_date +update_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +096A16B9-7840-44A8-A450-F127ED1354C7 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +6D2EA011-6633-4D84-8E55-F854B11B33A8 +idx_pid +idx_pid +1575627715 +Mhb +1575627719 +Mhb +idx_pid + + + + + +D5AD0430-B8A3-4098-911C-C5853ADF4EAB +idx_sort +idx_sort +1575627715 +Mhb +1575627719 +Mhb +idx_sort + + + + + + + + + + +6C21474D-6E31-43C8-B630-FF1841F63FB2 +sys_dict_data +sys_dict_data +1575888977 +Mhb +1575888983 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '字典数据' ROW_FORMAT = Dynamic + + + +3F58B53B-D90D-4EAC-8885-98F92D97393E +id +id +1575888977 +Mhb +1575889099 +Mhb +id +bigint(32) +32 +1 + + +93F777B3-FB31-46E2-8C86-6514649A432A +dict_type_id +dict_type_id +1575888977 +Mhb +1575889099 +Mhb +字典类型ID +bigint(32) +32 +1 + + +3151FD0B-26AD-4B8C-BFDE-13150FD6E023 +dict_label +dict_label +1575888977 +Mhb +1575888983 +Mhb +varchar(255) +255 + + +E4A7FC9F-ED7F-4186-8CC7-F7496BD0DD77 +dict_value +dict_value +1575888977 +Mhb +1575888983 +Mhb +varchar(255) +255 + + +5DB469B0-7D4C-430A-A53C-DA82C022FFEC +remark +remark +1575888977 +Mhb +1575888983 +Mhb +varchar(255) +255 + + +2D38FDAB-0E2C-4D4C-AFB3-F84D2E934A6C +sort +sort +1575888977 +Mhb +1575888983 +Mhb +排序 +NULL +int(10) +10 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +DF1449A4-FC37-4DE1-BC58-F4646FC8BB5D +creator +creator +1575888977 +Mhb +1575889099 +Mhb +创建者 +NULL +bigint(32) +32 + + +8B787594-FB81-4C1B-B99D-08DCDB73483F +create_date +create_date +1575888977 +Mhb +1575888983 +Mhb +datetime + + +EF9F74EB-2F54-4000-8731-6FD54AF49EF8 +updater +updater +1575888977 +Mhb +1575889099 +Mhb +更新者 +NULL +bigint(32) +32 + + +930A19BC-C7DE-4CF0-9F7E-FB94A3D89FA8 +update_date +update_date +1575888977 +Mhb +1575888983 +Mhb +datetime + + + + +5D39F44E-C97C-4EDD-BE40-4A4D7CB68122 +Key_1 +Key_1 +1575888977 +Mhb +1575888983 +Mhb + + + + + +90898574-3825-42BD-99F4-01E40443531C +uk_dict_type_value +uk_dict_type_value +1575888977 +Mhb +1575888983 +Mhb +uk_dict_type_value +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,57={D1C795B8-8F7B-4AA7-A240-85C5B737C543},ExtUnique,4=true + + + + + + + + +9CB71773-7DE1-468F-9994-C6506B2B92C0 +idx_sort +idx_sort +1575888977 +Mhb +1575888983 +Mhb +idx_sort + + + + + + + + + + +1B482A57-1B23-4C5B-B955-1F982B1CEE49 +sys_dict_type +sys_dict_type +1575889007 +Mhb +1575889009 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '字典类型' ROW_FORMAT = Dynamic + + + +03B9DD8A-7F6D-47AE-88CD-719B3AFCD594 +id +id +1575889007 +Mhb +1575889066 +Mhb +id +bigint(32) +32 +1 + + +2C10EEC8-6DCC-4FE6-9C23-6572618DBE9E +dict_type +dict_type +1575889007 +Mhb +1575889009 +Mhb +varchar(100) +100 + + +B66550FC-E390-4D36-B904-3859D3F5AAF3 +dict_name +dict_name +1575889007 +Mhb +1575889009 +Mhb +varchar(255) +255 + + +73083542-E05D-4318-9777-E598401547E7 +remark +remark +1575889007 +Mhb +1575889009 +Mhb +varchar(255) +255 + + +9ABD4C19-01FE-4127-928A-3BE7B235293F +sort +sort +1575889007 +Mhb +1575889009 +Mhb +排序 +NULL +int(10) +10 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +6DAB2997-81D1-4DC7-97F4-57466F24CBB5 +creator +creator +1575889007 +Mhb +1575889066 +Mhb +创建者 +NULL +bigint(32) +32 + + +D840C92A-3AF7-4CC3-B7CA-AE9F92D8A4E1 +create_date +create_date +1575889007 +Mhb +1575889009 +Mhb +datetime + + +D0B20B56-B091-446D-AA83-9684CDEF6813 +updater +updater +1575889007 +Mhb +1575889066 +Mhb +更新者 +NULL +bigint(32) +32 + + +E78BE102-69B2-402F-AB56-910A2441C163 +update_date +update_date +1575889007 +Mhb +1575889009 +Mhb +datetime + + + + +80F0AA09-704F-451E-8243-04BF2B5733C7 +Key_1 +Key_1 +1575889007 +Mhb +1575889009 +Mhb + + + + + +B58F7149-042A-4F02-9A69-2604E62EADC9 +dict_type +dict_type +1575889007 +Mhb +1575889009 +Mhb +dict_type +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,57={D1C795B8-8F7B-4AA7-A240-85C5B737C543},ExtUnique,4=true + + + + + + + + + + + + +2F2FC176-0502-4464-9A63-2165384CE8F5 +sys_language +sys_language +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '国际化' ROW_FORMAT = Dynamic + + + +78DDD97F-01BC-4D07-8CE0-E295DC43D77B +table_name +table_name +1575627715 +Mhb +1575627719 +Mhb +varchar(32) +32 +1 + + +D96A0DF7-ABA7-4FB6-AD40-59B28C71CC05 +table_id +table_id +1575627715 +Mhb +1575862019 +Mhb +表主键 +bigint(32) +32 +1 + + +D0B719E8-3DDB-42A8-B636-AB6EA90854B4 +field_name +field_name +1575627715 +Mhb +1575627719 +Mhb +varchar(32) +32 +1 + + +6C611C25-9B68-4151-B3EA-14E5C6EF6BBD +field_value +field_value +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +9956297C-35B9-4975-912F-BBAB29C6F9F7 +language +language +1575627715 +Mhb +1575627719 +Mhb +varchar(10) +10 +1 + + + + +5E3CB867-43BC-49D0-B831-BF008A66B898 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + + + + +66CEE822-E213-45DC-9CC8-861DA9D6683A +idx_table_id +idx_table_id +1575627715 +Mhb +1575627719 +Mhb +idx_table_id + + + + + + + + + + +26AF1720-5B40-4B53-A9B3-190C99952181 +sys_log_error +sys_log_error +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '异常日志' ROW_FORMAT = Dynamic + + + +427B735A-94B7-4144-92C2-378A5F21AD49 +id +id +1575627715 +Mhb +1575860814 +Mhb +id +bigint(32) +32 +1 + + +2ABCD2A4-A863-4F1C-B4ED-B3C7EE7FBFA2 +request_uri +request_uri +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +10F4427C-4911-4ADC-9C5A-710B71FE3266 +request_method +request_method +1575627715 +Mhb +1575627719 +Mhb +varchar(20) +20 + + +AB3897EC-DC22-409A-A868-96C77CFF050D +request_params +request_params +1575627715 +Mhb +1575627719 +Mhb +text + + +76F89572-6BFB-4E3A-8522-12C1F53021EF +user_agent +user_agent +1575627715 +Mhb +1575627719 +Mhb +varchar(500) +500 + + +99D318E1-F035-4B93-90B1-BB54F2E2D882 +ip +ip +1575627715 +Mhb +1575627719 +Mhb +varchar(32) +32 + + +1B032144-9B70-4081-8CE3-9C8731992202 +error_info +error_info +1575627715 +Mhb +1575627719 +Mhb +text + + +A55433CF-E4B0-41DC-B4B5-DACE31429871 +creator +creator +1575627715 +Mhb +1575860814 +Mhb +创建者 +NULL +bigint(32) +32 + + +5EF35C60-4A2E-41D4-AFCF-7DFBB2C1317E +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +D9768FFE-44A1-444B-B960-7016280070C8 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +D940DBD9-88FC-4583-B353-90A58DE455A4 +idx_create_date +idx_create_date +1575627715 +Mhb +1575627719 +Mhb +idx_create_date + + + + + + + + + + +2380061C-D4F6-42E6-ADED-E19B797BD5DA +sys_log_login +sys_log_login +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '登录日志' ROW_FORMAT = Dynamic + + + +EA11F126-1895-4FB7-BD1D-F44A5B6DEE84 +id +id +1575627715 +Mhb +1575860871 +Mhb +id +bigint(32) +32 +1 + + +C9E783D8-C255-40CA-B614-9BCE7D35723A +operation +operation +1575627715 +Mhb +1575627719 +Mhb +用户操作 0:用户登录 1:用户退出 +NULL +tinyint(3) +3 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +C75D2E3C-21DC-481F-8402-1663098427DB +status +status +1575627715 +Mhb +1575627719 +Mhb +状态 0:失败 1:成功 2:账号已锁定 +tinyint(3) +3 +1 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +09ABAA4F-775A-4F0D-A149-C7AEE703E52E +user_agent +user_agent +1575627715 +Mhb +1575627719 +Mhb +varchar(500) +500 + + +084B3DB4-F6AF-446E-A110-C93489BBD3A2 +ip +ip +1575627715 +Mhb +1575627719 +Mhb +varchar(32) +32 + + +1AE4EFD0-4C2B-49CE-B308-32DF99EB5F8B +creator_name +creator_name +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +19AD544E-4425-4A9A-99CB-3530E09707E0 +creator +creator +1575627715 +Mhb +1575860871 +Mhb +创建者 +NULL +bigint(32) +32 + + +3D94AB21-5C3B-49E9-A686-CB195FC3D48B +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +70F8B6B9-567B-431D-BF46-AF2EEFF96D50 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +D5414B25-50A6-484B-A165-1E7C61D91724 +idx_status +idx_status +1575627715 +Mhb +1575627719 +Mhb +idx_status + + + + + +C9A69DDE-0FE3-4896-8CD1-456C003F7339 +idx_create_date +idx_create_date +1575627715 +Mhb +1575627719 +Mhb +idx_create_date + + + + + + + + + + +93F1EDF9-F27B-4EDC-B9B4-FB91DA648BE9 +sys_log_operation +sys_log_operation +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '操作日志' ROW_FORMAT = Dynamic + + + +57BE3274-2F38-424A-AE05-401BD923AF4E +id +id +1575627715 +Mhb +1575860286 +Mhb +id +bigint(32) +32 +1 + + +F9439ED2-128A-4A62-A4C6-1CD9E8A1F778 +operation +operation +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +4AE3E94D-E164-4817-84C6-53B2C887CCBA +request_uri +request_uri +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +C063592C-2467-4956-BA4C-A01FE1EF63AB +request_method +request_method +1575627715 +Mhb +1575627719 +Mhb +varchar(20) +20 + + +D46DDBBC-37D4-4054-B9E2-E8CFCCF63628 +request_params +request_params +1575627715 +Mhb +1575627719 +Mhb +text + + +0BB4AF57-D74F-4E52-A7B8-8B6FFE56FF22 +request_time +request_time +1575627715 +Mhb +1575627719 +Mhb +请求时长(毫秒) +int(10) +10 +1 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +762654F5-C9CA-4088-B406-3E779C72F13F +user_agent +user_agent +1575627715 +Mhb +1575627719 +Mhb +varchar(500) +500 + + +9599B8EF-AA8D-4912-9170-6C438594D234 +ip +ip +1575627715 +Mhb +1575627719 +Mhb +varchar(32) +32 + + +1ABE28F8-9CE4-4931-8BC8-C0754FCE22A5 +status +status +1575627715 +Mhb +1575627719 +Mhb +状态 0:失败 1:成功 +tinyint(3) +3 +1 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +B33D74E0-A229-4BD2-8D7F-EF986D931F5A +creator_name +creator_name +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +5EB6EAD6-8DE2-4403-BB8C-EBE24D46423A +creator +creator +1575627715 +Mhb +1575861976 +Mhb +创建者 +NULL +bigint(32) +32 + + +E6846B72-224B-4F7C-8066-094332A29A7E +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +DAE48F36-6C99-431C-B1A5-AAB1AAE20946 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +29FACFD7-CFC0-4770-AAC6-4FCFC8B70788 +idx_create_date +idx_create_date +1575627715 +Mhb +1575627719 +Mhb +idx_create_date + + + + + + + + + + +D611436E-27EF-46E2-B787-A289354824D7 +sys_mail_log +sys_mail_log +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '邮件发送记录' ROW_FORMAT = Dynamic + + + +ABE063DC-EE35-4992-8602-0729AA5A4EE4 +id +id +1575627715 +Mhb +1575860698 +Mhb +id +bigint(32) +32 +1 + + +95A5DDA5-6531-411D-9B28-41E282A1EEAA +template_id +template_id +1575627715 +Mhb +1575860698 +Mhb +邮件模板ID +bigint(32) +32 +1 + + +328CAE6E-C72C-488D-BB2B-B18460B7365E +mail_from +mail_from +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +67C576A8-49C6-486E-83B6-91800959B07B +mail_to +mail_to +1575627715 +Mhb +1575627719 +Mhb +varchar(400) +400 + + +60897F65-122D-47B7-B300-503E7750ECE7 +mail_cc +mail_cc +1575627715 +Mhb +1575627719 +Mhb +varchar(400) +400 + + +43D64500-A658-49C5-8CB8-8E964866B6D9 +subject +subject +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +464AC206-FFB7-4710-84CF-D5D38FAE4013 +content +content +1575627715 +Mhb +1575627719 +Mhb +text + + +EECFB0B6-0CEC-46E7-910B-906B8C115627 +status +status +1575627715 +Mhb +1575627719 +Mhb +发送状态 0:失败 1:成功 +NULL +tinyint(3) +3 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +E0C60476-7866-486F-B1FB-35A7AE051AE1 +creator +creator +1575627715 +Mhb +1575860698 +Mhb +创建者 +NULL +bigint(32) +32 + + +AB589EBD-BFDE-4677-961B-AD4A2A3976C1 +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +31286D33-2B76-4256-9731-9957E37CB6B1 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +EBA018CA-2321-4052-9706-2728E609E3B2 +idx_create_date +idx_create_date +1575627715 +Mhb +1575627719 +Mhb +idx_create_date + + + + + + + + + + +41C79146-5F02-4466-8EAE-6545338C0E42 +sys_mail_template +sys_mail_template +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '邮件模板' ROW_FORMAT = Dynamic + + + +4AC1F548-A110-4CF9-A19C-FF297749E235 +id +id +1575627715 +Mhb +1575860890 +Mhb +id +bigint(32) +32 +1 + + +55839EA1-7458-4D99-93FB-FAFF0D650906 +name +name +1575627715 +Mhb +1575627719 +Mhb +varchar(100) +100 + + +CEC616F2-411E-4012-9C5B-2179DA0FA6A6 +subject +subject +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +D3A5CCEC-D582-459C-9190-56878BA2DD8E +content +content +1575627715 +Mhb +1575627719 +Mhb +text + + +6E388731-7056-4E8A-A08E-F00D4B7F47AD +creator +creator +1575627715 +Mhb +1575860890 +Mhb +创建者 +NULL +bigint(32) +32 + + +0F59C1ED-BEEF-4611-85E1-D2B734C5583F +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + +F2E738E9-9BBE-45D9-ACB7-E7A3AE56F5FD +updater +updater +1575627715 +Mhb +1575860890 +Mhb +更新者 +NULL +bigint(32) +32 + + +E4BFD487-5EC6-4F23-8885-9934F2A00EC9 +update_date +update_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +8100DA95-F266-4AF5-B531-71AD03A90E5A +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +2255D6F0-6E19-4583-B0C3-BD34751BA401 +idx_create_date +idx_create_date +1575627715 +Mhb +1575627719 +Mhb +idx_create_date + + + + + + + + + + +3E050872-07DB-4891-8B01-C645FFF85D21 +sys_menu +sys_menu +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '菜单管理' ROW_FORMAT = Dynamic + + + +AC622DFC-3480-4008-AA3B-ED26881CAA93 +id +id +1575627715 +Mhb +1575860304 +Mhb +id +bigint(32) +32 +1 + + +121D5699-F67F-44C2-B491-56E17DED4FC0 +pid +pid +1575627715 +Mhb +1575860304 +Mhb +上级ID,一级菜单为0 +NULL +bigint(32) +32 + + +E59D2DA4-07CC-41B9-B33D-FF16AD57CACE +url +url +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +A4C9A30E-D00C-4A80-96EA-2CF74AAF5B0D +permissions +permissions +1575627715 +Mhb +1575627719 +Mhb +varchar(500) +500 + + +32789A89-C7ED-4623-85BC-537ACDE4DF2B +type +type +1575627715 +Mhb +1575627719 +Mhb +类型 0:菜单 1:按钮 +NULL +tinyint(3) +3 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +E6E567C8-B599-4841-A620-77026A9B4827 +icon +icon +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +68A5D78C-F9BD-404A-940F-BA09BE1CFE3F +sort +sort +1575627715 +Mhb +1575627719 +Mhb +排序 +NULL +int(11) +11 + + +226EFB13-B697-4DDF-887C-56F752A85710 +creator +creator +1575627715 +Mhb +1575861967 +Mhb +创建者 +NULL +bigint(32) +32 + + +329E62AF-DDC4-4E21-A3B3-6E969F96AB8F +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + +6BBD80F0-3679-4D2A-A9ED-6A2D2F988207 +updater +updater +1575627715 +Mhb +1575861967 +Mhb +更新者 +NULL +bigint(32) +32 + + +0FAAA683-7E5B-44C3-8EF1-363648D2C9F0 +update_date +update_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +72DE01D1-7B49-4B02-96BA-AC3D77A12A0F +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +58671D8B-FD69-476C-91FE-1B8F88832F5B +idx_pid +idx_pid +1575627715 +Mhb +1575627719 +Mhb +idx_pid + + + + + +A2834894-2D59-49BA-9A6F-CEE0FDEC17D9 +idx_sort +idx_sort +1575627715 +Mhb +1575627719 +Mhb +idx_sort + + + + + + + + + + +2D3D9596-404B-4E5F-BD8C-B9898F1DE56E +sys_oss +sys_oss +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '文件上传' ROW_FORMAT = Dynamic + + + +55F388A8-4FFE-4B7D-B6A3-A0AFF8CE2118 +id +id +1575627715 +Mhb +1575860953 +Mhb +id +bigint(32) +32 +1 + + +3F7EF8E5-628C-497D-BC3D-048448E34C5D +url +url +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +621C8AAC-7EB0-4384-9A7D-6287812F4596 +creator +creator +1575627715 +Mhb +1575860953 +Mhb +创建者 +NULL +bigint(32) +32 + + +FBEE4055-4887-423A-9063-F8160125EAAF +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +27A68632-900D-4778-95C5-26407BDF357C +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +61BC7698-640F-4D46-88CE-F4B3923A9C3C +idx_create_date +idx_create_date +1575627715 +Mhb +1575627719 +Mhb +idx_create_date + + + + + + + + + + +247AB0AE-CAAB-48E3-B2D3-B45E68C4ED75 +sys_params +sys_params +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '参数管理' ROW_FORMAT = Dynamic + + + +4B7C9891-5565-4E89-8418-0FE0F1CE220B +id +id +1575627715 +Mhb +1575860834 +Mhb +id +bigint(32) +32 +1 + + +15BA8EA1-CBC2-4EF2-AC5C-1939E8F09AC4 +param_code +param_code +1575627715 +Mhb +1575627719 +Mhb +varchar(32) +32 + + +945860B6-D134-485F-BBC7-8EA4C5888909 +param_value +param_value +1575627715 +Mhb +1575627719 +Mhb +varchar(2000) +2000 + + +43A17513-08B0-49F5-9958-33ACC001CCD9 +param_type +param_type +1575627715 +Mhb +1575627719 +Mhb +类型 0:系统参数 1:非系统参数 +1 +tinyint(3) +3 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +EADAF023-9C8F-4D8F-B023-21CB79E2DF5C +remark +remark +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +F476E89E-24F5-4E79-9199-CB942188B8EE +creator +creator +1575627715 +Mhb +1575860834 +Mhb +创建者 +NULL +bigint(32) +32 + + +CC0B4F24-1E2F-4E43-9F25-3EB2F12D3006 +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + +700805FD-B6CE-48C7-BD7D-E078FD1B07D9 +updater +updater +1575627715 +Mhb +1575860834 +Mhb +更新者 +NULL +bigint(32) +32 + + +3A416029-C771-4755-BA16-8C12B9F49104 +update_date +update_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +036A6EAF-1D71-4181-825A-661F31502F2C +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +CFC7D93C-A23D-44EE-A0D9-D927FB3B81E9 +uk_param_code +uk_param_code +1575627715 +Mhb +1575627719 +Mhb +uk_param_code +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,57={D1C795B8-8F7B-4AA7-A240-85C5B737C543},ExtUnique,4=true + + + + + + + +DA4BEFAB-FA06-4EC5-AB46-01EA8D270A71 +idx_create_date +idx_create_date +1575627715 +Mhb +1575627719 +Mhb +idx_create_date + + + + + + + + + + +C6F2E10E-0E90-40BA-8D4D-E8A536A47F96 +sys_region +sys_region +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '行政区域' ROW_FORMAT = Dynamic + + + +59C04A52-F0C9-4D2D-A15C-3BE998F23827 +id +id +1575627715 +Mhb +1575860771 +Mhb +id +bigint(32) +32 +1 + + +CB875F9A-9177-4C90-9DBE-A1A968A99112 +pid +pid +1575627715 +Mhb +1575860771 +Mhb +上级ID,一级为0 +NULL +bigint(32) +32 + + +0BD08184-57DC-4FFC-9804-AA6E0E98DAAC +name +name +1575627715 +Mhb +1575627719 +Mhb +varchar(100) +100 + + +CEC11AB1-EFAF-49C6-B078-634636169DC7 +tree_level +tree_level +1575627715 +Mhb +1575627719 +Mhb +层级 +NULL +tinyint(4) +4 + + +A85210C8-E455-4543-A02C-8BED32173C54 +leaf +leaf +1575627715 +Mhb +1575627719 +Mhb +是否叶子节点 0:否 1:是 +NULL +tinyint(4) +4 + + +C1659EAD-78EF-4A41-B341-70CB2788736A +sort +sort +1575627715 +Mhb +1575860771 +Mhb +排序 +NULL +bigint(32) +32 + + +BF8751E2-188C-43ED-AB7E-1D5C74ADD389 +creator +creator +1575627715 +Mhb +1575860771 +Mhb +创建者 +NULL +bigint(32) +32 + + +46641AC0-B8B5-4456-8E8F-CCFE754B4FCA +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + +C6502EC0-3C01-4136-A21C-3117586F66F6 +updater +updater +1575627715 +Mhb +1575860771 +Mhb +更新者 +NULL +bigint(32) +32 + + +1C6A4C0E-8256-4589-85ED-FB3733D2CAA6 +update_date +update_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +42CB078D-2C48-4779-B869-95C7F69625B8 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + + + + + + +40CDA285-E748-4E22-8242-BCA72ABFAA08 +sys_role +sys_role +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色管理' ROW_FORMAT = Dynamic + + + +217A7AFC-2DF7-4CD4-B670-DEB6EC6717AC +id +id +1575627715 +Mhb +1575860914 +Mhb +id +bigint(32) +32 +1 + + +49464548-E018-4B1D-8F56-E27574445729 +name +name +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +FF95C973-C099-4353-8E51-A2C5416FDF5C +remark +remark +1575627715 +Mhb +1575627719 +Mhb +varchar(100) +100 + + +D1B90730-E941-4704-85A0-66299AF57221 +dept_id +dept_id +1575627715 +Mhb +1575860914 +Mhb +部门ID +NULL +bigint(32) +32 + + +D5D89783-B6F3-4A31-A668-C71B74B77792 +creator +creator +1575627715 +Mhb +1575860914 +Mhb +创建者 +NULL +bigint(32) +32 + + +CCA11AB6-8EDD-4CCF-9B5E-CDE87157A613 +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + +794E5CC5-2A01-40F6-8F62-78960848E8AB +updater +updater +1575627715 +Mhb +1575860914 +Mhb +更新者 +NULL +bigint(32) +32 + + +F56062C6-409C-4BE3-8B95-6E0187F17462 +update_date +update_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +A2D679AB-19B6-41BC-B4F6-00EE9110FA05 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +9F1A53FB-7A5D-4C6B-A4C4-6847631E1868 +idx_dept_id +idx_dept_id +1575627715 +Mhb +1575627719 +Mhb +idx_dept_id + + + + + + + + + + +EE744184-1867-4539-A0CA-5B9647487C4C +sys_role_data_scope +sys_role_data_scope +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色数据权限' ROW_FORMAT = Dynamic + + + +F612EA36-9962-4961-8B1F-D6E7AFB1FE7D +id +id +1575627715 +Mhb +1575860976 +Mhb +id +bigint(32) +32 +1 + + +B0FE92E4-8688-44AE-8728-658DAE7B477D +role_id +role_id +1575627715 +Mhb +1575860976 +Mhb +角色ID +NULL +bigint(32) +32 + + +68D23DAA-CDB2-4212-BF57-4BA2FF021529 +dept_id +dept_id +1575627715 +Mhb +1575860976 +Mhb +部门ID +NULL +bigint(32) +32 + + +366667E3-52D2-4823-8230-11D143D6C883 +creator +creator +1575627715 +Mhb +1575860976 +Mhb +创建者 +NULL +bigint(32) +32 + + +8005ADE8-FA90-4633-AB9A-CFC21D91EAE8 +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +BEA5FBF9-456B-4437-BDE3-3CFD7FB3954B +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +FD62465C-9456-4A6F-AAB2-C29B169C3344 +idx_role_id +idx_role_id +1575627715 +Mhb +1575627719 +Mhb +idx_role_id + + + + + + + + + + +3164016F-45D2-412C-A8D1-DB0AC2CB04D1 +sys_role_menu +sys_role_menu +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色菜单关系' ROW_FORMAT = Dynamic + + + +0D7BBAAD-CB81-4B93-A98A-B94C035C66ED +id +id +1575627715 +Mhb +1575861025 +Mhb +id +bigint(32) +32 +1 + + +81CB727A-67E0-4023-A0C2-41EB54321B42 +role_id +role_id +1575627715 +Mhb +1575861025 +Mhb +角色ID +NULL +bigint(32) +32 + + +A62A0E48-4B28-422E-BF48-8206EA8D53BA +menu_id +menu_id +1575627715 +Mhb +1575861025 +Mhb +菜单ID +NULL +bigint(32) +32 + + +DD8F097F-BAD8-46EF-A728-88CA938AA639 +creator +creator +1575627715 +Mhb +1575861025 +Mhb +创建者 +NULL +bigint(32) +32 + + +20920ECA-25EC-4AB6-819A-25BBD630EE33 +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +C981CFC7-2EA0-485D-8042-CEC356DEFDC6 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +D617E5AB-0AE8-4CF7-AC2C-99CCA00411B7 +idx_role_id +idx_role_id +1575627715 +Mhb +1575627719 +Mhb +idx_role_id + + + + + +CAF344D3-D95F-4A84-9A74-80CFFE2EFF59 +idx_menu_id +idx_menu_id +1575627715 +Mhb +1575627719 +Mhb +idx_menu_id + + + + + + + + + + +24E81675-4E7F-4319-B703-D9A562AEFDE0 +sys_role_user +sys_role_user +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色用户关系' ROW_FORMAT = Dynamic + + + +CE22484B-6B1C-43AA-9F30-0F4222DFE1AD +id +id +1575627715 +Mhb +1575861003 +Mhb +id +bigint(32) +32 +1 + + +03690EDB-90EC-43DE-BD43-30106141C83A +role_id +role_id +1575627715 +Mhb +1575861003 +Mhb +角色ID +NULL +bigint(32) +32 + + +33DAD906-AFEF-479D-9489-2037BF10FD9D +user_id +user_id +1575627715 +Mhb +1575861003 +Mhb +用户ID +NULL +bigint(32) +32 + + +C4173478-19A5-4AB4-8312-416FAA249B94 +creator +creator +1575627715 +Mhb +1575861003 +Mhb +创建者 +NULL +bigint(32) +32 + + +BACEFE68-8CD4-4272-970C-BE8E0AB3F7D4 +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +4F317FA2-C006-4810-BF2F-F7B2B567781E +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +BFF9419B-032A-43F6-8018-939EB5213CED +idx_role_id +idx_role_id +1575627715 +Mhb +1575627719 +Mhb +idx_role_id + + + + + +C335C619-CA22-4755-AC44-D641CDEDD48E +idx_user_id +idx_user_id +1575627715 +Mhb +1575627719 +Mhb +idx_user_id + + + + + + + + + + +1AC9C4B2-5D19-4B26-897A-7C1BFFF63F7E +sys_sms +sys_sms +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '短信' ROW_FORMAT = Dynamic + + + +8A21AD7C-3E3A-4D72-8C33-A1897740B2DE +id +id +1575627715 +Mhb +1575860802 +Mhb +id +bigint(32) +32 +1 + + +F40FDC7D-594A-43DE-AA2B-6A6BBBFFF0FC +platform +platform +1575627715 +Mhb +1575627719 +Mhb +平台类型 +tinyint(3) +3 +1 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +CA8E0C8F-1007-4319-A741-9C0FD7222604 +mobile +mobile +1575627715 +Mhb +1575627719 +Mhb +varchar(20) +20 + + +EBD36F17-DF4D-4931-94B2-AA918BB9A02E +params_1 +params_1 +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +9AC68093-4163-44FB-90AE-87FF682A83E0 +params_2 +params_2 +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +2BC8A341-B440-405E-8E4C-F763DE32EB55 +params_3 +params_3 +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +0E652889-5821-49C6-8CEF-6AD64478A51F +params_4 +params_4 +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +FAD4C6E1-B25D-4CDF-8B05-ED34BC5DFCFB +status +status +1575627715 +Mhb +1575627719 +Mhb +发送状态 0:失败 1:成功 +NULL +tinyint(3) +3 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +6FED6DC6-7149-4FF6-9A48-5B13393ABE01 +creator +creator +1575627715 +Mhb +1575860802 +Mhb +创建者 +NULL +bigint(32) +32 + + +F5F72AEA-3888-4C18-8C64-45B6A47E6837 +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +95D56D87-1198-41B3-B9BC-F9681E991376 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +C3DE5639-6BC6-4873-9FD0-78564AB27A8A +idx_create_date +idx_create_date +1575627715 +Mhb +1575627719 +Mhb +idx_create_date + + + + + + + + + + +A58A7698-071B-44D7-AF80-D6D8921DC48A +sys_user +sys_user +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统用户' ROW_FORMAT = Dynamic + + + +AC7A4615-459F-4A48-9E68-B2577EF93BC3 +id +id +1575627715 +Mhb +1575860277 +Mhb +id +bigint(32) +32 +1 + + +17B53829-6D56-4598-AEA9-C06EF2834D97 +username +username +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +D41C3FBE-0992-421B-9CC8-BE1BC090AFF0 +password +password +1575627715 +Mhb +1575627719 +Mhb +varchar(100) +100 + + +DEF24AE2-AB2E-4CC4-82C0-F587CDB86208 +real_name +real_name +1575627715 +Mhb +1575627719 +Mhb +varchar(50) +50 + + +924123F1-3B59-4FAF-9741-9AD042E80606 +head_url +head_url +1575627715 +Mhb +1575627719 +Mhb +varchar(200) +200 + + +1043B155-5ACF-4001-A70A-E558AAB616A8 +gender +gender +1575627715 +Mhb +1575627719 +Mhb +性别 0:男 1:女 2:保密 +NULL +tinyint(3) +3 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +A239B1A1-AE14-4A3B-86B2-9D2F7FF9CED4 +email +email +1575627715 +Mhb +1575627719 +Mhb +varchar(100) +100 + + +6888AE0F-E133-4488-A7B5-B6E03C50C19A +mobile +mobile +1575627715 +Mhb +1575627719 +Mhb +varchar(100) +100 + + +BC22BBFB-68A5-45BC-8261-B81E89C11205 +dept_id +dept_id +1575627715 +Mhb +1575861998 +Mhb +部门ID +NULL +bigint(32) +32 + + +F617DEF0-53F7-4C81-A0B1-4EEB84BDA889 +super_admin +super_admin +1575627715 +Mhb +1575627719 +Mhb +超级管理员 0:否 1:是 +NULL +tinyint(3) +3 +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,56={4A2BD2F3-4A8A-4421-8A48-A8029BDA28E8},Unsigned,4=true + + + + +7F7E5A58-921F-4D62-A615-B8EC20A1874B +status +status +1575627715 +Mhb +1575627719 +Mhb +状态 0:停用 1:正常 +NULL +tinyint(4) +4 + + +DC4FD58A-5646-4686-976C-CB87E91E6E6A +creator +creator +1575627715 +Mhb +1575861998 +Mhb +创建者 +NULL +bigint(32) +32 + + +22BB5FCF-209F-4F41-8879-ACB787BC7C1C +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + +D2B92E58-1E65-4EC0-806C-44C1C0C4A049 +updater +updater +1575627715 +Mhb +1575861998 +Mhb +更新者 +NULL +bigint(32) +32 + + +04970014-4F19-485C-BCE5-669B1E00AD21 +update_date +update_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +00D374D0-EF55-46C9-9576-B3D9C36F8845 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +A897E52A-0D35-424C-AAD8-5C3DBC88A2F9 +uk_username +uk_username +1575627715 +Mhb +1575627719 +Mhb +uk_username +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,57={D1C795B8-8F7B-4AA7-A240-85C5B737C543},ExtUnique,4=true + + + + + + + +5002034A-4E71-4BBA-8AD4-822583E53791 +idx_create_date +idx_create_date +1575627715 +Mhb +1575627719 +Mhb +idx_create_date + + + + + + + + + + +A8C9390D-ACFD-4884-A2BB-81FC7E963F06 +sys_user_token +sys_user_token +1575627715 +Mhb +1575627719 +Mhb +ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统用户Token' ROW_FORMAT = Dynamic + + + +83E02F1F-1C82-48A6-82DA-CD4EFA9D14A4 +id +id +1575627715 +Mhb +1575860928 +Mhb +id +bigint(32) +32 +1 + + +E3AF756A-1C01-4B12-B129-7314509AEC9C +user_id +user_id +1575627715 +Mhb +1575860928 +Mhb +用户id +bigint(32) +32 +1 + + +92C51463-0DAD-4A4C-9884-671003A7C354 +token +token +1575627715 +Mhb +1575627719 +Mhb +varchar(100) +100 + + +A6EE45F6-AF53-4F3B-A4BC-2F316E1BC5DF +expire_date +expire_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + +2B4C27F5-FE17-4EE6-86A4-31D4B5657C56 +update_date +update_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + +277CECC7-4653-4C4B-854C-9BAAC9A846A4 +create_date +create_date +1575627715 +Mhb +1575627719 +Mhb +datetime + + + + +341ADA0F-3333-469F-B49B-56DDB0BBF8F7 +Key_1 +Key_1 +1575627715 +Mhb +1575627719 +Mhb + + + + + +789407F0-85D0-4339-9B16-6BF7AEDB7132 +user_id +user_id +1575627715 +Mhb +1575627719 +Mhb +user_id +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,57={D1C795B8-8F7B-4AA7-A240-85C5B737C543},ExtUnique,4=true + + + + + + + +4F9F2EFA-373A-45C9-99C4-91005B5A0669 +token +token +1575627715 +Mhb +1575627719 +Mhb +token +{F4F16ECD-F2F1-4006-AF6F-638D5C65F35E},MYSQL50,57={D1C795B8-8F7B-4AA7-A240-85C5B737C543},ExtUnique,4=true + + + + + + + + + + + + +34248566-81C1-440F-A2DC-310D27B597C2 +control_bayonet_mid +control_bayonet_mid +1574155394 +Mhb +1575624501 +Mhb +布控和摄像头中间表 + + + +BE8962A9-0BF5-4D70-B0B8-49386D8FA61D +id +id +1574155394 +Mhb +1575861116 +Mhb +id +bigint(32) +32 +1 + + +9A3EF00D-C9FE-4624-9DE9-24D52CCCA692 +id_control_task +id_control_task +1575624441 +Mhb +1575861116 +Mhb +id布控id +bigint(32) +32 + + +CBB59FA0-0E7A-485E-AA38-D2A266CA557F +id_face_camera +id_face_camera +1575624473 +Mhb +1575861116 +Mhb +摄像头id +bigint(32) +32 + + +BE8A507C-3BC6-4C32-9C51-8DA1BC1DCDB8 +is_valid +is_valid +1574155394 +Mhb +1575624135 +Mhb +是否有效 Y有效 N无效 +varchar(1) +1 + + +C034A691-DA39-4D27-857F-E1F4322623B1 +create_time +create_time +1574155394 +Mhb +1575624135 +Mhb +创建时间 +datetime + + +7DECBF16-045C-476F-B97F-5691E8724BA0 +update_time +update_time +1574155394 +Mhb +1575624135 +Mhb +更新时间 +datetime + + +602EA424-77B9-436E-B861-D9D13DA52FE9 +create_by +create_by +1574233787 +Mhb +1575624135 +Mhb +创建人 +varchar(32) +32 + + +86FF23B8-EDCB-439F-8DAC-8494EEB4308D +update_by +update_by +1574233787 +Mhb +1575624135 +Mhb +更新人 +varchar(32) +32 + + + + +D831BF3F-A19F-498D-80DE-E27A5E90CDDA +Key_1 +Key_1 +1574218123 +Mhb +1575624135 +Mhb + + + + + + + + + + + + +CA640E14-FD6F-4E42-855B-0A8CC8CED08F +Reference_1 +Reference_1 +1573443498 +Mhb +1573443498 +Mhb +0..* +1 +1 + + + + + + + + + + + +B97457BA-0E2B-4AB8-BD73-C1B917CDBB52 +1573443498 +Mhb +1573443498 +Mhb + + + + + + + + + + +EAC66D9E-DEDF-48C7-938A-FC51012212AE +Reference_2 +Reference_2 +1575624441 +Mhb +1575624441 +Mhb +0..* +1 +1 + + + + + + + + + + + +C4454DC3-3B36-4F7B-8C84-9206DA6A8034 +1575624441 +Mhb +1575624441 +Mhb + + + + + + + + + + +776ACDFD-7BEC-44C7-B8E0-2CDCF4AA96D6 +Reference_3 +Reference_3 +1575624473 +Mhb +1575624473 +Mhb +0..* +1 +1 + + + + + + + + + + + +FC20B0EB-6A62-44D9-A605-55B0FDC144A8 +1575624473 +Mhb +1575624473 +Mhb + + + + + + + + + + +969DEED2-95A2-4879-953C-903E5078A5A5 +Reference_4 +Reference_4 +1575624521 +Mhb +1575624521 +Mhb +0..* +1 +1 + + + + + + + + + + + +296E410E-E215-4872-B62D-359A9E7406E5 +1575624521 +Mhb +1575624521 +Mhb + + + + + + + + + + +FD5A8738-CF6F-4899-820D-A34ED667AEB6 +Reference_5 +Reference_5 +1575624526 +Mhb +1575624526 +Mhb +0..* +1 +1 + + + + + + + + + + + +7D51A18B-4561-48AA-86E7-9C48C377C5A0 +1575624526 +Mhb +1575624526 +Mhb + + + + + + + + + + + + +232A460E-291D-4EE1-AAE3-1613C9E99263 +PUBLIC +PUBLIC +1573436672 +Mhb +1573436672 +Mhb + + + + +09B937B0-C216-4794-9D7E-4ECE097A3E2E +MySQL 5.0 +MYSQL50 +1573436673 +Mhb +1573436673 +Mhb +file:///%_DBMS%/mysql50.xdb +F4F16ECD-F2F1-4006-AF6F-638D5C65F35E +4BA9F647-DAB1-11D1-9944-006097355D9B +1276524678 + + + + + + + + + + \ No newline at end of file diff --git a/doc/数据库变更字段-2020-01-07.sql b/doc/数据库变更字段-2020-01-07.sql new file mode 100644 index 0000000..07bf44f --- /dev/null +++ b/doc/数据库变更字段-2020-01-07.sql @@ -0,0 +1,7 @@ +alter table face_camera add id_version VARCHAR(32) COMMENT "摄像头类型ID"; + + ALTER TABLE face_camera CHANGE id_version id_brand VARCHAR(32) COMMENT "摄像头品牌ID"; + + ALTER TABLE face_camera CHANGE camerat_longitude camera_longitude VARCHAR(100) COMMENT "摄像头经度"; + + ALTER table face_camera add port VARCHAR(32) COMMENT "端口号"; diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..0acdeb1 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,57 @@ +version: '3' +services: + + minio: + image: minio/minio + container_name: minio + environment: + MINIO_ACCESS_KEY: sunseaiot + MINIO_SECRET_KEY: sunseaiot + restart: always + hostname: minio + ports: + - "9000:9000" + volumes: + - "./minio/data:/data" + command: server /data + minio_mc: + image: minio/mc + container_name: minio_mc + entrypoint: /bin/sh + command: mc config + + redis: + image: redis + container_name: redis + hostname: redis + restart: always +# command: redis-server --requirepass ldjy@2019 + ports: + - "40008:6379" + volumes: + - "./redis/data:/data" + mysql: + image: mysql:5.7 + container_name: mysql + hostname: mysql + restart: always + ports: + - "33060:3306" + volumes: + - "./mysql/conf:/etc/mysql/conf.d" + - "./mysql/data:/var/lib/mysql" + - "./mysql/logs:/logs" + environment: + MYSQL_ROOT_PASSWORD: "123456" + MYSQL_USER: 'root' + MYSQL_PASS: '123456' + + dkha-eureka: + build: ./face-server + volumes: + - "./face-server/face.log:/face.log" + container_name: face-server + restart: always + hostname: face-server + ports: + - "8899:8899" diff --git a/docker-compose1.yml b/docker-compose1.yml new file mode 100644 index 0000000..f33c0e2 --- /dev/null +++ b/docker-compose1.yml @@ -0,0 +1,77 @@ +version: '3' +services: + + face_minio: + image: face_minio + container_name: face_minio + restart: always + hostname: face_minio + ports: + - "9000:9000" + command: server /data + volumes: + - "./minio:/data" + environment: + MINIO_ACCESS_KEY: sunseaiot + MINIO_SECRET_KEY: sunseaiot + + face_redis: + image: face_redis + container_name: face_redis + hostname: face_redis + restart: always + command: redis-server --appendonly yes + ports: + - "6379:6379" + face_mysql: + image: face_mysql + container_name: face_mysql + hostname: face_mysql + restart: always + command: mysqld + ports: + - "3306:3306" + volumes: + - "./mysql/config:/etc/mysql/conf.d" + - "./mysql/data:/var/lib/mysql" + - "./mysql/logs:/logs" + - "/etc/localtime:/etc/localtime" + environment: + MYSQL_ROOT_PASSWORD: "123456" + MYSQL_USER: 'root' + MYSQL_PASS: '123456' + + face_rabbitmq: + image: face_rabbitmq + container_name: face_rabbitmq + hostname: face_rabbitmq + restart: always + command: rabbitmq-server + ports: + - "15672:15672" + - "25672:25672" + - "4369:4369" + - "5671:5671" + - "5672:5672" + + face_es: + image: face_es + container_name: face_es + hostname: face_es + restart: always + command: eswrapper + ports: + - "9200:9200" + - "9300:9300" + + face_nginx: + image: face_nginx + container_name: face_nginx + hostname: face_nginx + restart: always + ports: + - "80:80" + volumes: + - "./nginx/conf.d:/etc/nginx/conf.d" + - "./nginx/face:/usr/share/nginx/html" + - "./nginx/log:/var/log/nginx" diff --git a/face-common/pom.xml b/face-common/pom.xml new file mode 100644 index 0000000..4365904 --- /dev/null +++ b/face-common/pom.xml @@ -0,0 +1,126 @@ + + + + face-application + com.dkha + 1.0-SNAPSHOT + + 4.0.0 + + face-common + + + + org.springframework.boot + spring-boot-starter-web + + + org.apache.mina + mina-core + 2.1.3 + + + cn.afterturn + easypoi-base + + + cn.afterturn + easypoi-web + + + cn.afterturn + easypoi-annotation + + + redis.clients + jedis + + + org.springframework.boot + spring-boot-starter-data-redis + + + com.alibaba + fastjson + + + + io.minio + minio + + + com.github.axet + kaptcha + + + com.baomidou + mybatis-plus-generator + + + com.ecwid.consul + consul-api + + + com.auth0 + java-jwt + + + org.jsoup + jsoup + + + commons-io + commons-io + + + io.springfox + springfox-swagger2 + + + io.springfox + springfox-swagger-ui + + + mysql + mysql-connector-java + + + org.freemarker + freemarker + + + org.projectlombok + lombok + + + + + org.apache.poi + poi + ${poi.version} + + + org.apache.poi + poi-ooxml + ${poi.version} + + + org.apache.poi + poi-ooxml-schemas + ${poi.version} + + + + + + org.springframework.boot + spring-boot-maven-plugin + + exec + + + + + diff --git a/face-common/src/main/java/com/dkha/common/CommonApplication.java b/face-common/src/main/java/com/dkha/common/CommonApplication.java new file mode 100644 index 0000000..e14bfb6 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/CommonApplication.java @@ -0,0 +1,19 @@ +package com.dkha.common; + + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author Spring + */ +@SpringBootApplication(exclude = { + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class}) + +public class CommonApplication { + + public static void main(String[] args) { + SpringApplication.run(CommonApplication.class, args); + } + +} diff --git a/face-common/src/main/java/com/dkha/common/consul/BaseLock.java b/face-common/src/main/java/com/dkha/common/consul/BaseLock.java new file mode 100644 index 0000000..99fd640 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/consul/BaseLock.java @@ -0,0 +1,71 @@ +package com.dkha.common.consul; + +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.session.model.NewSession; +import com.ecwid.consul.v1.session.model.Session; + +import java.util.ArrayList; +import java.util.List; + +public class BaseLock { + + protected ConsulClient consulClient; + private String sessionName; + protected String sessionId = null; + protected String keyPath; // 互斥锁、信号量存储在consul中的基础key路径 + + protected CheckTtl checkTtl; // Check Ttl + /** + * @param consulClient + * @param lockKey 同步锁在consul的KV存储中的Key路径,会自动增加prefix前缀,方便归类查询 + * @param + */ + + protected BaseLock(ConsulClient consulClient, String sessionName, String lockKey) { + this.consulClient = consulClient; + this.keyPath = lockKey; + this.sessionName=sessionName; + } + /** + * @param consulClient + * @param lockKey 同步锁在consul的KV存储中的Key路径,会自动增加prefix前缀,方便归类查询 + * @param checkTtl 对锁Session的TTL + */ + protected BaseLock(ConsulClient consulClient, String lockKey, CheckTtl checkTtl) { + this.consulClient = consulClient; + this.keyPath = lockKey; + this.checkTtl = checkTtl; + } + /** + * 创建session + * @param sessionName + * @return + */ + + protected String createSession(String sessionName) { + NewSession newSession = new NewSession(); + newSession.setName(sessionName); + if(checkTtl != null) { + checkTtl.start(); + // 如果有CheckTtl,就为该Session设置Check相关信息 + List checks = new ArrayList<>(); + checks.add(checkTtl.getCheckId()); + newSession.setChecks(checks); + newSession.setBehavior(Session.Behavior.DELETE); + } + + return consulClient.sessionCreate(newSession, null).getValue(); + } + + +/** + * 根据成员变量sessionId来销毁session + */ + + protected void destroySession() { + if (sessionId != null) { + consulClient.sessionDestroy(sessionId, null); + sessionId = null; + } + } +} diff --git a/face-common/src/main/java/com/dkha/common/consul/CheckTtl.java b/face-common/src/main/java/com/dkha/common/consul/CheckTtl.java new file mode 100644 index 0000000..a19ca62 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/consul/CheckTtl.java @@ -0,0 +1,89 @@ +package com.dkha.common.consul; + +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.OperationException; +import com.ecwid.consul.v1.agent.model.NewCheck; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.util.Timer; +import java.util.TimerTask; + +@Slf4j +/** + * + */ +public class CheckTtl { + + private ConsulClient consulClient; + + @Getter + private String checkId; + private NewCheck check; + private Timer timer; + + private int ttlDelay = 5000; + private int ttlPeriod = 10000; + + public CheckTtl(String checkId, ConsulClient consulClient) { + this.checkId = checkId; + this.consulClient = consulClient; + } + + public void agentCheckRegister() { + this.check = new NewCheck(); + check.setId(checkId); + check.setName(checkId); + check.setTtl("30s"); + check.setInterval("10s"); + check.setTimeout("10s"); + this.consulClient.agentCheckRegister(check); + } + + public void agentCheckDegister() { + if (this.checkId != null) { + this.consulClient.agentCheckDeregister(checkId); + } + } + + + public boolean isRunning() { + if (this.timer == null) { + return false; + } + return true; + } + + public void start() { + if (!isRunning()) { + agentCheckRegister(); + consulClient.agentCheckPass(checkId); + this.timer = new Timer(); + timer.scheduleAtFixedRate(new TtlTask(), ttlDelay, ttlPeriod); + } + } + + public void stop() { + if (this.timer != null) { + agentCheckDegister(); + timer.cancel(); + } + } + + class TtlTask extends TimerTask { + + @Override + public void run() { + try { + log.debug("{} run ttl...", checkId); + consulClient.agentCheckPass(checkId); + } catch (OperationException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + } + +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/consul/Lock.java b/face-common/src/main/java/com/dkha/common/consul/Lock.java new file mode 100644 index 0000000..6f8d46b --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/consul/Lock.java @@ -0,0 +1,84 @@ +package com.dkha.common.consul; + +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.kv.model.PutParams; + +import java.time.LocalDateTime; + +public class Lock extends BaseLock { + + private static final String prefix = "lock/"; // 同步锁参数前缀 + + /** + * @param consulClient + * @param lockKey 同步锁在consul的KV存储中的Key路径,会自动增加prefix前缀,方便归类查询 + */ + + public Lock(ConsulClient consulClient, String sessionName, String lockKey) { + super(consulClient, sessionName, prefix + lockKey); + } + + public Lock(ConsulClient consulClient, String sessionName, CheckTtl checkTtl) { + super(consulClient, sessionName, checkTtl); + } + + /** + * 获取同步锁 + * + * @param block 是否阻塞,直到获取到锁为止,默认尝试间隔时间为500ms。 + * @return + */ + + public Boolean lock(boolean block) throws InterruptedException { + return lock(block, 500L, null); + } + + + /** + * 获取同步锁 + * + * @param block 是否阻塞,直到获取到锁为止 + * @param timeInterval block=true时有效,再次尝试的间隔时间 + * @param maxTimes block=true时有效,最大尝试次数 + * @return + */ + + public Boolean lock(boolean block, Long timeInterval, Integer maxTimes) throws InterruptedException { + if (sessionId != null) { + throw new RuntimeException(sessionId + " - Already locked!"); + } + sessionId = createSession("lock-" + this.keyPath); + int count = 1; + while (true) { + PutParams putParams = new PutParams(); + putParams.setAcquireSession(sessionId); + if (consulClient.setKVValue(keyPath, "lock:" + LocalDateTime.now(), putParams).getValue()) { + return true; + } else if (block) { + if (maxTimes != null && count >= maxTimes) { + return false; + } else { + count++; + if (timeInterval != null) + Thread.sleep(timeInterval); + continue; + } + } else { + return false; + } + } + } + + /** + * 释放同步锁 + * + * @return + */ + public Boolean unlock() { + PutParams putParams = new PutParams(); + putParams.setReleaseSession(sessionId); + boolean result = consulClient.setKVValue(keyPath, "unlock:" + LocalDateTime.now(), putParams).getValue(); + destroySession(); + return result; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/ApiUrlEnum.java b/face-common/src/main/java/com/dkha/common/enums/ApiUrlEnum.java new file mode 100644 index 0000000..6d2c68a --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/ApiUrlEnum.java @@ -0,0 +1,42 @@ +package com.dkha.common.enums; + +import lombok.Getter; +import org.springframework.beans.factory.annotation.Value; + +/** + * @version V1.0 + * @Description: TODO(请求api地址枚举维护类) + * All rights 成都电科慧安 + * @Title: ApiUrl + * @Package com.dkha.common.enums + * @author: panhui + * @date: 2019/12/10 10:37 + * @Copyright: 成都电科慧安 + */ +@Getter +public enum ApiUrlEnum { +// @Value("${api.server.prefix}") 请求前缀维护在face-common的faceApiUrl.properties 中 +// String link; + + ALARM_POSTURL("alarm", "查看单个报警任务(业务场景卡口)post"), + ALARMS_POSTURL("alarms", "查看批量报警post"), + ALARMS_STATUS("taskStatus", "视频任务状态查询"), + FACELIBS_POSTURL("faceLibs", "查看人脸"), + FACELIB_POSTURL("faceLib", "添加人脸"), + FACELIST_POSTURL("face", "添加人像"), + FACE_POSTURL("face", "添加人像"), + TASK_POSTURL("control", "任务操作"), + TASK_VEDIO_POSTURL("controlVedio", "视频比对任务操作"), + FACE_SEARCH_LIB("faceSearchLib", "人脸库检索"), + FACE_SEARCH("faceSearch", "人脸检测"), + FACE_GROUP("faceGroup", "分组检索"), + FACE_COMPARISON("faceComparison", "一比一比对"), + CAMERA("camera", "摄像头操作"); + private String url; + private String message; + + ApiUrlEnum(String url, String message) { + this.url = url; + this.message = message; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/BoardAndLodgingEnums.java b/face-common/src/main/java/com/dkha/common/enums/BoardAndLodgingEnums.java new file mode 100644 index 0000000..eb823ed --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/BoardAndLodgingEnums.java @@ -0,0 +1,19 @@ +package com.dkha.common.enums; + +/** + * 住宿码表 + */ +public enum BoardAndLodgingEnums { + + BOARD("0", "包吃"), + LODGING("1", "包住"), + BOARDANDLODGING("2", "包吃包住"); + + public String name; + public String code; + + BoardAndLodgingEnums(String name, String code) { + this.name = name; + this.code = code; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/CompanyCheckEnums.java b/face-common/src/main/java/com/dkha/common/enums/CompanyCheckEnums.java new file mode 100644 index 0000000..5ab0a22 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/CompanyCheckEnums.java @@ -0,0 +1,22 @@ +package com.dkha.common.enums; + +/** + * @Description: + * @Author: yanping + * @Date: 2019/9/30 18:44 + */ +public enum CompanyCheckEnums { + + PASS("1", "已通过"), + FAIL("2", "未通过"), + PENDING("0", "待审核"); + + + public String code; + public String name; + + CompanyCheckEnums(String code, String name) { + this.code = code; + this.name = name; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/CompanyMessageEnums.java b/face-common/src/main/java/com/dkha/common/enums/CompanyMessageEnums.java new file mode 100644 index 0000000..d8e3aef --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/CompanyMessageEnums.java @@ -0,0 +1,19 @@ +package com.dkha.common.enums; + +/** + * @Description: + * @Author: yangjun + * @Date: 2019/9/23 17:44 + */ +public enum CompanyMessageEnums { + SIGNED("2", "劳动人员同意岗位"), + UNSIGNED("1", "劳动人员发起岗位申请"), + RELIEVE("3", "劳动人员拒绝岗位"); + public String code; + public String name; + + CompanyMessageEnums(String code, String name) { + this.code = code; + this.name = name; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/ContractFileStausEnums.java b/face-common/src/main/java/com/dkha/common/enums/ContractFileStausEnums.java new file mode 100644 index 0000000..f2fee46 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/ContractFileStausEnums.java @@ -0,0 +1,18 @@ +package com.dkha.common.enums; + +/** + * 合同附件上传状态 + */ +public enum ContractFileStausEnums { + + UPLOAD("1", "已上传"), + UNUPLOAD("2", "待上传"); + + public String code; + public String name; + + ContractFileStausEnums(String code, String name) { + this.code = code; + this.name = name; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/ContractStatusEnums.java b/face-common/src/main/java/com/dkha/common/enums/ContractStatusEnums.java new file mode 100644 index 0000000..bebbfd2 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/ContractStatusEnums.java @@ -0,0 +1,19 @@ +package com.dkha.common.enums; + +/** + * 合同状态枚举 + */ +public enum ContractStatusEnums { + + SIGNED("2", "已签订"), + UNSIGNED("1", "待签订"), + RELIEVE("3", "已解除"); + + public String code; + public String name; + + ContractStatusEnums(String code, String name) { + this.code = code; + this.name = name; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/ContractType.java b/face-common/src/main/java/com/dkha/common/enums/ContractType.java new file mode 100644 index 0000000..470d6ab --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/ContractType.java @@ -0,0 +1,18 @@ +package com.dkha.common.enums; + +/** + * 合同类型 + */ +public enum ContractType { + + ORG("1", "有组织就业"), + SCATTERED("2", "自主零散就业"); + + public String code; + public String name; + + ContractType(String code, String name) { + this.code = code; + this.name = name; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/ContralEnums.java b/face-common/src/main/java/com/dkha/common/enums/ContralEnums.java new file mode 100644 index 0000000..9acf354 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/ContralEnums.java @@ -0,0 +1,44 @@ +package com.dkha.common.enums; + +import lombok.Getter; + +/** + * @version V1.0 + * @Description: TODO(布控任务类型) + * All rights 成都电科慧安 + * @Title: ContralEnums + * @Package com.dkha.common.enums + * @author: panhui + * @date: 2019/12/11 17:27 + * @Copyright: 成都电科慧安 + */ +@Getter +public enum ContralEnums { + + + ARREST(0,"抓捕类"), + MONITOR(1,"监控类"), + PROMPT(2,"提示类"); + + + private Integer code; + private String message; + + ContralEnums(Integer code, String message) { + this.code = code; + this.message = message; + } + + public static ContralEnums getTypeByValue(Integer code) + { + if (null==code){ + return ARREST; + } + for (ContralEnums enums : ContralEnums.values()) { + if (enums.getCode().intValue() == code.intValue()) { + return enums; + } + } + return ARREST; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/DictTypeEnums.java b/face-common/src/main/java/com/dkha/common/enums/DictTypeEnums.java new file mode 100644 index 0000000..e4da2bf --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/DictTypeEnums.java @@ -0,0 +1,42 @@ +package com.dkha.common.enums; + +/** + * @ClassName: DictTypeEnums + * @Description: (字典类型枚举) + * @author: 严平 + * @date: 2019-09-18 + * @Copyright: 成都电科惠安 + */ +public enum DictTypeEnums { + + + UNIT_TYPE("unittype", "单位类型"), + GENDER("gender", "性别"), + REGION("region", "摄像头区域"), + EDUCATION("education","教育程度"), + NATION("nation","民族"), + ACCOMMODATION("accommodation","食宿安排"), + SALARY("salary","收入区间"), + MARITALSTATUS("maritalstatus","婚姻状况"), + POLITICAL("political","政治面貌"), + ACCOUNT("account","户口性质"), + POST_SKILL("postSkill","职业技能"), + INDUSTRY("industry","所属行业"), + STAFF_SCALE("staffScale","公司人员规模"), + WORKING_SYSTEM("workingSystem","工作制度"), + EMPLOYEE_CHANNEL("employeeChannel","就业渠道"), + ACADEMIC("academic","学历要求"), + EMPLOYMENT_METHOD("employmentMethod","用工方式"), + TRAINING_TYPE("trainingType","培训类型"), + ORGANIZED_EMPLOYMENT("organizedEmployment","有组织就业"), + SELF_EMPLOYMENT("selfEmployment","自主零散就业"), + AREA("area","全国地区"), + LABOR_STATUS("laborStatus","劳动力状况"); + public String code; + public String name; + + DictTypeEnums(String code, String name) { + this.code = code; + this.name = name; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/EmployeeChannel.java b/face-common/src/main/java/com/dkha/common/enums/EmployeeChannel.java new file mode 100644 index 0000000..08a75e4 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/EmployeeChannel.java @@ -0,0 +1,39 @@ +package com.dkha.common.enums; + +/** + * 就业渠道 + */ +public enum EmployeeChannel { + + NEARBY("1", "就近就地就业"), + ACROSS("2", "疆内跨地州就业"), + INLAND("3", "内地省市就业"), + CORPS("4", "兵团就业"), + TRANSFER("5", "有组织转移就业"), + + SMALLBUSINESS("6", "“十小”服务业"), + + PARK("7", "园区企业就业"), + SPIN("8", "纺织服装产业就业"), + ELECTRONIC("9", "电子装配、假发、玩具等部分劳动密集型就业"), + VILLAGE_WORKSHOP("10", "乡村生产车间就业就业"), + TOURISM_SERVICE("11", "旅游服务就业"), + FIXED_INVESTMENT("12", "固定资产投资项目建设领域就业"); + + public String code; + public String name; + + EmployeeChannel(String code, String name) { + this.code = code; + this.name = name; + } + + public static EmployeeChannel getByCode(String code) { + for(EmployeeChannel employeeChannel : EmployeeChannel.values()){ + if(code.equals(employeeChannel.code)){ + return employeeChannel; + } + } + return null; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/ErrEnum.java b/face-common/src/main/java/com/dkha/common/enums/ErrEnum.java new file mode 100644 index 0000000..5675e97 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/ErrEnum.java @@ -0,0 +1,35 @@ +package com.dkha.common.enums; + +import lombok.Getter; + +/** + * @version V1.0 + * @Description: TODO(api中返回的错误代码) + * All rights 成都电科慧安 + * @Title: errEnum + * @Package com.dkha.api.modules.errnums + * @author: panhui + * @date: 2019/12/2 11:42 + * @Copyright: 成都电科慧安 + */ +@Getter +public enum ErrEnum { + OK(200,"成功"),CREATED(201,"创建成功"), + + ACCEPTED(202,"更新成功"),BAD_REQUEST(400,"请求的地址不存在或者包含不支持的参数"), + + UNAUTHORIZED(401,"未授权"),FORBIDDEN(403,"被禁止访问"), + + NOT_FOUND(404,"请求资源不存在"),ERROR(500,"内部错误"); + + + private Integer code; + private String msg; + + ErrEnum(Integer code, String msg) { + this.code = code; + this.msg = msg; + } + + +} diff --git a/face-common/src/main/java/com/dkha/common/enums/ExpiryTimeTypeEnums.java b/face-common/src/main/java/com/dkha/common/enums/ExpiryTimeTypeEnums.java new file mode 100644 index 0000000..c7a1e7e --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/ExpiryTimeTypeEnums.java @@ -0,0 +1,22 @@ +package com.dkha.common.enums; + +/** + * 岗位招聘失效时间枚举 + */ +public enum ExpiryTimeTypeEnums { + + + ONE_WEEK("1", "一周"), + TWO_WEEK("2", "半个月"), + ONE_MONTH("3", "一个月"), + THREE_MONTH("4", "三个月"), + SIX_MONTH("5", "半年"); + + public String code; + public String name; + + ExpiryTimeTypeEnums(String code, String name) { + this.code = code; + this.name = name; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/IndustryTypeEnum.java b/face-common/src/main/java/com/dkha/common/enums/IndustryTypeEnum.java new file mode 100644 index 0000000..e6da482 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/IndustryTypeEnum.java @@ -0,0 +1,30 @@ +package com.dkha.common.enums; + +/** + * @author Spring + * @date 2019/11/22 + * @Description: 产业类型枚举 + */ +public enum IndustryTypeEnum { + + FIRST_INDUSTRY("1", "一产"), + SECOND_INDUSTRY("2", "二产"), + THIRD_INDUSTRY("3", "三产"); + + public String code; + public String name; + + IndustryTypeEnum(String code, String name) { + this.code = code; + this.name = name; + } + + public static IndustryTypeEnum getByCode(String code) { + for(IndustryTypeEnum industryType : IndustryTypeEnum.values()){ + if(code.equals(industryType.code)){ + return industryType; + } + } + return null; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/IsOnWorkingEnums.java b/face-common/src/main/java/com/dkha/common/enums/IsOnWorkingEnums.java new file mode 100644 index 0000000..d5f1d3b --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/IsOnWorkingEnums.java @@ -0,0 +1,14 @@ +package com.dkha.common.enums; + +public enum IsOnWorkingEnums { + ON_WORKING("Y", "在职"), + NOT_ON_WORKING("N", "离职"); + + public String code; + public String name; + + IsOnWorkingEnums(String code, String name) { + this.code = code; + this.name = name; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/IsPoorEnums.java b/face-common/src/main/java/com/dkha/common/enums/IsPoorEnums.java new file mode 100644 index 0000000..88ba21b --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/IsPoorEnums.java @@ -0,0 +1,13 @@ +package com.dkha.common.enums; + +public enum IsPoorEnums { + Y("Y", "是"), + N("N", "否"); + public String code; + public String name; + + IsPoorEnums(String code, String name) { + this.code = code; + this.name = name; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/LaborMessageEnms.java b/face-common/src/main/java/com/dkha/common/enums/LaborMessageEnms.java new file mode 100644 index 0000000..1d282fd --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/LaborMessageEnms.java @@ -0,0 +1,20 @@ +package com.dkha.common.enums; + +/** + * @ClassName: LaborMessageEnms + * @Description:(please write your description) + * @author: 严平 + * @date: 2019-09-24 + * @Copyright: 成都电科惠安 + */ +public enum LaborMessageEnms { + SIGNED("1", "用人单位同意岗位"), + RELIEVE("2", "用人单位拒绝岗位"); + public String code; + public String name; + + LaborMessageEnms(String code, String name) { + this.code = code; + this.name = name; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/MsgEnums.java b/face-common/src/main/java/com/dkha/common/enums/MsgEnums.java new file mode 100644 index 0000000..f958bdb --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/MsgEnums.java @@ -0,0 +1,34 @@ +package com.dkha.common.enums; + + +/** + * 预警消息推送 + */ +public enum MsgEnums { + +// Completion warning Income alarm Unemployment alarm + COMPLETION_ALARM(1,"15日旷工人员"), + NO_INCOME_ALARM(2,"6个月没有收入人员"), + UNEMPLOYMENT_ALARM(3,"失业人数"), + UNEMPLOYED_FAMILY(4,"一户零就业户数"), + NEW_COMPANY_ALARM(5,"新公司申请"), + TOTAL_LABORFORCE(6,"劳动力总数"), + ON_WORK(7,"已就业人数"), + ON_POOL(8,"贫困户户数"), + + UNEMPLOYMENT(3,"失业"), + UNEMPLOYED(4,"一户零就业"), + POOR(8,"贫困"), + ; + + + + public Integer type; + public String msg; + + MsgEnums(Integer type,String msg) + { + this.type=type; + this.msg=msg; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/OpinionEnums.java b/face-common/src/main/java/com/dkha/common/enums/OpinionEnums.java new file mode 100644 index 0000000..f8f4df7 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/OpinionEnums.java @@ -0,0 +1,22 @@ +package com.dkha.common.enums; + +/** + * 录取意见状态 + */ +public enum OpinionEnums { + + PASS("1", "通过"), + FAIL("2", "未通过"), + PENDING("0", "待处理"); + + + public String code; + public String name; + + OpinionEnums(String code, String name) { + this.code = code; + this.name = name; + } + + +} diff --git a/face-common/src/main/java/com/dkha/common/enums/PlatformDictTypeEnum.java b/face-common/src/main/java/com/dkha/common/enums/PlatformDictTypeEnum.java new file mode 100644 index 0000000..aaf5289 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/PlatformDictTypeEnum.java @@ -0,0 +1,23 @@ +package com.dkha.common.enums; + +/** + * @author Spring + * @date 2018/5/18-11:30 + * @Description: 全局字典枚举 -- 全平台统一维护 + */ +public enum PlatformDictTypeEnum { + + COMPANY_TYPE("company", "公司类型枚举Type"), + EDUCATION("education", "学历枚举类型"), + POST_SKILL("postSkill", "职业技能枚举类型"), + REGION("region", "区域枚举类型"), + BOARD_AND_LODGING("accommodation", "食宿安排枚举类型"); +// WORK_ADDRESS("workAddress", "工作地点枚举类型"); + public String code; + public String name; + + PlatformDictTypeEnum(String code, String name) { + this.code = code; + this.name = name; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/PlatformTypeEnum.java b/face-common/src/main/java/com/dkha/common/enums/PlatformTypeEnum.java new file mode 100644 index 0000000..e6a3091 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/PlatformTypeEnum.java @@ -0,0 +1,21 @@ +package com.dkha.common.enums; + +/** + * @Author Spring + * @Since 2019/9/11 17:36 + * @Description 平台类型枚举 + */ +public enum PlatformTypeEnum { + + API("API", "APP平台"), + COMPANY("COMPANY", "劳动就业岗位发布平台"), + GOVERNMENT("GOVERNMENT", "劳动就业服务平台"); + + public String code; + public String name; + + PlatformTypeEnum(String code, String name) { + this.code = code; + this.name = name; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/ProjectType.java b/face-common/src/main/java/com/dkha/common/enums/ProjectType.java new file mode 100644 index 0000000..342841e --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/ProjectType.java @@ -0,0 +1,19 @@ +package com.dkha.common.enums; + +/** + * + */ +public enum ProjectType { + + APPROVAL("0", "审批"), + CHECK("1", "核准"), + FILING("2", "备案"); + public String code; + public String name; + + ProjectType(String code, String name) { + this.code = code; + this.name = name; + } + +} diff --git a/face-common/src/main/java/com/dkha/common/enums/SEXEnums.java b/face-common/src/main/java/com/dkha/common/enums/SEXEnums.java new file mode 100644 index 0000000..23d3f96 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/SEXEnums.java @@ -0,0 +1,30 @@ +package com.dkha.common.enums; + +/** + * 性别枚举 + */ +public enum SEXEnums { + MAN("0", "男"), + WOMAN("1", "女"), + NOLIMIT("2", "保密"); + public String code; + public String name; + + SEXEnums(String code, String name) { + this.code = code; + this.name = name; + } + public static SEXEnums getTypeByValue(String code) + { + if (null==code){ + return NOLIMIT; + } + for (SEXEnums enums : SEXEnums.values()) { + if (enums.code.equals(code)) { + return enums; + } + } + return NOLIMIT; + } + +} diff --git a/face-common/src/main/java/com/dkha/common/enums/SocketEnum.java b/face-common/src/main/java/com/dkha/common/enums/SocketEnum.java new file mode 100644 index 0000000..2de38e0 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/SocketEnum.java @@ -0,0 +1,28 @@ +package com.dkha.common.enums; + +import lombok.Getter; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: SocketEnum + * @Package com.dkha.common.enums + * @author: panhui + * @date: 2020/1/3 15:50 + * @Copyright: 成都电科慧安 + */ +@Getter +public enum SocketEnum { + + WARNING("WARNING","预警"), + BAYONET("BAYONET","卡口"); + + private String code; + private String msg; + + SocketEnum(String code, String msg) { + this.code = code; + this.msg = msg; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/TaskStatuEnum.java b/face-common/src/main/java/com/dkha/common/enums/TaskStatuEnum.java new file mode 100644 index 0000000..b7ee251 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/TaskStatuEnum.java @@ -0,0 +1,29 @@ +package com.dkha.common.enums; + +import lombok.Getter; + +/** + * @version V1.0 + * @Description: 布控任务 + * @Title: + * @author: huangyugang + * @date: 2019/12/18 16:22 + * @Copyright: 成都电科慧安 + */ +@Getter +public enum TaskStatuEnum { + STATUS_UNDEF("STATUSUNDEF","未知"), + STATUS_STARTING("STATUSSTARTING","正在打开"), + STATUS_WORKING("STATUSWORKING","工作中"), + STATUS_RESTATING("STATUSRESTATING","正在重新打开"), + STATUS_OVER("STATUSOVER","任务已经结束"); + private String code; + private String message; + + TaskStatuEnum(String code, String message) + { + this.code=code; + this.message=message; + } + +} diff --git a/face-common/src/main/java/com/dkha/common/enums/TaskStatusEnum.java b/face-common/src/main/java/com/dkha/common/enums/TaskStatusEnum.java new file mode 100644 index 0000000..a80de0f --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/TaskStatusEnum.java @@ -0,0 +1,23 @@ +package com.dkha.common.enums; + +/** + * @version V1.0 + * @Description: 布控任务状态 + * @Title: + * @author: huangyugang + * @date: 2019/12/11 9:13 + * @Copyright: 成都电科慧安 + */ +public enum TaskStatusEnum { + RUN("0", "运行中"), + STOP("-1", "停止运行"), + SUSPEND("1","暂停运行"); + + public String code; + public String name; + + TaskStatusEnum(String code, String name) { + this.code = code; + this.name = name; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/TrainingAssessmentStatus.java b/face-common/src/main/java/com/dkha/common/enums/TrainingAssessmentStatus.java new file mode 100644 index 0000000..e3bb097 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/TrainingAssessmentStatus.java @@ -0,0 +1,15 @@ +package com.dkha.common.enums; + +public enum TrainingAssessmentStatus { + PASS("0", "通过"), + + NOT_PASS("1", "未通过"), + INIT("2", "初始状态"); + public String code; + public String name; + + TrainingAssessmentStatus(String code, String name) { + this.code = code; + this.name = name; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/YNEnums.java b/face-common/src/main/java/com/dkha/common/enums/YNEnums.java new file mode 100644 index 0000000..47d7366 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/YNEnums.java @@ -0,0 +1,20 @@ +package com.dkha.common.enums; + +/** + * @author Spring + * @date 2018/5/18-11:30 + * @Description: 逻辑判断枚举 + */ +public enum YNEnums { + + YES("Y", "是"), + NO("N", "否"); + + public String code; + public String name; + + YNEnums(String code, String name) { + this.code = code; + this.name = name; + } +} diff --git a/face-common/src/main/java/com/dkha/common/enums/YNNumberEnum.java b/face-common/src/main/java/com/dkha/common/enums/YNNumberEnum.java new file mode 100644 index 0000000..5437a93 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/enums/YNNumberEnum.java @@ -0,0 +1,20 @@ +package com.dkha.common.enums; + +/** + * @ClassName: 是否枚举 + * @Description: 使用数字 + * @author: yanping + * @date: 2020-01-06 + * @Copyright: 成都电科惠安 + */ +public enum YNNumberEnum { + YES(1, "是"), + NO(0, "否"); + public Integer code; + public String name; + + YNNumberEnum(Integer code, String name) { + this.code = code; + this.name = name; + } +} diff --git a/face-common/src/main/java/com/dkha/common/exception/AuthorityException.java b/face-common/src/main/java/com/dkha/common/exception/AuthorityException.java new file mode 100644 index 0000000..5cbff2e --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/exception/AuthorityException.java @@ -0,0 +1,27 @@ +package com.dkha.common.exception; + +/** + * @Author Spring + * @Since 2019/9/21 11:58 + * @Description 权限相关异常--主要用于权限拦截器 + * + */ + +public class AuthorityException extends RuntimeException { + + public AuthorityException(String s) { + super(s); + } + + public AuthorityException(String s, Throwable throwable) { + super(s, throwable); + } + + public AuthorityException(Throwable throwable) { + super(throwable); + } + + public AuthorityException() { + + } +} diff --git a/face-common/src/main/java/com/dkha/common/exception/DkAuthorityException.java b/face-common/src/main/java/com/dkha/common/exception/DkAuthorityException.java new file mode 100644 index 0000000..694e0ca --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/exception/DkAuthorityException.java @@ -0,0 +1,27 @@ +package com.dkha.common.exception; + +/** + * @Author Spring + * @Since 2019/9/21 11:58 + * @Description 权限相关异常--主要用于权限拦截器 + * + */ + +public class DkAuthorityException extends RuntimeException { + + public DkAuthorityException(String s) { + super(s); + } + + public DkAuthorityException(String s, Throwable throwable) { + super(s, throwable); + } + + public DkAuthorityException(Throwable throwable) { + super(throwable); + } + + public DkAuthorityException() { + + } +} diff --git a/face-common/src/main/java/com/dkha/common/exception/DkException.java b/face-common/src/main/java/com/dkha/common/exception/DkException.java new file mode 100644 index 0000000..81e898c --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/exception/DkException.java @@ -0,0 +1,78 @@ +package com.dkha.common.exception; + + +import com.dkha.common.systemcode.SystemCode; + +/** + * @author Spring + * @date 2018/5/18-11:30 + * @Description: 自定义异常 + */ +public class DkException extends RuntimeException { + /** + * 异常码 + */ + private int code; + /** + * 异常信息 + */ + private String msg; + + public DkException() { + this.code = SystemCode.HANDLER_FAILED.code; + this.msg = SystemCode.HANDLER_FAILED.des; + } + + public DkException(int code) { + this.code = code; + this.msg = SystemCode.get(code).des; + } + public DkException(int code,String msg) { + this.code = code; + this.msg = msg; + } + public DkException(int code, Throwable e) { + super(e); + this.code = code; + this.msg = SystemCode.get(code).des; + } + + public DkException(String msg) { + super(msg); + this.code = SystemCode.HANDLER_FAILED.code; + this.msg = msg; + } + + public DkException(String msg, Throwable e) { + super(msg, e); + this.code = SystemCode.HANDLER_FAILED.code; + this.msg = msg; + } + public DkException(SystemCode systemCode) { + super(systemCode.des); + this.code = systemCode.code; + this.msg = systemCode.des; + } + + public DkException(Throwable e) { + super(e); + this.code = SystemCode.HANDLER_FAILED.code; + this.msg = SystemCode.HANDLER_FAILED.des; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } +} diff --git a/face-common/src/main/java/com/dkha/common/exception/EmployeeException.java b/face-common/src/main/java/com/dkha/common/exception/EmployeeException.java new file mode 100644 index 0000000..bca8a59 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/exception/EmployeeException.java @@ -0,0 +1,25 @@ +package com.dkha.common.exception; + +/** + * @author Spring + * @date 2018/5/18-11:30 + * @Description: 自定义异常 + */ +public class EmployeeException extends RuntimeException { + + public EmployeeException(String s) { + super(s); + } + + public EmployeeException(String s, Throwable throwable) { + super(s, throwable); + } + + public EmployeeException(Throwable throwable) { + super(throwable); + } + + public EmployeeException() { + + } +} diff --git a/face-common/src/main/java/com/dkha/common/fileupload/MinioUtil.java b/face-common/src/main/java/com/dkha/common/fileupload/MinioUtil.java new file mode 100644 index 0000000..adec556 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/fileupload/MinioUtil.java @@ -0,0 +1,391 @@ +package com.dkha.common.fileupload; + +import com.alibaba.fastjson.JSONObject; +import com.dkha.common.util.UtilValidate; +import io.minio.MinioClient; +import io.minio.ObjectStat; +import io.minio.Result; +import io.minio.messages.DeleteError; +import io.minio.messages.Item; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +/** + * @ClassName: + * @Description: (please write your description) + * @author: {开发人的姓名} + * @date: + * @Copyright: 成都电科惠安 + */ +@Component +public class MinioUtil { + + public static final Logger logger = LoggerFactory.getLogger(MinioUtil.class); + + @Value("${minio.url}") + private String url; + @Value("${minio.accessKey}") + private String accessKey; + + @Value("${minio.secretKey}") + private String secretKey; + + @Value("${minio.bucketName}") + private String bucketName; + + + /** + * @param inputStream + * @param suffix + * @return + * @throws Exception + * @Title: uploadImage + * @Description:上传图片 + */ + public JSONObject uploadImage(InputStream inputStream, String fileName, String suffix) throws Exception { + return upload(inputStream, fileName, suffix, "image/jpeg"); + } + + /** + * 上传图片 + * + * @param inputStream + * @param suffix + * @return + * @throws Exception + */ + public JSONObject uploadImage(InputStream inputStream, String suffix) throws Exception { + return upload(inputStream, null, suffix, "image/jpeg"); + } + + /** + * @param inputStream + * @param suffix + * @return + * @throws Exception + * @Title: uploadVideo + * @Description:上传视频 + */ + public JSONObject uploadVideo(InputStream inputStream, String fileName, String suffix) throws Exception { + return upload(inputStream, fileName, suffix, "video/mp4"); + } + + + /** + * @param inputStream + * @param suffix + * @return + * @throws Exception + * @Title: uploadVideo + * @Description:上传文件 + */ + public JSONObject uploadFile(InputStream inputStream, String fileName, String suffix) throws Exception { + return upload(inputStream, fileName, suffix, "application/octet-stream"); +// return upload(inputStream, fileName, suffix, "audio/mp3"); + } + + /** + * @param inputStream + * @param suffix + * @return + * @throws Exception + * @Title: uploadVideo + * @Description:上传文件 + */ + public JSONObject uploadFiles(InputStream inputStream, String folder,String fileName, String suffix) throws Exception { + return uploads(inputStream, folder,fileName, suffix, "application/octet-stream"); +// return upload(inputStream, fileName, suffix, "audio/mp3"); + } + /** + * 上传字符串大文本内容 + * + * @param str + * @return + * @throws Exception + * @Title: uploadString + * @Description:描述方法 + */ + public JSONObject uploadString(String str, String fileName) throws Exception { + if (!StringUtils.isEmpty(str)) { + return new JSONObject(); + } + InputStream inputStream = new ByteArrayInputStream(str.getBytes()); + return upload(inputStream, fileName, null, "text/html"); + } + + + /** + * @return + * @throws Exception + * @Title: upload + * @Description:上传主功能 + */ + private JSONObject upload(InputStream inputStream, String fileName, String suffix, String contentType) throws Exception { + JSONObject map = new JSONObject(); + MinioClient minioClient = new MinioClient(url, accessKey, secretKey); + // 检查存储桶是否已经存在 + boolean isExist = minioClient.bucketExists(bucketName); + if (isExist) { +// System.out.println("Bucket already exists."); + } else { + // 创建一个名为asiatrip的存储桶,用于存储文件。 + minioClient.makeBucket(bucketName); + } + + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + String ymd = sdf.format(new Date()); +// String objectName = ymd + "/" + fileName + "/" + UUID.randomUUID() + (suffix != null ? suffix : ""); + String objectName = ymd + "/" + (UtilValidate.isEmpty(fileName) ? getUniqueFileName() : fileName) + (suffix != null ? suffix : ""); + minioClient.putObject(bucketName, objectName, inputStream, contentType); + String url = minioClient.getObjectUrl(bucketName, objectName); + map.put("flag", "0"); + map.put("mess", "上传成功"); + map.put("url", url); + map.put("fullName", objectName); +// map.put("path", bucketName + "/" + objectName); + map.put("path", objectName); + return map; + } + /** + * @return + * @throws Exception + * @Title: upload + * @Description:上传主功能 + */ + private JSONObject uploads(InputStream inputStream,String folder, String fileName, String suffix, String contentType) throws Exception { + JSONObject map = new JSONObject(); + MinioClient minioClient = new MinioClient(url, accessKey, secretKey); + // 检查存储桶是否已经存在 + boolean isExist = minioClient.bucketExists(bucketName); + if (isExist) { +// System.out.println("Bucket already exists."); + } else { + // 创建一个名为asiatrip的存储桶,用于存储文件。 + minioClient.makeBucket(bucketName); + } + + String objectName = folder + "/" + (UtilValidate.isEmpty(fileName) ? getUniqueFileName() : fileName) + (suffix != null ? suffix : ""); + minioClient.putObject(bucketName, objectName, inputStream, contentType); + String url = minioClient.getObjectUrl(bucketName, objectName); + map.put("flag", "0"); + map.put("mess", "上传成功"); + map.put("url", url); + map.put("fullName", objectName); +// map.put("path", bucketName + "/" + objectName); + map.put("path", objectName); + return map; + } + /** + * 获取上传对象信息 + * + * @param bucketName + * @param objectName + * @return + * @throws Exception + */ + public ObjectStat objectStat(String bucketName, String objectName) throws Exception { + MinioClient minioClient = new MinioClient(url, accessKey, secretKey); + ObjectStat objectStat = minioClient.statObject(bucketName, objectName); + return objectStat; + } + + /** + * 删除多个 + * + * @param bucketName + * @param objectNames + * @return + * @throws Exception + */ + public JSONObject removeObjects(String bucketName, List objectNames) throws Exception { + JSONObject map = new JSONObject(); + MinioClient minioClient = new MinioClient(url, accessKey, secretKey); + for (Result errorResult : minioClient.removeObjects(bucketName, objectNames)) { + DeleteError error = errorResult.get(); + System.out.println("Failed to remove '" + error.objectName() + "'. Error:" + error.message()); + map.put("results", error); + } +// Iterable> results =minioClient.removeObjects(bucketName,objectNames); +// map.put("results",results); + return map; + } + + /** + * 删除文件 + * + * @param bucketName + * @param objectName + * @return + * @throws Exception + */ + public JSONObject removeObject(String bucketName, String objectName) throws Exception { + JSONObject map = new JSONObject(); + MinioClient minioClient = new MinioClient(url, accessKey, secretKey); + minioClient.removeObject(bucketName, objectName); + map.put("results", "ok"); + return map; + } + + /** + * 根据存储箱和前缀查询对象集合 + * + * @param bucketName + * @param prefix 文件对象前缀可以不传) + * @return + */ + public Iterable> listObjects(String bucketName, String prefix) { + Iterable> myObjects = new ArrayList<>(); + try { + MinioClient minioClient = new MinioClient(url, accessKey, secretKey); + // Check whether 'mybucket' exists or not. + boolean found = minioClient.bucketExists(bucketName); + if (found) { + //如果prefix为null或者‘’ + if ("".equals(prefix) || prefix == null) { + myObjects = minioClient.listObjects(bucketName); + } else { + //前缀查询 + myObjects = minioClient.listObjects(bucketName, prefix); + } + } else { + System.out.println("mybucket does not exist"); + } + } catch (Exception e) { + e.printStackTrace(); + System.out.println("Error occurred: " + e); + } + return myObjects; + } + + /** + * 根据桶和前缀输出里面所有的信息 + * + * @param bucketName + * @param prefix + */ + public void printObjectsMsg(String bucketName, String prefix) { + Iterable> results = listObjects(bucketName, prefix); + for (Result result : results) { + Item item = null; + try { + item = result.get(); + } catch (Exception e) { + e.printStackTrace(); + } + logger.info(item.lastModified() + ", " + item.size() + ", " + item.objectName()); + } + } + + /** + * 以流的形式下载文件 + * + * @param bucketName 桶名称 + * @param objectName 对象名称 + * @return + */ + public void downloadFile(String bucketName, String objectName, HttpServletResponse response,String fileName) { + try { + MinioClient minioClient = new MinioClient(url, accessKey, secretKey); + InputStream inputStream = minioClient.getObject(bucketName, objectName); + OutputStream os = response.getOutputStream(); + BufferedInputStream br = new BufferedInputStream(inputStream); + byte[] buf = new byte[1024]; + int len = 0; + response.reset(); + response.setContentType("application/octet-stream"); +// response.setHeader("Access-Control-Allow-Origin", "localhost:8001"); + response.setHeader("Content-Disposition", "attachment; filename=" + new String(fileName.getBytes("utf-8"), "ISO-8859-1")); + OutputStream out = response.getOutputStream(); + while ((len = br.read(buf)) > 0) { + out.write(buf, 0, len); + } + br.close(); + out.close(); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + + } + + /** + * 获取唯一文件名 + * + * @return + */ + public String getUniqueFileName() { + return UUID.randomUUID().toString().replaceAll("-", ""); + } + + /** + * 通过图片路径获取桶名称 + * + * @param fileUrl + * @return 桶名称 + */ + public String getBucketNameByUrl(String fileUrl) { + String[] splitArray = fileUrl.split("/"); + return splitArray[3]; + } + + + /** + * 通过图片路径获取对象名称/文件名称 + * + * @param fileUrl + * @return + */ + public String getObjectNameByUrl(String fileUrl) { + String[] splitArray = fileUrl.split(getBucketNameByUrl(fileUrl)); + String splitResult = splitArray[1].replaceFirst("/", ""); + //临时地址处理 + if (splitResult.contains("?")) { + String[] split = splitResult.split("\\?"); + return split[0]; + } + return splitResult; + } + + /** + * 获取文件名称 包括后缀 + * + * @param fileUrl + * @return + */ + public String getFileName(String fileUrl) { + String[] split = fileUrl.split("/"); + return split[split.length - 1]; + } + + /** + * 截取minio有效的url 将问号后面的所有内容去掉 + * + * @param minioUrl + * @return + */ + public String interceptValidUrl(String minioUrl) { + if (UtilValidate.isNotEmpty(minioUrl)) { + return minioUrl.substring(0, minioUrl.indexOf("?")); + } + return null; + } + + public static void main(String[] args) throws Exception { + System.out.println(UUID.randomUUID().toString().replaceAll("-", "")); + } + +} diff --git a/face-common/src/main/java/com/dkha/common/http/ConfigBean.java b/face-common/src/main/java/com/dkha/common/http/ConfigBean.java new file mode 100644 index 0000000..a87e9de --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/http/ConfigBean.java @@ -0,0 +1,25 @@ +package com.dkha.common.http; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: + * @Author: Spring + * @CreateDate: 2019/8/5 14:19 + */ +@Configuration +public class ConfigBean { + + /** + * @ConditionalOnMissingBean bean不存在的情况下才注入 + * @return + */ + @Bean + @ConditionalOnMissingBean + public RestTemplate getRestTemplate() { + return new RestTemplate(); + } +} diff --git a/face-common/src/main/java/com/dkha/common/http/HttpUtil.java b/face-common/src/main/java/com/dkha/common/http/HttpUtil.java new file mode 100644 index 0000000..e3d5910 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/http/HttpUtil.java @@ -0,0 +1,175 @@ +package com.dkha.common.http; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.dkha.common.modules.vo.face.ApiAlarmVO; +import com.dkha.common.util.UtilValidate; +import jdk.nashorn.internal.scripts.JS; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.*; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import javax.servlet.http.HttpServletRequest; +import java.io.BufferedReader; +import java.io.IOException; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + + +/** + * @Author Spring + * @Since 2019/10/31 18:21 + * @Description + */ +@Component +public class HttpUtil { + + public static final Logger logger = LoggerFactory.getLogger(HttpUtil.class); + + @Autowired + private RestTemplate restTemplate; + + /** + * post request + * @param url + * @param requestObj request params + * @param resultClass + * @param + * @return + */ + public T post(String url, Object requestObj, Class resultClass) { + T t = restTemplate.postForObject(url, this.getHeaders(requestObj), resultClass); +// logger.info("post result: {}", JSON.toJSONString(resultClass)); + return t; + } + + /** + * put request + * @param url + * @param requestObj + * @param resultClass + * @param + * @return + */ + public T put(String url, Object requestObj, Class resultClass) { + ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.PUT, this.getHeaders(requestObj), resultClass); +// logger.info("put result: {}", JSON.toJSONString(resultClass)); + return responseEntity.getBody(); + } + + /** + * get request + * @param url + * @param resultClass + * @param + * @return + */ + public T get(String url, Class resultClass) { + ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.GET, this.getHeaders(null), resultClass); + return responseEntity.getBody(); + } + public T get(String url, Object requestObj, Class resultClass) { + ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.GET, this.getHeaders(requestObj), resultClass); + return responseEntity.getBody(); + } + + public T delete(String url, Class resultClass) { + ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.DELETE, this.getHeaders(null), resultClass); + +// logger.info("delete result: {}", JSON.toJSONString(resultClass)); + return responseEntity.getBody(); + } + + /** + * 判断返回是否成功 + * @param resultObject + * @return + */ + public boolean isSuccess(Object resultObject) { + String resultJson = JSON.toJSONString(resultObject); + Map map = JSON.parseObject(resultJson, Map.class); + if (UtilValidate.isNotEmpty(map) && map.get("rtn").toString().equals("0")) { + return true; + } else { + return false; + } + } + + /**\ + * 获取POST请求参数 + * @param request + * @return + */ + public static String getPostRequestParam(HttpServletRequest request) throws IOException { + String bodyStr = getRequestPostBytes(request); + return new String(bodyStr.getBytes(), "UTF-8"); + } + + /** + * 描述:获取 post 请求的 byte[] 数组 + *
+     * 举例:
+     * 
+ * @param request + * @return + * @throws IOException + */ + public static String getRequestPostBytes(HttpServletRequest request) throws IOException { + + BufferedReader br = request.getReader(); + + String str; + String wholeStr = ""; + while((str = br.readLine()) != null){ + wholeStr += str; + } + return wholeStr.toString(); + } + + /** + * 获取HTTP请求头信息 + * @param request + * @return + */ + public static Map getRequestHeadMsg(HttpServletRequest request) { + Map requestHeaderMsgMap = new HashMap<>(); + Enumeration headerNames = request.getHeaderNames(); + while (headerNames.hasMoreElements()) { + String key = (String) headerNames.nextElement(); + String value = request.getHeader(key); + requestHeaderMsgMap.put(key, value); + } + return requestHeaderMsgMap; + } + + /** + * 请求头设置 + */ + private HttpEntity getHeaders(Object requestObject) { + HttpHeaders headers = new HttpHeaders(); + MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); + headers.setContentType(type); + headers.add("Accept", MediaType.APPLICATION_JSON.toString()); + //请求url不包含login,则需要设置请求头 + /*if (!(JSON.toJSONString(requestObject).contains("name") && JSON.toJSONString(requestObject).contains("password"))) { + headers.add("session_id", FaceSessionCache.get()); + }*/ + +// if (JSON.toJSONString(requestObject).contains("token") ) { +// try { +// ApiAlarmVO apiAlarmVO=(ApiAlarmVO)requestObject; +// headers.add("token",apiAlarmVO.getToken() ); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } + + + HttpEntity headerEntity = new HttpEntity<>(UtilValidate.isEmpty(requestObject) ? null : JSON.toJSONString(requestObject), headers); + return headerEntity; + } +} diff --git a/face-common/src/main/java/com/dkha/common/jwt/JwtConstantEnum.java b/face-common/src/main/java/com/dkha/common/jwt/JwtConstantEnum.java new file mode 100644 index 0000000..f7e9810 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/jwt/JwtConstantEnum.java @@ -0,0 +1,22 @@ +package com.dkha.common.jwt; + +/** + * @Author Spring + * @Since 2019/9/11 17:36 + * @Description + */ +public enum JwtConstantEnum { + + PLATFORM("platform", "platform"), + USER_ID("uerId", "userId"), + UUID("uuid", "uuid"); + + + public String code; + public String msg; + + JwtConstantEnum(String code, String msg) { + this.code = code; + this.msg = msg; + } +} diff --git a/face-common/src/main/java/com/dkha/common/jwt/JwtHelper.java b/face-common/src/main/java/com/dkha/common/jwt/JwtHelper.java new file mode 100644 index 0000000..96062f8 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/jwt/JwtHelper.java @@ -0,0 +1,97 @@ +package com.dkha.common.jwt; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.exceptions.TokenExpiredException; +import com.auth0.jwt.interfaces.Claim; +import com.auth0.jwt.interfaces.DecodedJWT; +import com.dkha.common.exception.AuthorityException; +import com.dkha.common.exception.EmployeeException; +import com.dkha.common.systemcode.SystemCode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.Map; + +/** + * 后端主要实现用户的验证、token的签发、从http中解析出token串、token的验证、token的刷新等 + * 在本类中并未全部实现,有待完善 + * @Author: Spring + * Created on 2018/4/23. + */ +public class JwtHelper { + + private static final Logger logger = LoggerFactory.getLogger(JwtHelper.class); + + /** + * 用于HS256 hash加密算法,也可采用非对称的RS256公私钥加密 https://www.cnblogs.com/hehheai/p/6513871.html + */ + private static final String secret = "dk_employment_2019.10.12"; + + /** + * JWT生成方法,采用id和expiresTime,除保留字段,用户可自定义其余字段 + * 以下为保留字段 + * + * iss(Issuser):如果签发的时候这个claim的值是“a.com”,验证的时候如果这个claim的值不是“a.com”就属于验证失败; + * sub(Subject):如果签发的时候这个claim的值是“liuyunzhuge”,验证的时候如果这个claim的值不是“liuyunzhuge”就属于验证失败; + * aud(Audience):如果签发的时候这个claim的值是“['b.com','c.com']”,验证的时候这个claim的值至少要包含b.com,c.com的其中一个才能验证通过; + * exp(Expiration time):如果验证的时候超过了这个claim指定的时间,就属于验证失败; + * nbf(Not Before):如果验证的时候小于这个claim指定的时间,就属于验证失败; + * iat(Issued at):它可以用来做一些maxAge之类的验证,假如验证时间与这个claim指定的时间相差的时间大于通过maxAge指定的一个值,就属于验证失败; + * jti(JWT ID):如果签发的时候这个claim的值是“1”,验证的时候如果这个claim的值不是“1”就属于验证失败 + * + * @return + */ + public static String generateJWT(String platform, String userId, String uuid) { + + /**设置JWT头部信息*/ + Map headerMap = new HashMap(2); + headerMap.put("typ", "JWT"); + headerMap.put("alg", "HS256"); + String token = null; + try { + token = JWT.create().withHeader(headerMap) + .withClaim(JwtConstantEnum.PLATFORM.code, platform) + .withClaim(JwtConstantEnum.USER_ID.code, userId) + .withClaim(JwtConstantEnum.UUID.code, uuid) + .sign(Algorithm.HMAC256(secret)); + } catch (UnsupportedEncodingException e) { + logger.error(e.getMessage(), e); + throw new EmployeeException(e); + } + return token; + } + + + /** + * 验证JWT 该验证只能验证JWT保留字段,具体自定义验证需自定义完成 + * 具体的错误类型可以通过设置求参数通过下面的main函数验证 + * @param token + * @return + */ + public static Map verifyToken(String token) { + DecodedJWT jwt = null; + try { + JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret)).build(); + jwt = verifier.verify(token); + return jwt.getClaims(); + } catch (UnsupportedEncodingException e) { + logger.error(e.getMessage(), e); + throw new AuthorityException(SystemCode.TOKEN_ERROR.code.toString()); + } catch (TokenExpiredException e) { + logger.error(e.getMessage(), e); + throw new AuthorityException(SystemCode.TOKEN_EXPIRED.code.toString()); + } catch (Exception e) { + logger.error(e.getMessage(), e); + throw new AuthorityException(SystemCode.TOKEN_ERROR.code.toString()); + } + } + + public static void main(String[] args) { + //JwtHelper.verifyToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIn0.kEZueQ8xZ_FKvlOxfC01bTaW3EqUGV9HJKKeeor6XQ1"); + } + +} diff --git a/face-common/src/main/java/com/dkha/common/kaptcha/KaptchaConfig.java b/face-common/src/main/java/com/dkha/common/kaptcha/KaptchaConfig.java new file mode 100644 index 0000000..6d86986 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/kaptcha/KaptchaConfig.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.common.kaptcha; + +import com.google.code.kaptcha.impl.DefaultKaptcha; +import com.google.code.kaptcha.util.Config; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Properties; + + +/** + * 生成验证码配置 + * + * @author Mark sunlightcs@gmail.com + */ +@Configuration +public class KaptchaConfig { + + @Bean + public DefaultKaptcha producer() { + Properties properties = new Properties(); + properties.put("kaptcha.border", "no"); + properties.put("kaptcha.textproducer.font.color", "black"); + properties.put("kaptcha.textproducer.font.names", "Arial,Courier,cmr10,宋体,楷体,微软雅黑"); + properties.put("kaptcha.textproducer.char.space", "5"); + Config config = new Config(properties); + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/ApiVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/ApiVO.java new file mode 100644 index 0000000..a25f0a1 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/ApiVO.java @@ -0,0 +1,34 @@ +package com.dkha.common.modules.vo; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ApiVO + * @Package com.dkha.common.entity.vo + * @author: panhui + * @date: 2019/11/27 9:36 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="通用接口参数类 发送和接收通用", description="用于和底层传输统一参数格式") +public class ApiVO { + @ApiModelProperty(value = "错误码") + private Integer code; + @ApiModelProperty(value = "错误提示") + private String message; + @ApiModelProperty(value = "操作命令对应不同的接口") + private String cmd; + @ApiModelProperty(value = "请求参数") + private Object data; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/ReturnVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/ReturnVO.java new file mode 100644 index 0000000..1f70d49 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/ReturnVO.java @@ -0,0 +1,150 @@ +package com.dkha.common.modules.vo; + + +import com.dkha.common.enums.ErrEnum; +import com.dkha.common.exception.DkException; +import com.dkha.common.util.UtilValidate; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.BindingResult; + +import java.io.Serializable; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ReturnVO + * @Package com.dkha.api.modules + * @author: panhui + * @date: 2019/12/2 13:34 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="API通用返回", description="Api通用返回結構類") +public class ReturnVO implements Serializable { + + private Integer code; + private String message; + private Object data; + private static final long serialVersionUID = 1L; + + + public ReturnVO(Object data, Integer code, String message) { + this.code = code; + this.data = data; + this.message = message; + } + + public ReturnVO(Integer code, String message) { + this.code = code; + this.data = null; + this.message = message; + } + + /** + * 操作成功返回集 code为200 + */ + public ReturnVO successResult(Object data) { + ReturnVO ReturnVO = new ReturnVO(); + ReturnVO.code = ErrEnum.OK.getCode(); + ReturnVO.data = data; + ReturnVO.message = ErrEnum.OK.getMsg(); + return ReturnVO; + } + + /** + * 操作成功返回集 code为200 + * @param message + * @param data + */ + public ReturnVO successResult(String message, Object data) { + ReturnVO ReturnVO = new ReturnVO(); + ReturnVO.code = ErrEnum.OK.getCode(); + ReturnVO.data = data; + ReturnVO.message = UtilValidate.isEmpty(message) ? ErrEnum.OK.getMsg() : message; + return ReturnVO; + } + + /** + * 操作失败返回集 默认code 500 + * @param message + * @return + */ + public ReturnVO failResult(String message) { + ReturnVO ReturnVO = new ReturnVO(); + ReturnVO.code = ErrEnum.ERROR.getCode(); + ReturnVO.data = null; + ReturnVO.message = message; + return ReturnVO; + } + + /** + * 参数不正确 默认code + * @param message + * @return + */ + public ReturnVO paramErrorResult(String message) { + ReturnVO ReturnVO = new ReturnVO(); + ReturnVO.code = ErrEnum.BAD_REQUEST.getCode(); + ReturnVO.data = null; + ReturnVO.message = (UtilValidate.isEmpty(message)? ErrEnum.BAD_REQUEST.getMsg():message); + return ReturnVO; + } + + /** + * 没有查询到数据 默认code + * @param message + * @return + */ + public ReturnVO notInfoResult(String message) { + ReturnVO ReturnVO = new ReturnVO(); + ReturnVO.code = ErrEnum.NOT_FOUND.getCode(); + ReturnVO.data = null; + ReturnVO.message = (UtilValidate.isEmpty(message)? ErrEnum.NOT_FOUND.getMsg():message); + return ReturnVO; + } + + /** + * 操作失败返回集 + * @param + * @return + */ + public ReturnVO fail() { + ReturnVO ReturnVO = new ReturnVO(); + ReturnVO.code = ErrEnum.ERROR.getCode(); + ReturnVO.data = null; + ReturnVO.message = ErrEnum.ERROR.getMsg(); + return ReturnVO; + } + + /** + * 操作失败返回集 + * @param data + * @param message + * @param code + */ + public ReturnVO failResult(Integer code, String message, Object data) { + ReturnVO ReturnVO = new ReturnVO(); + ReturnVO.code = UtilValidate.isEmpty(code) ? ErrEnum.ERROR.getCode() : code; + ReturnVO.data = data; + ReturnVO.message = UtilValidate.isEmpty(message) ? ErrEnum.ERROR.getMsg() : message; + return ReturnVO; + } + + /** + * 用于Hibernate-validate vo校验 + * @param bindingResult + */ + public void validate(BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new DkException(bindingResult.getFieldError().getDefaultMessage()); + } + } +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/camera/AssociationPeopleVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/camera/AssociationPeopleVO.java new file mode 100644 index 0000000..6d6c7e5 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/camera/AssociationPeopleVO.java @@ -0,0 +1,32 @@ +package com.dkha.common.modules.vo.camera; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: AssociationPeopleVO + * @Package com.dkha.common.modules.vo.camera + * @author: panhui + * @date: 2020/1/9 17:57 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="人脸特征id关联的预警信息", description="人脸特征id关联的预警信息") +public class AssociationPeopleVO { + @ApiModelProperty(value = "特征id") + private String featId; + @ApiModelProperty(value = "预警信息") + private List armIds; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/camera/BayOnetCameraVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/camera/BayOnetCameraVO.java new file mode 100644 index 0000000..6c11502 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/camera/BayOnetCameraVO.java @@ -0,0 +1,48 @@ +package com.dkha.common.modules.vo.camera; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.tomcat.jni.Library; + +import java.util.List; +import java.util.Map; + +/** + * @version V1.0 + * @Description: TODO(人物轨迹中redis存储单个摄像头分组信息) + * All rights 成都电科慧安 + * @Title: BayOnetCameraVO + * @Package com.dkha.common.modules.vo.camera + * @author: panhui + * @date: 2020/1/9 17:38 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="人物轨迹数据", description="人物轨迹中redis存储单个摄像头分组信息") +public class BayOnetCameraVO { + + @ApiModelProperty(value = "摄像头id") + private String cameraId; + + @ApiModelProperty(value = "关联库id") + private String associationLibraryId; + +// @ApiModelProperty(value = "关联的人物数据") +// private PeopleVO peopleVO; + + @ApiModelProperty(value = "处理抓拍条数") + public Long warningNum = 0L; + + @ApiModelProperty(value = "关于人脸的featids") + private List featIds; +// @ApiModelProperty(value = "关联任务信息预警的id,人脸特征id-》不同的预警id信息") +// private List associationPeople; + +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/camera/CameraInfoVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/camera/CameraInfoVO.java new file mode 100644 index 0000000..d28cdcd --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/camera/CameraInfoVO.java @@ -0,0 +1,27 @@ +package com.dkha.common.modules.vo.camera; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: CameraInfoVO + * @Package com.dkha.task.modual.vo.track + * @author: panhui + * @date: 2020/1/8 18:05 + * @Copyright: 成都电科慧安 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +public class CameraInfoVO { + + private String idFaceCamera; + private String cameraName; + private String cameraLongitude; + private String cameraLatitude; + private String status; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/camera/PeopleComparableVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/camera/PeopleComparableVO.java new file mode 100644 index 0000000..b7e5d1c --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/camera/PeopleComparableVO.java @@ -0,0 +1,44 @@ +package com.dkha.common.modules.vo.camera; + +import com.dkha.common.modules.vo.face.FeatureVO; +import com.dkha.common.modules.vo.position.PositionVO; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: PeopleComparableVO + * @Package com.dkha.common.modules.vo.camera + * @author: panhui + * @date: 2020/1/14 16:20 + * @Copyright: 成都电科慧安 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +public class PeopleComparableVO implements Comparable{ + + private String cameraId; + private CameraInfoVO cameraInfoVO; + private String esId; + private String faceUrl; + private String bgUrl; + private PositionVO position; + private Long timestamp; + private String time; + private Double score; + private FeatureVO featureVO; + private String faceId; + + @Override + public int compareTo(PeopleComparableVO peopleComparableVO) { + if(this.timestamp.intValue()!=peopleComparableVO.getTimestamp().intValue()) + { + return (this.timestamp.intValue()-peopleComparableVO.getTimestamp().intValue()); + } + return 0; + } +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/camera/PeopleVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/camera/PeopleVO.java new file mode 100644 index 0000000..45bf682 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/camera/PeopleVO.java @@ -0,0 +1,35 @@ +package com.dkha.common.modules.vo.camera; + +import com.dkha.common.modules.vo.face.FeatureVO; +import com.dkha.common.modules.vo.position.PositionVO; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @version V1.0 + * @Description: TODO(绑定轨迹中需要的人脸数据) + * All rights 成都电科慧安 + * @Title: PeopleVO + * @Package com.dkha.task.modual.vo.track + * @author: panhui + * @date: 2020/1/10 11:36 + * @Copyright: 成都电科慧安 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +public class PeopleVO implements Serializable { + private String esId; + private String faceUrl; + private String cameraId; + private String bgUrl; + private PositionVO position; + private Long timestamp; + private String time; + private Double score; + private FeatureVO featureVO; + private String faceId; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/control/ControlTaskVedioVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/control/ControlTaskVedioVO.java new file mode 100644 index 0000000..085c355 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/control/ControlTaskVedioVO.java @@ -0,0 +1,42 @@ +package com.dkha.common.modules.vo.control; + +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.util.List; + +/** + *

+ * 布控表 + *

+ * + * @author Spring + * @since 2019-11-20 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) + +public class ControlTaskVedioVO{ + + private static final long serialVersionUID = 1L; + private String idControlTask; + @ApiModelProperty(value = "布控阈值") + private Double threshold; + @ApiModelProperty(value = "布控名称") + private String name; + @TableField(exist = false) + @ApiModelProperty(value = "url") + private String url; + + @TableField(exist = false) + @ApiModelProperty(value = "库id") + private List libraryId; + + @ApiModelProperty(value = "任务id") + private String taskId; + +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/control/ControlVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/control/ControlVO.java new file mode 100644 index 0000000..bdc54fb --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/control/ControlVO.java @@ -0,0 +1,43 @@ +package com.dkha.common.modules.vo.control; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ControlVO + * @Package com.dkha.common.entity.vo.control + * @author: panhui + * @date: 2019/11/27 10:55 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value = "布控-新增/删除", description = "用于布控和底层传输统一参数格式") +public class ControlVO { + @ApiModelProperty(value = "任务id") + private String taskId_cameraId; + @ApiModelProperty(value = "任务地址根据下面类型来传递不同的地址比如:rtsp和http") + private String vdUrl; + @ApiModelProperty(value = "任务类型VdUrlRtsp rtsp流类型url VdUrlGb28181 gb28181流类型url VdUrlHttp http视频文件类型url") + private String vdType; + @ApiModelProperty(value = "库列表id") + private List libIds; + @ApiModelProperty(value = "最小分值,取值范围0.00~1.00") + private Double minScore; + @ApiModelProperty(value = "每个库最大返回结果数, 0~100") + private Double maxRetNb; + + @ApiModelProperty(value = "删除任务列表") + private List taskIdCameraIds; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/control/TaskControlVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/control/TaskControlVO.java new file mode 100644 index 0000000..6df71ac --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/control/TaskControlVO.java @@ -0,0 +1,84 @@ +package com.dkha.common.modules.vo.control; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.hibernate.validator.constraints.Length; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * @version V1.0 + * @Description: 应用层布控任务VO + * @Title: + * @author: huangyugang + * @date: 2019/12/10 9:14 + * @Copyright: 成都电科慧安 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ApiModel(value="ControlTask对象", description="布控任务") +public class TaskControlVO implements Serializable { + + @ApiModelProperty(value = "任务ID") + private Long idControlTask; + @ApiModelProperty(value = "布控对象(id 人像库id 或者上传图片id)") + private String controlObject; + + @ApiModelProperty(value = "任务名称") + @NotNull + @Length(min=3,message = "任务名称最小长度不能小于3") + private String taskName; + + @ApiModelProperty(value = "处置类型-码值 抓捕类1,监控类2,提示类0 默认选择0") + @NotNull(message = "处置类型不能为空") + private String disposalType; + + @ApiModelProperty(value = "布控类型-码值 长期布控 0,临时布控 1 默认选择0 ") + @NotNull(message = "布控类型不能为空") + private String controlType; + + @ApiModelProperty(value = "布控开始时间") + @DateTimeFormat(pattern = "yyy-MM-dd HH:mm") + private Date controlStartTime; + + @ApiModelProperty(value = "布控结束时间") + @DateTimeFormat(pattern = "yyy-MM-dd HH:mm") + private Date controlEndTime; + + @ApiModelProperty(value = "布控区域") + // @NotNull(message = "布控区域不能为空") + private String controlRegion; + + @ApiModelProperty(value = "布控阈值") + @NotNull(message = "布控阀值不能为空必须是0-1之间") + @Max(value = 1,message = "布控阈值 最大值为1") + @Min(value = 0,message = "布控阈值 最小值为0") + private Double controlThreshold; + + @ApiModelProperty(value = "布控对象库ID列表") + @NotNull + @Size(min = 1) + private List libIds; + + @ApiModelProperty(value = "布控的摄像头ID列表") + @NotNull + @Size(min = 1) + private List listcamera; + + @ApiModelProperty(value = "备注信息") + private String remarks; + + @ApiModelProperty(value = "上传图片布控的url") + private String imgurl; + + +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/control/VideoControlVo.java b/face-common/src/main/java/com/dkha/common/modules/vo/control/VideoControlVo.java new file mode 100644 index 0000000..8a9c518 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/control/VideoControlVo.java @@ -0,0 +1,48 @@ +package com.dkha.common.modules.vo.control; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * @version V1.0 + * @Description: + * @Title: + * @author: huangyugang + * @date: 2019/12/11 15:21 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value = "视频比对布控", description = "用于布控和底层传输统一参数格式") +public class VideoControlVo { + @ApiModelProperty(value = "任务名称") + private String taskName; + + @ApiModelProperty(value = "布控阈值") + @NotNull(message = "布控阀值不能为空必须是0-1之间") + @Max(value = 1,message = "布控阈值 最大值为1") + @Min(value = 0,message = "布控阈值 最小值为0") + private Double controlThreshold; + + @ApiModelProperty(value = "布控对象库ID列表") + @NotNull + @Size(min = 1) + private List libIds; + + @ApiModelProperty(value = "布控视频URL地址") + @NotNull + private String videourl; + +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/cut/CutVo.java b/face-common/src/main/java/com/dkha/common/modules/vo/cut/CutVo.java new file mode 100644 index 0000000..6ee2007 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/cut/CutVo.java @@ -0,0 +1,24 @@ +package com.dkha.common.modules.vo.cut; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @Author Spring + * @Since 2019/12/13 16:43 + * @Description 裁剪图片 + */ +@Data +public class CutVo { + + @ApiModelProperty(value = "图片路径") + private String url; + @ApiModelProperty(value = "坐标 x") + private Integer x; + @ApiModelProperty(value = "坐标 y") + private Integer y; + @ApiModelProperty(value = "坐标 w") + private Integer w; + @ApiModelProperty(value = "坐标 h") + private Integer h; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/dto/FaceLibraryVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/dto/FaceLibraryVO.java new file mode 100644 index 0000000..caceb87 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/dto/FaceLibraryVO.java @@ -0,0 +1,39 @@ +package com.dkha.common.modules.vo.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: FaceLibraryVO + * @Package com.dkha.api.modules.vo + * @author: yangjun + * @date: 2019/12/3 15:13 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="特征库", description="特征库信息") +public class FaceLibraryVO { + @ApiModelProperty(value="库id") + private String libraryId; + @ApiModelProperty(value="库名称") + private String name; + @ApiModelProperty(value="库类型") + private String type; + @ApiModelProperty(value="额外信息") + private String extraMeta; + + @ApiModelProperty(value = "创建时间") + private Date createTime; +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/dto/ImageListVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/dto/ImageListVO.java new file mode 100644 index 0000000..30dfb57 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/dto/ImageListVO.java @@ -0,0 +1,35 @@ +package com.dkha.common.modules.vo.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ImagesVO + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/12/3 15:14 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value = "批量图片入库接口", description = "用于图片入库接口") +public class ImageListVO { + @ApiModelProperty(value = "目标库id") + @NotNull(message = "目标库id不能为空") + private String libraryId; + + @ApiModelProperty(value = "人脸相关信息") + private List faces; +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/dto/ImageVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/dto/ImageVO.java new file mode 100644 index 0000000..ff4f5a0 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/dto/ImageVO.java @@ -0,0 +1,50 @@ +package com.dkha.common.modules.vo.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ImagesVO + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/12/3 15:14 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value = "用于图片入库接口", description = "用于图片入库接口") +public class ImageVO { + + @ApiModelProperty(value = "需要入库的人脸地址") + @NotBlank(message = "人脸图片地址不能为空") + private String url; + + @ApiModelProperty(value = "身份证id可空") + private String idCard; + + @ApiModelProperty(value = "性别可空") + private String gender; + + @ApiModelProperty(value = "姓名") + private String name; + + @ApiModelProperty(value = "名族") + private String nation; + + @ApiModelProperty(value = "特征信息") + private String feature; + + @ApiModelProperty(value = "额外信息") + private String extraMeta; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/AlarmReturnVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/AlarmReturnVO.java new file mode 100644 index 0000000..edde3a7 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/AlarmReturnVO.java @@ -0,0 +1,72 @@ +package com.dkha.common.modules.vo.face; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: TODO(预警报警返回接口) + * All rights 成都电科慧安 + * @Title: AlarmReturnVO + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/12/2 11:16 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="预警报警接口返回给业务层的数据", description="预警报警接口返回给业务层的数据") +public class AlarmReturnVO { + + + @ApiModelProperty(value = "任务id") + private String taskId; + + @ApiModelProperty(value = "摄像头id") + private String cameraId; + + @ApiModelProperty(value = "摄像头名称") + private String cameraName; + + @ApiModelProperty(value = "任务名称") + private String taskName; + + + @ApiModelProperty(value = "任务处置类型") + private String taskType; + + @ApiModelProperty(value = "背景图片") + private String faceBgUrl; + @ApiModelProperty(value = "背景高度") + private Integer bgHeight; + @ApiModelProperty(value = "背景宽度") + private Integer bgWidth; + + @ApiModelProperty(value = "报警唯一id") + private String alarmId; + + @ApiModelProperty(value="抓拍时间") + private Long timestamp; + + @ApiModelProperty(value="抓拍时间") + private String date; + + + @ApiModelProperty(value = "人脸比中信息") + private List faces; + + @ApiModelProperty(value = "今日数量") + private long toDaySnapShot; + @ApiModelProperty(value = "总数") + private long totalSnapShot; + + +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiAlarmVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiAlarmVO.java new file mode 100644 index 0000000..3bbf840 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiAlarmVO.java @@ -0,0 +1,50 @@ +package com.dkha.common.modules.vo.face; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ApiAlarmVO + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/11/29 16:00 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="预警任务参数", description="业务层调用返回的数据") +public class ApiAlarmVO { + + + @ApiModelProperty(value="任务id") + private String taskId; + + @ApiModelProperty(value="任务id列表") + private List taskIds; + + @ApiModelProperty(value = "摄像头列表") + private List cameraIds; + + @ApiModelProperty(value = "查询参数筛选") + private PageVO page; + + @ApiModelProperty(value = "摄像头id仅用于卡口类型业务") + private String cameraId; + + @ApiModelProperty(value = "任务类别:0 报警任务,1是视频任务") + private Integer taskType; + + @ApiModelProperty(value = "任务类别:0 报警任务,1是视频任务") + private String token; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceOneSearchFaceVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceOneSearchFaceVO.java new file mode 100644 index 0000000..ba096bb --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceOneSearchFaceVO.java @@ -0,0 +1,29 @@ +package com.dkha.common.modules.vo.face; + + +import com.dkha.common.modules.vo.position.PositionVO; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ApiFaceOneSearchFaceVO + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/12/9 11:38 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value = "人脸库1:1比对返回", description = "人脸检索") +public class ApiFaceOneSearchFaceVO { + private PositionVO faceRect; + private String url; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceOneSearchReturnFaceVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceOneSearchReturnFaceVO.java new file mode 100644 index 0000000..86e245a --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceOneSearchReturnFaceVO.java @@ -0,0 +1,32 @@ +package com.dkha.common.modules.vo.face; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ApiFaceOneSearchReturnFaceVO + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/12/9 11:42 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value = "人脸库1:1比对返回", description = "人脸检索") +public class ApiFaceOneSearchReturnFaceVO { + + private Double hitSimilarity; + private List faces; + + private String extraMeta; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearGroupReturnVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearGroupReturnVO.java new file mode 100644 index 0000000..8cf3835 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearGroupReturnVO.java @@ -0,0 +1,30 @@ +package com.dkha.common.modules.vo.face; + + +import com.dkha.common.modules.vo.position.PositionVO; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ApiFaceSearGroupReturnVO + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/12/9 13:00 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value = "人脸分组检索返回数据", description = "人脸分组检索返回数据") +public class ApiFaceSearGroupReturnVO { + private PositionVO faceRect; + private String url;//背景图片 + private double hitSimilarity;//命中的相似度 +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearchFaceVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearchFaceVO.java new file mode 100644 index 0000000..caa7246 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearchFaceVO.java @@ -0,0 +1,32 @@ +package com.dkha.common.modules.vo.face; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ApiFaceSearchFaceVo + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/12/9 15:03 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value = "人脸库检索faces返回", description = "人脸检索") +public class ApiFaceSearchFaceVO { + @ApiModelProperty(value = "比中分数") + private Double hitSimilarity; + @ApiModelProperty(value = "比中人脸的人脸id") + private String faceId; + @ApiModelProperty(value = "人脸库id") + private String libraryId; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearchFacesVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearchFacesVO.java new file mode 100644 index 0000000..15d047a --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearchFacesVO.java @@ -0,0 +1,35 @@ +package com.dkha.common.modules.vo.face; + + +import com.dkha.common.modules.vo.position.PositionVO; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ApiFaceSearchFacesVO + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/12/9 10:32 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value = "人脸库检索faces返回", description = "人脸检索") +public class ApiFaceSearchFacesVO { + + private String url; + private PositionVO faceRect; + @ApiModelProperty(value = "当前库检索结果") + private List faceList; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearchReturnVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearchReturnVO.java new file mode 100644 index 0000000..ba4c5c5 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearchReturnVO.java @@ -0,0 +1,30 @@ +package com.dkha.common.modules.vo.face; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ApiFaceSearchReturnVO + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/12/6 18:34 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value = "人脸库检索返回", description = "人脸检索") +public class ApiFaceSearchReturnVO { + private List faces; + private PageVO pageVO; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearchVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearchVO.java new file mode 100644 index 0000000..6159b2e --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceSearchVO.java @@ -0,0 +1,36 @@ +package com.dkha.common.modules.vo.face; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ApiFaceSearcVO + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/12/6 18:28 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="人脸检索类", description="人脸检索类") +public class ApiFaceSearchVO { + @ApiModelProperty(value = "人脸url列表") + private String url; + @ApiModelProperty(value = "人脸库列表") + private List libraryIds; + @ApiModelProperty(value = "每个库最大返回结果数, 0~100") + private Double minScore; + @ApiModelProperty(value = "分页数据") + private PageVO pageVO; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceVO.java new file mode 100644 index 0000000..0b85bc6 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiFaceVO.java @@ -0,0 +1,40 @@ +package com.dkha.common.modules.vo.face; + + +import com.dkha.common.modules.vo.position.PositionVO; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: TODO(用于接口返回实体) + * All rights 成都电科慧安 + * @Title: FaceVO + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/12/2 14:11 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +//@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="预警报警组装给业务层的数据实体类", description="预警报警组装给业务层的数据实体类") +public class ApiFaceVO { + + @ApiModelProperty(value="人脸坐标") + private PositionVO faceRect; + + @ApiModelProperty(value="人脸比中信息") + private List compare; + + @ApiModelProperty(value="特征") + private FeatureVO feature; + +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiSearchFaceRectVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiSearchFaceRectVO.java new file mode 100644 index 0000000..6695be4 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/ApiSearchFaceRectVO.java @@ -0,0 +1,29 @@ +package com.dkha.common.modules.vo.face; + + +import com.dkha.common.modules.vo.position.PositionVO; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ApiSearchFaceRectVo + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/12/9 12:36 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="人脸检测返回人脸信息", description="人脸检测返回人脸信息") +public class ApiSearchFaceRectVO { + private PositionVO faceRect; + private String url; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/ComparisonVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/ComparisonVO.java new file mode 100644 index 0000000..be45f2d --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/ComparisonVO.java @@ -0,0 +1,34 @@ +package com.dkha.common.modules.vo.face; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ComparisonVO + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/12/2 14:42 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +//@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="比中人脸信息", description="比中人脸信息") +public class ComparisonVO { + @ApiModelProperty(value="比中库id") + private String libraryId; + + @ApiModelProperty(value="比中库中的人脸id") + private String comparisonFaceId; + + @ApiModelProperty(value="比中分值") + private Double hitSimilarity; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/ControlTaskVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/ControlTaskVO.java new file mode 100644 index 0000000..8b871f1 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/ControlTaskVO.java @@ -0,0 +1,46 @@ +package com.dkha.common.modules.vo.face; + +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.util.List; + +/** + *

+ * 布控表 + *

+ * + * @author Spring + * @since 2019-11-20 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) + +public class ControlTaskVO extends GovShortBaseEntity{ + + private static final long serialVersionUID = 1L; + private String idControlTask; + @ApiModelProperty(value = "布控阈值") + private Double threshold; + @ApiModelProperty(value = "布控名称") + private String name; + + @ApiModelProperty(value = "额外信息") + private String extraMeta; + + @TableField(exist = false) + @ApiModelProperty(value = "摄像头id") + private List cameraId; + + @TableField(exist = false) + @ApiModelProperty(value = "库id") + private List libraryId; + + @ApiModelProperty(value = "任务id") + private String taskId; + +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/EsReturnVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/EsReturnVO.java new file mode 100644 index 0000000..15d17b8 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/EsReturnVO.java @@ -0,0 +1,34 @@ +package com.dkha.common.modules.vo.face; + + +import com.dkha.common.modules.vo.warning.WarningVO; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ESReturnVO + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/11/29 18:30 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="查询es返回数据的实体类", description="业务层调用返回的数据") +public class EsReturnVO { + + @ApiModelProperty(value="警报数据") + private WarningVO content; + + @ApiModelProperty(value="总数") + private Long totalElements; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/FaceBayonetVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/FaceBayonetVO.java new file mode 100644 index 0000000..85411d5 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/FaceBayonetVO.java @@ -0,0 +1,46 @@ +package com.dkha.common.modules.vo.face; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: FaceBayonetVO + * @Package com.dkha.api.modules.vo + * @author: yangjun + * @date: 2019/12/5 17:57 + * @Copyright: 成都电科慧安 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value="FaceBayonet对象", description="摄像头表") +public class FaceBayonetVO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + private String carmeraId; + + @ApiModelProperty(value = "摄像头名称") + private String name; + + @ApiModelProperty(value = "摄像头地址") + private String url; + + @ApiModelProperty(value = "摄像头类型") + private String type; + + @ApiModelProperty(value = "额外信息") + private String extraMeta; + + @ApiModelProperty(value = "创建时间") + private Date createTime; +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/FaceLibraryVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/FaceLibraryVO.java new file mode 100644 index 0000000..b02af9a --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/FaceLibraryVO.java @@ -0,0 +1,39 @@ +package com.dkha.common.modules.vo.face; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: FaceLibraryVO + * @Package com.dkha.api.modules.vo + * @author: yangjun + * @date: 2019/12/3 15:13 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="特征库", description="特征库信息") +public class FaceLibraryVO { + @ApiModelProperty(value="库id") + private String libraryId; + @ApiModelProperty(value="库名称") + private String name; + @ApiModelProperty(value="库类型") + private String type; + @ApiModelProperty(value="额外信息") + private String extraMeta; + + @ApiModelProperty(value = "创建时间") + private Date createTime; +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/FaceTrackVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/FaceTrackVO.java new file mode 100644 index 0000000..564a4f3 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/FaceTrackVO.java @@ -0,0 +1,46 @@ +package com.dkha.common.modules.vo.face; + + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + * + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 2020-01-10 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class FaceTrackVO implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 图片url + */ + private String url; + /** + * 人像id + */ + private String faceId; + /** + * 摄像头id + */ + private Long idFaceCamera; + /** + * 库id + */ + private String startTime; + /** + * 人物数据 + */ + private String endTime; + + /** + * 轨迹判定阈值 + */ + private Double trajectoryThreshold; +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/FeatureVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/FeatureVO.java new file mode 100644 index 0000000..e7d30b5 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/FeatureVO.java @@ -0,0 +1,31 @@ +package com.dkha.common.modules.vo.face; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: FeatureVO + * @Package com.dkha.common.entity.vo.position + * @author: panhui + * @date: 2019/12/13 14:42 + * @Copyright: 成都电科慧安 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="特征类", description="人脸特征类") +public class FeatureVO { + + @ApiModelProperty(value = "人脸检查后年龄") + private Integer age; + @ApiModelProperty(value = "人脸检查后性别") + private String gender ; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/GovShortBaseEntity.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/GovShortBaseEntity.java new file mode 100644 index 0000000..bf99bff --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/GovShortBaseEntity.java @@ -0,0 +1,44 @@ +package com.dkha.common.modules.vo.face; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * @ClassName: + * @Description:(please write your description) + * @author: {yangjun} + * @date: + * @Copyright: 成都电科惠安 + */ +@Data +public class GovShortBaseEntity implements Serializable { + private static final long serialVersionUID = 1L; + + @TableField(fill = FieldFill.INSERT) + @ApiModelProperty(value = "是否有效 Y有效 N无效 作逻辑删除使用") + private String isValid; + + @TableField(fill = FieldFill.INSERT) + @ApiModelProperty(value = "创建人") + private String createBy; + + @TableField(fill = FieldFill.INSERT_UPDATE) + @ApiModelProperty(value = "更新人") + private String updateBy; + + @TableField(fill = FieldFill.INSERT) + @ApiModelProperty(value = "创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + @TableField(fill = FieldFill.INSERT_UPDATE) + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "更新时间") + private Date updateTime; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/HitConditionVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/HitConditionVO.java new file mode 100644 index 0000000..8809bce --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/HitConditionVO.java @@ -0,0 +1,41 @@ +package com.dkha.common.modules.vo.face; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: TODO(预警任务中过滤参数) + * All rights 成都电科慧安 + * @Title: HitConditionVO + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/11/29 17:08 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="预警任务中过滤参数", description="业务层调用返回的数据") +public class HitConditionVO { + + @ApiModelProperty(value = "当前页") + private Integer pageNo; + + @ApiModelProperty(value = "每页条数") + private Integer pageSize; + + @ApiModelProperty(value = "开始时间戳") + private Long startTimestamp; + + @ApiModelProperty(value = "结束时间戳") + private Long stopTimestamp; + + @ApiModelProperty(value = "排序时间戳默认DESC传递ASC") + private String order; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/ImageListVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/ImageListVO.java new file mode 100644 index 0000000..6c3293e --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/ImageListVO.java @@ -0,0 +1,35 @@ +package com.dkha.common.modules.vo.face; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ImagesVO + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/12/3 15:14 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value = "批量图片入库接口", description = "用于图片入库接口") +public class ImageListVO { + @ApiModelProperty(value = "目标库id") + @NotNull(message = "目标库id不能为空") + private String libraryId; + + @ApiModelProperty(value = "人脸相关信息") + private List faces; +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/ImageReturnVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/ImageReturnVO.java new file mode 100644 index 0000000..8f6cfb2 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/ImageReturnVO.java @@ -0,0 +1,50 @@ +package com.dkha.common.modules.vo.face; + + +import com.dkha.common.modules.vo.position.PositionVO; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ImageReturnVO + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/12/3 18:28 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value = "用于图片入库返回参数", description = "用于图片入库返回参数") +public class ImageReturnVO { + @ApiModelProperty(value = "成功的人脸id") + private String faceId; + @ApiModelProperty(value = "人脸库id") + private String libraryId; + @ApiModelProperty(value = "人脸id") + private String idFaceid; + @ApiModelProperty(value = "人脸坐标") + private PositionVO faceRect; + @ApiModelProperty(value = "传递的人脸信息") + private ImagesVO face; + + public ImageReturnVO(String faceId, String libraryId,String idFaceid, PositionVO faceRect, ImagesVO face) + { + this.faceId=faceId; + this.libraryId=libraryId; + this.idFaceid=idFaceid; + this.faceRect=faceRect; + this.face=face; + } + + @ApiModelProperty(value = "批量导入是否导入成功") + private Boolean isSuccess; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/ImageVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/ImageVO.java new file mode 100644 index 0000000..c46c31e --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/ImageVO.java @@ -0,0 +1,50 @@ +package com.dkha.common.modules.vo.face; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ImagesVO + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/12/3 15:14 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value = "用于图片入库接口", description = "用于图片入库接口") +public class ImageVO { + + @ApiModelProperty(value = "需要入库的人脸地址") + @NotBlank(message = "人脸图片地址不能为空") + private String url; + + @ApiModelProperty(value = "身份证id可空") + private String idCard; + + @ApiModelProperty(value = "性别可空") + private String gender; + + @ApiModelProperty(value = "姓名") + private String name; + + @ApiModelProperty(value = "名族") + private String nation; + + @ApiModelProperty(value = "特征信息") + private String feature; + + @ApiModelProperty(value = "额外信息") + private String extraMeta; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/ImagesVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/ImagesVO.java new file mode 100644 index 0000000..463c0ef --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/ImagesVO.java @@ -0,0 +1,65 @@ +package com.dkha.common.modules.vo.face; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import java.util.Date; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ImagesVO + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/12/3 15:14 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value = "用于图片入库接口", description = "用于图片入库接口") +public class ImagesVO { + @ApiModelProperty(value = "目标库id") + @NotBlank(message = "目标库id不能为空") + private String libraryId; + + @ApiModelProperty(value = "需要入库的人脸地址") + @NotBlank(message = "人脸图片地址不能为空") + private String url; + + @ApiModelProperty(value = "人脸id") + private String faceId; + + @ApiModelProperty(value = "身份证id可空") + private String idCard; + + @ApiModelProperty(value = "性别可空") + private String gender; + + @ApiModelProperty(value = "姓名") + private String name; + + @ApiModelProperty(value = "名族") + private String nation; + + @ApiModelProperty(value = "特征信息") + private String feature; + + @ApiModelProperty(value = "额外信息") + private String extraMeta; + + @ApiModelProperty(value = "入库后人脸的URL") + private String faceUrl; + + @ApiModelProperty(value = "创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/PagePortraitVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/PagePortraitVO.java new file mode 100644 index 0000000..296e5db --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/PagePortraitVO.java @@ -0,0 +1,31 @@ +package com.dkha.common.modules.vo.face; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: PagePortraitVO + * @Package com.dkha.api.modules.vo + * @author: panhui + * @date: 2019/12/5 10:06 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="人脸列表参数接收类", description="人脸列表参数接收类") +public class PagePortraitVO { + private String libraryId; + /**摄像头类型*/ + private String type; + /**库名称*/ + private String factoryName; + private PageVO page; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/face/PageVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/face/PageVO.java new file mode 100644 index 0000000..51e0826 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/face/PageVO.java @@ -0,0 +1,44 @@ +package com.dkha.common.modules.vo.face; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: PageVO + * @Package com.dkha.api.modules + * @author: panhui + * @date: 2019/12/5 10:13 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="用于列表查询后续的分页", description="用于列表查询后续的分页") +public class PageVO { + + @ApiModelProperty(value = "排序 默认按时间DESC ASC") + private String order="DESC"; + + @ApiModelProperty(value = "开始时间戳") + private Long startTimestamp; + + @ApiModelProperty(value = "结束时间戳") + private Long stopTimestamp; + + @ApiModelProperty(value = "当前页") + private Integer pageNo=1; + + @ApiModelProperty(value = "每页条数") + private Integer pageSize=10; + + @ApiModelProperty(value = "总数") + private Long total; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareListVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareListVO.java new file mode 100644 index 0000000..6244bb3 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareListVO.java @@ -0,0 +1,33 @@ +package com.dkha.common.modules.vo.facelib; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: 比中返回结果 + * All rights 成都电科慧安 + * @Title: CompareList + * @Package com.dkha.common.entity.vo.facelib + * @author: panhui + * @date: 2019/11/27 15:20 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="比中结果通用", description="用于和底层传输统一参数格式") +public class CompareListVO { + @ApiModelProperty(value = "比中库里面的人脸id") + private String comparisonFaceId; + + @ApiModelProperty(value = "库id") + private String libId; + @ApiModelProperty(value = "比分") + private Double score; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareRequestVo.java b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareRequestVo.java new file mode 100644 index 0000000..b7d5e94 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareRequestVo.java @@ -0,0 +1,21 @@ +package com.dkha.common.modules.vo.facelib; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * @Author Spring + * @Since 2019/12/11 16:32 + * @Description 分组请求vo + */ +@Data +public class CompareRequestVo { + + @ApiModelProperty(value = "需要分组的url集合") + private List urlList; + + @ApiModelProperty(value = "阀值") + private Double minScore; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareResultDetailVo.java b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareResultDetailVo.java new file mode 100644 index 0000000..67abf5d --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareResultDetailVo.java @@ -0,0 +1,19 @@ +package com.dkha.common.modules.vo.facelib; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @Author Spring + * @Since 2019/12/11 16:23 + * @Description 分组比对结果详情 + */ +@Data +public class CompareResultDetailVo { + + @ApiModelProperty(value = "图片url") + private String url; + + @ApiModelProperty(value = "相似度") + private double score; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareResultSubVo.java b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareResultSubVo.java new file mode 100644 index 0000000..07d19a4 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareResultSubVo.java @@ -0,0 +1,22 @@ +package com.dkha.common.modules.vo.facelib; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * @Author Spring + * @Since 2019/12/11 16:18 + * @Description 人脸分组结果集,子项 + */ +@Data +public class CompareResultSubVo { + + @ApiModelProperty(value = "结果url--随机获取其中一个") + private String resultUrl; + + @ApiModelProperty(value = "除结果url后,其余的url集合") + private List compareResultSubVoList = new ArrayList<>(); +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareResultVo.java b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareResultVo.java new file mode 100644 index 0000000..3297eca --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/CompareResultVo.java @@ -0,0 +1,19 @@ +package com.dkha.common.modules.vo.facelib; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * @Author Spring + * @Since 2019/12/11 16:17 + * @Description 比较结果集合 + */ +@Data +public class CompareResultVo { + + @ApiModelProperty(value = "分组比对返回结果集") + private List compareResultSubVoList = new ArrayList<>(); +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/facelib/FaceDeleteVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/FaceDeleteVO.java new file mode 100644 index 0000000..97466e8 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/FaceDeleteVO.java @@ -0,0 +1,32 @@ +package com.dkha.common.modules.vo.facelib; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: 人脸删除请求 + * All rights 成都电科慧安 + * @Title: FaceDeleteVO + * @Package com.dkha.common.entity.vo.facelib + * @author: yangjun + * @date: 2019/11/27 11:16 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="人脸删除通用接口请求参数类", description="用于和底层传输统一参数格式") +public class FaceDeleteVO { + @ApiModelProperty(value = "库id") + private String libId; + @ApiModelProperty(value = "人脸id") + private List faceIds; +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/facelib/FaceLibaryReturnVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/FaceLibaryReturnVO.java new file mode 100644 index 0000000..b405b3b --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/FaceLibaryReturnVO.java @@ -0,0 +1,34 @@ +package com.dkha.common.modules.vo.facelib; + + +import com.dkha.common.modules.vo.position.FaceVO; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: 人脸入库返回 + * All rights 成都电科慧安 + * @Title: FaceLibaryReturnVO + * @Package com.dkha.common.entity.vo.facelib + * @author: yangjun + * @date: 2019/11/27 10:15 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="人脸入库通用接口返回参数类", description="用于和底层传输统一参数格式") +public class FaceLibaryReturnVO { + @ApiModelProperty(value = "人脸相关信息") + private List faces; + @ApiModelProperty(value = "库id") + private String libId; +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/facelib/FaceLibaryVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/FaceLibaryVO.java new file mode 100644 index 0000000..a8467e8 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/FaceLibaryVO.java @@ -0,0 +1,34 @@ +package com.dkha.common.modules.vo.facelib; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: 人脸入库请求 + * All rights 成都电科慧安 + * @Title: FaceLibaryVO + * @Package com.dkha.common.entity.vo.facelib + * @author: yangjun + * @date: 2019/11/27 10:03 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="人脸入库通用接口请求参数类", description="用于和底层传输统一参数格式") +public class FaceLibaryVO { + @ApiModelProperty(value = "库id") + private String libId; + @ApiModelProperty(value = "图片url") + private List imgs; + @ApiModelProperty(value = "人员信息") + private PersonalInformationVO personalInformation; +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/facelib/FileImageVo.java b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/FileImageVo.java new file mode 100644 index 0000000..486dc82 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/FileImageVo.java @@ -0,0 +1,19 @@ +package com.dkha.common.modules.vo.facelib; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * + */ +@Data +public class FileImageVo { + + @ApiModelProperty(value = "url") + private String url; + + @ApiModelProperty(value = "url") + private List urls; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/facelib/OneToOneResultVo.java b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/OneToOneResultVo.java new file mode 100644 index 0000000..e816a2e --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/OneToOneResultVo.java @@ -0,0 +1,22 @@ +package com.dkha.common.modules.vo.facelib; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * @Author Spring + * @Since 2019/12/11 17:37 + * @Description 一比一比对返回结果集 + */ +@Data +public class OneToOneResultVo { + + @ApiModelProperty(value = "url集合") + private List urls = new ArrayList<>(); + + @ApiModelProperty(value = "分数") + private double score; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/facelib/OnecompareOneVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/OnecompareOneVO.java new file mode 100644 index 0000000..935907b --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/OnecompareOneVO.java @@ -0,0 +1,34 @@ +package com.dkha.common.modules.vo.facelib; + + +import com.dkha.common.modules.vo.search.FaceCompareVO; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: OnecompareOneVO + * @Package com.dkha.common.entity.vo.facelib + * @author: yangjun + * @date: 2019/12/6 16:17 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="比中结果", description="用于和底层传输统一参数格式") +public class OnecompareOneVO { + @ApiModelProperty(value = "相似度") + private Double hitSimilarity; + private List faces; + +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/facelib/PersonalInformationVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/PersonalInformationVO.java new file mode 100644 index 0000000..033b6a2 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/facelib/PersonalInformationVO.java @@ -0,0 +1,37 @@ +package com.dkha.common.modules.vo.facelib; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: 人员信息(年龄** 性别 ** 身份证** 特征) + * All rights 成都电科慧安 + * @Title: PersonalInformationVO + * @Package com.dkha.common.entity.vo.facelib + * @author: yangjun + * @date: 2019/11/27 10:09 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="人员信息通用接口参数类", description="用于和底层传输统一参数格式") +public class PersonalInformationVO { + @ApiModelProperty(value = "姓名") + private String name; + @ApiModelProperty(value = "年龄") + private String age; + @ApiModelProperty(value = "性别") + private String sex; + @ApiModelProperty(value = "身份证号码") + private String idCard; + @ApiModelProperty(value = "特征") + private String feature; + +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/libary/FaceLibraryVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/libary/FaceLibraryVO.java new file mode 100644 index 0000000..5c015bf --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/libary/FaceLibraryVO.java @@ -0,0 +1,39 @@ +package com.dkha.common.modules.vo.libary; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: FaceLibraryVO + * @Package com.dkha.api.modules.vo + * @author: yangjun + * @date: 2019/12/3 15:13 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="特征库", description="特征库信息") +public class FaceLibraryVO { + @ApiModelProperty(value="库id") + private String libraryId; + @ApiModelProperty(value="库名称") + private String name; + @ApiModelProperty(value="库类型") + private String type; + @ApiModelProperty(value="额外信息") + private String extraMeta; + + @ApiModelProperty(value = "创建时间") + private Date createTime; +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/libary/LibaryVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/libary/LibaryVO.java new file mode 100644 index 0000000..67a7093 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/libary/LibaryVO.java @@ -0,0 +1,31 @@ +package com.dkha.common.modules.vo.libary; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: 库新增 + * All rights 成都电科慧安 + * @Title: LibaryVO + * @Package com.dkha.common.entity.vo.libary + * @author: yangjun + * @date: 2019/11/27 9:59 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="库通用接口参数类", description="用于和底层传输统一参数格式") +public class LibaryVO { + @ApiModelProperty(value = "库id列表") + private List libIds; + +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/position/FScoreCompVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/position/FScoreCompVO.java new file mode 100644 index 0000000..5fb5f24 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/position/FScoreCompVO.java @@ -0,0 +1,14 @@ +package com.dkha.common.modules.vo.position; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class FScoreCompVO { + private String faceId; + private String comparisonFaceId; + private Double score; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/position/FaceCompareVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/position/FaceCompareVO.java new file mode 100644 index 0000000..d803756 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/position/FaceCompareVO.java @@ -0,0 +1,36 @@ +package com.dkha.common.modules.vo.position; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: + * All rights 成都电科慧安 + * @Title: faceVO + * @Package com.dkha.common.entity.vo.face + * @author: panhui + * @date: 2019/11/27 10:36 + * @Copyright: 成都电科慧安 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="人脸和坐标相关类", description="人脸和坐标相关类") +public class FaceCompareVO { + + @ApiModelProperty(value = "背景图片") + private String url; + @ApiModelProperty(value = "人脸id") + private String faceId; + @ApiModelProperty(value = "坐标") + private PositionVO position; + @ApiModelProperty(value = "额外信息") + private Object extraMeta; + +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/position/FaceVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/position/FaceVO.java new file mode 100644 index 0000000..145b14b --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/position/FaceVO.java @@ -0,0 +1,40 @@ +package com.dkha.common.modules.vo.position; + + +import com.dkha.common.modules.vo.facelib.CompareListVO; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: + * All rights 成都电科慧安 + * @Title: faceVO + * @Package com.dkha.common.entity.vo.face + * @author: panhui + * @date: 2019/11/27 10:36 + * @Copyright: 成都电科慧安 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="人脸和坐标相关类", description="人脸和坐标相关类") +public class FaceVO { + + @ApiModelProperty(value = "背景图片") + private String bgImg; + @ApiModelProperty(value = "人脸id") + private String faceId; + @ApiModelProperty(value = "坐标") + private PositionVO position; + @ApiModelProperty(value = "人脸比中结果集 注:人脸入库不需要返回此字段") + private List compareList; + +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/position/GroupInfoVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/position/GroupInfoVO.java new file mode 100644 index 0000000..8ada990 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/position/GroupInfoVO.java @@ -0,0 +1,21 @@ +package com.dkha.common.modules.vo.position; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class GroupInfoVO { + + private String head;//头像id + private String headUrl;//头像图片地址 + private String bgpic;//背景图片 + private Integer x;//x坐标 + private Integer y;//y坐标 + private Integer width;//长 + private Integer height;//宽 + + +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/position/GroupPositionVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/position/GroupPositionVO.java new file mode 100644 index 0000000..4e7f392 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/position/GroupPositionVO.java @@ -0,0 +1,37 @@ +package com.dkha.common.modules.vo.position; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + + +/** + * @version V1.0 + * @Description: 人脸坐标位置 + * All rights 成都电科慧安 + * @Title: PositionVO + * @Package com.dkha.common.entity.vo.face + * @author: panhui + * @date: 2019/11/27 10:36 + * @Copyright: 成都电科慧安 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="坐标类", description="人脸坐标") +public class GroupPositionVO { + @ApiModelProperty(value = "人脸对应的id") + private String faceId; + private Integer x; + private Integer y; + private Integer w; + private Integer h; + private String headUrl;//头像图片地址 + private String bgUrl;//背景图片 + private double hitSimilarity;//命中的相似度 + +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/position/GroupRelation.java b/face-common/src/main/java/com/dkha/common/modules/vo/position/GroupRelation.java new file mode 100644 index 0000000..37a9b49 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/position/GroupRelation.java @@ -0,0 +1,26 @@ +package com.dkha.common.modules.vo.position; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * 做分组后的关联id + * All rights 成都电科慧安 + * @ClassName: GroupRelation + * @Description:TODO(please write your description) + * @author: dkha{panhui} + * @date: 2019年10月25日 下午6:27:50 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class GroupRelation { + + private String headId;//关联id + private List groupInfoVO;//关联数据 + +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/position/GroupVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/position/GroupVO.java new file mode 100644 index 0000000..c1a99b8 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/position/GroupVO.java @@ -0,0 +1,36 @@ +package com.dkha.common.modules.vo.position; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.Map; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: GroupVO + * @Package com.dkha.common.entity.vo.position + * @author: yangjun + * @date: 2019/12/2 15:32 + * @Copyright: 成都电科慧安 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="人脸分组相关类", description="人脸和坐标相关类") +public class GroupVO { + @ApiModelProperty(value = "人脸对id") + private Map faceId; + @ApiModelProperty(value = "人脸对应的坐标") + private List faceIds; + @ApiModelProperty(value = "人脸比对结果") + private List fScoreComp; + +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/position/Imginfo.java b/face-common/src/main/java/com/dkha/common/modules/vo/position/Imginfo.java new file mode 100644 index 0000000..7609589 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/position/Imginfo.java @@ -0,0 +1,17 @@ +package com.dkha.common.modules.vo.position; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Imginfo { + + private List faceIds; + private Integer reSizeH; + private Integer reSizeW; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/position/PortraitListVo.java b/face-common/src/main/java/com/dkha/common/modules/vo/position/PortraitListVo.java new file mode 100644 index 0000000..b81aa6c --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/position/PortraitListVo.java @@ -0,0 +1,28 @@ +package com.dkha.common.modules.vo.position; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: PortraitListVo + * @Package com.dkha.server.modules.vo.position + * @author: yangjun + * @date: 2019/12/10 17:16 + * @Copyright: 成都电科慧安 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="人像id列表", description="人脸坐标") +public class PortraitListVo { + private List idPortrait; +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/position/PositionVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/position/PositionVO.java new file mode 100644 index 0000000..ba39b00 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/position/PositionVO.java @@ -0,0 +1,38 @@ +package com.dkha.common.modules.vo.position; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: 人脸坐标位置 + * All rights 成都电科慧安 + * @Title: PositionVO + * @Package com.dkha.common.entity.vo.face + * @author: panhui + * @date: 2019/11/27 10:36 + * @Copyright: 成都电科慧安 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="坐标类", description="人脸坐标") +public class PositionVO { + private Integer x; + private Integer y; + private Integer w; + private Integer h; + public PositionVO(Integer x,Integer y,Integer w,Integer h) + { + this.x=x; + this.y=y; + this.w=w; + this.h=h; + } + private Integer bgWidth; + private Integer bgHeight; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/search/FaceCheckVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/search/FaceCheckVO.java new file mode 100644 index 0000000..b1aa01a --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/search/FaceCheckVO.java @@ -0,0 +1,34 @@ +package com.dkha.common.modules.vo.search; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: 人脸库检查/人脸分组参数 + * All rights 成都电科慧安 + * @Title: FaceSearchVO + * @Package com.dkha.common.entity.vo.search + * @author: yangjun + * @date: 2019/11/27 10:40 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="人脸库检测通用接口参数类", description="用于和底层传输统一参数格式") +public class FaceCheckVO { + @ApiModelProperty(value = "人脸url列表") + private List imgs; + @ApiModelProperty(value = "每个库最大返回结果数, 0~100") + private Double minScore; + @ApiModelProperty(value = "每个库最大返回结果数, 0~100") + private Integer maxRetNb; +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/search/FaceCompareVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/search/FaceCompareVO.java new file mode 100644 index 0000000..eb62468 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/search/FaceCompareVO.java @@ -0,0 +1,33 @@ +package com.dkha.common.modules.vo.search; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: 人脸库检查/人脸分组参数 + * All rights 成都电科慧安 + * @Title: FaceSearchVO + * @Package com.dkha.common.entity.vo.search + * @author: yangjun + * @date: 2019/11/27 10:40 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="人脸库检测通用接口参数类", description="用于和底层传输统一参数格式") +public class FaceCompareVO { + @ApiModelProperty(value = "人脸图片1") + private String image1; + @ApiModelProperty(value = "人脸图片2") + private String image2; + @ApiModelProperty(value = "拓展字段") + private String extraMeta; + +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/search/FaceSearchVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/search/FaceSearchVO.java new file mode 100644 index 0000000..726f5f0 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/search/FaceSearchVO.java @@ -0,0 +1,37 @@ +package com.dkha.common.modules.vo.search; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: 人脸库检索参数 + * All rights 成都电科慧安 + * @Title: FaceSearchVO + * @Package com.dkha.common.entity.vo.search + * @author: yangjun + * @date: 2019/11/27 10:40 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="人脸库检索通用接口参数类", description="用于和底层传输统一参数格式") +public class FaceSearchVO { + @ApiModelProperty(value = "人脸url列表") + private List imgs; + @ApiModelProperty(value = "人脸库列表") + private List libIds; + @ApiModelProperty(value = "每个库最大返回结果数, 0~100") + private Double minScore; + @ApiModelProperty(value = "每个库最大返回结果数, 0~100") + private Integer maxRetNb; + +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/search/SearchFutureVo.java b/face-common/src/main/java/com/dkha/common/modules/vo/search/SearchFutureVo.java new file mode 100644 index 0000000..737236e --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/search/SearchFutureVo.java @@ -0,0 +1,21 @@ +package com.dkha.common.modules.vo.search; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * @Author Spring + * @Since 2019/12/10 16:16 + * @Description 查询结果特征Id集合 + */ +@Data +public class SearchFutureVo { + + @ApiModelProperty(value = "库Id") + private String libId; + + @ApiModelProperty(value = "搜索结果人脸Id集合") + private List faceIdLIst; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/search/SearchPortraitVo.java b/face-common/src/main/java/com/dkha/common/modules/vo/search/SearchPortraitVo.java new file mode 100644 index 0000000..c1d07d8 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/search/SearchPortraitVo.java @@ -0,0 +1,42 @@ +package com.dkha.common.modules.vo.search; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @Author Spring + * @Since 2019/12/10 15:07 + * @Description 人脸库检索返回数据 + */ +@Data +public class SearchPortraitVo implements Comparable{ + + @ApiModelProperty(value = "人脸Id") + private String idPortrait; + + @ApiModelProperty(value = "姓名") + private String name; + + @ApiModelProperty(value = "性别") + private String sex; + + @ApiModelProperty(value = "身份证号码") + private String idCard; + + @ApiModelProperty(value = "相似度") + private Double similarityDegree = new Double(0L); + + @ApiModelProperty(value = "库Id") + private String idLibrary; + + @ApiModelProperty(value = "库名称/来源") + private String libraryName; + + @ApiModelProperty(value = "人脸图片") + private String url; + + @Override + public int compareTo(SearchPortraitVo o) { + return o.getSimilarityDegree().compareTo(this.getSimilarityDegree()); + } +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/search/SearchRequestVo.java b/face-common/src/main/java/com/dkha/common/modules/vo/search/SearchRequestVo.java new file mode 100644 index 0000000..d21339f --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/search/SearchRequestVo.java @@ -0,0 +1,39 @@ +package com.dkha.common.modules.vo.search; + +import com.dkha.common.page.PageParam; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @Author Spring + * @Since 2019/12/10 15:33 + * @Description 人脸库检索请求Vo + */ +@Data +public class SearchRequestVo { + + @ApiModelProperty(value = "人像库Id") + private List libIdList; + + @ApiModelProperty(value = "人脸图像请求集合") + private List faceImageRequestList; + + @ApiModelProperty(value = "人脸ID,分数集合,及其对应分数--由sdk返回") + private Map faceApiResultMap; + + @ApiModelProperty(value = "姓名/身份证号码") + private String search; + + @ApiModelProperty(value = "性别 0男 1女") + private String sex; + + @ApiModelProperty(value = "阀值") + private String minScore; + + @ApiModelProperty(value = "分页相关参数") + private PageParam pageParam; + +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/search/SearchResultVo.java b/face-common/src/main/java/com/dkha/common/modules/vo/search/SearchResultVo.java new file mode 100644 index 0000000..6823b7f --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/search/SearchResultVo.java @@ -0,0 +1,34 @@ +package com.dkha.common.modules.vo.search; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @Author Spring + * @Since 2019/12/10 16:12 + * @Description 库搜索返回结果集 + */ +@Data +public class SearchResultVo { + + @ApiModelProperty(value = "人脸ID,分数集合,及其对应分数--由sdk返回") + private Map faceApiResultMap = new HashMap<>(); + + @ApiModelProperty(value = "人脸图像请求集合") + private List faceImageRequestList = new ArrayList<>(); + + @ApiModelProperty(value = "人脸检索分页返回数据集合") + private Page resultPage; + + @ApiModelProperty(value = "请求对应search参数") + private String requestSearch; + + @ApiModelProperty(value = "请求对应库Id集合") + private List requestLibIdList = new ArrayList<>(); +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/upload/ImageUploadResult.java b/face-common/src/main/java/com/dkha/common/modules/vo/upload/ImageUploadResult.java new file mode 100644 index 0000000..5dc48fd --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/upload/ImageUploadResult.java @@ -0,0 +1,24 @@ +package com.dkha.common.modules.vo.upload; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * @Author Spring + * @Since 2019/12/11 15:34 + * @Description 图片上传结果集合 + */ +@Data +public class ImageUploadResult { + + @ApiModelProperty(value = "上传成功后对应url集合") + private List successFileUrlList; + @ApiModelProperty(value = "总的文件数") + private int totalFiles; + @ApiModelProperty(value = "失败文件数") + private int failFiles; + @ApiModelProperty(value = "成功文件数") + private int successFiles; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/warning/BayoneReturnListVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/warning/BayoneReturnListVO.java new file mode 100644 index 0000000..24e56b0 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/warning/BayoneReturnListVO.java @@ -0,0 +1,37 @@ +package com.dkha.common.modules.vo.warning; + +import com.dkha.common.modules.vo.face.AlarmReturnVO; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: BayoneReturnListVO + * @Package com.dkha.common.modules.vo.warning + * @author: panhui + * @date: 2020/1/6 16:55 + * @Copyright: 成都电科慧安 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="卡口抓拍返回list数据", description="卡口抓拍返回list数据") +public class BayoneReturnListVO { + @ApiModelProperty(value = "人脸信息") + private List result; + + @ApiModelProperty(value = "今日抓拍数量") + private long toDaySnapShot; + + @ApiModelProperty(value = "累计抓拍") + private long totalSnapShot; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/warning/BayonetReturnVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/warning/BayonetReturnVO.java new file mode 100644 index 0000000..a22bf26 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/warning/BayonetReturnVO.java @@ -0,0 +1,37 @@ +package com.dkha.common.modules.vo.warning; + +import com.dkha.common.modules.vo.face.AlarmReturnVO; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: BayonetReturnVO + * @Package com.dkha.server.modules.vo.warning + * @author: panhui + * @date: 2019/12/10 16:29 + * @Copyright: 成都电科慧安 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="卡口返回数据", description="卡口返回数据") +public class BayonetReturnVO { + + @ApiModelProperty(value = "人脸信息") + private AlarmReturnVO result; + + @ApiModelProperty(value = "今日抓拍数量") + private Long toDaySnapShot; + + @ApiModelProperty(value = "累计抓拍") + private Long totalSnapShot; + +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/warning/BgImageSize.java b/face-common/src/main/java/com/dkha/common/modules/vo/warning/BgImageSize.java new file mode 100644 index 0000000..8435754 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/warning/BgImageSize.java @@ -0,0 +1,27 @@ +package com.dkha.common.modules.vo.warning; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: BgImageSize + * @Package com.dkha.common.modules.vo.warning + * @author: panhui + * @date: 2020/1/8 9:14 + * @Copyright: 成都电科慧安 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class BgImageSize implements Serializable { + private String cameraId; + private Integer bgWidth; + private Integer bgHeight; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/warning/CameraVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/warning/CameraVO.java new file mode 100644 index 0000000..fc3c59e --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/warning/CameraVO.java @@ -0,0 +1,62 @@ +package com.dkha.common.modules.vo.warning; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: CameraVO + * @Package com.dkha.common.modules.vo.warning + * @author: panhui + * @date: 2020/1/9 15:51 + * @Copyright: 成都电科慧安 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="摄像头数据", description="摄像头数据") +public class CameraVO { + /** + * 主键id + * 分布式全局唯一ID 长整型类型 + */ + @ApiModelProperty(value = "摄像头id") + private Long idFaceCamera; + /** + * 摄像头名称 + */ + @ApiModelProperty(value = "摄像头名称") + private String cameraName; + + /** + * 摄像头详细地址 + */ + @ApiModelProperty(value = "摄像头详细地址") + private String cameraAddress; + /** + * 摄像头经度 + */ + @ApiModelProperty(value = "摄像头经度") + public static final String CAMERA_LONGITUDE="camera_longitude"; + private String cameraLongitude; + /** + * 摄像头纬度 + */ + @ApiModelProperty(value = "摄像头纬度") + public static final String CAMERA_LATITUDE="camera_latitude"; + private String cameraLatitude; + /** + * 是否运行 Y启动 N未启动 + */ + @ApiModelProperty(value = "是否运行,Y启动 N未启动") + private String status; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/warning/CameraWarningVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/warning/CameraWarningVO.java new file mode 100644 index 0000000..d9d98cb --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/warning/CameraWarningVO.java @@ -0,0 +1,27 @@ +package com.dkha.common.modules.vo.warning; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: CameraWarningVO + * @Package com.dkha.common.modules.vo.warning + * @author: panhui + * @date: 2020/1/9 15:47 + * @Copyright: 成都电科慧安 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@ApiModel(value="地图模式中摄像头和预警信息", description="地图模式中摄像头和预警信息") +public class CameraWarningVO { + + private WarningPageVO warning; + private CameraVO camera; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/warning/FScoreCompVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/warning/FScoreCompVO.java new file mode 100644 index 0000000..55ead41 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/warning/FScoreCompVO.java @@ -0,0 +1,14 @@ +package com.dkha.common.modules.vo.warning; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class FScoreCompVO { + private String feat1; + private String feat2; + private Double score; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/warning/GroupInfoVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/warning/GroupInfoVO.java new file mode 100644 index 0000000..26c8927 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/warning/GroupInfoVO.java @@ -0,0 +1,21 @@ +package com.dkha.common.modules.vo.warning; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class GroupInfoVO { + + private String head;//头像id + private String headUrl;//头像图片地址 + private String bgpic;//背景图片 + private Integer x;//x坐标 + private Integer y;//y坐标 + private Integer width;//长 + private Integer height;//宽 + + +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/warning/GroupRelation.java b/face-common/src/main/java/com/dkha/common/modules/vo/warning/GroupRelation.java new file mode 100644 index 0000000..77802e8 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/warning/GroupRelation.java @@ -0,0 +1,25 @@ +package com.dkha.common.modules.vo.warning; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * 做分组后的关联id + * All rights 成都电科慧安 + * @ClassName: GroupRelation + * @Description:TODO(please write your description) + * @author: dkha{panhui} + * @date: 2019年10月25日 下午6:27:50 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class GroupRelation { + + private String headId;//关联id + private List groupInfoVO;//关联数据 +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/warning/GroupVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/warning/GroupVO.java new file mode 100644 index 0000000..3a2b104 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/warning/GroupVO.java @@ -0,0 +1,19 @@ +package com.dkha.common.modules.vo.warning; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.Map; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class GroupVO { + private HeadVo head; + private Map faceIds; + private Map position; + private List fScoreComp; + +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/warning/HeadVo.java b/face-common/src/main/java/com/dkha/common/modules/vo/warning/HeadVo.java new file mode 100644 index 0000000..b047cc8 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/warning/HeadVo.java @@ -0,0 +1,18 @@ +package com.dkha.common.modules.vo.warning; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class HeadVo { + + private String protId; + private Integer wappId; + private Integer serId; + private Integer ret; + private String errInfo; + private String version; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/warning/Imginfo.java b/face-common/src/main/java/com/dkha/common/modules/vo/warning/Imginfo.java new file mode 100644 index 0000000..a5b60f9 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/warning/Imginfo.java @@ -0,0 +1,17 @@ +package com.dkha.common.modules.vo.warning; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Imginfo { + + private List faceIds; + private Integer reSizeH; + private Integer reSizeW; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/warning/P5sVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/warning/P5sVO.java new file mode 100644 index 0000000..8494fda --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/warning/P5sVO.java @@ -0,0 +1,19 @@ +package com.dkha.common.modules.vo.warning; + +public class P5sVO { + + private Integer x1; + private Integer y1; + + private Integer x2; + private Integer y2; + + private Integer x3; + private Integer y3; + + private Integer x4; + private Integer y4; + + private Integer x5; + private Integer y; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/warning/PositionVo.java b/face-common/src/main/java/com/dkha/common/modules/vo/warning/PositionVo.java new file mode 100644 index 0000000..9c02f02 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/warning/PositionVo.java @@ -0,0 +1,17 @@ +package com.dkha.common.modules.vo.warning; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +@NoArgsConstructor +@Data +public class PositionVo { + + private String faceId; + private RectVO rect; + private P5sVO p5s; + private String extId; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/warning/RectVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/warning/RectVO.java new file mode 100644 index 0000000..5ff8602 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/warning/RectVO.java @@ -0,0 +1,16 @@ +package com.dkha.common.modules.vo.warning; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class RectVO { + + private Integer left; + private Integer top; + private Integer right; + private Integer bottom; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/warning/WarningBayonetReturnVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/warning/WarningBayonetReturnVO.java new file mode 100644 index 0000000..91a9e5d --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/warning/WarningBayonetReturnVO.java @@ -0,0 +1,35 @@ +package com.dkha.common.modules.vo.warning; + +import com.dkha.common.modules.vo.face.AlarmReturnVO; +import com.dkha.common.modules.vo.face.PageVO; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: TODO(卡口返回数据) + * All rights 成都电科慧安 + * @Title: WarningBayonetReturnVO + * @Package com.dkha.server.modules.vo.warning + * @author: panhui + * @date: 2019/12/10 11:42 + * @Copyright: 成都电科慧安 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +//@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="卡口返回数据", description="卡口返回数据") +public class WarningBayonetReturnVO { + + @ApiModelProperty(value = "预警信息") + private List result; + @ApiModelProperty(value = "分页数据") + private PageVO page; +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/warning/WarningPageVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/warning/WarningPageVO.java new file mode 100644 index 0000000..99f6459 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/warning/WarningPageVO.java @@ -0,0 +1,69 @@ +package com.dkha.common.modules.vo.warning; + +import com.dkha.common.modules.vo.position.PositionVO; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: WarningPageVO + * @Package com.dkha.server.modules.vo.warning + * @author: panhui + * @date: 2019/12/12 9:00 + * @Copyright: 成都电科慧安 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +//@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="预警页面展示的vo", description="前端页面展示数据") +public class WarningPageVO { + + @ApiModelProperty(value = "背景图片") + private String bgImg; + @ApiModelProperty(value = "坐标") + private PositionVO positionVO; + + @ApiModelProperty(value = "比分") + private Double score; + @ApiModelProperty(value = "时间") + private String time; + + + @ApiModelProperty(value = "比中头像地址") + private String faceUrl; + @ApiModelProperty(value = "姓名") + private String name; + @ApiModelProperty(value = "性别") + private String sex; + @ApiModelProperty(value = "身份证号码") + private String idCard; + @ApiModelProperty(value = "年龄") + private Integer age; + + + @ApiModelProperty(value = "任务id") + private String taskId; + @ApiModelProperty(value = "任务名称") + private String taskName; + @ApiModelProperty(value = "任务类型") + private String taskType; + + @ApiModelProperty(value = "库名称") + private String libName; + @ApiModelProperty(value = "库id") + private String libId; + + + @ApiModelProperty(value = "摄像头区域") + private String cameraRegion; + @ApiModelProperty(value = "摄像头id") + private String cameraId; + +} diff --git a/face-common/src/main/java/com/dkha/common/modules/vo/warning/WarningVO.java b/face-common/src/main/java/com/dkha/common/modules/vo/warning/WarningVO.java new file mode 100644 index 0000000..51d078e --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/modules/vo/warning/WarningVO.java @@ -0,0 +1,54 @@ +package com.dkha.common.modules.vo.warning; + + +import com.dkha.common.modules.vo.position.FaceVO; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.Id; + +import java.util.List; + +/** + * @version V1.0 + * @Description: 预警信息 + * All rights 成都电科慧安 + * @Title: WarningVO + * @Package com.dkha.common.entity.vo.warning + * @author: panhui + * @date: 2019/11/27 9:49 + * @Copyright: 成都电科慧安 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +//@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="预警", description="用于和底层传输统一参数格式") +public class WarningVO { + @ApiModelProperty(value = "报警唯一id") + @Id +// @Field(type= FieldType.Keyword) + private String id; + @ApiModelProperty(value="时间戳用来排序") + private Long timestamp; + @ApiModelProperty(value = "消息日期") + private String date; + @ApiModelProperty(value = "任务id") + private String taskIdCameraId;//task_id_ph_0001 + @ApiModelProperty(value = "api端任务id") + private String taskId;//task_id_ph + @ApiModelProperty(value = "摄像头id") + private String cameraId;//0001 + @ApiModelProperty(value = "背景图片") + private String bgImg; + @ApiModelProperty(value = "背景高度") + private Integer bgHeight; + @ApiModelProperty(value = "背景宽度") + private Integer bgWidth; + @ApiModelProperty(value = "人脸坐标列表") + private List faces; + +} diff --git a/face-common/src/main/java/com/dkha/common/mybatis/CodeGenerator.java b/face-common/src/main/java/com/dkha/common/mybatis/CodeGenerator.java new file mode 100644 index 0000000..8c96c44 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/mybatis/CodeGenerator.java @@ -0,0 +1,178 @@ +package com.dkha.common.mybatis; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.core.toolkit.StringPool; +import com.baomidou.mybatisplus.generator.AutoGenerator; +import com.baomidou.mybatisplus.generator.InjectionConfig; +import com.baomidou.mybatisplus.generator.config.*; +import com.baomidou.mybatisplus.generator.config.po.TableInfo; +import com.baomidou.mybatisplus.generator.config.rules.DateType; +import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; +import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; + +import java.awt.*; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + + +/** + * @Description: mybatis-plus 代码生成器 + * @Author: Spring + * @CreateDate: 2019/8/1 17:47 + */ + +public class CodeGenerator { + + /** + * 代码生成 + * @param folderPath 输出文件夹路径 + */ + public static void generate(String folderPath) throws IOException { + + deleteDir(folderPath); + + // 代码生成器 + AutoGenerator mpg = new AutoGenerator(); + + // 全局配置 + GlobalConfig gc = new GlobalConfig(); + String projectPath = folderPath; + gc.setOutputDir(projectPath + "/src/main/java"); + gc.setAuthor("Spring"); + gc.setOpen(false); + //生成时间为Date类 + gc.setDateType(DateType.ONLY_DATE); + //实体属性 Swagger2 注解 + gc.setSwagger2(true); + //分布式全局唯一Id生成策略 + gc.setIdType(IdType.ID_WORKER_STR); + mpg.setGlobalConfig(gc); + + // 数据源配置 + DataSourceConfig dsc = new DataSourceConfig(); +// dsc.setUrl("jdbc:mysql://192.168.3.240:3301/employ?useUnicode=true&useSSL=false&characterEncoding=utf8"); + dsc.setUrl("jdbc:mysql://10.51.10.201:3301/face_application?useUnicode=true&useSSL=false&characterEncoding=utf8"); + + dsc.setDriverName("com.mysql.jdbc.Driver"); + dsc.setUsername("root"); + dsc.setPassword("123456"); + mpg.setDataSource(dsc); + + // 包配置 + PackageConfig pc = new PackageConfig(); + pc.setParent("com.dkha.server"); + pc.setEntity("modules.entities"); + pc.setService("services"); + pc.setServiceImpl("services.impl"); + pc.setMapper("mappers"); + pc.setController("controllers"); + mpg.setPackageInfo(pc); + + // 自定义配置 + InjectionConfig cfg = new InjectionConfig() { + @Override + public void initMap() { + // to do nothing + } + }; + + // 如果模板引擎是 freemarker + String templatePath = "/templates/mapper.xml.ftl"; + // 自定义输出配置 + List focList = new ArrayList<>(); + // 自定义配置会被优先输出 + focList.add(new FileOutConfig(templatePath) { + @Override + public String outputFile(TableInfo tableInfo) { + // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!! + return projectPath + "/src/main/resources/mappers/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; + } + }); + + cfg.setFileOutConfigList(focList); + mpg.setCfg(cfg); + + // 配置模板 + TemplateConfig templateConfig = new TemplateConfig(); + + templateConfig.setXml(null); + mpg.setTemplate(templateConfig); + + // 策略配置 + StrategyConfig strategy = new StrategyConfig(); + strategy.setNaming(NamingStrategy.underline_to_camel); + strategy.setColumnNaming(NamingStrategy.underline_to_camel); + strategy.setEntityLombokModel(true); + strategy.setRestControllerStyle(true); + strategy.setSuperEntityColumns("id"); + strategy.setControllerMappingHyphenStyle(true); + strategy.setTablePrefix(pc.getModuleName() + "_"); + //是否显示属性注解 + strategy.setEntityTableFieldAnnotationEnable(false); + mpg.setStrategy(strategy); + mpg.setTemplateEngine(new FreemarkerTemplateEngine()); + mpg.execute(); + + //弹出生成代码文件夹 + Desktop.getDesktop().open(new File(folderPath)); + } + + /** + * delete dir + * @param folderPath + */ + public static void deleteDir(String folderPath) { + try { + //删除完里面所有内容 + delAllFile(folderPath); + String filePath = folderPath; + filePath = filePath.toString(); + File myFilePath = new File(filePath); + myFilePath.delete(); //删除空文件夹 + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * delete all file + * @param path + * @return + */ + public static boolean delAllFile(String path) { + boolean flag = false; + File file = new File(path); + if (!file.exists()) { + return flag; + } + if (!file.isDirectory()) { + return flag; + } + String[] tempList = file.list(); + File temp = null; + for (int i = 0; i < tempList.length; i++) { + if (path.endsWith(File.separator)) { + temp = new File(path + tempList[i]); + } else { + temp = new File(path + File.separator + tempList[i]); + } + if (temp.isFile()) { + temp.delete(); + } + if (temp.isDirectory()) { + //先删除文件夹里面的文件 + delAllFile(path + "/" + tempList[i]); + //再删除空文件夹 + deleteDir(path + "/" + tempList[i]); + flag = true; + } + } + return flag; + } + + public static void main(String[] args) throws IOException { + generate("d:\\mybatis-code-generate"); + } +} diff --git a/face-common/src/main/java/com/dkha/common/page/PageParam.java b/face-common/src/main/java/com/dkha/common/page/PageParam.java new file mode 100644 index 0000000..7be219e --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/page/PageParam.java @@ -0,0 +1,101 @@ +package com.dkha.common.page; + +import org.springframework.util.StringUtils; + +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 分页类 用于分页传参 + * @author Spring + * @create 2016-12-10 14:38 + **/ +public class PageParam { + + /** + * 当前页码 + */ + private int pageNo = 1; + + /** + * 每页记录数 默认10条 + */ + private int pageSize = 10; + + /** + * 搜索条件 + */ + private Map note=new HashMap(); + + /** + * 排序条件 + */ + private Map sort=new HashMap(); + + /** + * 拼接搜索条件 + * @return + */ + public String getSortString() { + return sort.entrySet() + .stream() + //过滤掉key和value都为空的项 + .filter(x -> !StringUtils.isEmpty(x.getKey())&&!StringUtils.isEmpty(x.getValue())) + //map转list + .map(x -> x.getKey() + " " + x.getValue()) + //逗号拼接 + .collect(Collectors.joining(",")); + } + + /** + * 模糊查询拼接 + * @param params + * @param likes + * @return + */ + public Map paramsToLike(Map params, String... likes){ + for (String like : likes){ + String val = params.get(like); + if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotEmpty(val)){ + params.put(like, "%" + val + "%"); + }else { + params.put(like, null); + } + } + return params; + } + + public int getPageNo() { + return pageNo; + } + + public void setPageNo(int pageNo) { + this.pageNo = pageNo; + } + + public int getPageSize() { + return pageSize; + } + + public void setPageSize(int pageSize) { + this.pageSize = pageSize; + } + + public Map getNote() { + return note; + } + + public void setNote(Map note) { + this.note = note; + } + + public Map getSort() { + return sort; + } + + public void setSort(Map sort) { + this.sort = sort; + } + +} diff --git a/face-common/src/main/java/com/dkha/common/pool/EmployeeThreadPool.java b/face-common/src/main/java/com/dkha/common/pool/EmployeeThreadPool.java new file mode 100644 index 0000000..b0de760 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/pool/EmployeeThreadPool.java @@ -0,0 +1,25 @@ +package com.dkha.common.pool; + + +import org.apache.commons.lang3.concurrent.BasicThreadFactory; + +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; + +/** + * @Author Spring + * @Since 2019/8/15 11:55 + * @Description 系统线程池 + */ +public class EmployeeThreadPool { + + /** + * 不要手动设置线程池并发线程数量,应根据线程所执行的任务是IO型任务还是CPU密集计算型任务进行设置,粗略设置如下 + * 如果是CPU密集型应用,则线程池大小设置为N+1 + * 如果是IO密集型应用,则线程池大小设置为2N+1 + * 线程IO时间占整个执行时间比例越高,则可以适当放大并发数,反之适当减少并发数量 + */ + public static ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(2 * Runtime.getRuntime().availableProcessors() + 1, + new BasicThreadFactory.Builder().namingPattern("async-face-pool-%d").daemon(true).build()); + +} diff --git a/face-common/src/main/java/com/dkha/common/pwd/MD5.java b/face-common/src/main/java/com/dkha/common/pwd/MD5.java new file mode 100644 index 0000000..e7bda7a --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/pwd/MD5.java @@ -0,0 +1,70 @@ +package com.dkha.common.pwd; + +import java.security.MessageDigest; + +public class MD5 { + + private static String byteArrayToHexString(byte b[]) { + StringBuffer resultSb = new StringBuffer(); + for (int i = 0; i < b.length; i++) + resultSb.append(byteToHexString(b[i])); + + return resultSb.toString(); + } + + private static String byteToHexString(byte b) { + int n = b; + if (n < 0) + n += 256; + int d1 = n / 16; + int d2 = n % 16; + return hexDigits[d1] + hexDigits[d2]; + } + + public static String MD5Encode(String origin, String charsetname) { + String resultString = null; + try { + resultString = new String(origin); + MessageDigest md = MessageDigest.getInstance("MD5"); + if (charsetname == null || "".equals(charsetname)) + resultString = byteArrayToHexString(md.digest(resultString + .getBytes())); + else + resultString = byteArrayToHexString(md.digest(resultString + .getBytes(charsetname))); + } catch (Exception exception) { + } + return resultString; + } + + private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5", + "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}; + + public final static String getMessageDigest(String s) { + char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + + try { + byte[] btInput = s.getBytes(); + // 获得MD5摘要算法的 MessageDigest 对象 + MessageDigest mdInst = MessageDigest.getInstance("MD5"); + // 使用指定的字节更新摘要 + mdInst.update(btInput); + // 获得密文 + byte[] md = mdInst.digest(); + // 把密文转换成十六进制的字符串形式 + int j = md.length; + char str[] = new char[j * 2]; + int k = 0; + for (int i = 0; i < j; i++) { + byte byte0 = md[i]; + str[k++] = hexDigits[byte0 >>> 4 & 0xf]; + str[k++] = hexDigits[byte0 & 0xf]; + } + return new String(str); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + + } +} diff --git a/face-common/src/main/java/com/dkha/common/pwd/SHA1.java b/face-common/src/main/java/com/dkha/common/pwd/SHA1.java new file mode 100644 index 0000000..f18da3e --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/pwd/SHA1.java @@ -0,0 +1,47 @@ +package com.dkha.common.pwd; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * sha转换 + */ +public class SHA1 { + + private static Logger logger = LoggerFactory.getLogger(SHA1.class); + + public static String convert(String password) { + MessageDigest messageDigest; + try { + messageDigest = MessageDigest.getInstance("SHA-1"); + messageDigest.update(password.getBytes("UTF-8")); + password = SHA1.byte2hex(messageDigest.digest()); + } catch (NoSuchAlgorithmException e) { + logger.error(e.getMessage(), e); + } catch (UnsupportedEncodingException e) { + logger.error(e.getMessage(), e); + } + return password; + } + + private static String byte2hex(byte[] b) { + String hs = ""; + String stmp = ""; + for (int n = 0; n < b.length; n++) { + stmp = (Integer.toHexString(b[n] & 0xFF)); + if (stmp.length() == 1) + hs = hs + "0" + stmp; + else + hs = hs + stmp; + } + return hs; + } + + public static void main(String[] args) { + System.out.println(SHA1.convert("123123")); + } +} diff --git a/face-common/src/main/java/com/dkha/common/redis/RedisConfig.java b/face-common/src/main/java/com/dkha/common/redis/RedisConfig.java new file mode 100644 index 0000000..876a092 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/redis/RedisConfig.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.common.redis; + +import com.dkha.common.redis.serializer.JsonRedisSerializer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +import javax.annotation.Resource; + +/** + * Redis配置 + * + * @author Mark sunlightcs@gmail.com + */ +@Configuration +public class RedisConfig { + @Resource + private RedisConnectionFactory factory; + + @Bean + public RedisTemplate redisTemplate() { + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(new JsonRedisSerializer<>(Object.class)); + redisTemplate.setHashKeySerializer(new StringRedisSerializer()); + redisTemplate.setHashValueSerializer(new JsonRedisSerializer<>(Object.class)); + redisTemplate.setConnectionFactory(factory); + + return redisTemplate; + } +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/redis/RedisKeys.java b/face-common/src/main/java/com/dkha/common/redis/RedisKeys.java new file mode 100644 index 0000000..0fc0eca --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/redis/RedisKeys.java @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.common.redis; + + +/** + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class RedisKeys { + /** + * 系统参数Key + */ + public static String getSysParamsKey(){ + return "sys:params"; + } + + /** + * 验证码Key + */ + public static String getCaptchaKey(String uuid){ + return "sys:captcha:" + uuid; + } + + /** + * socketSessionId Key + */ + public static String getSessionIdKey(String sessionId){ + return "sys:sessionId:" + sessionId; + } + /** + * 摄像头id + * @param cameraId + * @return + */ + public static String getCameraSize(String cameraId){return "task:socket:"+cameraId;} + + + /** + * 用來軌跡追蹤保存摄像头信息 + * @param cameraId + * @return + */ + public static String getCameraByTrack(String time,String cameraId){return "task:track:"+time+":"+cameraId;} + + /** + * 用來軌跡追蹤保存摄像头信息 + * @param faceId + * @return + */ + public static String getCameraByFaceId(String time,String cameraId,String faceId){return "task:track:"+time+":"+cameraId+":face:"+faceId;} + + /** + * 用來軌跡追蹤保存摄像头信息 + * @param time + * @param cameraId + * @return + */ + public static String getCameraByExpired(String time,String cameraId){return "task:expired:"+time+":"+cameraId;} + +} diff --git a/face-common/src/main/java/com/dkha/common/redis/RedisUtils.java b/face-common/src/main/java/com/dkha/common/redis/RedisUtils.java new file mode 100644 index 0000000..634ca1b --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/redis/RedisUtils.java @@ -0,0 +1,144 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.common.redis; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.HashOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * Redis工具类 + * + * @author Mark sunlightcs@gmail.com + */ +@Component +public class RedisUtils { + @Autowired + private RedisTemplate redisTemplate; + + /** 默认过期时长为1天,单位:秒 */ + public final static long DEFAULT_EXPIRE = 60 * 60 * 24L; + + /** 长登录--保持15天 */ + public final static long LONG_LOGIN_EXPIRE = 60 * 60 * 24 * 15L; + + /** 短登录-保持30分钟 */ + public final static long SHORT_LOGIN_EXPIRE = 60 * 30L; + + /** 30分钟缓存有效期 */ + public final static long SHORT_DEFAULT_EXPIRE = 60 * 30L; + + /** 默认短信过期时间 */ + public final static long SHORT_MESSAGE_EXPIRE = 60 * 5L; + + /** 不设置过期时长 */ + public final static long NOT_EXPIRE = -1L; + + public void set(String key, Object value, long expire){ + redisTemplate.opsForValue().set(key, value); + if(expire != NOT_EXPIRE){ + expire(key, expire); + } + } + /** + * 检测key是否存在 + * @param key + * @return + */ + public boolean exists(String key) + { + return redisTemplate.hasKey(key); + } + public void set(String key, Object value){ + set(key, value, DEFAULT_EXPIRE); + } + + public Object get(String key, long expire) { + Object value = redisTemplate.opsForValue().get(key); + if(expire != NOT_EXPIRE){ + expire(key, expire); + } + return value; + } + + + public Object get(String key) { + return get(key, NOT_EXPIRE); + } + + public void delete(String key) { + redisTemplate.delete(key); + } + + public void delete(Collection keys) { + redisTemplate.delete(keys); + } + + public Object hGet(String key, String field) { + return redisTemplate.opsForHash().get(key, field); + } + + public Map hGetAll(String key){ + HashOperations hashOperations = redisTemplate.opsForHash(); + return hashOperations.entries(key); + } + + public void hMSet(String key, Map map){ + hMSet(key, map, DEFAULT_EXPIRE); + } + + public void hMSet(String key, Map map, long expire){ + redisTemplate.opsForHash().putAll(key, map); + + if(expire != NOT_EXPIRE){ + expire(key, expire); + } + } + + public void hSet(String key, String field, Object value) { + hSet(key, field, value, DEFAULT_EXPIRE); + } + + public void hSet(String key, String field, Object value, long expire) { + redisTemplate.opsForHash().put(key, field, value); + + if(expire != NOT_EXPIRE){ + expire(key, expire); + } + } + + public void expire(String key, long expire){ + redisTemplate.expire(key, expire, TimeUnit.SECONDS); + } + + public void hDel(String key, Object... fields){ + redisTemplate.opsForHash().delete(key, fields); + } + + public void leftPush(String key, Object value){ + leftPush(key, value, DEFAULT_EXPIRE); + } + + public void leftPush(String key, Object value, long expire){ + redisTemplate.opsForList().leftPush(key, value); + + if(expire != NOT_EXPIRE){ + expire(key, expire); + } + } + + public Object rightPop(String key){ + return redisTemplate.opsForList().rightPop(key); + } +} diff --git a/face-common/src/main/java/com/dkha/common/redis/serializer/JsonRedisSerializer.java b/face-common/src/main/java/com/dkha/common/redis/serializer/JsonRedisSerializer.java new file mode 100644 index 0000000..d6c4843 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/redis/serializer/JsonRedisSerializer.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.common.redis.serializer; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.util.IOUtils; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.SerializationException; + + +/** + * Redis序列化 + * + * @author Mark sunlightcs@gmail.com + */ +public class JsonRedisSerializer implements RedisSerializer { + private static ParserConfig defaultRedisConfig = new ParserConfig(); + static { + defaultRedisConfig.setAutoTypeSupport(true); + } + + private Class type; + + public JsonRedisSerializer(Class type) { + this.type = type; + } + + @Override + public byte[] serialize(T t) throws SerializationException { + if (t == null) { + return new byte[0]; + } + return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(IOUtils.UTF8); + } + + @Override + public T deserialize(byte[] bytes) throws SerializationException { + if (bytes == null || bytes.length <= 0) { + return null; + } + String str = new String(bytes, IOUtils.UTF8); + + return JSON.parseObject(str, type, defaultRedisConfig); + } +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/result/CommonResult.java b/face-common/src/main/java/com/dkha/common/result/CommonResult.java new file mode 100644 index 0000000..a3b8084 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/result/CommonResult.java @@ -0,0 +1,145 @@ +package com.dkha.common.result; + + +import com.dkha.common.exception.DkException; +import com.dkha.common.systemcode.SystemCode; +import com.dkha.common.util.UtilValidate; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.ControllerAdvice; + +import java.io.Serializable; + +/** + * @Author Spring + * @Since 2019/8/15 11:55 + * @Description 通用结果类 每个controller都集成该类,从而实现统返回结果 + * 约束如下:成功的状态码返回0 + * 错误操作或者特殊状态码 统一返回非0 错误码默认采用60001 + */ +@ControllerAdvice +public class CommonResult implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 返回信息码 */ + private Integer code; + /** 返回的文字信息 */ + private String message; + /** 返回数据 */ + private Object data; + + /** + * 用于auto write + */ + public CommonResult(){ + + } + + public CommonResult(Object data, Integer code, String message) { + this.code = code; + this.data = data; + this.message = message; + } + + public CommonResult(Integer code, String message) { + this.code = code; + this.data = null; + this.message = message; + } + + /** + * 操作成功返回集 code为0 + */ + public CommonResult successResult(Object data) { + CommonResult commonResult = new CommonResult(); + commonResult.code = SystemCode.HANDLER_SUCCESS.code; + commonResult.data = data; + commonResult.message = SystemCode.HANDLER_SUCCESS.des; + return commonResult; + } + + /** + * 操作成功返回集 code为0 + * @param message + * @param data + */ + public CommonResult successResult(String message, Object data) { + CommonResult commonResult = new CommonResult(); + commonResult.code = SystemCode.HANDLER_SUCCESS.code; + commonResult.data = data; + commonResult.message = UtilValidate.isEmpty(message) ? SystemCode.HANDLER_SUCCESS.des : message; + return commonResult; + } + + /** + * 操作失败返回集 默认code 60001 + * @param message + * @return + */ + public CommonResult failResult(String message) { + CommonResult commonResult = new CommonResult(); + commonResult.code = SystemCode.HANDLER_FAILED.code; + commonResult.data = null; + commonResult.message = message; + return commonResult; + } + + /** + * 操作失败返回集 默认code + * @return + */ + public CommonResult failResult(SystemCode systemCode) { + CommonResult commonResult = new CommonResult(); + commonResult.code = systemCode.code; + commonResult.data = null; + commonResult.message = systemCode.des; + return commonResult; + } + + /** + * 操作失败返回集 + * @param data + * @param message + * @param code + */ + public CommonResult failResult(Integer code, String message, Object data) { + CommonResult commonResult = new CommonResult(); + commonResult.code = UtilValidate.isEmpty(code) ? SystemCode.HANDLER_FAILED.code : code; + commonResult.data = data; + commonResult.message = UtilValidate.isEmpty(message) ? SystemCode.HANDLER_FAILED.des : message; + return commonResult; + } + /** + * 用于Hibernate-validate vo校验 + * @param bindingResult + */ + public void validate(BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new DkException(bindingResult.getFieldError().getDefaultMessage()); + } + } + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public Object getData() { + return data; + } + + public void setData(Object data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} + diff --git a/face-common/src/main/java/com/dkha/common/signature/SignatureUtil.java b/face-common/src/main/java/com/dkha/common/signature/SignatureUtil.java new file mode 100644 index 0000000..ef9fbb9 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/signature/SignatureUtil.java @@ -0,0 +1,144 @@ +package com.dkha.common.signature; + +import com.dkha.common.http.HttpUtil; +import com.dkha.common.util.UtilValidate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.DigestUtils; +import sun.misc.BASE64Encoder; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +/** + * @Author Spring + * @Since 2019/9/26 22:14 + * @Description 接口签名校验 + */ + +public class SignatureUtil { + + public static final Logger logger = LoggerFactory.getLogger(SignatureUtil.class); + + public static final String HMAC_SHA1_ALGORITHM = "HmacSHA1"; + + /** + * 校验签名 + * @param request + * @param secretKey 秘钥 + * @param time 请求时间 + * @param signature 请求过来的签名 + * @return + */ + public static boolean validateSignature(HttpServletRequest request, String secretKey, String time, String signature) { + if (signature(request, secretKey, time).equals(signature)) { + return true; + } + return false; + } + + /** + * 生成签名 + * @param request + * @param secretKey 秘钥 + * @param time 请求时间 + * @return + * + * 签名生成算法如下 + * StringToSing = HTTP-Verb +”\n”+      //http请求的动作 + * + *             Content-MD5+”\n”+     //http请求的MD5值 + * + *             Content-Type+”\n”+     //http请求的类型 + * + *             Date+”\n”+            //http请求时间 + * + *             CanonicalizdResource;  //http请求资源--当前版本不适用该字段做为签名 + * + * 签名生成算法 + * Signature = Base64( HMAC-SHA1( AccessSecret, UTF-8-Encoding-Of(StringToSign)) ) + * + * https://help.aliyun.com/knowledge_detail/106305.html + * https://blog.csdn.net/huanggang028/article/details/9004322 + */ + public static String signature(HttpServletRequest request, String secretKey, String time) { + //获取请求方法 + String requestMethod = request.getMethod(); + String requestData = ""; + try { + requestData = HttpUtil.getRequestPostBytes(request); + } catch (IOException e) { + logger.error(e.getMessage(), e); + return null; + } + String contentType = request.getContentType(); + String waitSignStr = requestMethod + "\n" + (UtilValidate.isEmpty(requestData) ? "" : md5Encode(requestData) + "\n") + contentType + "\n" + time; + try { + waitSignStr = new String(waitSignStr.getBytes(), "utf-8"); + } catch (UnsupportedEncodingException e) { + logger.error(e.getMessage(), e); + return null; + } + String cipherText = hamcsha1(waitSignStr, secretKey); + cipherText = base64Encode(cipherText); + return cipherText; + } + + + /** + * HMAC_SHA1 签名 + * @param data 消息 + * @param secretKey 签名密钥 + * @return + */ + public static String hamcsha1(String data, String secretKey) { + try { + SecretKeySpec signingKey = new SecretKeySpec(secretKey.getBytes(), HMAC_SHA1_ALGORITHM); + Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM); + mac.init(signingKey); + return byte2hex(mac.doFinal(data.getBytes())); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (InvalidKeyException e) { + e.printStackTrace(); + } + return null; + } + + /** + * md5 加密 + * @param data + * @return + */ + public static String md5Encode(String data) { + return DigestUtils.md5DigestAsHex(data.getBytes()); + } + + public static String base64Encode(String data) { + BASE64Encoder encoder = new BASE64Encoder(); + return encoder.encode(data.getBytes()); + } + + /** + * 字节数组转16进制 + * @param b 字节数组 + * @return + */ + public static String byte2hex(byte[] b) { + StringBuilder hs = new StringBuilder(); + String stmp; + for (int n = 0; b != null && n < b.length; n++) { + stmp = Integer.toHexString(b[n] & 0XFF); + if (stmp.length() == 1) { + hs.append('0'); + } + hs.append(stmp); + } + return hs.toString().toUpperCase(); + } +} diff --git a/face-common/src/main/java/com/dkha/common/systemcode/SystemCode.java b/face-common/src/main/java/com/dkha/common/systemcode/SystemCode.java new file mode 100644 index 0000000..6c06efa --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/systemcode/SystemCode.java @@ -0,0 +1,148 @@ +package com.dkha.common.systemcode; + + +/** + * @Author Spring + * @Since 2018/8/15 11:55 + * @Description 系统通用返回码 约束如下: + * 操作成功 统一返回code 0 + * 错误操作或者特殊状态码 统一返回非0 错误码默认采用60001 + */ +public enum SystemCode { + + WX_GET_CONFIG_ERROR(40000, "获取微信参数错误"), + WX_UPLOAD_ERROR(40001, "获取微信参数错误"), + + /** + * -----------------------------统一异常捕获(50***)异常码定义------------------------------------- + */ + + INTERNAL_PROGRAM_ERROR(50000, "程序内部错误,操作失败"), + DATA_ACCESS_EXCEPTION(50001, "数据库操作失败"), + COMMUNICATIONS_EXCEPTION(50002, "数据库连接中断"), + CONSTRAINT_VIOLATION_EXCEPTION(50002, "对象已经存在,请勿重复操作"), + DATA_INTEGRITY_VIOLATION_EXCEPTION(50003, "对象已经存在,请勿重复操作"), + MYSQL_INTEGRITY_CONSTRAINT_VIOLATION_EXCEPTION(50004, "对象已经存在,请勿重复操作"), + NULL_POINTER_EXCEPTION(50005, "调用了未经初始化的对象或者是不存在的对象"), + IO_EXCEPTION(50006, "IO异常"), + CLASS_NOT_FOUND_EXCEPTION(50007, "指定的类不存在"), + ARITHMETIC_EXCEPTION(50008, "数学运算异常"), + ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION(50009, "数组下标越界"), + ILLEGAL_ARGUMENT_EXCEPTION(50010, "参数错误或非法"), + ClassCastException(50011, "类型强制转换错误"), + SQL_EXCEPTION(50013, "操作数据库异常"), + SECURITY_EXCEPTION(50012, "违背安全原则异常"), + NO_SUCH_METHOD_EXCEPTION(50014, "方法未找到异常"), + INTERNAL_ERROR(50015, "内部错误"), + CONNECT_EXCEPTION(50016, "服务器连接异常"), + CANCELLATION_EXCEPTION(50017, "任务已被取消的异常"), + API_EXCEPTION(50018, "阿里服务器错误"), + PARSE_EXCEPTION(50019, "日期格式错误"), + DATA_OVER_LONG(50020, "数据超长"), + + /**-----------------------------统一异常捕获(50***)异常码定义-------------------------------------*/ + + + /** + * -----------------------------参数异常(51***)异常码定义------------------------------------- + */ + + ParaIsNull(51002, "参数为空"), + paraNotRight(51003, "参数非法"), + + /** + * -----------------------------公共操作成功、失败(60***)异常码定义------------------------------------- + */ + + HANDLER_SUCCESS(0, "操作成功"), + HANDLER_FAILED(60001, "操作失败"), + SAVE_SUCCESS(60002, "新增成功"), + SAVE_SUCCESS_(60017, "保存成功"), + SAVE_FAILED(60003, "新增失败"), + DELETE_SUCCESS(60004, "删除成功"), + DELETE_FAILED(60005, "删除失败"), + UPDATE_SUCCESS(60006, "修改成功"), + UPDATE_FAILED(60007, "修改失败"), + SET_SUCCESS(60008, "设置成功"), + SET_FAILED(60009, "设置失败"), + NO_DATA(60010, "无对应数据"), + SYNC_SUCCESS(60011, "同步成功"), + SYNC_FAILED(60012, "同步失败"), + SYNC_DATA_IS_NULL(60013, "同步数据为空"), + SYNC_DATA_NOT_ALL_SUCCESS(60014, "同步数据部分成功"), + FIND_SUCCESS(60015, "查询成功"), + FIND_FAILED(60016, "查询失败"), + COMMODITY_NUM_NOT_ENOUGH_FOR_ADD(60017, "商品数量不足"), + + COMMODITY_NUM_NOT_ENOUGH_FOR_REDUCE(60018, "商品数量不足"), + + COMMODITY_NOT_ENABLE(60019, "商品已下架"), + EXCEL_ERROR_DATA(60020, "excel错误数据"), + + ORDER_INVALID(61000, "订单已无效"), + + WX_PAY_ERROR(62000, "微信支付异常"), + + /** + * -----------------------------登录成功、失败(70***)异常码定义------------------------------------- + */ + + LOGIN_SUCCESS(70000,"登录成功"), + LOGIN_FAILED(70001,"登录失败"), + LOGIN_FAILED_USERNAME(70002,"用户名不存在"), + LOGIN_FAILED_PASSWORD(70003,"密码错误"), + LOGIN_FAILED_USERNAME_OR_PASSWORD(70004,"用户名或密码错误"), + LOGIN_FAILED_SESSION_TIMEOUT(70005,"重新登录"), + LOGIN_ERROR_USER(70006,"用户状态异常"), + ACCOUNT_ENABLE(70007, "账号已停用"), + ACCOUNT_CAN_NOT_EMPTY(70008, "账号不能为空"), + PASSWORD_CAN_NOT_EMPTY(70009, "密码不能为空"), + LOGIN_LIMIT(70010, "账号已锁定,请联系主管部门管理人员初始化登录密码!"), + + TOKEN_ERROR(71000, "token无效"), + TOKEN_EXPIRED(71001, "token已过期"), + SESSION_EXPIRE(71002, "账号已过期,请重新登录!"), + VERIFICATION_CODE_ERROR(71003, "图形验证码错误!"), + SINGLE_EQUIPMENT_ERROR(71004, "当前账号已在其他设备登录!"), + SHORT_MESSAGE_CODE_ERROR(71005, "短信验证码错误!"), + SHORT_MESSAGE_CAN_NOT_NULL(71006, "短信验证码不能为空!"), + SHORT_MESSAGE_EXPIRED(71007, "短信验证码已过期!"), + SIGNATURE_ERROR(71008, "签名错误!"), + PHONE_ALREADY_REGISTER(71009, "当前手机号已注册!"), + USER_NOT_FOLLOW(72000, "当前用户未关注微信公众号."), + ACCOUNT_WAIT_REVIEW(72001, "账号待审核."), + ACCOUNT_REVIEW_NOT_PASS(72002, "账号审核未通过."), + NOT_AUTHORIZATION(72003, "当前用户暂无权限."), + + REDIS_ERROR(80001, "redis错误"), + DATA_CAN_NOT_EMPTY(80002, "数据不能为空!"), + LABEL_ERROR(80003, "查不到身份信息,请到人社局录入!"), + IDCARD_ERROR(80005, "身份证号码输入不正确!"), + FILE_ERROR(80006, "文件名格式不正确!"), + DELETELIB_ERROR(80007, "该库有关联的布控信息,不能删除!"), + FACESRH_ERROR(80008, "没有人脸信息!"), + LABELCONLL_ERROR(80004, "岗位已经收藏过了!"); + + public Integer code; + public String des; + + SystemCode(Integer code, String des) { + this.code = code; + this.des = des; + } + + public static SystemCode get(Integer code) { + for (SystemCode errorCode : SystemCode.values()) { + if (errorCode.code.toString().equals(code.toString())) { + return errorCode; + } + } + return null; + } + + @Override + public String toString() { + return "code:" + code + ", des:" + des; + } + +} diff --git a/face-common/src/main/java/com/dkha/common/util/Base64ImageUtils.java b/face-common/src/main/java/com/dkha/common/util/Base64ImageUtils.java new file mode 100644 index 0000000..b4cc126 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/Base64ImageUtils.java @@ -0,0 +1,444 @@ +package com.dkha.common.util; + +import com.dkha.common.modules.vo.position.PositionVO; +import com.google.gson.Gson; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import sun.misc.BASE64Decoder; +import sun.misc.BASE64Encoder; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.*; +import java.net.MalformedURLException; +import java.net.URL; + +@Component +public class Base64ImageUtils { + + public static final Logger logger = LoggerFactory.getLogger(Base64ImageUtils.class); + + /** + * 将网络图片进行Base64位编码 + * + * @param imageUrl 图片的url路径,如http://.....xx.jpg + * @return + */ + public static String encodeImgageToBase64(URL imageUrl) {// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + ByteArrayOutputStream outputStream = null; + try { + BufferedImage bufferedImage = ImageIO.read(imageUrl); + outputStream = new ByteArrayOutputStream(); + ImageIO.write(bufferedImage, "png", outputStream); + // 对字节数组Base64编码 + BASE64Encoder encoder = new BASE64Encoder(); + byte[] by = outputStream.toByteArray(); + return encoder.encode(by); + } catch (MalformedURLException e1) { + e1.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (outputStream != null) { + try { + outputStream.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + + return null;///encoder.encode(by);// 返回Base64编码过的字节数组字符串 + } + + /** + * 将网络图片进行Base64位编码 + * + * @param imageUrl 图片的url路径,如http://.....xx.jpg + * @return + */ + public static BufferedImage urlToBufferImage(URL imageUrl) {// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + try { + BufferedImage bufferedImage = ImageIO.read(imageUrl); + return bufferedImage; + } catch (MalformedURLException e1) { + } catch (IOException e) { + } finally { + + } + + + return null;///encoder.encode(by);// 返回Base64编码过的字节数组字符串 + } + + /** + * 将图片流转换为Base64 + * + * @param bufferedImage + * @return + */ + public static String encodeImgageToBase64(BufferedImage bufferedImage) {// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + ByteArrayOutputStream outputStream = null; + try { +// BufferedImage bufferedImage = ImageIO.read(imageUrl); + outputStream = new ByteArrayOutputStream(); + ImageIO.write(bufferedImage, "png", outputStream); + // 对字节数组Base64编码 + BASE64Encoder encoder = new BASE64Encoder(); + byte[] by = outputStream.toByteArray(); + return encoder.encode(by); + } catch (MalformedURLException e1) { + e1.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (outputStream != null) { + try { + outputStream.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + + return null;///encoder.encode(by);// 返回Base64编码过的字节数组字符串 + } + + /** + * 将本地图片进行Base64位编码 + * + * @param imageFile 图片的url路径,如F:/.....xx.jpg + * @return + */ + public static String encodeImgageToBase64(File imageFile) {// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + ByteArrayOutputStream outputStream = null; + try { + BufferedImage bufferedImage = ImageIO.read(imageFile); + outputStream = new ByteArrayOutputStream(); + ImageIO.write(bufferedImage, "png", outputStream); + // 对字节数组Base64编码 + BASE64Encoder encoder = new BASE64Encoder(); + + byte[] by = outputStream.toByteArray(); + return encoder.encode(by); + } catch (MalformedURLException e1) { + e1.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (outputStream != null) { + try { + outputStream.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + return null; + // 返回Base64编码过的字节数组字符串 + } + + /** + * 将Base64位编码的图片进行解码,并保存到指定目录 + * + * @param base64 base64编码的图片信息 + * @return + */ + public static void decodeBase64ToImage(String base64, String path, + String imgName) { + BASE64Decoder decoder = new BASE64Decoder(); + FileOutputStream write = null; + try { + write = new FileOutputStream(new File(path + + imgName)); + byte[] decoderBytes = decoder.decodeBuffer(base64); + write.write(decoderBytes); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + write.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + } + + /** + * 将Base64位编码的图片进行解码,输出byte + * + * @param base64 base64编码的图片信息 + * @return + */ + public static byte[] decodeBase64ToImage(String base64) { + BASE64Decoder decoder = new BASE64Decoder(); + try { + byte[] decoderBytes = decoder.decodeBuffer(base64); + return decoderBytes; + } catch (IOException e) { + return null; + } finally { + } + } + + /** + * @return + */ + public static InputStream encodeImgage(BufferedImage subimage) { + ByteArrayOutputStream outputStream = null; + try { + /**如果根据坐标找不到人脸的时候*/ + if (UtilValidate.isNotEmpty(subimage)) { + outputStream = new ByteArrayOutputStream(); + ImageIO.write(subimage, "png", outputStream); + byte[] by = outputStream.toByteArray(); + /**将byte转为InputStream*/ + InputStream sbs = new ByteArrayInputStream(by); + return sbs; + } + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + public static InputStream encodeImgage(BufferedImage subimage, String imagetype) { + ByteArrayOutputStream outputStream = null; + try { + /**如果根据坐标找不到人脸的时候*/ + if (UtilValidate.isNotEmpty(subimage)) { + outputStream = new ByteArrayOutputStream(); + ImageIO.write(subimage, "png", outputStream); + byte[] by = outputStream.toByteArray(); + /**将byte转为InputStream*/ + InputStream sbs = new ByteArrayInputStream(by); + return sbs; + } + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 对返回的人脸坐标进行扩大处理 + * deelPostion + * + * @param picwidth 原图长 + * @param picheight 原图宽 + * @return ImgPositionVO + */ + public static PositionVO deelPostion(PositionVO positionVO, Integer picwidth, Integer picheight) { + + int xold = positionVO.getX(); + int yold = positionVO.getY(); + int widthold = positionVO.getW(); + int heightold = positionVO.getH(); + + int x = ((xold - widthold / 2)); + int y = (yold - heightold / 2); + int width = widthold * 2; + int height = heightold * 2; + if (width > picwidth) { + width = picwidth; + } + if (height > picheight) { + height = picheight; + } + + if (x + width > picwidth) { + x = picwidth-width; + } + if (x < 0) {x = 0;} + if (y + height > picheight) { + y = picheight-height ; + } + if (y < 0) { + y=0; + } + return new PositionVO(x, y, width, height); + } + + /** + * 根据坐标 获取头部位置 + * + * @param + * @param positionVo 坐标类 + * @return + */ + public static InputStream encodeHeadImage(BufferedImage bufferedImage, PositionVO positionVo) { + try { +// BufferedImage bufferedImage = ImageIO.read(url); + //获取整个背景图片的宽度和高度 +// int picWidth = bufferedImage.getWidth(); +// int picHeight = bufferedImage.getHeight(); +// +// int xOld = positionVo.getX(); +// int yOld = positionVo.getY(); +// int widthOld = positionVo.getW(); +// int heightOld = positionVo.getH(); +// +// int x = ((xOld - widthOld/2)); +// int y = (yOld - heightOld/2); +// int width = widthOld * 2; +// int height = heightOld * 2; +// if(width > picWidth) +// { +// width = picWidth; +// } +// if(height > picHeight) +// { +// height = picHeight; +// } +// +// if(x+width > picWidth) +// { +// x = x - picWidth; +// } +// +// if(x < 0) { +// x = 0; +// } +// if(y + height > picHeight) +// { +// y= y - picHeight; +// +// } +// if(y < 0) { +// y = 0; +// } + BufferedImage subimage = bufferedImage.getSubimage(positionVo.getX(), positionVo.getY(), positionVo.getW(), positionVo.getH()); + return encodeImgage(subimage); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + return null; + } + + /** + * base64转成InputStream + * + * @param base64string + * @return + */ + public static InputStream BaseToInputStream(String base64string) { + try { + byte[] bytes = decodeBase64ToImage(base64string); + /**将byte转为InputStream*/ + InputStream sbs = new ByteArrayInputStream(bytes); + return sbs; + } catch (Exception e) { + logger.error(e.getMessage(), e); + + } + return null; + + } + + public static void main(String[] args) { +// URL url = null; +// try { +// url = new URL("http://img1.imgtn.bdimg.com/it/u=2064054871,2037178638&fm=200&gp=0.jpg"); +// } catch (MalformedURLException e) { +// e.printStackTrace(); +// } +// String encoderStr = Base64ImageUtils.encodeImgageToBase64(url); +// System.out.println(encoderStr); +// +// Base64ImageUtils.decodeBase64ToImage(encoderStr, "E:/", "football.jpg"); +// +// PositionVO positionVO = new PositionVO(); +// positionVO.setX(1080); +// positionVO.setY(657); +// positionVO.setW(34); +// positionVO.setH(43); +// positionVO.setBgHeight(607); +// positionVO.setBgWidth(1080); +//// PositionVO positionVO1 =Base64ImageUtils.deelPostion(positionVO,1080,607); +//// logger.info("结果",positionVO1); +// String a = "http://10.51.10.203:32080/g10203/M00/09/50/CjMKy14eqj-AKvQFAAlJMLj0vEY312.jpg"; +// +// +// BufferedImage bufferedImage = null; +// try { +// url = new URL("http://10.51.10.203:32080/g10203/M00/0B/16/CjMKy14e0hyAekdqAAEJd1FBfaY815.jpg"); +// } catch (MalformedURLException e) { +// e.printStackTrace(); +// } +// int x=694; +// int y=744; +// int w=240; +// int h=324; +// int bgw=1920; +// int bgh=1080; +// +// PositionVO positionVO=new PositionVO(); +// positionVO.setW(w); +// positionVO.setX(x); +// positionVO.setY(y); +// positionVO.setH(h); +// positionVO.setBgWidth(bgw); +// positionVO.setBgHeight(bgh); +// +// Gson gson=new Gson(); +// System.out.println(gson.toJson(positionVO)); +// BufferedImage bufferedImage=urlToBufferImage(url); +// PositionVO positionVO1=deelPostion(positionVO,positionVO.getBgWidth(),positionVO.getBgHeight()); +// System.out.println(gson.toJson(positionVO1)); +// BufferedImage bufferedImage2=bufferedImage.getSubimage(positionVO1.getX(),positionVO1.getY(),positionVO1.getW(),positionVO1.getH()); +// BufferedImage bufferedImage3=bufferedImage.getSubimage(positionVO.getX(),positionVO.getY(),positionVO.getW(),positionVO.getH()); +// +// +// +// try { +// File file1 =new File("D:/test/curtvedio/img/"+System.currentTimeMillis()+".png"); +// ImageIO.write(bufferedImage2, "png",file1); +// File file2 =new File("D:/test/curtvedio/img/"+System.currentTimeMillis()+".png"); +// ImageIO.write(bufferedImage3, "png",file2); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// +// +//// String encoderStr = Base64ImageUtils.encodeImgageToBase64(url); +//// System.out.println(encoderStr); +// +// +//// Base64ImageUtils.decodeBase64ToImage(encoderStr, "E:/", "football.jpg"); +//======= +// bufferedImage = Base64ImageUtils.urlToBufferImage(new URL(a)); +// +// } catch (MalformedURLException e) { +// e.printStackTrace(); +// } +// PositionVO positionVo = Base64ImageUtils.deelPostion(positionVO, bufferedImage.getWidth(), bufferedImage.getHeight()); +// positionVo.setBgHeight(bufferedImage.getHeight()); +// positionVo.setBgWidth(bufferedImage.getWidth()); +// InputStream in = Base64ImageUtils.encodeHeadImage(bufferedImage, positionVo); +// +// File file = new File("E:/footba.jpg");//文件名 相对路径(项目名根目录下) +// try { +// FileOutputStream fos = new FileOutputStream(file);//true表示追加,如果文件存在 向里面继续添加内容 +// byte[] bytes = new byte[1024]; +// while ((in.read(bytes)) != -1) { +// fos.write(bytes); +// } +// in.close(); +// fos.close();//关闭流 +// } catch (IOException e) { +// e.printStackTrace(); +// } +// +//>>>>>>> 6f675f6d18b0403c24529d795e1b57ca27a1f970 + + } + +} diff --git a/face-common/src/main/java/com/dkha/common/util/ContextUtil.java b/face-common/src/main/java/com/dkha/common/util/ContextUtil.java new file mode 100644 index 0000000..42175cd --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/ContextUtil.java @@ -0,0 +1,33 @@ +package com.dkha.common.util; + +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +/** + * @Author Spring + * @Since 2019/8/15 14:10 + * @Description Spring上下文工具类 + */ +public class ContextUtil { + + /** + * get request + * @return + */ + public static HttpServletRequest getRequest() { + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + return request; + } + + /** + * get session + * @return + */ + public static HttpSession getSession() { + HttpSession session = getRequest().getSession(); + return session; + } +} diff --git a/face-common/src/main/java/com/dkha/common/util/DateUtils.java b/face-common/src/main/java/com/dkha/common/util/DateUtils.java new file mode 100644 index 0000000..9ddf9b2 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/DateUtils.java @@ -0,0 +1,1221 @@ +package com.dkha.common.util; + +import org.springframework.util.StringUtils; + +import java.beans.PropertyEditorSupport; +import java.sql.Timestamp; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * @Author Spring + * @Since 2016/8/15 14:10 + * @Description 日期工具类 + */ +public class DateUtils extends PropertyEditorSupport { + + public static final SimpleDateFormat date_sdf = new SimpleDateFormat("yyyy-MM-dd"); + public static final SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyyMMdd"); + public static final SimpleDateFormat date_sdf_wz = new SimpleDateFormat("yyyy年MM月dd日"); + public static final SimpleDateFormat time_sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + public static final SimpleDateFormat yyyymmddhhmmss = new SimpleDateFormat("yyyyMMddHHmmss"); + public static final SimpleDateFormat short_time_sdf = new SimpleDateFormat("HH:mm"); + public static final SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat yyyyMM = new SimpleDateFormat("yyyy-MM"); + + /** + * 时间格式(yyyy-MM-dd HH:mm:ss) + */ + public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; + + // 以毫秒表示的时间 + private static final long DAY_IN_MILLIS = 24 * 3600 * 1000; + private static final long HOUR_IN_MILLIS = 3600 * 1000; + private static final long MINUTE_IN_MILLIS = 60 * 1000; + private static final long SECOND_IN_MILLIS = 1000; + + // 指定模式的时间格式 + private static SimpleDateFormat getSDFormat(String pattern) { + return new SimpleDateFormat(pattern); + } + + /** + * 当前日历,这里用中国时间表示 + * + * @return 以当地时区表示的系统当前日历 + */ + public static Calendar getCalendar() { + return Calendar.getInstance(); + } + + /** + * 指定毫秒数表示的日历 + * + * @param millis 毫秒数 + * @return 指定毫秒数表示的日历 + */ + public static Calendar getCalendar(long millis) { + Calendar cal = Calendar.getInstance(); + cal.setTime(new Date(millis)); + return cal; + } + + // //////////////////////////////////////////////////////////////////////////// + // getDate + // 各种方式获取的Date + // //////////////////////////////////////////////////////////////////////////// + + /** + * 当前日期 + * + * @return 系统当前时间 + */ + public static Date getDate() { + return new Date(); + } + + /** + * @param dt + * @return (1 = 星期天, 2 = 星期一, … … 7 = 星期六 + */ + public static int getWeekOfDate(Date dt) { + Calendar cal = Calendar.getInstance(); + cal.setTime(dt); + return cal.get(Calendar.DAY_OF_WEEK); + } + + /** + * 获取指定时间属于周几 + * + * @param date 指定日期 + * @return + */ + public static int getChinaWeekOfDate(Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + int week = cal.get(Calendar.DAY_OF_WEEK) - 1; + if (week == 0) { + week = 7; + } + return week; + } + + /** + * 指定毫秒数表示的日期 + * + * @param millis 毫秒数 + * @return 指定毫秒数表示的日期 + */ + public static Date getDate(long millis) { + return new Date(millis); + } + + /** + * 时间戳转换为字符串 + * + * @param time + * @return + */ + public static String timestamptoStr(Timestamp time) { + Date date = null; + if (null != time) { + date = new Date(time.getTime()); + } + return date2Str(date_sdf); + } + + /** + * 字符串转换时间戳 + * + * @param str + * @return + */ + public static Timestamp str2Timestamp(String str) { + Date date = str2Date(str, date_sdf); + return new Timestamp(date.getTime()); + } + + /** + * 字符串转换成日期 + * + * @param str + * @param sdf + * @return + */ + public static Date str2Date(String str, SimpleDateFormat sdf) { + if (null == str || "".equals(str)) { + return null; + } + Date date = null; + try { + date = sdf.parse(str); + return date; + } catch (ParseException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 日期转换为字符串 + * + * @param date_sdf 日期格式 + * @return 字符串 + */ + public static String date2Str(SimpleDateFormat date_sdf) { + Date date = getDate(); + if (null == date) { + return null; + } + return date_sdf.format(date); + } + + /** + * 格式化时间 + * + * @param date + * @param format + * @return + */ + public static String dateformat(String date, String format) { + SimpleDateFormat sformat = new SimpleDateFormat(format); + Date _date = null; + try { + _date = sformat.parse(date); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return sformat.format(_date); + } + + /** + * 日期转换为字符串 + * + * @param date 日期 + * @param date_sdf 日期格式 + * @return 字符串 + */ + public static String date2Str(Date date, SimpleDateFormat date_sdf) { + if (null == date) { + return null; + } + return date_sdf.format(date); + } + + /** + * 日期转换为字符串 + * + * @param format 日期格式 + * @return 字符串 + */ + public static String getDate(String format) { + Date date = new Date(); + if (null == date) { + return null; + } + SimpleDateFormat sdf = new SimpleDateFormat(format); + return sdf.format(date); + } + + /** + * 指定毫秒数的时间戳 + * + * @param millis 毫秒数 + * @return 指定毫秒数的时间戳 + */ + public static Timestamp getTimestamp(long millis) { + return new Timestamp(millis); + } + + /** + * 以字符形式表示的时间戳 + * + * @param time 毫秒数 + * @return 以字符形式表示的时间戳 + */ + public static Timestamp getTimestamp(String time) { + return new Timestamp(Long.parseLong(time)); + } + + /** + * 系统当前的时间戳 + * + * @return 系统当前的时间戳 + */ + public static Timestamp getTimestamp() { + return new Timestamp(new Date().getTime()); + } + + /** + * 指定日期的时间戳 + * + * @param date 指定日期 + * @return 指定日期的时间戳 + */ + public static Timestamp getTimestamp(Date date) { + return new Timestamp(date.getTime()); + } + + /** + * 指定日历的时间戳 + * + * @param cal 指定日历 + * @return 指定日历的时间戳 + */ + public static Timestamp getCalendarTimestamp(Calendar cal) { + return new Timestamp(cal.getTime().getTime()); + } + + public static Timestamp gettimestamp() { + Date dt = new Date(); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String nowTime = df.format(dt); + Timestamp buydate = Timestamp.valueOf(nowTime); + return buydate; + } + + // //////////////////////////////////////////////////////////////////////////// + // getMillis + // 各种方式获取的Millis + // //////////////////////////////////////////////////////////////////////////// + + /** + * 系统时间的毫秒数 + * + * @return 系统时间的毫秒数 + */ + public static long getMillis() { + return new Date().getTime(); + } + + /** + * 指定日历的毫秒数 + * + * @param cal 指定日历 + * @return 指定日历的毫秒数 + */ + public static long getMillis(Calendar cal) { + return cal.getTime().getTime(); + } + + /** + * 指定日期的毫秒数 + * + * @param date 指定日期 + * @return 指定日期的毫秒数 + */ + public static long getMillis(Date date) { + return date.getTime(); + } + + /** + * 指定时间戳的毫秒数 + * + * @param ts 指定时间戳 + * @return 指定时间戳的毫秒数 + */ + public static long getMillis(Timestamp ts) { + return ts.getTime(); + } + + // //////////////////////////////////////////////////////////////////////////// + // formatDate + // 将日期按照一定的格式转化为字符串 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 默认方式表示的系统当前日期,具体格式:年-月-日 + * + * @return 默认日期按“年-月-日“格式显示 + */ + public static String formatDate() { + return date_sdf.format(getCalendar().getTime()); + } + + /** + * 获取时间字符串 + */ + public static String getDataString(SimpleDateFormat formatstr) { + return formatstr.format(getCalendar().getTime()); + } + + /** + * 指定日期的默认显示,具体格式:年-月-日 + * + * @param cal 指定的日期 + * @return 指定日期按“年-月-日“格式显示 + */ + public static String formatDate(Calendar cal) { + return date_sdf.format(cal.getTime()); + } + + /** + * 指定日期的默认显示,具体格式:年-月-日 + * + * @param date 指定的日期 + * @return 指定日期按“年-月-日“格式显示 + */ + public static String formatDate(Date date) { + return date_sdf.format(date); + } + + /** + * 指定毫秒数表示日期的默认显示,具体格式:年-月-日 + * + * @param millis 指定的毫秒数 + * @return 指定毫秒数表示日期按“年-月-日“格式显示 + */ + public static String formatDate(long millis) { + return date_sdf.format(new Date(millis)); + } + + /** + * 默认日期按指定格式显示 + * + * @param pattern 指定的格式 + * @return 默认日期按指定格式显示 + */ + public static String formatDate(String pattern) { + return getSDFormat(pattern).format(getCalendar().getTime()); + } + + /** + * 指定日期按指定格式显示 + * + * @param cal 指定的日期 + * @param pattern 指定的格式 + * @return 指定日期按指定格式显示 + */ + public static String formatDate(Calendar cal, String pattern) { + return getSDFormat(pattern).format(cal.getTime()); + } + + /** + * 指定日期按指定格式显示 + * + * @param date 指定的日期 + * @param pattern 指定的格式 + * @return 指定日期按指定格式显示 + */ + public static String formatDate(Date date, String pattern) { + return getSDFormat(pattern).format(date); + } + + // //////////////////////////////////////////////////////////////////////////// + // formatTime + // 将日期按照一定的格式转化为字符串 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 默认方式表示的系统当前日期,具体格式:年-月-日 时:分 + * + * @return 默认日期按“年-月-日 时:分“格式显示 + */ + public static String formatTime() { + return time_sdf.format(getCalendar().getTime()); + } + + /** + * 指定毫秒数表示日期的默认显示,具体格式:年-月-日 时:分 + * + * @param millis 指定的毫秒数 + * @return 指定毫秒数表示日期按“年-月-日 时:分“格式显示 + */ + public static String formatTime(long millis) { + return time_sdf.format(new Date(millis)); + } + + /** + * 指定日期的默认显示,具体格式:年-月-日 时:分 + * + * @param cal 指定的日期 + * @return 指定日期按“年-月-日 时:分“格式显示 + */ + public static String formatTime(Calendar cal) { + return time_sdf.format(cal.getTime()); + } + + /** + * 指定日期的默认显示,具体格式:年-月-日 时:分 + * + * @param date 指定的日期 + * @return 指定日期按“年-月-日 时:分“格式显示 + */ + public static String formatTime(Date date) { + return time_sdf.format(date); + } + + // //////////////////////////////////////////////////////////////////////////// + // formatShortTime + // 将日期按照一定的格式转化为字符串 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 默认方式表示的系统当前日期,具体格式:时:分 + * + * @return 默认日期按“时:分“格式显示 + */ + public static String formatShortTime() { + return short_time_sdf.format(getCalendar().getTime()); + } + + /** + * 指定毫秒数表示日期的默认显示,具体格式:时:分 + * + * @param millis 指定的毫秒数 + * @return 指定毫秒数表示日期按“时:分“格式显示 + */ + public static String formatShortTime(long millis) { + return short_time_sdf.format(new Date(millis)); + } + + /** + * 指定日期的默认显示,具体格式:时:分 + * + * @param cal 指定的日期 + * @return 指定日期按“时:分“格式显示 + */ + public static String formatShortTime(Calendar cal) { + return short_time_sdf.format(cal.getTime()); + } + + /** + * 指定日期的默认显示,具体格式:时:分 + * + * @param date 指定的日期 + * @return 指定日期按“时:分“格式显示 + */ + public static String formatShortTime(Date date) { + return short_time_sdf.format(date); + } + + // //////////////////////////////////////////////////////////////////////////// + // parseDate + // parseCalendar + // parseTimestamp + // 将字符串按照一定的格式转化为日期或时间 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间 + * + * @param src 将要转换的原始字符窜 + * @param pattern 转换的匹配格式 + * @return 如果转换成功则返回转换后的日期 + * @throws ParseException + * @throws ParseException + */ + public static Date parseDate(String src, String pattern) + throws ParseException { + return getSDFormat(pattern).parse(src); + + } + + /** + * 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间 + * + * @param src 将要转换的原始字符窜 + * @param pattern 转换的匹配格式 + * @return 如果转换成功则返回转换后的日期 + * @throws ParseException + * @throws ParseException + */ + public static Calendar parseCalendar(String src, String pattern) + throws ParseException { + + Date date = parseDate(src, pattern); + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + return cal; + } + + public static String formatAddDate(String src, String pattern, int amount) + throws ParseException { + Calendar cal; + cal = parseCalendar(src, pattern); + cal.add(Calendar.DATE, amount); + return formatDate(cal); + } + + /** + * 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间 + * + * @param src 将要转换的原始字符窜 + * @param pattern 转换的匹配格式 + * @return 如果转换成功则返回转换后的时间戳 + * @throws ParseException + * @throws ParseException + */ + public static Timestamp parseTimestamp(String src, String pattern) + throws ParseException { + Date date = parseDate(src, pattern); + return new Timestamp(date.getTime()); + } + + // //////////////////////////////////////////////////////////////////////////// + // dateDiff + // 计算两个日期之间的差值 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 计算两个时间之间的差值,根据标志的不同而不同 + * + * @param flag 计算标志,表示按照年/月/日/时/分/秒等计算 + * @param calSrc 减数 + * @param calDes 被减数 + * @return 两个日期之间的差值 + */ + public static int dateDiff(char flag, Calendar calSrc, Calendar calDes) { + + long millisDiff = getMillis(calSrc) - getMillis(calDes); + + if (flag == 'y') { + return (calSrc.get(calSrc.YEAR) - calDes.get(calDes.YEAR)); + } + /*月*/ + if (flag == 'M') { + return (calSrc.get(calSrc.MONTH) - calDes.get(calDes.MONTH)); + } + //这里的一天是指60*60*24这个毫秒数 + if (flag == 'd') { + return (int) (millisDiff / DAY_IN_MILLIS); + } + //这里的一天是指天文学上面的一天 + if (flag == 'D') { + return (calSrc.get(calSrc.DAY_OF_YEAR) - calDes.get(calDes.DAY_OF_YEAR)); + } + + if (flag == 'h') { + return (int) (millisDiff / HOUR_IN_MILLIS); + } + + if (flag == 'm') { + return (int) (millisDiff / MINUTE_IN_MILLIS); + } + + if (flag == 's') { + return (int) (millisDiff / SECOND_IN_MILLIS); + } + + return 0; + } + + /** + * 计算两个时间之间的差值,根据标志的不同而不同 + * + * @param flag 计算标志,表示按照年/月/日/时/分/秒等计算 + * @param start 开始日期 + * @param end 结束日期 + * @return 两个日期之间的差值 + */ + public static int dateDiff(char flag, Date start, Date end) { + Calendar s = date2Calendar(start); + Calendar e = date2Calendar(end); + return dateDiff(flag, e, s); + } + + /** + * 计算两个时间之间相差的天数 + * + * @param start 开始日期 + * @param end 结束日期 + */ + public static int dayDiff(Date start, Date end) { + return dateDiff('d', start, end); + } + + /** + * String类型 转换为Date, + * 如果参数长度为10 转换格式”yyyy-MM-dd“ + * 如果参数长度为19 转换格式”yyyy-MM-dd HH:mm:ss“ + * * @param text + * String类型的时间值 + */ + public void setAsText(String text) throws IllegalArgumentException { + if (StringUtils.hasText(text)) { + try { + if (text.indexOf(":") == -1 && text.length() == 10) { + setValue(this.date_sdf.parse(text)); + } else if (text.indexOf(":") > 0 && text.length() == 19) { + setValue(this.datetimeFormat.parse(text)); + } else { + throw new IllegalArgumentException( + "Could not parse date, date format is error "); + } + } catch (ParseException ex) { + IllegalArgumentException iae = new IllegalArgumentException( + "Could not parse date: " + ex.getMessage()); + iae.initCause(ex); + throw iae; + } + } else { + setValue(null); + } + } + + public static int getYear() { + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTime(getDate()); + return calendar.get(Calendar.YEAR); + } + + public static int getHour() { + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTime(getDate()); + return calendar.get(Calendar.HOUR_OF_DAY); + } + + public static int getMinute() { + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTime(getDate()); + return calendar.get(Calendar.MINUTE); + } + + public static int getYear(Date date) { + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTime(date); + return calendar.get(Calendar.YEAR); + } + + /** + * 获取date当天的开始时间 + * + * @return Date + */ + public static Date getDayStartTime(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + Date start = calendar.getTime(); + return start; + } + + /** + * 获取date当天的开始时间 + * + * @return String + */ + public static String getDayStartTimeByString(Date date) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return sdf.format(getDayStartTime(date)); + } + + /** + * 获取date当天的结束时间 + * + * @return + */ + public static Date getDayEndTime(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + Date start = calendar.getTime(); + calendar.add(Calendar.DAY_OF_MONTH, 1); + calendar.add(Calendar.SECOND, -1); + Date end = calendar.getTime(); + return end; + } + + /** + * 获取Date当天的结束时间 + * + * @return String + */ + public static String getDayEndTimeByString(Date date) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return sdf.format(getDayEndTime(date)); + } + + /** + * 向前推算时间 + * + * @param date 基础时间,以此时间为基础开始推算 + * @param days 向前推算天数 + * @return 推算结果 + */ + public static Date getDateBeforeByDay(Date date, int days) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - days); + return calendar.getTime(); + } + + /** + * 向后推算时间 + * + * @param date 基础时间,以此时间为基础开始推算 + * @param days 向后推算天数 + * @return 推算结果 + */ + public static Date getDateAfterByDay(Date date, int days) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + days); + return calendar.getTime(); + } + + /** + * 向后推算事件 + * + * @param date + * @param minutes + * @return + */ + public static Date getDateAfterByMinutes(Date date, int minutes) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) + minutes); + return calendar.getTime(); + } + + /** + * 向前推算事件 + * + * @param date + * @param minutes + * @return + */ + public static Date getDateBeforeMyMinutes(Date date, int minutes) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) - minutes); + return calendar.getTime(); + } + + /** + * 向前推算时间 + * + * @param date 基础时间,以此时间为基础开始推算 + * @param months 向前推算月份数 + * @return + */ + public static Date getDateBeforeByMonth(Date date, int months) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.add(Calendar.MONTH, -months); + return calendar.getTime(); + } + + /** + * 向后推算时间 + * + * @param date 基础时间,以此时间为基础开始推算 + * @param months 向后推算月份数 + * @return + */ + public static Date getDateAfterByMonth(Date date, int months) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.add(Calendar.MONTH, months); + return calendar.getTime(); + } + + /** + * 向前推算时间 + * + * @param date 基础时间, 以此时间为基础时间开始推算 + * @param hours 向前推算的小时数 + * @param minutes 向前推算的分钟数 + * @return + */ + public static Date getDateBeforeByHoursAndMinutes(Date date, int hours, int minutes) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - hours); + calendar.set(Calendar.MINUTE, calendar.get(calendar.MINUTE) - minutes); + return calendar.getTime(); + } + + /** + * 向后推算时间 + * + * @param date 基础时间,以此时间为基础时间开始推算 + * @param hours 向后推算的小时数 + * @param minutes 向后推算的分钟数 + * @return + */ + public static Date getDateAfterByHoursAndMinutes(Date date, int hours, int minutes) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.add(Calendar.HOUR_OF_DAY, hours); + calendar.add(Calendar.MINUTE, minutes); + return calendar.getTime(); + } + + /** + * date2Calendar + * + * @param date + * @return + */ + public static Calendar date2Calendar(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + return calendar; + } + + /** + * calendar2Date + * + * @param calendar + * @return + */ + public static Date calendar2Date(Calendar calendar) { + Date date = calendar.getTime(); + return date; + } + + /** + * 获取当前月份 + * + * @return + */ + public static int getCurrentMonth() { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(System.currentTimeMillis()); + return calendar.get(calendar.MONTH) + 1; + } + + /** + * 获取时间月份 + * + * @param date + * @return + */ + public static int getMonthByDate(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + return calendar.get(calendar.MONTH) + 1; + } + + /** + * 获取当前是哪一天 + * + * @return + */ + public static int getCurrentDay() { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(System.currentTimeMillis()); + return calendar.get(calendar.DAY_OF_MONTH); + } + + /** + * 获取当前date中的号数 + * + * @param date + * @return + */ + public static int getCurrentDayByDate(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + return calendar.get(calendar.DAY_OF_MONTH); + } + + /** + * 获取当前年 + * + * @return + */ + public static int getCurrentYear() { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(System.currentTimeMillis()); + return calendar.get(calendar.YEAR); + } + + /** + * 获取Date对应的Month的第一天 + * + * @param date + * @return + */ + public static String getMonthFirstDayByDate(Date date) { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + Calendar c = Calendar.getInstance(); + c.setTime(date); + c.add(Calendar.MONTH, 0); + c.set(Calendar.DAY_OF_MONTH, 1);//设置为1号,当前日期既为本月第一天 + return format.format(c.getTime()); + + } + + /** + * 获取Date对应的Month的最后一天 + * + * @param date + * @return + */ + public static String getMonthLastDayByDate(Date date) { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + Calendar cale = Calendar.getInstance(); + cale.setTime(date); + cale.set(Calendar.DAY_OF_MONTH, 0);//设置为1号,当前日期既为本月第一天 + return format.format(cale.getTime()); + } + + /** + * 计算是否为平年闰年 + * + * @param year + * @return + */ + public static Boolean isLeapYear(int year) { + if (year % 100 == 0) { + if (year % 400 == 0) { + return true; + } + } else { + if (year % 4 == 0) { + return true; + } + } + return false; + } + + public static int getLastDayOfMonth(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + final int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); + return lastDay; + } + + /** + * 将12:00这种格式的时间转换为javaDate类型时间,其中的年月日为当前时间的年月日 + * + * @param dateStr + * @return + */ + public static Date hourAndMinuteStr2Date(String dateStr) { + int year = getCurrentYear(); + int month = getCurrentMonth(); + int day = getCurrentDay(); + dateStr = year + "-" + month + "-" + day + " " + dateStr; + Date date = str2Date(dateStr, new SimpleDateFormat("yyyy-MM-dd HH:mm")); + return date; + } + + /** + * 根据传入的Date,将12:00这种格式的时间转换为javaDate类型时间,其中的年月日为date对应的年月日 + * + * @param dateStr + * @param date + * @return + */ + public static Date hourAndMinuteStr2Date(String dateStr, Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + int year = calendar.get(Calendar.YEAR); + int month = calendar.get(Calendar.MONTH) + 1; + int day = calendar.get(Calendar.DAY_OF_MONTH); + dateStr = year + "-" + month + "-" + day + " " + dateStr; + Date resultDate = str2Date(dateStr, new SimpleDateFormat("yyyy-MM-dd HH:mm")); + return resultDate; + } + + /** + * 获取时间中的小时和分钟 如23:12 + * + * @param date + * @return 23:12 + */ + public static String getDateHourAndMinuteStr(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + String hour = calendar.get(Calendar.HOUR_OF_DAY) + ""; + String minute = calendar.get(Calendar.MINUTE) + ""; + if (hour.length() == 1) { + hour = "0" + hour; + } + if (minute.length() == 1) { + minute = "0" + minute; + } + return hour + ":" + minute; + } + + /** + * 获取和东八区对应的时区差 如果返回结果小于0,说明所在的时区低于东八区,反之高于东八区 + * + * @param dateArea + * @return mapd的key分别为hour和minute分别对应相差的小时和分钟数 + */ + public static Map getDateAreaDiff(String dateArea) { + /*判断时区*/ + int hoursDiff = 0; //相差的小时数,如果为负数,表示时间慢于北京时间,反之快于北京时间 + int minutesDiff = 0; //相差的分钟数,如果为负数,表示时间慢于北京时间,反之快于北京时间 + if (dateArea.contains("-")) { //如果为西时区,东时区快于西时区 + dateArea = dateArea.replace("-", ""); + double timeDiff = (Double.parseDouble(dateArea) / 100) + 8; //相差的时间 + String timeDiffStr = timeDiff + ""; + if (Double.toString(timeDiff).contains(".")) { //如果为非整数小时差 + String[] timeSplits = timeDiffStr.split("\\."); + hoursDiff = 0 - Integer.parseInt(timeSplits[0]); + minutesDiff = 0 - Integer.parseInt(timeSplits[1]); + } else { + hoursDiff = 0 - (int) timeDiff; //相差整数小时数 + } + } else { //为东时区 + dateArea = dateArea.replace("+", ""); + if (Double.parseDouble(dateArea) / 100 - 8 > 0) { //如果所在时区大于东八区 + double timeDiff = (Double.parseDouble(dateArea) / 100) - 8; //相差的时间 + String timeDiffStr = timeDiff + ""; + if (timeDiffStr.contains(".")) { //如果相差为非整数小时差 + String[] timeSplits = timeDiffStr.split("\\."); + hoursDiff = Integer.parseInt(timeSplits[0]); + minutesDiff = Integer.parseInt(timeSplits[1]); + } else { //相差为整数小时差 + hoursDiff = (int) timeDiff; + } + } else { //如果所在的时区低于东八区 + String currentDateArea = Double.toString(Double.parseDouble(dateArea) / 100); + if (currentDateArea.contains(".")) { //如果所在的时区不为整数时区 + /*以60进制计算时间差*/ + String[] splits = currentDateArea.split("\\."); + int currentDate = 60 * Integer.parseInt(splits[0]) + (int) (Double.parseDouble(splits[1])); + int BeiJingDate = 8 * 60; + int dateDiff = currentDate - BeiJingDate; //获取相差分钟数 + hoursDiff = dateDiff / 60; + minutesDiff = dateDiff % 60; + } else { //如果所在的时区为整数时区 + double timeDiff = Double.parseDouble(currentDateArea); //相差的时间 + hoursDiff = (int) timeDiff; + } + } + } + Map map = new HashMap(); + map.put("hour", hoursDiff); + map.put("minute", minutesDiff); + return map; + } + + /** + * 格式化字符串形式日期 + * + * @param date + * @param yyyyMMdd + * @return + */ + public static String formatDateStr(String date, SimpleDateFormat yyyyMMdd) { + try { + Date parse = yyyyMMdd.parse(date); + return yyyyMMdd.format(parse); + } catch (ParseException e) { + return null; + } + } + + public static long getFirstDayNextNextWeek() { + Calendar calc = Calendar.getInstance(); + //设置一周的第一天是星期一 + calc.setFirstDayOfWeek(Calendar.MONDAY); + //在今天的基础上加一周 + calc.add(Calendar.WEEK_OF_YEAR, 1); + //获取当前设置的一周第一天 + int initDay = calc.getFirstDayOfWeek();// 每个星期的第一天根据locale不同而不同 + //下周的第一天 + calc.set(Calendar.DAY_OF_WEEK, initDay); + // 下下周的第一天(+7) + calc.add(Calendar.DAY_OF_MONTH, 7); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + String dateStr = sdf.format(calc.getTime()); + dateStr += " 00:00:00"; + Long time = calc.getTimeInMillis(); + try { + Date date = datetimeFormat.parse(dateStr); + time = date.getTime(); + } catch (ParseException e) { + e.printStackTrace(); + } + return time; + } + + /** + * 通过年份计算年龄 + * + * @param birthday + * @return + */ + public static int getAgeByYear(Date birthday) { + if (birthday == null) { + return 0; + } + Date now = new Date(System.currentTimeMillis()); + SimpleDateFormat yyyy = new SimpleDateFormat("yyyy"); + String birthYear = yyyy.format(birthday); + String nowYear = yyyy.format(now); + return Integer.parseInt(nowYear) - Integer.parseInt(birthYear); + + } + + public static int getAge(Date birthDay) { +// long now = System.currentTimeMillis(); +// long birth = birthDay.getTime(); +// return (int)((now-birth)/(long)365*24*60*60*1000); + Calendar cal = Calendar.getInstance(); + if (cal.before(birthDay)) { //出生日期晚于当前时间,无法计算 + throw new IllegalArgumentException( + "The birthDay is before Now.It's unbelievable!"); + } + int yearNow = cal.get(Calendar.YEAR); //当前年份 + int monthNow = cal.get(Calendar.MONTH); //当前月份 + int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH); //当前日期 + cal.setTime(birthDay); + int yearBirth = cal.get(Calendar.YEAR); + int monthBirth = cal.get(Calendar.MONTH); + int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH); + int age = yearNow - yearBirth; //计算整岁数 + if (monthNow <= monthBirth) { + if (monthNow == monthBirth) { + if (dayOfMonthNow < dayOfMonthBirth) { + age--;//当前日期在生日之前,年龄减一 + } + } else { + age--;//当前月份在生日之前,年龄减一 + } + } + return age; + } + + /*public Date getDateByLocal(Locale locale) { + new Date() + }*/ + + /** + * 获取一天开始时间 eg 00:00:00 + * + * @param date + * @return + */ + public static Date getDayBegin(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + return calendar.getTime(); + } + + /** + * 获取一天结束时间 eg 23:59:59 + * + * @param date + * @return + */ + public static Date getDayEnd(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.HOUR_OF_DAY, 23); + calendar.set(Calendar.MINUTE, 59); + calendar.set(Calendar.SECOND, 59); + return calendar.getTime(); + } + + public static void main(String[] args) throws ParseException { + System.out.println(DateUtils.getMonthLastDayByDate(new Date(2017 - 1900, 2, 1))); + } +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/util/EnumUtil.java b/face-common/src/main/java/com/dkha/common/util/EnumUtil.java new file mode 100644 index 0000000..6525fa9 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/EnumUtil.java @@ -0,0 +1,186 @@ +package com.dkha.common.util; + + + +import java.lang.reflect.Field; +import java.util.*; +import java.util.stream.Collectors; + +/** + * Created by Bray.ye on 2016/12/22 16:54. + */ +public class EnumUtil { + + private final static String KEY = "code"; + private final static String VALUE = "name"; + //权重,用于排序 + private final static String WEIGHT = "weight"; + + /** + * 枚举转map + * @param enumClazz + * @param + * @return + */ + public final static > Map toMap(Class enumClazz) { + Map map = new HashMap<>(); + try { + Field code_ = enumClazz.getDeclaredField(KEY); + Field name_ = enumClazz.getDeclaredField(VALUE); + code_.setAccessible(true); + name_.setAccessible(true); + EnumSet xes = EnumSet.allOf(enumClazz); + map = xes.stream().collect(Collectors.toMap( + x -> { + String code = null; + try { + code = (String) code_.get(x); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + return code; + }, + x -> { + String name = null; + try { + name = (String) name_.get(x); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + return name; + } + )); + /* for (X x : xes) { + String code = (String) code_.get(x); + String name = (String) name_.get(x); + map.put(code, name); + //System.out.println(code + ", " +name); + }*/ + } catch (Exception e) { + e.printStackTrace(); + } + return map; + } + + + /** + * 枚举转map(根绝权重weight排序, 排升序) + * @param enumClazz + * @param + * @return + */ + public final static > Map toMapSortByWeight(Class enumClazz) { + //用于保存有序结果集 + List sortList = new ArrayList<>(); + Map resultMap = new LinkedHashMap<>(); + try { + Field code_ = enumClazz.getDeclaredField(KEY); + Field name_ = enumClazz.getDeclaredField(VALUE); + Field weight_ = enumClazz.getDeclaredField(WEIGHT); + code_.setAccessible(true); + name_.setAccessible(true); + EnumSet xes = EnumSet.allOf(enumClazz); + for (X x : xes) { + InnerSortDS innerSortDS = new InnerSortDS(); + innerSortDS.setCode((String) code_.get(x)); + innerSortDS.setName((String) name_.get(x)); + innerSortDS.setWeight((int) weight_.get(x)); + sortList.add(innerSortDS); + } + } catch (Exception e) { + e.printStackTrace(); + } + if (sortList != null && sortList.size() > 0) { + int listLength = sortList.size(); + InnerSortDS innerSortDSTemp; + //冒泡排降序 + for (int i = 0; i < listLength - 1; i++) { + for (int j = i; j < listLength; j++) { + if (sortList.get(i).getWeight() > sortList.get(j).getWeight()) { + innerSortDSTemp = sortList.get(j); + sortList.set(j, sortList.get(i)); + sortList.set(i, innerSortDSTemp); + } + } + } + + /**遍历排序后的list,并转为map*/ + for (InnerSortDS innerSortDS : sortList) { + resultMap.put(innerSortDS.getCode(), innerSortDS.getName()); + } + } + return resultMap; + } + /** + * 枚举转list + * @param enumClazz + * @param + * @return + */ + public final static > List> toList(Class enumClazz) { + List> list = toMap(enumClazz).entrySet().stream().map(entry -> { + Map map = new HashMap(); + map.put(KEY, entry.getKey()); + map.put(VALUE, entry.getValue()); + return map; + }).collect(Collectors.toList()); + /*List> list = new ArrayList<>(); + for (Map.Entry entry : toMap(enumClazz).entrySet()) { + Map map = new HashMap(); + map.put(KEY, entry.getKey()); + map.put(VALUE, entry.getValue()); + list.add(map); + }*/ + return list; + } + + /** + * 通过code获取name + * @param enumClazz + * @param + * @return + */ + public final static > String getNameByCode(String code, Class enumClazz) { + Map map = toMap(enumClazz); + if (UtilValidate.isNotEmpty(map)) { + return map.get(code); + } + return null; + } + + /** + * 用于排序内部类(数据结构) + */ + static class InnerSortDS { + + private String code; + private String name; + /** 排序权重 */ + private int weight; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getWeight() { + return weight; + } + + public void setWeight(int weight) { + this.weight = weight; + } + } + +} diff --git a/face-common/src/main/java/com/dkha/common/util/ExcelUtils.java b/face-common/src/main/java/com/dkha/common/util/ExcelUtils.java new file mode 100644 index 0000000..1a99b1a --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/ExcelUtils.java @@ -0,0 +1,403 @@ + +package com.dkha.common.util; + + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import com.dkha.common.exception.DkException; +import com.dkha.common.exception.EmployeeException; +import io.swagger.annotations.ApiModelProperty; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.hssf.usermodel.HSSFDateUtil; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Field; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +import static org.apache.poi.ss.usermodel.Cell.CELL_TYPE_BLANK; + +/** + * excel工具类 + * + * @author Mark sunlightcs@gmail.com + */ +public class ExcelUtils { + private static Logger logger = LoggerFactory.getLogger(ExcelUtils.class); + + /** + * 获取workbook对象 + * + * @param multipartFile + * @return + * @throws Exception + */ + public static Workbook getWorkbook(MultipartFile multipartFile) throws Exception { + if (multipartFile.isEmpty()) { + throw new EmployeeException("文件不存在"); + } + if (!multipartFile.getOriginalFilename().endsWith("xls") && !multipartFile.getOriginalFilename().endsWith("xlsx")) { + + throw new EmployeeException("请上传excel文件"); + } + Workbook workbook = null; + InputStream is = multipartFile.getInputStream(); + if (multipartFile.getOriginalFilename().endsWith("xls")) { + workbook = new HSSFWorkbook(is); + } + if (multipartFile.getOriginalFilename().endsWith("xlsx")) { + workbook = new XSSFWorkbook(is); + } + return workbook; + } + + + /** + * Excel导出 + * + * @param response response + * @param fileName 文件名 + * @param list 数据List + * @param pojoClass 对象Class + */ + public static void exportExcel(HttpServletResponse response, String fileName, ArrayList list, + Class pojoClass) throws Exception { + if (StringUtils.isBlank(fileName)) { + //当前日期 + fileName = DateUtils.formatDate(new Date()); + } + Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), pojoClass, list); + write(response, workbook, fileName); + + } + + /** + * 导出excel表头 + * + * @param response + * @param pojo + * @param + */ + public static Workbook downloadTemplate(HttpServletResponse response, Class pojo) throws Exception { + String[] swaggerValues = getSwaggerValue(pojo); + Workbook workbook = new HSSFWorkbook(); + Sheet sheet = workbook.createSheet(); + Row row = sheet.createRow(0); + for (int i = 0; i < swaggerValues.length; i++) { + row.createCell(i).setCellValue(swaggerValues[i]); + } +// //锁定第一行无法修改 +// sheet.createFreezePane(0, 1, 0, 1); + + return workbook; + } + + + /** + * 获取swagger属性值 + * + * @param pojoClass + * @return + * @author hechenggang + */ + public static String[] getSwaggerValue(Class pojoClass) { + Field[] fields = pojoClass.getDeclaredFields(); + Field field; + int length = fields.length; + String[] value = new String[length]; + for (int i = 0; i < length; i++) { + fields[i].setAccessible(true); + } + for (int i = 0; i < length; i++) { + try { + field = pojoClass.getDeclaredField(fields[i].getName()); + ApiModelProperty apiModelProperty = field.getAnnotation(ApiModelProperty.class); + if (apiModelProperty != null) { + value[i] = apiModelProperty.value(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + return value; + } + + + /** + * // * Excel导出,先sourceList转换成List,再导出 + * // * + * // * @param response response + * // * @param fileName 文件名 + * // * @param sourceList 原数据List + * // * @param targetClass 目标对象Class + * // + */ +// public static void exportExcelToTarget(HttpServletResponse response, String fileName, Collection sourceList, +// Class targetClass) throws Exception { +// List targetList = new ArrayList<>(sourceList.size()); +// for (Object source : sourceList) { +// Object target = targetClass.newInstance(); +// BeanUtils.copyProperties(source, target); +// targetList.add(target); +// } +// +// exportExcel(response, fileName, targetList, targetClass); +// } + +// public static List readExcel(MultipartFile file, int sheetNo, int startRowNo, int startColNo, int fieldRowNo) +// throws Exception { +// Workbook wb = null; +// String fileName = file.getOriginalFilename(); +// String extString = StringUtils.substringAfterLast(fileName, "."); +// if ("xls".equalsIgnoreCase(extString)) { +// wb = new HSSFWorkbook(file.getInputStream()); +// } else if ("xlsx".equalsIgnoreCase(extString)) { +// wb = new XSSFWorkbook(file.getInputStream()); +// } else { +// throw new Exception("请上传Excel文件!"); +// } +// Map map = null; +// Row row = null; +// Sheet sheet = wb.getSheetAt(sheetNo); +// Row fieldRow = sheet.getRow(fieldRowNo); +// int rowNum = sheet.getPhysicalNumberOfRows(); +// int colNum = fieldRow.getPhysicalNumberOfCells(); +// List datas = new ArrayList(); +// for (int i = startRowNo; i <= rowNum; i++) { +// map = new HashMap(); +// row = sheet.getRow(i); +// for (int j = startColNo; j < colNum; j++) { +// map.put(getCellContent(fieldRow.getCell(j)), getCellContent(row.getCell(j))); +// } +// datas.add(map); +// } +// return datas; +// } +// +// private static String getCellContent(Cell cell) { +// if (null == cell) { +// return null; +// } +// StringBuffer buffer = new StringBuffer(); +// switch (cell.getCellType()) { +// case Cell.CELL_TYPE_NUMERIC: // 数字 +// buffer.append(String.valueOf(cell.getNumericCellValue())); +// break; +// case Cell.CELL_TYPE_STRING: // 字符串 +// buffer.append(cell.getStringCellValue()); +// break; +// case Cell.CELL_TYPE_FORMULA: // 公式 +// buffer.append(cell.getCellFormula()); +// break; +// default: +// return null; +// } +// return buffer.toString(); +// } + + // /** +// * @param map +// * @param obj +// * @return +// * @throws Exception +// */ +// public static Object parseMap2Bean(Map map, Object obj) throws Exception { +// try { +// org.apache.commons.beanutils.BeanUtils.populate(obj, map); +// } catch (Exception e) { +// throw new Exception("转换失败!", e); +// } +// return obj; +// } +// +// /** +// * @param list +// * @param +// * @return +// * @throws Exception +// */ +// public static List parseMap2Bean(List list, Class cla zz) throws Exception { +// List lst = new ArrayList(); +// try { +// for (Map map : list) { +// lst.add(parseMap2Bean(map, clazz.newInstance())); +// } +// } catch (Exception e) { +// throw new Exception("转换失败!", e); +// } +// return lst; +// } + public static void write(HttpServletResponse response, Workbook workbook, String fileName) throws Exception { + response.setCharacterEncoding("UTF-8"); + response.setContentType("application/vnd.ms-excel;charset=UTF-8"); +// response.setHeader("content-Type", "application/octet-stream"); + if (UtilValidate.isEmpty(fileName)) { + response.setHeader("Content-Disposition", + "attachment;filename=" + URLEncoder.encode("模板文件", "UTF-8") + ".xls"); + } else { + response.setHeader("Content-Disposition", + "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xls"); + } + response.setContentType("*/*"); + ServletOutputStream out = response.getOutputStream(); + workbook.write(out); + out.flush(); + } + + public static void writeErroData(HttpServletResponse response, List> error, String fileName, Class pojo) throws Exception { + + response.setCharacterEncoding("UTF-8"); + response.setContentType("application/vnd.ms-excel;charset=UTF-8"); +// response.setHeader("content-Type", "application/octet-stream"); + if (UtilValidate.isEmpty(fileName)) { + response.setHeader("Content-Disposition", + "attachment;filename=" + System.currentTimeMillis() + ".xls"); + } else { + response.setHeader("Content-Disposition", + "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xls"); + } + response.setContentType("*/*"); + Workbook workbook = new HSSFWorkbook(); + Sheet sheet = workbook.createSheet(); + //设置表头 + Row firstRow = sheet.createRow(0); + String[] swagger = getSwaggerValue(pojo); + int i = 0; + for (i = 0; i < swagger.length; i++) { + Cell cell = firstRow.createCell(i); + cell.setCellValue(swagger[i]); + } + firstRow.createCell(i).setCellValue("错误原因(修改数据后请删除此列再上传)"); + // + + for (i = 0; i < error.size(); i++) { + Row row = sheet.createRow(i + 1); + List rowList = error.get(i); + for (int j = 0; j < rowList.size(); j++) { + if (rowList.size() > 10) { + if (j == 6 || j == 7) { + double month = Double.parseDouble(rowList.get(j)); + Date date = HSSFDateUtil.getJavaDate(month); + + row.createCell(j).setCellValue(DateUtils.formatDate(date, "yyyy-MM")); + } else { + row.createCell(j).setCellValue(rowList.get(j)); + } + } else { + if (j == 2) { + double month = Double.parseDouble(rowList.get(j)); + Date date = HSSFDateUtil.getJavaDate(month); + + row.createCell(j).setCellValue(DateUtils.formatDate(date, "yyyy-MM")); + } else { + row.createCell(j).setCellValue(rowList.get(j)); + } + } + } + + } + ServletOutputStream out = response.getOutputStream(); + workbook.write(out); + out.flush(); + } + + + public static void downloadTemplate(HttpServletResponse servletResponse, String fileName) throws Exception { + ClassPathResource classPathResource = new ClassPathResource(fileName + ".xls"); + InputStream inputStream = classPathResource.getInputStream(); + servletResponse.setCharacterEncoding("UTF-8"); + servletResponse.setContentType("application/vnd.ms-excel;charset=UTF-8"); +// response.setHeader("content-Type", "application/octet-stream"); + servletResponse.setHeader("Content-Disposition", + "attachment;filename=" + URLEncoder.encode("摄像头导入模板", "UTF-8") + ".xls"); + OutputStream out = servletResponse.getOutputStream(); + int length = 0; + byte[] bytes = new byte[1024]; + while ((length = inputStream.read(bytes)) != -1) { + out.write(bytes, 0, length); + } + out.flush(); + out.close(); + inputStream.close(); + } + + /** + * 获取excel文件 + * + * @param multipartFile excel文件 + * @param pojo 转化的实体类 + * @param + * @return + * @throws Exception + */ + public static List readExcel(MultipartFile multipartFile, Class pojo) throws Exception { + Workbook workbook = getWorkbook(multipartFile); + List dataList = new ArrayList<>(); + Sheet sheet = workbook.getSheetAt(0); + //获取实际的行数 + int rowNo = (sheet.getLastRowNum() - sheet.getFirstRowNum()) + 1; + Field[] fields = pojo.getDeclaredFields(); + //从第三行开始读取数据 + for (int i = 2; i < rowNo; i++) { + Row row = sheet.getRow(i); + //校验空行 + if (row == null || row.toString().isEmpty()) { + break; + } + //定义封装数据的实体类 + T t = pojo.newInstance(); + Cell cell = null; + int cellType = 0; + for (int j = 0; j < fields.length; j++) { + try { + cell = row.getCell(j); + cellType = cell.getCellType(); + } catch (NullPointerException e) { + fields[j].set(t, ""); + continue; + } + try { + switch (cellType) { + case Cell.CELL_TYPE_NUMERIC: + if (fields.getClass().getName().equals("String")) { + fields[j].set(t, String.valueOf(cell.getNumericCellValue())); + } + fields[j].set(t, cell.getNumericCellValue()); + break; + case Cell.CELL_TYPE_STRING://字符串类型 + if (cell.getStringCellValue().equals("null")) { + fields[j].set(t, ""); + } else { + fields[j].set(t, cell.getStringCellValue()); + } + break; + case CELL_TYPE_BLANK://空单元格类型 + fields[j].set(t, ""); + break; + } + } catch (Exception e) { + logger.error("数据转换错误"); + } + + } + dataList.add(t); + } + return dataList; + } +} diff --git a/face-common/src/main/java/com/dkha/common/util/HttpContextUtils.java b/face-common/src/main/java/com/dkha/common/util/HttpContextUtils.java new file mode 100644 index 0000000..e971f54 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/HttpContextUtils.java @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.common.util; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpHeaders; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +/** + * Http + * + * @author Mark sunlightcs@gmail.com + */ +public class HttpContextUtils { + + public static HttpServletRequest getHttpServletRequest() { + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); + if(requestAttributes == null){ + return null; + } + + return ((ServletRequestAttributes) requestAttributes).getRequest(); + } + + public static Map getParameterMap(HttpServletRequest request) { + Enumeration parameters = request.getParameterNames(); + + Map params = new HashMap<>(); + while (parameters.hasMoreElements()) { + String parameter = parameters.nextElement(); + String value = request.getParameter(parameter); + if (StringUtils.isNotBlank(value)) { + params.put(parameter, value); + } + } + + return params; + } + + public static String getDomain(){ + HttpServletRequest request = getHttpServletRequest(); + StringBuffer url = request.getRequestURL(); + return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString(); + } + + public static String getOrigin(){ + HttpServletRequest request = getHttpServletRequest(); + return request.getHeader(HttpHeaders.ORIGIN); + } + + public static String getLanguage() { + //默认语言 + String defaultLanguage = "zh-CN"; + //request + HttpServletRequest request = getHttpServletRequest(); + if(request == null){ + return defaultLanguage; + } + + //请求语言 + defaultLanguage = request.getHeader(HttpHeaders.ACCEPT_LANGUAGE); + + return defaultLanguage; + } +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/util/IdCardUtil.java b/face-common/src/main/java/com/dkha/common/util/IdCardUtil.java new file mode 100644 index 0000000..2471940 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/IdCardUtil.java @@ -0,0 +1,427 @@ +package com.dkha.common.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + *

+ * 身份证合法性校验 + *

+ * + *
+ * --15位身份证号码:第7、8位为出生年份(两位数),第9、10位为出生月份,第11、12位代表出生日期,第15位代表性别,奇数为男,偶数为女。
+ * --18位身份证号码:第7、8、9、10位为出生年份(四位数),第11、第12位为出生月份,第13、14位代表出生日期,第17位代表性别,奇数为男,偶数为女。
+ *    最后一位为校验位
+ * 
+ * + * @author 313921 + */ +public class IdCardUtil { + + private static Logger logger = LoggerFactory.getLogger(IdCardUtil.class); + + /** + *
+     * 省、直辖市代码表:
+     *     11 : 北京  12 : 天津  13 : 河北       14 : 山西  15 : 内蒙古
+     *     21 : 辽宁  22 : 吉林  23 : 黑龙江  31 : 上海  32 : 江苏
+     *     33 : 浙江  34 : 安徽  35 : 福建       36 : 江西  37 : 山东
+     *     41 : 河南  42 : 湖北  43 : 湖南       44 : 广东  45 : 广西      46 : 海南
+     *     50 : 重庆  51 : 四川  52 : 贵州       53 : 云南  54 : 西藏
+     *     61 : 陕西  62 : 甘肃  63 : 青海       64 : 宁夏  65 : 新疆
+     *     71 : 台湾
+     *     81 : 香港  82 : 澳门
+     *     91 : 国外
+     * 
+ */ + private static String[] cityCode = { "11", "12", "13", "14", "15", "21", + "22", "23", "31", "32", "33", "34", "35", "36", "37", "41", "42", + "43", "44", "45", "46", "50", "51", "52", "53", "54", "61", "62", + "63", "64", "65", "71", "81", "82", "91" }; + + /** + * 每位加权因子 + */ + private static int power[] = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, + 8, 4, 2 }; + + /** + * 验证所有的身份证的合法性 + * + * @param idcard + * 身份证 + * @return 合法返回true,否则返回false + */ + public static boolean isValidatedAllIdcard(String idcard) { + if (idcard == null || "".equals(idcard)) { + return false; + } + int s=15; + if (idcard.length() == s) { + return validate15IDCard(idcard); + } + int s1=18; + if(idcard.length()==s1) { + return validate18Idcard(idcard); + } + return false; + + } + + /** + *

+ * 判断18位身份证的合法性 + *

+ * 根据〖中华人民共和国国家标准GB11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。 + * 排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。 + *

+ * 顺序码: 表示在同一地址码所标识的区域范围内,对同年、同月、同 日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配 给女性。 + *

+ *

+ * 1.前1、2位数字表示:所在省份的代码; 2.第3、4位数字表示:所在城市的代码; 3.第5、6位数字表示:所在区县的代码; + * 4.第7~14位数字表示:出生年、月、日; 5.第15、16位数字表示:所在地的派出所的代码; + * 6.第17位数字表示性别:奇数表示男性,偶数表示女性; + * 7.第18位数字是校检码:也有的说是个人信息码,一般是随计算机的随机产生,用来检验身份证的正确性。校检码可以是0~9的数字,有时也用x表示。 + *

+ *

+ * 第十八位数字(校验码)的计算方法为: 1.将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7 9 10 5 8 4 + * 2 1 6 3 7 9 10 5 8 4 2 + *

+ *

+ * 2.将这17位数字和系数相乘的结果相加。 + *

+ *

+ * 3.用加出来和除以11,看余数是多少 + *

+ * 4.余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字。其分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3 + * 2。 + *

+ * 5.通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的Ⅹ。如果余数是10,身份证的最后一位号码就是2。 + *

+ * + * @param idcard + * @return + */ + public static boolean validate18Idcard(String idcard) { + if (idcard == null) { + return false; + } + + // 非18位为假 + int s=18; + if (idcard.length() != s) { + logger.error("身份证位数不正确!"); + return false; + } + // 获取前17位 + String idcard17 = idcard.substring(0, 17); + + // 前17位全部为数字 + if (!isDigital(idcard17)) { + return false; + } + + String provinceid = idcard.substring(0, 2); + // 校验省份 + if (!checkProvinceid(provinceid)) { + return false; + } + + // 校验出生日期 + String birthday = idcard.substring(6, 14); + + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + + try { + Date birthDate = sdf.parse(birthday); + String tmpDate = sdf.format(birthDate); + // 出生年月日不正确 + if (!tmpDate.equals(birthday)) { + return false; + } + + } catch (ParseException e1) { + + return false; + } + + // 获取第18位 + String idcard18Code = idcard.substring(17, 18); + + char c[] = idcard17.toCharArray(); + + int bit[] = converCharToInt(c); + + int sum17 = 0; + + sum17 = getPowerSum(bit); + + // 将和值与11取模得到余数进行校验码判断 + String checkCode = getCheckCodeBySum(sum17); + if (null == checkCode) { + return false; + } + // 将身份证的第18位与算出来的校码进行匹配,不相等就为假 + if (!idcard18Code.equalsIgnoreCase(checkCode)) { + return false; + } + //System.out.println("正确"); + return true; + } + + /** + * 校验15位身份证 + * + *
+     * 只校验省份和出生年月日
+     * 
+ * + * @param idcard + * @return + */ + public static boolean validate15IDCard(String idcard) { + if (idcard == null) { + return false; + } + // 非15位为假 + int s=15; + if (idcard.length() != s) { + return false; + } + + // 15全部为数字 + if (!isDigital(idcard)) { + return false; + } + + String provinceid = idcard.substring(0, 2); + // 校验省份 + if (!checkProvinceid(provinceid)) { + return false; + } + + String birthday = idcard.substring(6, 12); + + SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd"); + + try { + Date birthDate = sdf.parse(birthday); + String tmpDate = sdf.format(birthDate); + // 身份证日期错误 + if (!tmpDate.equals(birthday)) { + return false; + } + + } catch (ParseException e1) { + + return false; + } + + return true; + } + + /** + * 将15位的身份证转成18位身份证 + * + * @param idcard + * @return + */ + public static String convertIdcarBy15bit(String idcard) { + if (idcard == null) { + return null; + } + + // 非15位身份证 + int s=15; + if (idcard.length() != s) { + return null; + } + + // 15全部为数字 + if (!isDigital(idcard)) { + return null; + } + + String provinceid = idcard.substring(0, 2); + // 校验省份 + if (!checkProvinceid(provinceid)) { + return null; + } + + String birthday = idcard.substring(6, 12); + + SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd"); + + Date birthdate = null; + try { + birthdate = sdf.parse(birthday); + String tmpDate = sdf.format(birthdate); + // 身份证日期错误 + if (!tmpDate.equals(birthday)) { + return null; + } + + } catch (ParseException e1) { + return null; + } + + Calendar cday = Calendar.getInstance(); + cday.setTime(birthdate); + String year = String.valueOf(cday.get(Calendar.YEAR)); + + String idcard17 = idcard.substring(0, 6) + year + idcard.substring(8); + + char c[] = idcard17.toCharArray(); + String checkCode = ""; + + // 将字符数组转为整型数组 + int bit[] = converCharToInt(c); + + int sum17 = 0; + sum17 = getPowerSum(bit); + + // 获取和值与11取模得到余数进行校验码 + checkCode = getCheckCodeBySum(sum17); + + // 获取不到校验位 + if (null == checkCode) { + return null; + } + // 将前17位与第18位校验码拼接 + idcard17 += checkCode; + return idcard17; + } + + /** + * 校验省份 + * + * @param provinceid + * @return 合法返回TRUE,否则返回FALSE + */ + private static boolean checkProvinceid(String provinceid) { + for (String id : cityCode) { + if (id.equals(provinceid)) { + return true; + } + } + return false; + } + + /** + * 数字验证 + * + * @param str + * @return + */ + private static boolean isDigital(String str) { + return str.matches("^[0-9]*$"); + } + + /** + * 将身份证的每位和对应位的加权因子相乘之后,再得到和值 + * + * @param bit + * @return + */ + private static int getPowerSum(int[] bit) { + + int sum = 0; + + if (power.length != bit.length) { + return sum; + } + + for (int i = 0; i < bit.length; i++) { + for (int j = 0; j < power.length; j++) { + if (i == j) { + sum = sum + bit[i] * power[j]; + } + } + } + return sum; + } + + /** + * 将和值与11取模得到余数进行校验码判断 + * + * @param sum17 + * @return 校验位 + */ + private static String getCheckCodeBySum(int sum17) { + String checkCode = null; + switch (sum17 % 11) { + case 10: + checkCode = "2"; + break; + case 9: + checkCode = "3"; + break; + case 8: + checkCode = "4"; + break; + case 7: + checkCode = "5"; + break; + case 6: + checkCode = "6"; + break; + case 5: + checkCode = "7"; + break; + case 4: + checkCode = "8"; + break; + case 3: + checkCode = "9"; + break; + case 2: + checkCode = "x"; + break; + case 1: + checkCode = "0"; + break; + case 0: + checkCode = "1"; + break; + default: + } + return checkCode; + } + + /** + * 将字符数组转为整型数组 + * + * @param c + * @return + * @throws NumberFormatException + */ + private static int[] converCharToInt(char[] c) throws NumberFormatException { + int[] a = new int[c.length]; + int k = 0; + for (char temp : c) { + a[k++] = Integer.parseInt(String.valueOf(temp)); + } + return a; + } + + + /*public static void main(String[] args) throws Exception { + String idcard15 = "130321860311519"; + String idcard18 = "210102198617083732";// + String idcard="610**************"; + //自己身份证测试 + System.out.println(isValidatedAllIdcard(idcard)); + // 15位身份证 + //System.out.println(isValidatedAllIdcard(idcard15)); + // 18位身份证 + //System.out.println(isValidatedAllIdcard(idcard18)); + // 15位身份证转18位身份证 + //System.out.println(convertIdcarBy15bit(idcard15)); + }*/ +} + diff --git a/face-common/src/main/java/com/dkha/common/util/IntUUID.java b/face-common/src/main/java/com/dkha/common/util/IntUUID.java new file mode 100644 index 0000000..a9c6801 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/IntUUID.java @@ -0,0 +1,40 @@ +package com.dkha.common.util; + +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @Description 生成32位int UUID + * 14位的当前系统时间(格式为:yyyyMMddHHmmss) + 当前电脑的IP地址的最后两位 + 当前线程的hashCode的前9位 + 7位的随机数 + * @Author Spring + * @Since 2019/8/14 10:53 + */ + +public class IntUUID { + + public static final AtomicInteger shortUUID = new AtomicInteger(0); + + public static int getShortUUID(){ + int current; + int next; + do { + current = shortUUID.get(); + next = current >= 2147483647 ? 0 : current + 1; + } while(!shortUUID.compareAndSet(current, next)); + return next; + } + + /** + * 获取字符串类型UUID + * @return + */ + public static synchronized String getStrUUID() { + return UUID.randomUUID().toString().replaceAll("-", ""); + } + + public static void main(String[] args) { + //System.out.println(IntUUID.getShortUUID()); + String uuid = UUID.randomUUID().toString().replaceAll("-", ""); + System.out.println(uuid); + } +} diff --git a/face-common/src/main/java/com/dkha/common/util/IpUtils.java b/face-common/src/main/java/com/dkha/common/util/IpUtils.java new file mode 100644 index 0000000..3801fa7 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/IpUtils.java @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.common.util; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; + +/** + * IP地址 + * @author Spring + */ +public class IpUtils { + private static Logger logger = LoggerFactory.getLogger(IpUtils.class); + + /** + * 获取IP地址 + * + * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址 + * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址 + */ + public static String getIpAddr(HttpServletRequest request) { + String unknown = "unknown"; + String ip = null; + try { + ip = request.getHeader("x-forwarded-for"); + //nginx代理存在的情况下 + if (UtilValidate.isNotEmpty(ip) && ip.contains(",")) { + ip = ip.split(",")[0]; + } + if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (StringUtils.isEmpty(ip) || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } + if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + } catch (Exception e) { + logger.error("IPUtils ERROR ", e); + } + + return ip; + } + +} diff --git a/face-common/src/main/java/com/dkha/common/util/JsonUtil.java b/face-common/src/main/java/com/dkha/common/util/JsonUtil.java new file mode 100644 index 0000000..3b555f4 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/JsonUtil.java @@ -0,0 +1,226 @@ +package com.dkha.common.util; + +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.*; +import lombok.Data; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * @Author Spring + * @Since 2019/12/11 14:24 + * @Description 基于jackson 对象序列化反序列化工具 + */ + +public class JsonUtil { + + private static Logger logger = LoggerFactory.getLogger(JsonUtil.class); + + private static ObjectMapper objectMapper = new ObjectMapper(); + + static { + //序列化的时候序列对象的所有属性 + objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS); + + // 如果是空对象的时候,不抛异常 + objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + //属性为null的转换--为空的值不参与反序列化 + //objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + // 取消默认转换timestamps对象 + objectMapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS, false); + // 所有日期统一格式 + objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); + // 忽略 在json字符串中存在, 但是在java对象中不存在对应属性的情况, 防止出错 + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } + + + public static String obj2String(T obj) { + if (obj == null) { + return null; + } + try { + return obj instanceof String ? (String)obj : objectMapper + .writeValueAsString + (obj); + } catch (Exception e) { + logger.error("Parse object to String error:" + e); + return null; + } + } + + /** + * 返回一个格式化好的字符串, 用于调试 + * @param obj + * @param + * @return + */ + public static String obj2StringPretty(T obj) { + if (obj == null) { + return null; + } + try { + return obj instanceof String ? (String)obj : objectMapper.writerWithDefaultPrettyPrinter() + .writeValueAsString + (obj); + } catch (Exception e) { + logger.error("Parse object to String error:" + e); + return null; + } + } + + /** + * 将字符串转成对象, 单个 + * @param str + * @param clazz + * @param + * @return + */ + public static T string2Obj(String str, Class clazz) { + if (UtilValidate.isEmpty(str) || clazz == null) { + return null; + } + try { + return clazz.equals(String.class) ? (T)str : objectMapper.readValue + (str, clazz); + } catch (IOException e) { + logger.error("Parse String to Object error :" + e); + return null; + } + } + + /** + * 将字符串转换成对象, 集合 + * List userEntityList1 = JsonUtil.string2Obj(str, new TypeReference>() {}); + * @param str + * @param typeReference + * @param + * @return + */ + public static T string2Obj(String str, TypeReference typeReference) { + if (UtilValidate.isEmpty(str) || typeReference == null) { + return null; + } + try { + return (T)(typeReference.getType().equals(String.class) ? (T)str : + objectMapper.readValue + (str, typeReference)); + } catch (IOException e) { + logger.error("Parse String to typeReference Object error :" + e); + return null; + } + } + /** + * 将字符串转换成对象, 集合 + * List sysUserEntityList2 = JsonUtil.string2Obj(str, List.class, SysUserEntity.class); + * @param str + * @param collectionClass + * @param + * @return + */ + public static T string2Obj(String str, Class collectionClass, Class... elementClasses) { + JavaType javaType = objectMapper.getTypeFactory() + .constructParametricType(collectionClass, elementClasses); + try { + return objectMapper.readValue(str, javaType); + } catch (IOException e) { + logger.error("Parse String to Object2 error :" + e); + return null; + } + } + + /** + * 测试代码 + */ + public static void main(String[] args) { + SysUserEntity userEntity = new SysUserEntity(); + userEntity.setUsername("张三"); + userEntity.setCreateTime(new Date()); + System.out.println(JsonUtil.obj2String(userEntity)); + List userEntityList = new ArrayList<>(); + userEntityList.add(userEntity); + System.out.println(JsonUtil.obj2String(userEntityList)); + + String str = "[{\"username\":\"张三\",\"createTime\":\"2019-12-11 14:38:01\"}, {\"username\":\"李四\",\"createTime\":\"2019-10-11 14:38:01\"}]"; + List userEntityList1 = JsonUtil.string2Obj(str, new TypeReference>() { + }); + System.out.println(userEntityList1.toString()); + + List sysUserEntityList2 = JsonUtil.string2Obj(str, List.class, SysUserEntity.class); + System.out.println(sysUserEntityList2.toString()); + + SysUserEntity userEntity1 = JsonUtil.string2Obj("", SysUserEntity.class); + } + + @Data + public static class SysUserEntity { + private static final long serialVersionUID = 1L; + /** + * 用户名 + */ + private String username; + /** + * 密码 + */ + private String password; + /** + * 姓名 + */ + private String realName; + /** + * 头像 + */ + private String headUrl; + /** + * 性别 0:男 1:女 2:保密 + */ + private Integer gender; + /** + * 邮箱 + */ + private String email; + /** + * 手机号 + */ + private String mobile; + /** + * 部门ID + */ + private Long deptId; + /** + * 超级管理员 0:否 1:是 + */ + private Integer superAdmin; + /** + * 状态 0:停用 1:正常 + */ + private Integer status; + /** + * 更新者 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateDate; + /** + * 部门名称 + */ + @TableField(exist=false) + private String deptName; + + private Date createTime; + } +} diff --git a/face-common/src/main/java/com/dkha/common/util/NameUtil.java b/face-common/src/main/java/com/dkha/common/util/NameUtil.java new file mode 100644 index 0000000..5835399 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/NameUtil.java @@ -0,0 +1,98 @@ +package com.dkha.common.util; + +import com.dkha.common.exception.EmployeeException; + +/** + * @ClassName: + * @Description:(please write your description) + * @author: {开发人的姓名} + * @date: + * @Copyright: 成都电科惠安 + */ +public class NameUtil { + + public static String createAsterisk(int length) { + StringBuffer stringBuffer = new StringBuffer(); + for (int i = 0; i < length; i++) { + stringBuffer.append("*"); + } + return stringBuffer.toString(); + } + + public static String getNames(String name) { + if (UtilValidate.isEmpty(name)) { + throw new EmployeeException("不能输入空"); + } + String[] show = name.split("·"); + if (show.length == 2) { + name = show[0] + createAsterisk(show[1].length()); + return name; + } + + return name; + } + + /** + * @param idCardNum 身份证号码 + * @param front 需要显示前几位 + * @param end 需要显示末几位 + * @return + */ + public static String idMask(String idCardNum, int front, int end) { + // 身份证不能为空 + if (UtilValidate.isEmpty(idCardNum)) { + throw new EmployeeException("不能输入空"); + } + // 需要截取的长度不能大于身份证号长度 +// if ((front + end) > idCardNum.length()) { +// throw new EmployeeException("需要截取的长度不能大于身份证号长度"); +// } +// // 需要截取的不能小于0 +// +// if (front < 0 || end < 0) { +// throw new EmployeeException("需要截取的不能小于0"); +// } + // 计算*的数量 + int asteriskCount = idCardNum.length() - (front + end); + StringBuffer asteriskStr = new StringBuffer(); +// for (int i = 0; i < asteriskCount; i++) { + asteriskStr.append("********"); +// } + String regex = "(\\w{" + String.valueOf(front) + "})(\\w+)(\\w{" + String.valueOf(end) + "})"; + return idCardNum.replaceAll(regex, "$1" + "********" + "$3"); + } + + + /** + * 正则表达式判断是否是数字: 完美 + * @param str + * @return + */ + public static boolean isNumber(String str){ + String reg = "^[0-9]+(.[0-9]+)?$"; + return str.matches(reg); + } + + /** + * ASCII码 ,不能判断小数点有几个 :1.1.1 也会返回true + * @param str + * @return + */ + public static boolean isNumeric(String str){ + for(int i=str.length();--i>=0;){ + int chr=str.charAt(i); + System.out.println(chr); + if(chr<48 || chr>57) { + if(chr != 46){ + return false; + } + } + } + return true; + } + +// public static void main(String[] args) { +// String id ="513902199202293979E.5"; +// System.out.println(NameUtil.isNumber(id)); +// } +} diff --git a/face-common/src/main/java/com/dkha/common/util/ShieldUtil.java b/face-common/src/main/java/com/dkha/common/util/ShieldUtil.java new file mode 100644 index 0000000..f77fa0a --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/ShieldUtil.java @@ -0,0 +1,56 @@ +package com.dkha.common.util; + +/** + * 身份证号,姓名屏蔽 + */ +public class ShieldUtil { + + /** + * 少数名字屏蔽·后 + * @param name + * @return + */ + public static String getShieldName(String name) { + + if (name != null && name.contains("·")) { + String[] strings = name.split("·"); + char[] c = strings[1].toCharArray(); + for (int i = 0; i < strings[1].toCharArray().length; i++) { + c[i] = '*'; + } + + strings[1] = new String(c); + name = strings[0] + "·" + strings[1]; + } + return name; + + } + + /** + * 身份证号屏蔽出生日期 + * @param idCardNo + * @return + */ + public static String getShieldIdCardNo(String idCardNo) { + if (idCardNo != null && idCardNo.trim().length() != 0) { + char[] c = idCardNo.toCharArray(); + for (int i = 0; i < c.length; i++) { + switch (i) { + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + c[i] = '*'; + break; + } + } + idCardNo = new String(c); + } + return idCardNo; + } + +} diff --git a/face-common/src/main/java/com/dkha/common/util/SpringBeanFactoryUtils.java b/face-common/src/main/java/com/dkha/common/util/SpringBeanFactoryUtils.java new file mode 100644 index 0000000..f7036e8 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/SpringBeanFactoryUtils.java @@ -0,0 +1,28 @@ +package com.dkha.common.util; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +/** + * @Author Spring + * @Since 2019/9/21 9:48 + * @Description 用于在Spring框架无法注入的情况下获取对应的Bean + */ +@Component +public class SpringBeanFactoryUtils implements ApplicationContextAware { + + private static ApplicationContext context = null; + + public static T getBean(Class type) { + return context.getBean(type); + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + if (SpringBeanFactoryUtils.context == null) { + SpringBeanFactoryUtils.context = applicationContext; + } + } +} diff --git a/face-common/src/main/java/com/dkha/common/util/SpringContextUtils.java b/face-common/src/main/java/com/dkha/common/util/SpringContextUtils.java new file mode 100644 index 0000000..1efbbfb --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/SpringContextUtils.java @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.common.util; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +/** + * Spring Context 工具类 + * + * @author Mark sunlightcs@gmail.com + */ +@Component +public class SpringContextUtils implements ApplicationContextAware { + public static ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + SpringContextUtils.applicationContext = applicationContext; + } + + public static Object getBean(String name) { + return applicationContext.getBean(name); + } + + public static T getBean(Class requiredType) { + return applicationContext.getBean(requiredType); + } + + public static T getBean(String name, Class requiredType) { + return applicationContext.getBean(name, requiredType); + } + + public static boolean containsBean(String name) { + return applicationContext.containsBean(name); + } + + public static boolean isSingleton(String name) { + return applicationContext.isSingleton(name); + } + + public static Class getType(String name) { + return applicationContext.getType(name); + } + +} \ No newline at end of file diff --git a/face-common/src/main/java/com/dkha/common/util/TimeUtil.java b/face-common/src/main/java/com/dkha/common/util/TimeUtil.java new file mode 100644 index 0000000..1747843 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/TimeUtil.java @@ -0,0 +1,101 @@ +package com.dkha.common.util; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: TimeUtil + * @Package com.dkha.common.util + * @author: panhui + * @date: 2019/12/10 15:09 + * @Copyright: 成都电科慧安 + */ +public class TimeUtil { + + /** + * 获取今天时间开始的时间 + * + * @return + */ + public static Long toDayStart() { + Date date=new Date(); + date.setHours(0); + date.setMinutes(0); + date.setSeconds(0); + return date.getTime(); + } + /** + * 获取今天时间结束的时间 + * + * @return + */ + public static Long toDayStop() + { + Date date=new Date(); + date.setHours(23); + date.setMinutes(59); + date.setSeconds(59); + return date.getTime(); + } + + /** + * 获取传入时间的开始的时间 + * + * @return + */ + public static Long toDateByTimeStart(String time) { + Date date=exchangeDate(time); + date.setHours(0); + date.setMinutes(0); + date.setSeconds(0); + return date.getTime(); + } + /** + * 获取传入时间结束的时间 + * + * @return + */ + public static Long toDateByTimeStop(String time) + { + Date date=exchangeDate(time); + date.setHours(23); + date.setMinutes(59); + date.setSeconds(59); + return date.getTime(); + } + + /** + * 将时间转换为时间戳 + * @param time + * @return + */ + public static Long exchangeTime(String time) + { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = null; + try { + date = simpleDateFormat.parse(time); + } catch (ParseException e) { + } + return date.getTime(); + } + /** + * 将时间转换为时间戳 + * @param time + * @return + */ + public static Date exchangeDate(String time) + { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = null; + try { + date = simpleDateFormat.parse(time); + } catch (ParseException e) { + } + return date; + } +} diff --git a/face-common/src/main/java/com/dkha/common/util/UUIDBits.java b/face-common/src/main/java/com/dkha/common/util/UUIDBits.java new file mode 100644 index 0000000..241ed87 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/UUIDBits.java @@ -0,0 +1,43 @@ +package com.dkha.common.util; + +import java.util.UUID; + +/** + * All rights 成都电科慧安 + * + * @ClassName: UUIDBits + * @program: dkha-cloud + * @description: + * @author: maming + * @create: 2019/11/18 10:47 + **/ + +public class UUIDBits { + + public static String[] chars = new String[] { "a", "b", "c", "d", "e", "f", + "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", + "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", + "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", + "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", + "W", "X", "Y", "Z" }; + + /** + * 生成6位UUID + * @return 6位UUID + */ + public static String getUUIDBits(Integer num) { + StringBuffer shortBuffer = new StringBuffer(); + String uuid = UUID.randomUUID().toString().replace("-", ""); + for (int i = 0; i < num; i++) { + String str = uuid.substring(i * 4, i * 4 + 4); + int x = Integer.parseInt(str, 16); + shortBuffer.append(chars[x % 0x3E]); + } + return shortBuffer.toString(); + } + + public static void main(String[] args) { + System.out.println(getUUIDBits(6)); + } +} + diff --git a/face-common/src/main/java/com/dkha/common/util/UrlUtil.java b/face-common/src/main/java/com/dkha/common/util/UrlUtil.java new file mode 100644 index 0000000..170cab0 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/UrlUtil.java @@ -0,0 +1,109 @@ +package com.dkha.common.util; + +import com.dkha.common.enums.ErrEnum; +import com.dkha.common.http.HttpUtil; +import com.dkha.common.modules.vo.ReturnVO; +import com.dkha.common.result.CommonResult; +import com.google.gson.Gson; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: UrlUtil + * @Package com.dkha.task.util + * @author: panhui + * @date: 2020/1/10 10:46 + * @Copyright: 成都电科慧安 + */ +public class UrlUtil { + /** + * 调用预警的信息 faceserver + * + * @param object + * @return + */ + public static String postData(String warningUrl, Object object, HttpUtil httpUtil, Gson gson) { + try { + CommonResult commonResult = (CommonResult) httpUtil.post(warningUrl, object, CommonResult.class); + if (commonResult.getCode().intValue() != 0 || UtilValidate.isEmpty(commonResult.getData())) { + return null; + } + return gson.toJson(commonResult.getData()); + } catch (Exception e) { + return null; + } + } + + /** + * 调用预警的信息 face-server + * + * @param warningUrl + * @return + */ + public static String getData(String warningUrl, HttpUtil httpUtil, Gson gson) { +// log.error("warningUrl={}",warningUrl); + try { + + CommonResult commonResult = (CommonResult) httpUtil.get(warningUrl, CommonResult.class); + if (commonResult.getCode().intValue() != 0 || UtilValidate.isEmpty(commonResult.getData())) { + return null; + } + return gson.toJson(commonResult.getData()); + } catch (Exception e) { + return null; + } + } + + /** + * 调用 api + * + * @param object + * @return + */ + public static String postApiData(String warningUrl, Object object, HttpUtil httpUtil, Gson gson) { + try { + ReturnVO returnVO = (ReturnVO) httpUtil.post(warningUrl, object, ReturnVO.class); + if (returnVO.getCode().intValue() != 200 || UtilValidate.isEmpty(returnVO.getData())) { + return null; + } + return gson.toJson(returnVO.getData()); + } catch (Exception e) { + return null; + } + } + + + /** + * 调用 api + * + * @param warningUrl + * @return + */ + public static String getApiData(String warningUrl, HttpUtil httpUtil, Gson gson) { +// log.error("warningUrl={}",warningUrl); + try { + + ReturnVO returnVO = (ReturnVO) httpUtil.get(warningUrl, ReturnVO.class); + if (returnVO.getCode().intValue() != 200 || UtilValidate.isEmpty(returnVO.getData())) { + return null; + } + return gson.toJson(returnVO.getData()); + } catch (Exception e) { + return null; + } + } + + public static String getData(String warningUrl, Object object, HttpUtil httpUtil, Gson gson) + { + CommonResult commonResult= (CommonResult) httpUtil.get(warningUrl,object,CommonResult.class); + //为授权 + if (commonResult.getCode().intValue()==ErrEnum.UNAUTHORIZED.getCode()){ + return gson.toJson(401); + } + if(commonResult.getCode().intValue()!=0 || UtilValidate.isEmpty(commonResult.getData())) { + return null; + } + return gson.toJson(commonResult.getData()); + } +} diff --git a/face-common/src/main/java/com/dkha/common/util/UtilValidate.java b/face-common/src/main/java/com/dkha/common/util/UtilValidate.java new file mode 100644 index 0000000..69531f4 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/UtilValidate.java @@ -0,0 +1,144 @@ +package com.dkha.common.util; + +import java.util.Collection; +import java.util.Map; + +/** + * @author Spring + * @date 2017/5/18-11:30 + * @Description: 通用验证工具类 + */ +public class UtilValidate { + + /** + * 验证一个对象是否非空,支持String,Map,Collection等。 + * @param o + * @return + */ + public static boolean isEmpty(Object o){ + return isBaseEmpty(o); + } + + /** + * 验证String是否为空 + * @param s + * @return + */ + public static boolean isEmpty(String s) { + return ((s == null) || (s.length() == 0)); + } + + /** + * 验证数组是否为空 + * @param arrays + * @return + */ + public static boolean isEmpty(Object [] arrays) { + return ((arrays == null) || (arrays.length == 0)); + } + + /** + * 验证一个集合是否为空 + * @param c + * @param + * @return + */ + public static boolean isEmpty(Collection c) { + return ((c == null) || (c.size() == 0)); + } + + /** + * 验证Map集合是否为空 + * @param m + * @param + * @param + * @return + */ + public static boolean isEmpty(Map m) { + return ((m == null) || (m.size() == 0)); + } + + /** + * 验证charsequence是否为空 + * @param c + * @return + */ + public static boolean isEmpty(CharSequence c) { + return ((c == null) || (c.length() == 0)); + } + + /** + * 验证一个对象是否非空,支持String,Map,Collection等。 + * @param o + * @return + */ + public static boolean isNotEmpty(Object o) { + return !isBaseEmpty(o); + } + + /** + * 验证String是否不为空 + * @param s + * @return + */ + public static boolean isNotEmpty(String s) { + return ((s != null) && (s.length() > 0)); + } + + /** + * 验证数组是否为空 + * @param arrays + * @return + */ + public static boolean isNotEmpty(Object [] arrays) { + return ((arrays != null) && (arrays.length > 0)); + } + + /** + * 验证Collection是否不为空 + * @param c + * @param + * @return + */ + public static boolean isNotEmpty(Collection c) { + return ((c != null) && (c.size() > 0)); + } + + /** + * 验证CharSequence是否不能为空 + * @param c + * @return + */ + public static boolean isNotEmpty(CharSequence c) { + return ((c != null) && (c.length() > 0)); + } + + /** + * 基类 + * @param value + * @return + */ + @SuppressWarnings("unchecked") + private static boolean isBaseEmpty(Object value) { + if (value == null) return true; + if (value instanceof String) return UtilValidate.isEmpty((String) value); + if (value instanceof Collection) return UtilValidate.isEmpty((Collection) value); + if (value instanceof Map) return UtilValidate.isEmpty((Map) value); + if (value instanceof CharSequence) return UtilValidate.isEmpty((CharSequence) value); + // These types would flood the log + // Number covers: BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, Short + if (value instanceof Boolean) return false; + if (value instanceof Number) return false; + if (value instanceof Character) return false; + if (value instanceof java.sql.Timestamp) return false; + return false; + } + + /** + * 系统测试方法 + * @param args + */ + public static void main(String[] args) { + System.out.println(UtilValidate.isEmpty("")); + } +} diff --git a/face-common/src/main/java/com/dkha/common/util/excel/ExcelField.java b/face-common/src/main/java/com/dkha/common/util/excel/ExcelField.java new file mode 100644 index 0000000..2918801 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/excel/ExcelField.java @@ -0,0 +1,59 @@ +/** + * Copyright © 2012-2016 JeeSite All rights reserved. + */ +package com.dkha.common.util.excel; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Excel注解定义 + * @author ThinkGem + * @version 2013-03-10 + */ +@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ExcelField { + + /** + * 导出字段名(默认调用当前字段的“get”方法,如指定导出字段为对象,请填写“对象名.对象属性”,例:“area.name”、“office.name”) + */ + String value() default ""; + + /** + * 导出字段标题(需要添加批注请用“**”分隔,标题**批注,仅对导出模板有效) + */ + String title(); + + /** + * 字段类型(0:导出导入;1:仅导出;2:仅导入) + */ + int type() default 0; + + /** + * 导出字段对齐方式(0:自动;1:靠左;2:居中;3:靠右) + */ + int align() default 0; + + /** + * 导出字段字段排序(升序) + */ + int sort() default 0; + + /** + * 如果是字典类型,请设置字典的type值 + */ + String dictType() default ""; + + /** + * 反射类型 + */ + Class fieldType() default Class.class; + + /** + * 字段归属组(根据分组导出导入) + */ + int[] groups() default {}; +} diff --git a/face-common/src/main/java/com/dkha/common/util/excel/ImportExcel.java b/face-common/src/main/java/com/dkha/common/util/excel/ImportExcel.java new file mode 100644 index 0000000..ed9cb24 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/excel/ImportExcel.java @@ -0,0 +1,343 @@ +package com.dkha.common.util.excel; + +import com.google.common.collect.Lists; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; + + +/** + * 导入Excel文件(支持“XLS”和“XLSX”格式) + * @author ThinkGem + * @version 2013-03-10 + */ +public class ImportExcel { + + private static Logger log = LoggerFactory.getLogger(ImportExcel.class); + + /** + * 工作薄对象 + */ + private Workbook wb; + + /** + * 工作表对象 + */ + private Sheet sheet; + + /** + * 标题行号 + */ + private int headerNum; + + /** + * 构造函数 + * @param fileName 导入文件,读取第一个工作表 + * @param headerNum 标题行号,数据行号=标题行号+1 + * @throws InvalidFormatException + * @throws IOException + */ + public ImportExcel(String fileName, int headerNum) + throws InvalidFormatException, IOException { + this(new File(fileName), headerNum); + } + + /** + * 构造函数 + * @param file 导入文件对象,读取第一个工作表 + * @param headerNum 标题行号,数据行号=标题行号+1 + * @throws InvalidFormatException + * @throws IOException + */ + public ImportExcel(File file, int headerNum) + throws InvalidFormatException, IOException { + this(file, headerNum, 0); + } + + /** + * 构造函数 + * @param fileName 导入文件 + * @param headerNum 标题行号,数据行号=标题行号+1 + * @param sheetIndex 工作表编号 + * @throws InvalidFormatException + * @throws IOException + */ + public ImportExcel(String fileName, int headerNum, int sheetIndex) + throws InvalidFormatException, IOException { + this(new File(fileName), headerNum, sheetIndex); + } + + /** + * 构造函数 + * @param file 导入文件对象 + * @param headerNum 标题行号,数据行号=标题行号+1 + * @param sheetIndex 工作表编号 + * @throws InvalidFormatException + * @throws IOException + */ + public ImportExcel(File file, int headerNum, int sheetIndex) + throws InvalidFormatException, IOException { + this(file.getName(), new FileInputStream(file), headerNum, sheetIndex); + } + + /** + * 构造函数 + * @param multipartFile 导入文件对象 + * @param headerNum 标题行号,数据行号=标题行号+1 + * @param sheetIndex 工作表编号 + * @throws InvalidFormatException + * @throws IOException + */ + public ImportExcel(MultipartFile multipartFile, int headerNum, int sheetIndex) + throws InvalidFormatException, IOException { + this(multipartFile.getOriginalFilename(), multipartFile.getInputStream(), headerNum, sheetIndex); + } + + /** + * @param fileName 导入文件对象 + * @param is 文件流 + * @param headerNum 标题行号,数据行号=标题行号+1 + * @param sheetIndex 工作表编号 + * @throws InvalidFormatException + * @throws IOException + */ + public ImportExcel(String fileName, InputStream is, int headerNum, int sheetIndex) + throws InvalidFormatException, IOException { + if (StringUtils.isBlank(fileName)){ + throw new RuntimeException("导入文档为空!"); + }else if(fileName.toLowerCase().endsWith("xls")){ + this.wb = new HSSFWorkbook(is); + }else if(fileName.toLowerCase().endsWith("xlsx")){ + this.wb = new XSSFWorkbook(is); + }else{ + throw new RuntimeException("文档格式不正确!"); + } + if (this.wb.getNumberOfSheets() List getDataList(Class cls, int... groups) throws InstantiationException, IllegalAccessException{ + List annotationList = Lists.newArrayList(); + // Get annotation field + Field[] fs = cls.getDeclaredFields(); + for (Field f : fs){ + ExcelField ef = f.getAnnotation(ExcelField.class); + if (ef != null && (ef.type()==0 || ef.type()==2)){ + if (groups!=null && groups.length>0){ + boolean inGroup = false; + for (int g : groups){ + if (inGroup){ + break; + } + for (int efg : ef.groups()){ + if (g == efg){ + inGroup = true; + annotationList.add(new Object[]{ef, f}); + break; + } + } + } + }else{ + annotationList.add(new Object[]{ef, f}); + } + } + } + // Get annotation method + Method[] ms = cls.getDeclaredMethods(); + for (Method m : ms){ + ExcelField ef = m.getAnnotation(ExcelField.class); + if (ef != null && (ef.type()==0 || ef.type()==2)){ + if (groups!=null && groups.length>0){ + boolean inGroup = false; + for (int g : groups){ + if (inGroup){ + break; + } + for (int efg : ef.groups()){ + if (g == efg){ + inGroup = true; + annotationList.add(new Object[]{ef, m}); + break; + } + } + } + }else{ + annotationList.add(new Object[]{ef, m}); + } + } + } + // Field sorting + Collections.sort(annotationList, new Comparator() { + @Override + public int compare(Object[] o1, Object[] o2) { + return new Integer(((ExcelField)o1[0]).sort()).compareTo( + new Integer(((ExcelField)o2[0]).sort())); + }; + }); + log.debug("Import column count:"+annotationList.size()); + // Get excel data + List dataList = Lists.newArrayList(); + //错误数据 + List error = Lists.newArrayList(); + for (int i = this.getDataRowNum(); i < this.getLastDataRowNum(); i++) { + E e = (E)cls.newInstance(); + int column = 0; + Row row = this.getRow(i); + StringBuilder sb = new StringBuilder(); + for (Object[] os : annotationList){ + Object val = this.getCellValue(row, column++); + if (val != null){ + ExcelField ef = (ExcelField)os[0]; + // Get param type and type cast + Class valType = Class.class; + if (os[1] instanceof Field){ + valType = ((Field)os[1]).getType(); + }else if (os[1] instanceof Method){ + Method method = ((Method)os[1]); + if ("get".equals(method.getName().substring(0, 3))){ + valType = method.getReturnType(); + }else if("set".equals(method.getName().substring(0, 3))){ + valType = ((Method)os[1]).getParameterTypes()[0]; + } + } + log.info("Import value type===>导入数据信息: ["+i+","+column+"] " + valType); + try { + if (valType == String.class){ + String s = String.valueOf(val.toString()); + if(StringUtils.endsWith(s, ".0")){ + val = StringUtils.substringBefore(s, ".0"); + }else{ + val = String.valueOf(val.toString()); + } + }else if (valType == Integer.class){ + val = Double.valueOf(val.toString()).intValue(); + }else if (valType == Long.class){ + val = Double.valueOf(val.toString()).longValue(); + }else if (valType == Double.class){ + val = Double.valueOf(val.toString()); + }else if (valType == Float.class){ + val = Float.valueOf(val.toString()); + }else if (valType == Date.class){ + val = DateUtil.getJavaDate((Double)val); + }else{ + if (ef.fieldType() != Class.class){ + val = ef.fieldType().getMethod("getValue", String.class).invoke(null, val.toString()); + }else{ + val = Class.forName(this.getClass().getName().replaceAll(this.getClass().getSimpleName(), + "fieldtype."+valType.getSimpleName()+"Type")).getMethod("getValue", String.class).invoke(null, val.toString()); + } + } + } catch (Exception ex) { + log.info("Get cell value ["+i+","+column+"] error: " + ex.toString()); + val=ex.getMessage(); + val = null; +// return error; + } + // set entity value + if (os[1] instanceof Field){ + Reflections.invokeSetter(e, ((Field)os[1]).getName(), val); + }else if (os[1] instanceof Method){ + String mthodName = ((Method)os[1]).getName(); + if ("get".equals(mthodName.substring(0, 3))){ + mthodName = "set"+StringUtils.substringAfter(mthodName, "get"); + } + Reflections.invokeMethod(e, mthodName, new Class[] {valType}, new Object[] {val}); + } + } + sb.append(val+", "); + } + dataList.add(e); + log.debug("Read success"); + } + return dataList; + } + + +} diff --git a/face-common/src/main/java/com/dkha/common/util/excel/Reflections.java b/face-common/src/main/java/com/dkha/common/util/excel/Reflections.java new file mode 100644 index 0000000..01ea016 --- /dev/null +++ b/face-common/src/main/java/com/dkha/common/util/excel/Reflections.java @@ -0,0 +1,299 @@ +/** + * Copyright (c) 2005-2012 springside.org.cn + */ +package com.dkha.common.util.excel; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.Assert; + +import java.lang.reflect.*; + +/** + * 反射工具类. + * 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数. + * @author calvin + * @version 2013-01-15 + */ +@SuppressWarnings("rawtypes") +public class Reflections { + + private static final String SETTER_PREFIX = "set"; + + private static final String GETTER_PREFIX = "get"; + + private static final String CGLIB_CLASS_SEPARATOR = "$$"; + + private static Logger logger = LoggerFactory.getLogger(Reflections.class); + + /** + * 调用Getter方法. + * 支持多级,如:对象名.对象名.方法 + */ + public static Object invokeGetter(Object obj, String propertyName) { + Object object = obj; + for (String name : StringUtils.split(propertyName, ".")){ + String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name); + object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); + } + return object; + } + + /** + * 调用Setter方法, 仅匹配方法名。 + * 支持多级,如:对象名.对象名.方法 + */ + public static void invokeSetter(Object obj, String propertyName, Object value) { + Object object = obj; + String[] names = StringUtils.split(propertyName, "."); + for (int i=0; i[] parameterTypes, + final Object[] args) { + Method method = getAccessibleMethod(obj, methodName, parameterTypes); + if (method == null) { + throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]"); + } + + try { + return method.invoke(obj, args); + } catch (Exception e) { + throw convertReflectionExceptionToUnchecked(e); + } + } + + /** + * 直接调用对象方法, 无视private/protected修饰符, + * 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用. + * 只匹配函数名,如果有多个同名函数调用第一个。 + */ + public static Object invokeMethodByName(final Object obj, final String methodName, final Object[] args) { + Method method = getAccessibleMethodByName(obj, methodName); + if (method == null) { + throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]"); + } + + try { + return method.invoke(obj, args); + } catch (Exception e) { + throw convertReflectionExceptionToUnchecked(e); + } + } + + /** + * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问. + * + * 如向上转型到Object仍无法找到, 返回null. + */ + public static Field getAccessibleField(final Object obj, final String fieldName) { + Validate.notNull(obj, "object can't be null"); + Validate.notBlank(fieldName, "fieldName can't be blank"); + for (Class superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) { + try { + Field field = superClass.getDeclaredField(fieldName); + makeAccessible(field); + return field; + } catch (NoSuchFieldException e) {//NOSONAR + // Field不在当前类定义,继续向上转型 + continue;// new add + } + } + return null; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 匹配函数名+参数类型。 + * + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) + */ + public static Method getAccessibleMethod(final Object obj, final String methodName, + final Class... parameterTypes) { + Validate.notNull(obj, "object can't be null"); + Validate.notBlank(methodName, "methodName can't be blank"); + + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { + try { + Method method = searchType.getDeclaredMethod(methodName, parameterTypes); + makeAccessible(method); + return method; + } catch (NoSuchMethodException e) { + // Method不在当前类定义,继续向上转型 + continue;// new add + } + } + return null; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 只匹配函数名。 + * + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) + */ + public static Method getAccessibleMethodByName(final Object obj, final String methodName) { + Validate.notNull(obj, "object can't be null"); + Validate.notBlank(methodName, "methodName can't be blank"); + + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { + Method[] methods = searchType.getDeclaredMethods(); + for (Method method : methods) { + if (method.getName().equals(methodName)) { + makeAccessible(method); + return method; + } + } + } + return null; + } + + /** + * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 + */ + public static void makeAccessible(Method method) { + if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) + && !method.isAccessible()) { + method.setAccessible(true); + } + } + + /** + * 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 + */ + public static void makeAccessible(Field field) { + if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier + .isFinal(field.getModifiers())) && !field.isAccessible()) { + field.setAccessible(true); + } + } + + /** + * 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处 + * 如无法找到, 返回Object.class. + * eg. + * public UserDao extends HibernateDao + * + * @param clazz The class to introspect + * @return the first generic declaration, or Object.class if cannot be determined + */ + @SuppressWarnings("unchecked") + public static Class getClassGenricType(final Class clazz) { + return getClassGenricType(clazz, 0); + } + + /** + * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. + * 如无法找到, 返回Object.class. + * + * 如public UserDao extends HibernateDao + * + * @param clazz clazz The class to introspect + * @param index the Index of the generic ddeclaration,start from 0. + * @return the index generic declaration, or Object.class if cannot be determined + */ + public static Class getClassGenricType(final Class clazz, final int index) { + + Type genType = clazz.getGenericSuperclass(); + + if (!(genType instanceof ParameterizedType)) { + logger.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType"); + return Object.class; + } + + Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); + + if (index >= params.length || index < 0) { + logger.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + + params.length); + return Object.class; + } + if (!(params[index] instanceof Class)) { + logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter"); + return Object.class; + } + + return (Class) params[index]; + } + + public static Class getUserClass(Object instance) { + Assert.notNull(instance, "Instance must not be null"); + Class clazz = instance.getClass(); + if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) { + Class superClass = clazz.getSuperclass(); + if (superClass != null && !Object.class.equals(superClass)) { + return superClass; + } + } + return clazz; + + } + + /** + * 将反射时的checked exception转换为unchecked exception. + */ + public static RuntimeException convertReflectionExceptionToUnchecked(Exception e) { + if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException + || e instanceof NoSuchMethodException) { + return new IllegalArgumentException(e); + } else if (e instanceof InvocationTargetException) { + return new RuntimeException(((InvocationTargetException) e).getTargetException()); + } else if (e instanceof RuntimeException) { + return (RuntimeException) e; + } + return new RuntimeException("Unexpected Checked Exception.", e); + } +} diff --git a/face-server/Dockerfile b/face-server/Dockerfile new file mode 100644 index 0000000..187249d --- /dev/null +++ b/face-server/Dockerfile @@ -0,0 +1,8 @@ +FROM centos7/jdk1.8 +#指定工作目录 +WORKDIR /usr/local +RUN touch face.log +ADD face-server-1.0-SNAPSHOT.jar face-server-1.0-SNAPSHOT.jar +#指定暴露的端口号 +EXPOSE 8899 +ENTRYPOINT java -jar face-server-1.0-SNAPSHOT.jar > face.log 2>&1 \ No newline at end of file diff --git a/face-server/pom.xml b/face-server/pom.xml new file mode 100644 index 0000000..350248a --- /dev/null +++ b/face-server/pom.xml @@ -0,0 +1,194 @@ + + + + face-application + com.dkha + 1.0-SNAPSHOT + + 4.0.0 + + face-server + + + + com.dkha + face-common + ${project.version} + + + org.apache.mina + mina-core + 2.1.3 + + + org.springframework.boot + spring-boot-starter-websocket + + + + org.springframework + springloaded + + + org.springframework.boot + spring-boot-devtools + true + true + + + + + + + + + org.springframework.boot + spring-boot-starter-actuator + + + com.github.axet + kaptcha + + + + io.springfox + springfox-swagger2 + + + io.springfox + springfox-swagger-ui + + + + com.baomidou + mybatis-plus-boot-starter + + + com.baomidou + mybatis-plus-generator + + + + + org.freemarker + freemarker + + + mysql + mysql-connector-java + + + org.projectlombok + lombok + + + com.alibaba + druid-spring-boot-starter + + + org.springframework.boot + spring-boot-starter-data-redis + + + redis.clients + jedis + + + + + io.minio + minio + + + com.alibaba + fastjson + + + io.netty + netty-all + + + org.apache.shiro + shiro-core + + + org.apache.shiro + shiro-spring + + + com.github.axet + kaptcha + + + + cn.afterturn + easypoi-base + + + cn.afterturn + easypoi-web + + + cn.afterturn + easypoi-annotation + + + org.aspectj + aspectjrt + + + org.apache.commons + commons-lang3 + + + com.sun.mail + javax.mail + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework.boot + spring-boot-starter-aop + + + + org.springframework.boot + spring-boot-starter-web + + + org.bytedeco + javacv + 1.4.3 + + + org.bytedeco.javacpp-presets + opencv + 3.4.3-1.4.3 + windows-x86_64 + + + + + org.bytedeco.javacpp-presets + ffmpeg-platform + 4.0.2-1.4.3 + + + + + + org.springframework.boot + spring-boot-maven-plugin + + com.dkha.server.FaceServerApplication + + + + + diff --git a/face-server/src/main/java/com/dkha/server/FaceServerApplication.java b/face-server/src/main/java/com/dkha/server/FaceServerApplication.java new file mode 100644 index 0000000..12e40ca --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/FaceServerApplication.java @@ -0,0 +1,50 @@ +package com.dkha.server; + +import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor; +import com.dkha.server.common.handler.MyMetaObjectHandler; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.scheduling.annotation.EnableScheduling; + +import java.net.InetSocketAddress; + + +@SpringBootApplication(exclude = { + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class},scanBasePackages = {"com.dkha.common", "com.dkha.server"}) +@MapperScan("com.dkha.server.mappers") +@MapperScan("com.dkha.server.system.modules.log.dao") +@MapperScan("com.dkha.server.system.modules.sys.dao") +@EnableScheduling +public class FaceServerApplication { + public static void main(String[] args) { + SpringApplication springApplication = new SpringApplication(FaceServerApplication.class); + ConfigurableApplicationContext configurableApplicationContext = springApplication.run(args); + //解决WebSocket不能注入的问题 + } + + /** + * mybatis-plus自动注入插件 + * + * @return + */ + @Bean + public MyMetaObjectHandler createMyMetaObjectHandler() { + return new MyMetaObjectHandler(); + } + + + /** + * mybatis-plus执行效率插件 + * @return + */ + //@Bean + // 设置 dev test 环境开启 + //@Profile({"dev"}) + public PerformanceInterceptor performanceInterceptor() { + return new PerformanceInterceptor(); + } + +} diff --git a/face-server/src/main/java/com/dkha/server/annotation/NoRepeatSubmitAnnotation.java b/face-server/src/main/java/com/dkha/server/annotation/NoRepeatSubmitAnnotation.java new file mode 100644 index 0000000..9c3d386 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/annotation/NoRepeatSubmitAnnotation.java @@ -0,0 +1,29 @@ +package com.dkha.server.annotation; + +import java.lang.annotation.*; +import java.util.concurrent.TimeUnit; + +/** + * @version V1.0 + * @Description: 对需要防止重复提交的页面添加该注解 + * @Title: 防止重复提交 + * @author: huangyugang + * @date: 2019/12/23 13:58 + * @Copyright: 成都电科慧安 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface NoRepeatSubmitAnnotation { + /** key前缀 */ + String prefix() default ""; + + /** 过期秒数,默认为5秒 */ + int expire() default 5; + + /** 超时时间单位,默认为秒 */ + TimeUnit timeUnit() default TimeUnit.SECONDS; + + /** Key的分隔符(默认 :) */ + String delimiter() default ":"; +} diff --git a/face-server/src/main/java/com/dkha/server/aspect/RepeatSubmitAspect.java b/face-server/src/main/java/com/dkha/server/aspect/RepeatSubmitAspect.java new file mode 100644 index 0000000..54a366c --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/aspect/RepeatSubmitAspect.java @@ -0,0 +1,93 @@ +package com.dkha.server.aspect; + +import com.dkha.common.exception.DkException; +import com.dkha.common.result.CommonResult; +import com.dkha.common.systemcode.SystemCode; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.annotation.NoRepeatSubmitAnnotation; +import com.dkha.server.system.modules.security.user.SecurityUser; +import lombok.extern.slf4j.Slf4j; +import org.apache.catalina.manager.util.SessionUtils; +import org.apache.commons.lang3.StringUtils; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisCallback; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.script.DefaultRedisScript; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.Objects; +import java.util.UUID; + +/** + * @version V1.0 + * @Description: 防止重复提交的切面 + * @Title: + * @author: huangyugang + * @date: 2019/12/23 14:01 + * @Copyright: 成都电科慧安 + */ +@Aspect +@Component +@Slf4j +public class RepeatSubmitAspect { + + /** lua */ + private static final String RELEASE_LOCK_LUA_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; + + @Autowired + private RedisTemplate redisTemplate; + + @Pointcut("@annotation(com.dkha.server.annotation.NoRepeatSubmitAnnotation)") + public void pointCut(){} + + @Around("pointCut()") + public Object around(ProceedingJoinPoint joinPoint) throws Throwable{ + log.info("接口幂等性验证:"); + // 可以根据业务获取用户唯一的个人信息,例如手机号码 + if(UtilValidate.isEmpty(SecurityUser.getUserId())) + { + throw new DkException(SystemCode.TOKEN_ERROR); + } + String phone = SecurityUser.getUserId().toString(); + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + NoRepeatSubmitAnnotation cacheLock = method.getAnnotation(NoRepeatSubmitAnnotation.class); + String prefix = cacheLock.prefix(); + if (StringUtils.isBlank(prefix)){ + throw new DkException("CacheLock prefix can't be null"); + } + // 拼接 key + String delimiter = cacheLock.delimiter(); + StringBuilder sb = new StringBuilder(); + sb.append(prefix).append(delimiter).append(phone); + final String lockKey = sb.toString(); + final String UUID = java.util.UUID.randomUUID().toString(); + try { + // 获取锁 + boolean success = redisTemplate.opsForValue().setIfAbsent(lockKey,UUID,cacheLock.expire(),cacheLock.timeUnit()); + if (!success){ + + throw new DkException("请勿重复提交"); + } + Object result= joinPoint.proceed(); + return result; + }finally { + // 最后记得释放锁 + DefaultRedisScript redisScript = new DefaultRedisScript<>(RELEASE_LOCK_LUA_SCRIPT,Long.class); + Long result = redisTemplate.execute(redisScript, Collections.singletonList(lockKey),UUID); + } + + } + +} diff --git a/face-server/src/main/java/com/dkha/server/aspect/portraitThread.java b/face-server/src/main/java/com/dkha/server/aspect/portraitThread.java new file mode 100644 index 0000000..467e640 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/aspect/portraitThread.java @@ -0,0 +1,41 @@ +package com.dkha.server.aspect; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: portraitThread + * @Package com.dkha.server.aspect + * @author: yangjun + * @date: 2019/12/27 16:48 + * @Copyright: 成都电科慧安 + */ +public class portraitThread implements Runnable{ + + /** + * 线程名称 + */ + private String threadName; + + /** + * 构造函数 + * + * @param threadName 线程名称 + */ + public portraitThread(String threadName) { + this.threadName = threadName; + } + + @Override + public void run() { + for (int i = 0; i < 100; i++) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("--->>>"+"开始执行"+i); + } + + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/common/config/InitStartDateConfig.java b/face-server/src/main/java/com/dkha/server/common/config/InitStartDateConfig.java new file mode 100644 index 0000000..b4f1714 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/common/config/InitStartDateConfig.java @@ -0,0 +1,32 @@ +package com.dkha.server.common.config; + +import com.dkha.common.util.UtilValidate; +import org.springframework.context.annotation.Bean; + +import java.util.Date; + +/** + * @version V1.0 + * @Description: TODO(系统启动创建一个时间) + * All rights 成都电科慧安 + * @Title: InitStartDateConfig + * @Package com.dkha.server.common.config + * @author: panhui + * @date: 2019/12/15 9:02 + * @Copyright: 成都电科慧安 + */ +public class InitStartDateConfig { + + public static Date initDate; + + static + { + if(UtilValidate.isEmpty(initDate)) + { + initDate=new Date(); + initDate.setHours(0); + initDate.setMinutes(0); + initDate.setSeconds(0); + } + } +} diff --git a/face-server/src/main/java/com/dkha/server/common/config/SwaggerConfig.java b/face-server/src/main/java/com/dkha/server/common/config/SwaggerConfig.java new file mode 100644 index 0000000..bbc5b26 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/common/config/SwaggerConfig.java @@ -0,0 +1,64 @@ +package com.dkha.server.common.config; + +import com.dkha.server.system.common.constant.Constant; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.ApiKey; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import java.util.List; + +import static com.google.common.collect.Lists.newArrayList; + +/** + * Swagger配置 + * + * @author Mark sunlightcs@gmail.com + */ +@Configuration +@EnableSwagger2 +public class SwaggerConfig { + + @Value("${swagger.show}") + private boolean isShow; + + @Bean + public Docket createRestApi() { + return new Docket(DocumentationType.SWAGGER_2) + .enable(isShow) + .apiInfo(apiInfo()) + .select() + //加了ApiOperation注解的类,生成接口文档 + .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) + //包下的类,生成接口文档 + //.apis(RequestHandlerSelectors.basePackage("io.renren.modules.job.controller")) + .paths(PathSelectors.any()) + .build() + .directModelSubstitute(java.util.Date.class, String.class) + .securitySchemes(security()); + } + + private ApiInfo apiInfo() { + return new ApiInfoBuilder() + .title("face server") + .description("faceServer api文档") + .version("V1.0") + .build(); + } + + + private List security() { + return newArrayList( + new ApiKey(Constant.TOKEN_HEADER, Constant.TOKEN_HEADER, "header") + ); + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/common/exception/DkExceptionHandler.java b/face-server/src/main/java/com/dkha/server/common/exception/DkExceptionHandler.java new file mode 100644 index 0000000..8c836df --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/common/exception/DkExceptionHandler.java @@ -0,0 +1,69 @@ +package com.dkha.server.common.exception; + +import com.dkha.common.exception.DkAuthorityException; +import com.dkha.common.exception.DkException; +import com.dkha.common.result.CommonResult; +import com.dkha.common.systemcode.SystemCode; +import com.dkha.server.system.common.utils.Result; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import javax.servlet.http.HttpServletRequest; + +/** + * @Author Spring + * @Since 2019/11/11 16:42 + * @Description 全局异常处理类--用于非系统异常处理 + * 系统异常全局异常处理类 + */ +@RestControllerAdvice +public class DkExceptionHandler extends CommonResult { + + private static final Logger logger = LoggerFactory.getLogger(DkExceptionHandler.class); + + /** + * Dk自定义异常全局处理 + * + * @param ex + * @return + */ + @ExceptionHandler(DkException.class) + public CommonResult handleDkException(DkException ex, HttpServletRequest request) { + logger.error(ex.getMessage(), ex); + return failResult(ex.getMsg()); + } + + /** + * 参数校验异常处理 + * + * @param ex + * @return + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + public CommonResult handleDkException(MethodArgumentNotValidException ex) { + logger.error(ex.getMessage(), ex); + return failResult(ex.getBindingResult().getFieldError().getDefaultMessage()); + + } + + /** + * 权限异常拦截--主要用于拦截token + * + * @param ex + * @return + */ + @ExceptionHandler(DkAuthorityException.class) + public CommonResult handleAuthorityException(DkAuthorityException ex) { + logger.error(ex.getMessage(), ex); + return failResult(SystemCode.TOKEN_ERROR.des); + } + + @ExceptionHandler(Exception.class) + public CommonResult handleException(Exception ex,HttpServletRequest request) { + logger.error(ex.getMessage(), ex); + return failResult(SystemCode.HANDLER_FAILED.des); + } +} diff --git a/face-server/src/main/java/com/dkha/server/common/handler/MyMetaObjectHandler.java b/face-server/src/main/java/com/dkha/server/common/handler/MyMetaObjectHandler.java new file mode 100644 index 0000000..7880a1d --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/common/handler/MyMetaObjectHandler.java @@ -0,0 +1,43 @@ +package com.dkha.server.common.handler; + +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import com.dkha.common.enums.YNEnums; +import com.dkha.server.system.modules.security.user.SecurityUser; +import org.apache.ibatis.reflection.MetaObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Date; + +/** + * 公共字段自动填充处理类 + */ +public class MyMetaObjectHandler implements MetaObjectHandler { + private static final Logger LOGGER = LoggerFactory.getLogger(MyMetaObjectHandler.class); + + + @Override + public void insertFill(MetaObject metaObject) { + + /** + * Ps:此处不能用下划线表示数据库字段,要使用驼峰命名 + */ + + Object isValidData = this.getFieldValByName( + "isValid", metaObject); + if (isValidData == null) { + this.setFieldValByName("isValid", YNEnums.YES.code, metaObject); + } + this.setFieldValByName("createTime", new Date(), metaObject); + this.setFieldValByName("createBy", String.valueOf(0L), metaObject); + this.setFieldValByName("updateTime", new Date(), metaObject); + this.setFieldValByName("updateBy", String.valueOf(0L), metaObject); + } + + @Override + public void updateFill(MetaObject metaObject) { + this.setUpdateFieldValByName("updateTime", new Date(), metaObject); + this.setUpdateFieldValByName("updateBy", String.valueOf(0L), metaObject); + } +} + diff --git a/face-server/src/main/java/com/dkha/server/controllers/CameraController.java b/face-server/src/main/java/com/dkha/server/controllers/CameraController.java new file mode 100644 index 0000000..69d8f51 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/controllers/CameraController.java @@ -0,0 +1,227 @@ +package com.dkha.server.controllers; + +import com.dkha.common.exception.DkException; +import com.dkha.common.page.PageParam; +import com.dkha.common.result.CommonResult; +import com.dkha.common.util.ExcelUtils; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.annotation.NoRepeatSubmitAnnotation; +import com.dkha.server.modules.entities.FaceCameraEntity; +import com.dkha.server.modules.entities.faceCamera.FaceCameraExcel; +import com.dkha.server.modules.entities.faceCamera.FaceCameraInfo; +import com.dkha.server.modules.entities.faceCamera.InsertFaceCamera; +import com.dkha.server.services.FaceCameraService; +import com.dkha.server.system.modules.sys.entity.SysRegionEntity; +import com.dkha.server.system.modules.sys.enums.RegionLevelEnum; +import com.dkha.server.system.modules.sys.enums.RegionTopEnum; +import com.dkha.server.system.modules.sys.service.SysRegionService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static com.dkha.common.systemcode.SystemCode.EXCEL_ERROR_DATA; + +@RestController +@RequestMapping(value = "/camera") +@Api(tags = "摄像头管理") +@Slf4j +public class CameraController extends CommonResult { + + @Resource + private SysRegionService sysRegionService; + + @Resource + private FaceCameraService faceCameraServiceImpl; + + @ApiOperation(value = "摄像头列表") + @PostMapping(value = "/getList") + @RequiresPermissions("camera:list") + public CommonResult getList(@ApiParam(required = true, name = "pageParam", value = "{\n" + + " \"note\": {\n" + + " \"cameraName\": \"摄像头名称\",\n" + + " \"cameraRegion\":\"摄像头区域\",\n" + + " \"cameratLocationtypeId\":\"位置类型\",\n" + + + "\"status\":\"是否运行 Y启动 N未启动\"\n" + + " },\n" + + " \"pageNo\": 1,\n" + + " \"pageSize\": 10,\n" + + " \"sort\": {\n" + + " \n" + + " },\n" + + " \"sex\": \"desc\"\n" + + "}") @RequestBody PageParam pageParam) { + + return successResult(faceCameraServiceImpl.getPage(pageParam)); + } + + @ApiOperation(value = "全部摄像头列表") + @GetMapping(value = "/getAllList") +// @RequiresPermissions("camera:list") + public CommonResult getAllList(String cameraName) { + return successResult(faceCameraServiceImpl.getAll(cameraName)); + } + + + @ApiOperation(value = "查看摄像头信息") + @GetMapping(value = "/findById/{idCamera}") + @RequiresPermissions("camera:info") + public CommonResult findById(@PathVariable("idCamera") long idCamera) { + return successResult(faceCameraServiceImpl.findById(idCamera)); + } + + @PostMapping(value = "/insert") + @ApiOperation(value = "新增摄像头") + @RequiresPermissions("camera:save") + @NoRepeatSubmitAnnotation(prefix = "camera/insert") + public CommonResult insert(@RequestBody @Valid InsertFaceCamera insertFaceCamera) { + try { + faceCameraServiceImpl.insertCamera(insertFaceCamera); + } catch (DkException e) { + return failResult(e.getMessage()); + } catch (Exception e) { + log.error("添加摄像头异常===>", e.getMessage()); + return failResult("操作失败"); + } + return successResult("添加成功"); + } + + +// @ApiOperation(value = "获取摄像头卡口树状图") +// @GetMapping(value = "/getBayonet") +// public CommonResult getBayonet() { +// return successResult(faceCameraServiceImpl.getBayonet(RegionTopEnum.FATHER.value())); +// } + + @ApiOperation(value = "获取摄像头卡口树状图") + @GetMapping(value = "/getBayonet") + public CommonResult getBayonet() { + List regionByLevel = sysRegionService.getRegionByLevel(RegionLevelEnum.ONE.value()); + List>> lists = new ArrayList<>(); + List> results = new ArrayList<>(); + for (SysRegionEntity region:regionByLevel) { + List> bayonet = faceCameraServiceImpl.getBayonet(region.getPid()); + results.add(bayonet.get(0)); + } + return successResult(results); + } + + +// @ApiOperation(value = "获取摄像头区域树状图") +// @GetMapping(value = "/getRegion") +// public CommonResult getRegion() { +// return successResult(faceCameraServiceImpl.getRegion(RegionTopEnum.FATHER.value())); +// } + + @ApiOperation(value = "获取摄像头区域树状图") + @GetMapping(value = "/getRegion") + public CommonResult getRegion() { + List regionByLevel = sysRegionService.getRegionByLevel(RegionLevelEnum.ONE.value()); + List> lists = new ArrayList<>(); + for (SysRegionEntity region:regionByLevel) { + List> mapList = faceCameraServiceImpl.getRegion(region.getPid()); + lists.add(mapList.get(0)); + } + return successResult(lists); + } + + @ApiOperation(value = "获取当前区域下的摄像头") + @GetMapping(value = "/getRegion/{regionId}") + public CommonResult getRegionCamera(@PathVariable("regionId") long regionId) { + return successResult(faceCameraServiceImpl.getCameraByRegionId(regionId)); + } + + @ApiOperation(value = "获取当前区域下尚未布控的摄像头") + @GetMapping(value = "/getRegion/unControl/{regionId}") + public CommonResult getRegionUnControlCamera(@PathVariable("regionId") long regionId) { + return successResult(faceCameraServiceImpl.getRegionUnControlCamera(regionId)); + } + + @ApiOperation(value = "获取当前区域下的所有摄像头") + @GetMapping(value = "/getRegion/all/{regionId}") + public CommonResult getAllRegionCamera(@PathVariable("regionId") long regionId) { + return successResult(faceCameraServiceImpl.getAllCameraByRegionId(regionId)); + } + + @ApiOperation(value = "删除摄像头") + @GetMapping(value = "/delete/{idCamera}") + @RequiresPermissions("camera:del") + public CommonResult delete(@PathVariable("idCamera") long idCamera) { + return successResult(faceCameraServiceImpl.delete(idCamera)); + } + + @ApiOperation(value = "更改摄像头状态") + @GetMapping(value = "/{idCamera}/{status}") + public CommonResult status(@PathVariable("idCamera") long idCamera, @PathVariable("status") boolean status) { + return successResult(faceCameraServiceImpl.status(idCamera, status)); + } + + @ApiOperation(value = "修改摄像头") + @PostMapping(value = "/update") + @RequiresPermissions("camera:update") + public CommonResult update(@RequestBody @Valid FaceCameraInfo faceCameraInfo) { + return successResult(faceCameraServiceImpl.update(faceCameraInfo)); + } + + + @ApiOperation(value = "经纬度查询摄像头信息") + @GetMapping(value = "/findByCoordinate") + public CommonResult findByCoordinate(@ApiParam(name = "经度") @RequestParam(name = "cameraLatitude") String cameraLongitude, + @RequestParam(name = "cameraLatitude") String cameraLatitude) { + FaceCameraEntity faceCameraInfo = faceCameraServiceImpl.findByCoordinate(cameraLongitude, cameraLatitude); + if (UtilValidate.isNotEmpty(faceCameraInfo)) { + return successResult(faceCameraInfo); + } + return failResult("未能查询到该摄像头"); + } + + @GetMapping(value = "/downloadExcel") + @ApiOperation(value = "下载模板") + public void downloadIncomeExcel(HttpServletResponse servletResponse) throws Exception { + ExcelUtils.downloadTemplate(servletResponse, "摄像头导入模板"); + } + + @PostMapping(value = "/import") + @ApiOperation(value = "摄像头导入功能") + public CommonResult importDailyTimeStatisticsExcel(@RequestParam(name = "processFile", required = true) MultipartFile multipartFile, + HttpServletResponse response + ) { + List data = faceCameraServiceImpl.importExcel(multipartFile); + if (UtilValidate.isEmpty(data)) { + return successResult("上传成功"); + } + return failResult(EXCEL_ERROR_DATA.code, "存在错误数据", data); + } +// private CheckTtl checkTtl; +// @GetMapping(value = "/test") +// @ApiOperation(value = "下载模板") +// public void test() { +// Lock lock = new Lock(new ConsulClient(), "lock-key", checkTtl); +// try { +// if (lock.lock(true, 500L, null)) { +// log.info("Thread {} start!", 1); +// // 处理业务逻辑 +// log.info("Thread {} end!", 2); +// }else { +// log.info("Thread {} end!", 3); +// } +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } finally { +// lock.unlock(); +// } +// } + + +} diff --git a/face-server/src/main/java/com/dkha/server/controllers/CompareController.java b/face-server/src/main/java/com/dkha/server/controllers/CompareController.java new file mode 100644 index 0000000..6fc85ae --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/controllers/CompareController.java @@ -0,0 +1,62 @@ +package com.dkha.server.controllers; + +import com.dkha.common.exception.DkException; +import com.dkha.common.modules.vo.facelib.CompareRequestVo; +import com.dkha.common.result.CommonResult; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.services.ICompareService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.authz.annotation.RequiresPermissions; +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 Spring + * @Since 2019/12/11 17:05 + * @Description + */ +@RestController +@RequestMapping(value = "/compare") +@Api(tags = "比对相关") +@Slf4j +public class CompareController extends CommonResult { + + @Autowired + private ICompareService compareService; + + @PostMapping(value = "/grouping") + @ApiOperation(value = "分组比对") + @RequiresPermissions("face:group:comparison") + public CommonResult groupingCompare( + @ApiParam(required = true, name = "compareRequestVo", value = "") + @RequestBody CompareRequestVo compareRequestVo) { + return successResult(compareService.groupingCompare(compareRequestVo)); + } + + @PostMapping(value = "/oneToOne") + @ApiOperation(value = "一比一比对") + @RequiresPermissions("face:onetoone:comparison") + public CommonResult oneToOneCompare( + @ApiParam(required = true, name = "compareRequestVo", value = "") + @RequestBody CompareRequestVo compareRequestVo) { + return successResult(compareService.oneToOne(compareRequestVo)); + } + @PostMapping(value = "/oneToOneImage") + @ApiOperation(value = "一比一比对上传 Image") + //@RequiresPermissions("employment:contract:upload") + public CommonResult oneToOneCompareImage1( + @ApiParam(required = true, name = "compareRequestVo", value = "") + @RequestBody CompareRequestVo compareRequestVo) { + if (UtilValidate.isEmpty(compareRequestVo.getUrlList())) { + throw new DkException("请选择需要比对的图片"); + } + String fileName = compareRequestVo.getUrlList().get(0); + return successResult(compareService.setFaceCompare(fileName.substring(fileName.indexOf(",")+1))); + } +} diff --git a/face-server/src/main/java/com/dkha/server/controllers/ControlTaskController.java b/face-server/src/main/java/com/dkha/server/controllers/ControlTaskController.java new file mode 100644 index 0000000..2e8d4b4 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/controllers/ControlTaskController.java @@ -0,0 +1,263 @@ +package com.dkha.server.controllers; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dkha.common.enums.YNEnums; +import com.dkha.common.exception.DkException; +import com.dkha.common.modules.vo.control.TaskControlVO; +import com.dkha.common.modules.vo.control.VideoControlVo; +import com.dkha.common.modules.vo.facelib.CompareRequestVo; +import com.dkha.common.modules.vo.facelib.FileImageVo; +import com.dkha.common.page.PageParam; +import com.dkha.common.result.CommonResult; +import com.dkha.common.systemcode.SystemCode; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.annotation.NoRepeatSubmitAnnotation; +import com.dkha.server.modules.entities.*; +import com.dkha.server.services.*; +import com.dkha.server.system.common.validator.ValidatorUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.regex.Pattern; + +/** + * @version V1.0 + * @Description: 布控任务控制器 + * @Title: + * @author: huangyugang + * @date: 2019-12-09 10:25 + * @Copyright: 成都电科慧安 + */ +@RestController +@RequestMapping("/control") +@Api(tags = "布控任务管理") +@Slf4j +public class ControlTaskController extends CommonResult { + + @Autowired + IControlTaskService iControlTaskService; + @Autowired + IControlLibraryMidService iControlLibraryMidService; + @Autowired + IControlBayonetMidService iControlBayonetMidService; + @Autowired + private ICompareService compareService; + + @ApiOperation(value = "获取布控任务列表") + @PostMapping(value = "/tasklist") + public CommonResult getTaskList(@ApiParam(required = true, name = "pageParam", value = "{\n" + + " \"note\": {\n" + + " \"taskName\": \"任务名称\",\n" + + " \"createBy\":\"创建人\",\n" + + " \"disposalType\":\" 处置类型-码值视频对比 -1 抓捕类1,监控类2,提示类0 默认选择0\",\n" + + " \"controlType\":\"布控类型-码值 长期布控 0,临时布控 1 默认选择0\",\n" + + " \"isValid\":\"运行中:0 停止运行-1 暂停运行 1\",\n" + + " },\n" + + " \"pageNo\": 1,\n" + + " \"pageSize\": 10,\n" + + "}") @RequestBody PageParam pageParam, BindingResult bindingResult) { + String disposetype= pageParam.getNote().get("disposalType"); + Page controlTask=null; + if(!StringUtils.isEmpty(disposetype)){ + controlTask = iControlTaskService.getList(pageParam,Integer.parseInt(disposetype)); + }else + { + controlTask = iControlTaskService.getList(pageParam,0); + } + return successResult(controlTask); + } + @ApiOperation(value = "获取视频比对布控任务列表") + @PostMapping(value = "/tasklistvideo") + public CommonResult getTaskVideoList(@ApiParam(required = true, name = "pageParam", value = "{\n" + + " \"note\": {\n" + + " \"taskName\": \"任务名称\",\n" + + " \"createBy\":\"创建人\",\n" + + " },\n" + + " \"pageNo\": 1,\n" + + " \"pageSize\": 10,\n" + + "}") @RequestBody PageParam pageParam, BindingResult bindingResult) { + + + Page controlTask = iControlTaskService.getList(pageParam,-1); + + + return successResult(controlTask); + } + + @PostMapping(value = "/inserttask") + @ApiOperation(value = "新增任务") + @NoRepeatSubmitAnnotation(prefix = "insertTask") + public CommonResult insertTask(@ApiParam(required = true, name = "controlTask") @RequestBody @Valid TaskControlVO taskvo , BindingResult bindingResult) { + this.validate(bindingResult); + if (UtilValidate.isEmpty(taskvo)) { + return failResult(SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.des, null); + } + return iControlTaskService.addControlTask(taskvo); + } + + + @PutMapping(value = "/updatetask") + @ApiOperation(value = "修改任务:修改名称,处置类别,备注") + public CommonResult updateTask(@ApiParam(required = true, name = "controlTask") @RequestBody TaskControlVO taskvo ) { + if (UtilValidate.isEmpty(taskvo)) { + return failResult(SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.des, null); + } + return iControlTaskService.updateControlTask(taskvo); + } + + + @DeleteMapping("/deletetask/{taskId}") + @ApiParam(required = true, name = "taskId", value = "") + @ApiOperation(value = "删除布控任务") + public CommonResult deleteTask(@PathVariable(value = "taskId") String taskId) { + if (UtilValidate.isEmpty(taskId)) { + return failResult("布控任务id不能为空!"); + } + return iControlTaskService.deleteControlTask(taskId); + } + + @GetMapping("/viewcontrol/{taskId}") + @ApiParam(required = true, name = "taskId", value = "") + @ApiOperation(value = "查看布控详细信息") + public CommonResult GetControlTaskByID(@PathVariable("taskId") String taskId){ + if(UtilValidate.isEmpty(taskId)) + { + return new CommonResult( null,SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "任务id不能为空!"); + } + ControlTask controlTask= iControlTaskService.getById(taskId); + QueryWrapper queryWrapper=new QueryWrapper(); + queryWrapper.eq("id_control_task", taskId); + List listlibrarymid = iControlLibraryMidService.list(queryWrapper); + Listlistlib=new ArrayList<>(); + if(listlibrarymid!=null&&listlibrarymid.size()>0) { + for (ControlLibraryMid clm : listlibrarymid) { + listlib.add(clm.getIdFactory().toString()); + } + } + List faceCameras = iControlBayonetMidService.selectFaceCameraBytaskID(taskId); + controlTask.setListfacecamera(faceCameras); + controlTask.setLibIds(listlib); + + return successResult(controlTask); + + } + + @GetMapping("/gettaskcamera/{taskno}") + @ApiParam(required = true, name = "taskId", value = "") + @ApiOperation(value = "根据任务获取摄像头列表") + public CommonResult GetCameraListByTaskID(@PathVariable("taskno") String taskno){ + if(UtilValidate.isEmpty(taskno)) + { + return new CommonResult( null,SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "任务id不能为空!"); + } + return iControlTaskService.getCameraListByTaskNO(taskno); + } + + @DeleteMapping("/stopcontrol/{taskId}") + @ApiParam(required = true, name = "taskId", value = "") + @ApiOperation(value = "根据任务ID停止任务") + public CommonResult StopControlByTaskID(@PathVariable("taskId") String taskId){ + if(UtilValidate.isEmpty(taskId)) + { + return new CommonResult( null,SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "任务id不能为空!"); + } + return iControlTaskService.stopControlByTaskID(taskId); + } + + @PostMapping("/suspendcontrol/{taskId}") + @ApiParam(required = true, name = "taskId", value = "") + @ApiOperation(value = "根据任务ID暂停任务") + public CommonResult SuspendByTaskID(@PathVariable("taskId") String taskId){ + if(UtilValidate.isEmpty(taskId)) + { + return new CommonResult( null,SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "任务id不能为空!"); + } + return iControlTaskService.suspendControlByTaskID(taskId); + } + @PostMapping("/resumecontrol/{taskId}") + @ApiParam(required = true, name = "taskId", value = "") + @ApiOperation(value = "根据任务ID恢复任务") + public CommonResult resumeByTaskID(@PathVariable("taskId") String taskId){ + if(UtilValidate.isEmpty(taskId)) + { + return new CommonResult( null,SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "任务id不能为空!"); + } + return iControlTaskService.resumeControlByTaskID(taskId); + } + + @ApiOperation("上传人像附件布控") + @PostMapping("/addtaskfaceFile") + @NoRepeatSubmitAnnotation(prefix = "addtaskfaceFile") + public CommonResult addtaskfaceFile(@RequestParam("file") MultipartFile multipartFile) { + if(multipartFile.isEmpty()){ + return new CommonResult( null,SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "上传文件不能为空!"); + } + return iControlTaskService.addtaskfaceFile(multipartFile); + } + + @PostMapping(value = "/getImage") + @ApiOperation(value = "上传 Image") + public CommonResult oneToOneCompareImage1( + @ApiParam(required = true, name = "compareRequestVo", value = "") + @RequestBody CompareRequestVo compareRequestVo) { + if (UtilValidate.isEmpty(compareRequestVo.getUrlList())) { + throw new DkException("请选择需要比对的图片"); + } + String fileName = compareRequestVo.getUrlList().get(0); + String s = compareService.setFaceCompare(fileName.substring(fileName.indexOf(",") + 1)); + return successResult(iControlTaskService.addtaskfaceFiles(s)); + } + @ApiOperation("上传人像附件布控Base64") + @PostMapping("/addtaskfaceFiles") + @NoRepeatSubmitAnnotation(prefix = "addtaskfaceFiles") + public CommonResult addtaskfaceFiles( @ApiParam(required = true, name = "FileImageVo", value = "") + @RequestBody FileImageVo fileImageVo) { + if(fileImageVo.getUrl().isEmpty()){ + return new CommonResult( null,SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "上传文件不能为空!"); + } + return iControlTaskService.addtaskfaceFiles(fileImageVo.getUrl()); + } + @ApiOperation("添加比对视频文件") + @PostMapping("/addcomparvideoFile") + @NoRepeatSubmitAnnotation(prefix = "addcomparvideoFile") + public CommonResult addvideofaceFile(@ApiParam(required = true, name = "file", value = "视频文件")@RequestParam("file") MultipartFile multipartFile) { + if(multipartFile.isEmpty()){ + return new CommonResult( null,SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "上传文件不能为空!"); + } + + return iControlTaskService.addcomplevideoFile(multipartFile); + } + + @ApiOperation("新增视频对比") + @PostMapping("/insertcmpviedo") + @RequiresPermissions("face:video:comparison") + @NoRepeatSubmitAnnotation(prefix = "insertcmpviedo") + public CommonResult addVideCompare(@ApiParam(required = true, name = "controlVO", value = "") @RequestBody @Valid VideoControlVo controlVO , BindingResult bindingResult) { + + this.validate(bindingResult); + if (UtilValidate.isEmpty(controlVO)) { + return failResult(SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.des, null); + } + return iControlTaskService.addcomplevideoTask(controlVO); + + + } + + + +} diff --git a/face-server/src/main/java/com/dkha/server/controllers/FaceController.java b/face-server/src/main/java/com/dkha/server/controllers/FaceController.java new file mode 100644 index 0000000..2a7ddaf --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/controllers/FaceController.java @@ -0,0 +1,113 @@ +package com.dkha.server.controllers; + +import com.alibaba.fastjson.JSONObject; +import com.dkha.common.exception.DkException; +import com.dkha.common.fileupload.MinioUtil; +import com.dkha.common.page.PageParam; +import com.dkha.common.result.CommonResult; +import com.dkha.common.util.ExcelUtils; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.annotation.NoRepeatSubmitAnnotation; +import com.dkha.server.modules.entities.FaceCameraEntity; +import com.dkha.server.modules.entities.faceCamera.FaceCameraExcel; +import com.dkha.server.modules.entities.faceCamera.FaceCameraInfo; +import com.dkha.server.modules.entities.faceCamera.InsertFaceCamera; +import com.dkha.server.services.FaceCameraService; +import com.dkha.server.system.modules.sys.entity.SysRegionEntity; +import com.dkha.server.system.modules.sys.enums.RegionLevelEnum; +import com.dkha.server.system.modules.sys.service.SysRegionService; +import com.dkha.server.util.RequestUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import sun.misc.BASE64Decoder; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.*; + +import static com.dkha.common.systemcode.SystemCode.EXCEL_ERROR_DATA; + + +@RestController +@RequestMapping("faces") +@Slf4j +public class FaceController extends CommonResult { + @Resource + private MinioUtil minioUtil; + + private Map faceRes = new HashMap<>(); + + private List list = new ArrayList<>(); + public FaceController(){ + FaceResEntity resEntity = new FaceResEntity(); + resEntity.setName("jhx"); + resEntity.setRphoto("http://192.168.60.52:9000/school/face/jhx.jpg"); + faceRes.put("eYJST7eY2mbnjGZvywPfxg==",resEntity); + } + + @RequestMapping("callback") + public String callback(HttpServletRequest request) throws IOException { + try { + String streamText = RequestUtil.getStreamText(request); + System.out.println(streamText); + JSONObject object = JSONObject.parseObject(streamText); + String str = object.get("photo").toString(); + String xsd = object.get("confidence").toString(); + byte[] _byte = new BASE64Decoder().decodeBuffer(str); + InputStream inputStream = new ByteArrayInputStream(_byte); + + String object1 = "http://192.168.60.52:9000/test/"+minioUtil.uploadImage(inputStream,"").getString("path"); + System.out.println(object1); + if( faceRes.get(object.getString("ImageID"))!=null){ + FaceResEntity resEntity = faceRes.get(object.getString("ImageID")); + resEntity.setCphoto(object1); + resEntity.setXsd(xsd.substring(0,5)); + list.add(resEntity); + } + } catch (Exception e) { + e.printStackTrace(); + } + return "ok"; + } + + @GetMapping("list") + public List getList(){ + return list; + } + +/* @GetMapping("one") + public List queryWrapper=new QueryWrapper<>(); + FaceLibrary faceLibrary=new FaceLibrary(); + faceLibrary.setIsValid("Y"); +// faceLibrary.setFactoryType("-1"); + queryWrapper.setEntity(faceLibrary); + queryWrapper.ne("factory_type","-1"); + libNumber=iFaceLibraryService.getBaseMapper().selectCount(queryWrapper); + }catch (Exception e){} + + try + { + //人脸数量 + QueryWrapper queryWrapper=new QueryWrapper<>(); + Portrait portrait=new Portrait(); + portrait.setIsValid("Y"); + queryWrapper.setEntity(portrait); + faceNumber=iPortraitService.getBaseMapper().selectCount(queryWrapper); + }catch (Exception e){} + + try + { + //布控任务数量 + QueryWrapper queryWrapper=new QueryWrapper<>(); + queryWrapper.ne("disposal_type","-1"); + taskNumber=iControlTaskService.getBaseMapper().selectCount(queryWrapper); + }catch (Exception e){} + + try { + //预警数量 + ApiAlarmVO apiAlarmVO=new ApiAlarmVO(); + PageVO pageVO=new PageVO(); + pageVO.setPageSize(1); + pageVO.setPageNo(1); + apiAlarmVO.setPage(pageVO); + ApiVO warningVO = (ApiVO) httpUtil.post(link + ApiUrlEnum.ALARMS_POSTURL.getUrl(), apiAlarmVO, ApiVO.class); + if (!UtilValidate.isEmpty(warningVO)) { + if (!UtilValidate.isEmpty(warningVO) && !UtilValidate.isEmpty(warningVO.getData())) { + WarningBayonetReturnVO wvo = gson.fromJson(gson.toJson(warningVO.getData()), WarningBayonetReturnVO.class); + warnNumber=wvo.getPage().getTotal(); + } + } + + }catch (Exception e) + { + log.error("首页展示数据失败:{}",e.getMessage()); + } + Map myMap=new HashMap<>(); + myMap.put("libNumber",libNumber); + myMap.put("faceNumber",faceNumber); + myMap.put("taskNumber",taskNumber); + myMap.put("warnNumber",warnNumber); + myMap.put("daysOfOperation",daysOfOperation); + return successResult(myMap); + } +} diff --git a/face-server/src/main/java/com/dkha/server/controllers/ResourcesController.java b/face-server/src/main/java/com/dkha/server/controllers/ResourcesController.java new file mode 100644 index 0000000..218e0a3 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/controllers/ResourcesController.java @@ -0,0 +1,369 @@ +package com.dkha.server.controllers; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dkha.common.enums.YNEnums; +import com.dkha.common.exception.DkException; +import com.dkha.common.modules.vo.face.ApiSearchFaceRectVO; +import com.dkha.common.modules.vo.facelib.FileImageVo; +import com.dkha.common.modules.vo.position.PortraitListVo; +import com.dkha.common.page.PageParam; +import com.dkha.common.result.CommonResult; +import com.dkha.common.systemcode.SystemCode; +import com.dkha.common.util.IdCardUtil; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.annotation.NoRepeatSubmitAnnotation; +import com.dkha.server.modules.entities.FaceLibrary; +import com.dkha.server.modules.entities.Portrait; +import com.dkha.server.services.IFaceLibraryService; +import com.dkha.server.services.IPortraitService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ClassPathResource; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ResourcesController + * @Package com.dkha.server.controllers + * @author: yangjun + * @date: 2019/12/9 15:49 + * @Copyright: 成都电科慧安 + */ +@RestController +@RequestMapping("/Resources") +@Api(tags="资源管理") +public class ResourcesController extends CommonResult { + public static final Logger logger = LoggerFactory.getLogger(ResourcesController.class); + /** + * 库 + */ + @Autowired + private IFaceLibraryService iFaceLibraryService; + /** + * 人像 + */ + @Autowired + private IPortraitService iPortraitService; + @PostMapping("/faceLib") + @ApiParam(required = true, name = "faceLibrary", value = "") + @ApiOperation(value = "新增库") + @RequiresPermissions("portrait:lib:save") + @NoRepeatSubmitAnnotation(prefix = "Resources/faceLib") + public CommonResult addFaceLibrary(@ApiParam(required = true, name = "faceLibrary", value = "{\n" + + " \"factoryName\": \"库名称\",\n" + + " \"factoryType\": \"库类型\",\n" + + " \"remarks\": \"备注\"\n" + + "}")@RequestBody FaceLibrary faceLibrary){ + if (UtilValidate.isEmpty(faceLibrary.getFactoryName())){ + throw new DkException("库名称不能为空"); + } + faceLibrary.setIsValid(YNEnums.YES.code); + faceLibrary.setCreateTime(new Date()); + faceLibrary.setUpdateTime(new Date()); + FaceLibrary faceLibrar = iFaceLibraryService.addLibrary(faceLibrary); + if(UtilValidate.isEmpty(faceLibrar)) + { + return failResult("添加任性库失败失败"); + } + return successResult(faceLibrar); + } + @PutMapping("/updateLibrary") + @ApiParam(required = true, name = "faceLibrary", value = "") + @ApiOperation(value = "修改库") + @RequiresPermissions("portrait:lib:update") + public CommonResult updateLibrary(@ApiParam(required = true, name = "faceLibrary", value = "{\n" + + " \"idFactory\": \"库id\",\n" + + " \"factoryName\": \"库名称\",\n" + + " \"factoryType\": \"库类型\",\n" + + " \"remarks\": \"备注\"\n" + + "}")@RequestBody FaceLibrary faceLibrary){ + if (UtilValidate.isEmpty(faceLibrary.getIdFactory())){ + throw new DkException("库ID不能为空"); + } + FaceLibrary faceLibrar = iFaceLibraryService.updateLibrary(faceLibrary); + if(UtilValidate.isEmpty(faceLibrar)) + { + return failResult("修改库失败"); + } + return successResult(faceLibrar); + } + @DeleteMapping("/faceLib/{libraryId}") + @ApiParam(required = true, name = "faceLibrary", value = "") + @ApiOperation(value = "删除库") + @RequiresPermissions("portrait:lib:del") + public CommonResult deleteLibrary(@ApiParam(required = true, name = "libraryId", value = "") + @PathVariable(value = "libraryId") Long libraryId){ + if (UtilValidate.isEmpty(libraryId)){ + throw new DkException("库id不能为空"); + } + FaceLibrary faceLibrar; + try { + faceLibrar= iFaceLibraryService.deleteLibrary(libraryId); + }catch (DkException e){ + logger.error(e.getMessage(), e); + return failResult(Integer.valueOf(e.getCode()),e.getMsg(), null); + } catch (Exception e) { + logger.error(e.getMessage(), e); + return failResult(SystemCode.HANDLER_FAILED.des); + } + return successResult(faceLibrar); + } + + /** + * 分页查询 + * @return + */ + @PostMapping("/libraryPage") + @ApiOperation(value = "人像库分页查询") + @RequiresPermissions("portrait:lib:info") + public CommonResult getLibraryPage(@ApiParam(required = true, name = "pageParam", value = "{\n" + + "\t\"pageNo\": \"当前页码\",\n" + + "\t\"pageSize\": \"每页显示数量 默认10\",\n" + + "\t\"note\": {\n" + + "\t\t\"factoryName\": \"库名称\"\n" + + "\t}\n" + + "}")@RequestBody PageParam pageParam){ + Page page = iFaceLibraryService.queryLibrary(pageParam); + return successResult(page); + } + @ApiOperation("上传人像附件") + @PostMapping("/addFile/{libraryId}") + @RequiresPermissions("portrait:save") + //@NoRepeatSubmitAnnotation(prefix = "Resources/addFile") + public CommonResult addFile(@PathVariable("libraryId") String libraryId, @RequestParam("processFile") MultipartFile multipartFile) { + if(UtilValidate.isEmpty(libraryId) ){ + throw new DkException("目标库不能为空"); + } + if(UtilValidate.isEmpty(multipartFile)){ + throw new DkException("请选择图片"); + } + Portrait portrait; + try { + portrait = iPortraitService.addPortrait(libraryId, multipartFile); + }catch (DkException e){ + logger.error(e.getMessage(), e); + return failResult(Integer.valueOf(e.getCode()),e.getMsg(), null); + } catch (Exception e) { + logger.error(e.getMessage(), e); + return failResult(SystemCode.HANDLER_FAILED.des); + } + + return successResult(portrait); + } + + @ApiOperation("布控图片上传人像附件") + @PostMapping("/addpngFile/{libraryId}") + @RequiresPermissions("portrait:save") + public CommonResult addpngFile(@PathVariable("libraryId") String libraryId, @RequestParam("processFile") MultipartFile multipartFile) { + if(UtilValidate.isEmpty(libraryId) ){ + throw new DkException("目标库不能为空"); + } + if(UtilValidate.isEmpty(multipartFile)){ + throw new DkException("请选择图片"); + } + Portrait portrait; + try { + portrait = iPortraitService.addPortraitPng(libraryId, multipartFile); + }catch (DkException e){ + logger.error(e.getMessage(), e); + return failResult(Integer.valueOf(e.getCode()),e.getMsg(), null); + } catch (Exception e) { + logger.error(e.getMessage(), e); + return failResult(SystemCode.HANDLER_FAILED.des); + } + + return successResult(portrait); + } + + @ApiOperation("人像检测") + @PostMapping("/pictureDetection") + //@RequiresPermissions("employment:contract:upload") + public CommonResult pictureDetection(@RequestParam("processFile") MultipartFile multipartFile) { + + if(UtilValidate.isEmpty(multipartFile)){ + throw new DkException("请选择图片"); + } + List apiSearchFaceRectVOS = new ArrayList<>(); + try{ + apiSearchFaceRectVOS = iPortraitService.pictureDetection(multipartFile); + }catch (DkException e){ + logger.error(e.getMessage(), e); + return failResult(Integer.valueOf(e.getCode()),e.getMsg(), null); + } catch (Exception e) { + logger.error(e.getMessage(), e); + return failResult(SystemCode.HANDLER_FAILED.des); + } + return successResult(apiSearchFaceRectVOS); + } + @ApiOperation("批量上传人像Base64") + @PostMapping("/batch/{libraryId}") + //@RequiresPermissions("employment:contract:upload" + public CommonResult addbatch(@PathVariable("libraryId") String libraryId, @RequestBody FileImageVo fileImageVo) { + if(UtilValidate.isEmpty(libraryId) ){ + throw new DkException("目标库不能为空"); + } + List portraits = new ArrayList<>(); + Portrait portrait = null; + /**base64上传到文件服务器的地址*/ + if(UtilValidate.isEmpty(fileImageVo.getUrls())){ + throw new DkException("请选择图片"); + }else{ + try { + if (fileImageVo.getUrls().size() > 0) { + for (String url : + fileImageVo.getUrls()) { + portrait = iPortraitService.addPortraitPngs(libraryId, url); + portraits.add(portrait); + } + } + } catch(Exception e){ + logger.error("批量上传人像异常" + e.getMessage()); + return failResult(e.getMessage()); + } + } + return successResult(portraits); + } + @ApiOperation("批量上传人像") + @PostMapping("/addFiles/{libraryId}") + //@RequiresPermissions("employment:contract:upload" + public CommonResult addFiles(@PathVariable("libraryId") String libraryId, @RequestParam("processFile") MultipartFile[] multipartFile) { + if(UtilValidate.isEmpty(libraryId) ){ + throw new DkException("目标库不能为空"); + } + if(UtilValidate.isEmpty(multipartFile)){ + throw new DkException("请选择图片"); + } + List portraits; + try { + portraits = iPortraitService.addPortraits(libraryId, multipartFile); + } catch (Exception e) { + logger.error("批量上传人像异常"+e.getMessage()); + return failResult(e.getMessage()); + } + return successResult(portraits); + } + + /** + * 人脸信息分页查询 + * @return + */ + @PostMapping("/queryPortrait") + @ApiOperation(value = "人像分页查询") + @RequiresPermissions("portrait:info") + public CommonResult getPortraitVO(@ApiParam(required = true, name = "pageParam", value = "{\n" + + "\t\"pageNo\": \"当前页码\",\n" + + "\t\"pageSize\": \"每页显示数量 默认10\",\n" + + "\t\"note\": {\n" + + "\t\"name\": \"姓名\",\n" + + "\t\"sex\": \"性别\",\n" + + "\t\"libraryId\": \"库id\"\n" + + "\t}\n" + + "}")@RequestBody PageParam pageParam){ + //ReturnVO page = iPortraitService.queryPortrait(pageParam) + Page page = iPortraitService.queryPortrait(pageParam); + return successResult(page); + } + + @PostMapping("/deletePortraits") + @ApiParam(required = true, name = "idPortrait", value = "") + @ApiOperation(value = "批量删除人像信息") + @RequiresPermissions("portrait:del") + public CommonResult deletePortraits(@ApiParam(required = true, name = "idPortrait", value = "") + @RequestBody PortraitListVo idPortrait){ + if (UtilValidate.isEmpty(idPortrait)){ + throw new DkException("人像id不能为空"); + } + List longs = iPortraitService.deletePortraits(idPortrait.getIdPortrait()); + if(UtilValidate.isEmpty(longs)) + { + return failResult("删除人像失败"); + } + return successResult(longs); + } + + @DeleteMapping("/deletePortrait/{idPortrait}") + @ApiParam(required = true, name = "idPortrait", value = "") + @ApiOperation(value = "删除人像信息") + @RequiresPermissions("portrait:del") + public CommonResult deletePortrait(@ApiParam(required = true, name = "idPortrait", value = "") + @PathVariable(value = "idPortrait") Long idPortrait){ + if (UtilValidate.isEmpty(idPortrait)){ + throw new DkException("人像id不能为空"); + } + Long aLong = iPortraitService.deletePortrait(idPortrait); + if(UtilValidate.isEmpty(aLong)) + { + return failResult("删除人像失败"); + } + return successResult(aLong); + } + + @PutMapping("/updatePortrait") + @ApiParam(required = true, name = "portrait", value = "") + @ApiOperation(value = "修改人像信息") + @RequiresPermissions("portrait:update") + public CommonResult updatePortrait(@ApiParam(required = true, name = "portrait", value = "{\n" + + " \"idPortrait\": \"id\",\n" + + " \"idCard\": \"身份证\",\n" + + " \"name\": \"姓名\",\n" + + " \"sex\": \"性别\"\n" + + "}") @RequestBody Portrait portrait){ + if (UtilValidate.isEmpty(portrait.getIdPortrait())){ + throw new DkException("id不能为空"); + } + if (UtilValidate.isNotEmpty(portrait.getIdCard())) { + if (!IdCardUtil.isValidatedAllIdcard(portrait.getIdCard())) { + throw new DkException(SystemCode.IDCARD_ERROR.code,"身份证号码输入不正确"); + } + } + Portrait portrait1 = iPortraitService.updatePortrait(portrait); + if(UtilValidate.isEmpty(portrait1)) + { + return failResult("修改人像失败"); + } + return successResult(portrait1); + } + @GetMapping(value = "/exportProjectTemplate") + @ApiOperation(value = "导出项目管理excel模板", httpMethod = "GET") + public void exportTemplate(HttpServletResponse response) { + + try { + ClassPathResource classPathResource = new ClassPathResource("项目信息导入模板.xlsx"); + InputStream inputStream = classPathResource.getInputStream(); + response.setCharacterEncoding("UTF-8"); + response.setContentType("application/vnd.ms-excel;charset=UTF-8"); + response.setHeader("Content-Disposition", + "attachment;filename=" + URLEncoder.encode("项目信息导入模板", "UTF-8") + ".xlsx"); + OutputStream out = response.getOutputStream(); + int length = 0; + byte[] bytes = new byte[1024]; + while ((length = inputStream.read(bytes)) != -1) { + out.write(bytes, 0, length); + } + out.flush(); + out.close(); + inputStream.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/controllers/SearchController.java b/face-server/src/main/java/com/dkha/server/controllers/SearchController.java new file mode 100644 index 0000000..7493953 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/controllers/SearchController.java @@ -0,0 +1,70 @@ +package com.dkha.server.controllers; + +import com.dkha.common.modules.vo.search.SearchRequestVo; +import com.dkha.common.result.CommonResult; +import com.dkha.common.systemcode.SystemCode; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.services.IFaceLibraryService; +import com.dkha.server.services.IFileService; +import com.dkha.server.services.IPortraitService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + * @Author Spring + * @Since 2019/12/9 15:32 + * @Description 人脸检索controller + */ +@RestController +@RequestMapping(value = "/search") +@Api(tags = "检索") +@Slf4j +public class SearchController extends CommonResult { + + @Autowired + private IFaceLibraryService faceLibraryService; + @Autowired + private IPortraitService portraitService; + + @GetMapping(value = "/libraries") + @ApiOperation(value = "获取所有的库") + public CommonResult findFaceLibraries() { + return successResult(faceLibraryService.findFaceLibraries()); + } + + + @PostMapping(value = "/search") + @ApiOperation(value = "检索功能") + public CommonResult search( + @ApiParam(required = true, name = "searchRequestVo", value = "{\n" + + "\t\"libIdList\": [\"要检索的人像库Id集合\"],\n" + + "\t\"faceImageRequestList\": [\"需要检索的图片上传后的url地址,注意,只能有一个url地址,此处参数做成集合形式,是为了兼容后续修改\"],\n" + + "\t\"faceApiResultMap\": {\n" + + "\t\t\"后台传输回来,请求的时候,请再次传输到后台\": 0.0\n" + + "\t},\n" + + "\n" + + "\t\"minScore\": \"搜索阀值\",\n" + + "\t\"pageParam\": {\n" + + "\t\t\"pageNo\": 1,\n" + + "\t\t\"pageSize\": 10,\n" + + "\t\t\"note\": {\n" + + "\t\t\t\"search\": \"姓名/身份证号码\",\n" + + "\t\t\t\"sex\": \"性别 0男 1女\"\n" + + "\t\t},\n" + + "\t\t\"sort\": {},\n" + + "\t\t\"sortString\": \"\"\n" + + "\t}\n" + + "}") + @RequestBody SearchRequestVo searchRequestVo) { + return successResult(portraitService.libSearchPage(searchRequestVo)); + } +} diff --git a/face-server/src/main/java/com/dkha/server/controllers/TrackController.java b/face-server/src/main/java/com/dkha/server/controllers/TrackController.java new file mode 100644 index 0000000..19bf7bc --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/controllers/TrackController.java @@ -0,0 +1,286 @@ +package com.dkha.server.controllers; + +import com.dkha.common.enums.ApiUrlEnum; +import com.dkha.common.modules.vo.camera.BayOnetCameraVO; +import com.dkha.common.modules.vo.camera.CameraInfoVO; +import com.dkha.common.modules.vo.camera.PeopleComparableVO; +import com.dkha.common.modules.vo.camera.PeopleVO; +import com.dkha.common.modules.vo.face.ApiFaceSearchReturnVO; +import com.dkha.common.modules.vo.face.ApiFaceSearchVO; +import com.dkha.common.modules.vo.face.FaceTrackVO; +import com.dkha.common.modules.vo.face.PageVO; +import com.dkha.common.redis.RedisKeys; +import com.dkha.common.redis.RedisUtils; +import com.dkha.common.result.CommonResult; +import com.dkha.common.systemcode.SystemCode; +import com.dkha.common.util.DateUtils; +import com.dkha.common.util.TimeUtil; +import com.dkha.common.systemcode.SystemCode; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.modules.entities.FaceCameraEntity; +import com.dkha.server.modules.entities.FaceTrackEntity; +import com.dkha.server.services.FaceCameraService; +import com.dkha.server.services.FaceTrackService; +import com.dkha.server.services.IControlBayonetMidService; +import com.dkha.server.services.impl.TrackTaskImpl; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.sun.jndi.toolkit.url.UrlUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: TrackController + * @Package com.dkha.server.controllers + * @author: panhui + * @date: 2020/1/13 18:02 + * @Copyright: 成都电科慧安 + */ +@RestController +@RequestMapping(value = "/track") +@Api(tags = "轨迹分析") +@Slf4j +public class TrackController extends CommonResult { + + + @Autowired + private Gson gson; + + @Autowired + private FaceTrackService faceTrackService; + @Autowired + private FaceCameraService faceCameraService; + + @GetMapping("/people/{idPortrait}") + @ApiOperation(value = "根据人脸id查询当前数据") + public CommonResult getPeopeTrack(@PathVariable("idPortrait") String idPortrait) { + //查询出唯一的数据 + if (UtilValidate.isEmpty(idPortrait)) { + return failResult("参数不能为空"); + } + List peopleVOS = new ArrayList<>(); + String time = new SimpleDateFormat("yyyy-MM-dd").format(System.currentTimeMillis()); + List list = trackTask.getRedisPeopleInfo(time, idPortrait); + if (UtilValidate.isNotEmpty(list)) { + peopleVOS.addAll(list); + } + //把数据库中的json转换为实体类数据 + FaceTrackEntity faceTrackEntity = faceTrackService.queryByIdPortrait(idPortrait); + if (UtilValidate.isNotEmpty(faceTrackEntity)) { + List peopleVOList = gson.fromJson(faceTrackEntity.getLinkedData(), new TypeToken>() { + }.getType()); + peopleVOS.addAll(peopleVOList); + } + if (UtilValidate.isEmpty(peopleVOS)) { + return successResult(new ArrayList<>()); + } +// for (PeopleVO peopleVO : peopleVOS) { +// peopleVO.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(peopleVO.getTimestamp())); +// } + return successResult(peopleVOS); + } + + @DeleteMapping("/people/{idPortrait}/{esId}") + @ApiOperation(value = "删除错误的信息") + public CommonResult deletePeopeTrack(@PathVariable("idPortrait") String idPortrait, @PathVariable("esId") String esId) { + //查询出唯一的数据 + if (UtilValidate.isEmpty(idPortrait)) { + return failResult("参数不能为空"); + } + //把数据库中的json转换为实体类数据 + FaceTrackEntity faceTrackEntity = faceTrackService.queryByIdPortrait(idPortrait); + if (UtilValidate.isEmpty(faceTrackEntity)) { + return successResult(null); + } + List peopleVOS = gson.fromJson(faceTrackEntity.getLinkedData(), new TypeToken>() { + }.getType()); + log.error("处理后{}", peopleVOS.size()); + if (UtilValidate.isEmpty(peopleVOS)) { + return successResult(null); + } + Iterator iterator = peopleVOS.iterator(); + while (iterator.hasNext()) { + if (iterator.next().getEsId().equals(esId)) { + iterator.remove(); + } + } + if (peopleVOS.size() > 0) { + faceTrackEntity.setCharacterData(gson.toJson(peopleVOS.get(0))); + } + faceTrackEntity.setLinkedData(gson.toJson(peopleVOS)); + faceTrackService.updateById(faceTrackEntity); + log.error("处理后{}", peopleVOS.size()); + return successResult(SystemCode.DELETE_SUCCESS.des); + } + + + @Autowired + private TrackTaskImpl trackTask; + +// @GetMapping("/people/test") +// @ApiOperation(value = "测试") +// public CommonResult test(String starTime, String stopTime) { +// +// String time = "2020-01-14"; +//// trackTask.setBingDataCamerID(time); +// Date date=new Date(); +// +// date.setDate(date.getDate()-1); +// System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date)); +//// String startTime = "2020-01-01", stopTime = "2020-02-02"; +//// for(int i=0;i<30+1;i++) +//// { +//// +//// } +//// System.out.println(DateUtils.dayDiff(DateUtils.str2Date(starTime, new SimpleDateFormat("yyyy-MM-dd")), DateUtils.str2Date(stopTime, new SimpleDateFormat("yyyy-MM-dd")))); +// return null; +// } + + + @PostMapping("/people/track") + @ApiOperation(value = "获取轨迹信息") + public CommonResult getTrack(@RequestBody FaceTrackVO faceTrackVO) { + + if (UtilValidate.isEmpty(faceTrackVO) || UtilValidate.isEmpty(faceTrackVO.getStartTime()) || UtilValidate.isEmpty(faceTrackVO.getEndTime()) || UtilValidate.isEmpty(faceTrackVO.getUrl()) || UtilValidate.isEmpty(faceTrackVO.getTrajectoryThreshold())) { + return failResult(SystemCode.ParaIsNull); + } + if (UtilValidate.isNotEmpty(faceTrackVO.getTrajectoryThreshold())) { + faceTrackVO.setTrajectoryThreshold(faceTrackVO.getTrajectoryThreshold() / 100); + } + /* { + "endTime": "2020-01-14", + "startTime": "2020-01-14", + "trajectoryThreshold": 80.0, + "url": "http://10.51.10.201:9001/middleware/20200114/camera/1578962105682-886.jpg" + }*/ + + + //判断是否是否今天 + //如果今天就直接读取redis + //如果不是今天就读取历史 + //如果包含今天或者历史就需要把所有数据读取出来分析 +// String nowTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()); + String nowTime = new SimpleDateFormat("yyyy-MM-dd").format(System.currentTimeMillis()); + List peopleVOS = new ArrayList<>(); + List libList = new ArrayList<>(); + //表示包含今天需要从redis读取 + //读取redis和数据库中所有需要比对的库id +// if (faceTrackVO.getStartTime().equals(nowTime) && faceTrackVO.getEndTime().equals(nowTime)) { +// //只读取redis所有的数据 +// libList = trackTask.getRedisLibId(nowTime); +// } else { + //读取数据库和redis数据 + if (faceTrackVO.getStartTime().equals(nowTime) || faceTrackVO.getEndTime().equals(nowTime)) { + libList = trackTask.getRedisLibId(nowTime); + } + List dbLibList = faceTrackService.findIdFatoryByTime(faceTrackVO); + if (UtilValidate.isNotEmpty(dbLibList)) { + libList.addAll(dbLibList); + } +// } + //进行人脸库比对、 + List compareIds = trackTask.faceCheck(faceTrackVO.getUrl(), libList, faceTrackVO.getTrajectoryThreshold()); + if (UtilValidate.isEmpty(compareIds)) { + return successResult(peopleVOS); + } + //先获取redis里面的数据,因为当天的数据不会放在数据库中 209 + //67 + compareIds.forEach(e -> + { + List peopleVOList = trackTask.getRedisPeopleInfo(nowTime, e); + if (UtilValidate.isNotEmpty(peopleVOList)) { + peopleVOS.addAll(peopleVOList); + } + }); + + //根据id查询数据 + List trackList = faceTrackService.findTrackByFaceId(compareIds); + //获取redis中的人脸数据 211 214 + if (UtilValidate.isNotEmpty(trackList)) { + trackList.forEach(e -> + { + try { + List list = new ArrayList<>(); + if (UtilValidate.isEmpty(e.getLinkedData()) || e.getLinkedData().equals("[]")) { + list = gson.fromJson(e.getCharacterData(), new TypeToken>() { + }.getType()); + } else { + list = gson.fromJson(e.getLinkedData(), new TypeToken>() { + }.getType()); + } + peopleVOS.addAll(list); +// peopleVOS.add(gson.fromJson(e.getLinkedData(), PeopleVO.class)); + } catch (Exception e1) { + e1.printStackTrace(); + System.out.println(e1.getMessage()); + } + }); + } + if (UtilValidate.isEmpty(peopleVOS)) { + return successResult(peopleVOS); + } + //将数据进行清洗,返回最终的人脸轨迹数据。按照时间绑定list list里面的数据如果那个人每更换摄像头 + //轨迹,那个轨迹只有当前一条,如果那人更换摄像头就会加入一条新摄像头里面的轨迹211 + Map> myMap = trackTask.filterPeople(peopleVOS); + if (UtilValidate.isEmpty(myMap)) { + return successResult(new HashMap<>()); + } + //数据筛选 按天进行分组、然后在筛选 +// trackList + List listPop = new ArrayList<>(); + if (UtilValidate.isNotEmpty(myMap)) { + int dayNum = 0; + if (faceTrackVO.getStartTime().equals(nowTime) && faceTrackVO.getEndTime().equals(nowTime)) { + dayNum = 1; + } else { + dayNum = DateUtils.dayDiff(DateUtils.str2Date(faceTrackVO.getStartTime(), new SimpleDateFormat("yyyy-MM-dd")), DateUtils.str2Date(faceTrackVO.getEndTime(), new SimpleDateFormat("yyyy-MM-dd"))); + + } + + for (int i = 0; i < dayNum + 1; i++) { + Date date = DateUtils.str2Date(faceTrackVO.getStartTime(), new SimpleDateFormat("yyyy-MM-dd")); + date.setDate(date.getDate() + i); + String time = new SimpleDateFormat("yyyy-MM-dd").format(date); + if (myMap.containsKey(time)) { + if (UtilValidate.isNotEmpty(myMap.get(time))) { + listPop.addAll(myMap.get(time)); + } + } + } +// } else { +// if (myMap.containsKey(nowTime)) { +// if (UtilValidate.isNotEmpty(myMap.get(nowTime))) { +// listPop.addAll(myMap.get(nowTime)); +// } +// } +// } + } + //根据摄像头id查询对应的摄像头信息 + if (UtilValidate.isNotEmpty(listPop)) { + + for (PeopleComparableVO pc : listPop) { + try { + CameraInfoVO cameraInfoVO = faceCameraService.selectFaceCameraID(pc.getCameraId()); + if (UtilValidate.isNotEmpty(cameraInfoVO)) { + pc.setCameraInfoVO(cameraInfoVO); + } else { + + } + } catch (Exception e) { + + } + } + } + return successResult(listPop); + } + +} diff --git a/face-server/src/main/java/com/dkha/server/controllers/WarningController.java b/face-server/src/main/java/com/dkha/server/controllers/WarningController.java new file mode 100644 index 0000000..71fb7e1 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/controllers/WarningController.java @@ -0,0 +1,705 @@ +package com.dkha.server.controllers; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dkha.common.enums.ApiUrlEnum; +import com.dkha.common.enums.ErrEnum; +import com.dkha.common.enums.SEXEnums; +import com.dkha.common.http.HttpUtil; +import com.dkha.common.modules.vo.ApiVO; +import com.dkha.common.modules.vo.face.*; +import com.dkha.common.modules.vo.position.PositionVO; +import com.dkha.common.modules.vo.warning.*; +import com.dkha.common.redis.RedisKeys; +import com.dkha.common.redis.RedisUtils; +import com.dkha.common.result.CommonResult; +import com.dkha.common.systemcode.SystemCode; +import com.dkha.common.util.Base64ImageUtils; +import com.dkha.common.util.DateUtils; +import com.dkha.common.util.TimeUtil; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.modules.entities.*; +import com.dkha.server.modules.entities.faceCamera.FaceCameraInfo; +import com.dkha.server.services.*; +import com.google.gson.Gson; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.awt.image.BufferedImage; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.*; + +/** + * @version V1.0 + * @Description: TODO(预警查询功能) + * All rights 成都电科慧安 + * @Title: WarningController + * @Package com.dkha.server.controllers + * @author: panhui + * @date: 2019/12/10 9:37 + * @Copyright: 成都电科慧安 + */ +@RestController +@RequestMapping(value = "/warning") +@Api(tags = "预警查询") +@Slf4j +public class WarningController extends CommonResult { + + @Autowired + private HttpUtil httpUtil; + + @Value("${api.server.prefix}") + private String link; + + @Autowired + private Gson gson; + + + @Autowired + private FaceCameraService faceCameraService; + + + @GetMapping("/todayBayonet/{carmeraId}")// {total} + @ApiOperation(value = "今日抓拍") + public CommonResult todayBayonet(@PathVariable("carmeraId") String carmeraId) { + if (UtilValidate.isEmpty(carmeraId)) { + return failResult(SystemCode.ParaIsNull); + } + ApiAlarmVO apiAlarmVO = new ApiAlarmVO(); + apiAlarmVO.setCameraId(carmeraId); + PageVO pageVO = new PageVO(); + pageVO.setPageSize(1); + pageVO.setStartTimestamp(TimeUtil.toDayStart()); + pageVO.setStopTimestamp(TimeUtil.toDayStop()); + apiAlarmVO.setPage(pageVO); + try { + ApiVO warningVO = (ApiVO) httpUtil.post(link + ApiUrlEnum.ALARM_POSTURL.getUrl(), apiAlarmVO, ApiVO.class); + BayonetReturnVO bayonetReturnVO = new BayonetReturnVO(); + if (!UtilValidate.isEmpty(warningVO) && !UtilValidate.isEmpty(warningVO.getData())) { + WarningBayonetReturnVO wvo = gson.fromJson(gson.toJson(warningVO.getData()), WarningBayonetReturnVO.class); + //因为数据没有 + if (!UtilValidate.isEmpty(wvo.getResult()) && wvo.getResult().size() > 0) { + wvo.getResult().forEach(a -> + { + a.getFaces().forEach(ea -> + { + try { + if (redisUtils.exists(RedisKeys.getCameraSize(a.getCameraId()))) { + BgImageSize bgImageSize = gson.fromJson(redisUtils.get(RedisKeys.getCameraSize(a.getCameraId())).toString(), BgImageSize.class); + PositionVO positionVo = Base64ImageUtils.deelPostion(ea.getFaceRect(), bgImageSize.getBgWidth(), bgImageSize.getBgHeight()); + positionVo.setBgHeight(bgImageSize.getBgWidth()); + positionVo.setBgWidth(bgImageSize.getBgHeight()); + ea.setFaceRect(positionVo); + } else { + BufferedImage bufferedImage = Base64ImageUtils.urlToBufferImage(new URL(a.getFaceBgUrl())); + PositionVO positionVo = Base64ImageUtils.deelPostion(ea.getFaceRect(), bufferedImage.getWidth(), bufferedImage.getHeight()); + positionVo.setBgHeight(bufferedImage.getHeight()); + positionVo.setBgWidth(bufferedImage.getWidth()); + ea.setFaceRect(positionVo); + redisUtils.set(RedisKeys.getCameraSize(a.getCameraId()), gson.toJson(new BgImageSize(a.getCameraId(), bufferedImage.getWidth(), bufferedImage.getHeight()))); + bufferedImage = null; + } + } catch (MalformedURLException e1) { + } + }); + }); + + bayonetReturnVO.setResult(wvo.getResult().get(0)); + bayonetReturnVO.setToDaySnapShot(wvo.getPage().getTotal()); + //累计抓拍 + pageVO.setStartTimestamp(null); + pageVO.setStopTimestamp(null); + //统计总数 + apiAlarmVO.setPage(pageVO); + ApiVO wo = (ApiVO) httpUtil.post(link + ApiUrlEnum.ALARM_POSTURL.getUrl(), apiAlarmVO, ApiVO.class); + + WarningBayonetReturnVO woVo = gson.fromJson(gson.toJson(wo.getData()), WarningBayonetReturnVO.class); + if (UtilValidate.isEmpty(woVo)) { + bayonetReturnVO.setTotalSnapShot(0L); + } else { + bayonetReturnVO.setTotalSnapShot(woVo.getPage().getTotal()); + } + } else { + bayonetReturnVO.setToDaySnapShot(0L); + bayonetReturnVO.setResult(new AlarmReturnVO()); + } + } + //累计抓拍 + pageVO.setStartTimestamp(null); + pageVO.setStopTimestamp(null); + //统计总数 + apiAlarmVO.setPage(pageVO); + ApiVO wo = (ApiVO) httpUtil.post(link + ApiUrlEnum.ALARM_POSTURL.getUrl(), apiAlarmVO, ApiVO.class); + WarningBayonetReturnVO wovo = gson.fromJson(gson.toJson(wo.getData()), WarningBayonetReturnVO.class); + if (UtilValidate.isEmpty(wovo)) { + bayonetReturnVO.setTotalSnapShot(0L); + } else { + bayonetReturnVO.setTotalSnapShot(wovo.getPage().getTotal()); + } + return successResult(bayonetReturnVO); + } catch (Exception e) { + e.printStackTrace(); + return failResult("查询异常:" + e.getMessage()); + } + } + + @GetMapping("/todayBayonetBySize/{carmeraId}/{pageSize}")// {total} + @ApiOperation(value = "今日抓拍根據條數返回") + public CommonResult todayBayonet(@PathVariable("carmeraId") String carmeraId, @PathVariable("pageSize") Integer pageSize) { + if (UtilValidate.isEmpty(carmeraId)) { + return failResult(SystemCode.ParaIsNull); + } + + ApiAlarmVO apiAlarmVO = new ApiAlarmVO(); + apiAlarmVO.setCameraId(carmeraId); + PageVO pageVO = new PageVO(); + pageVO.setPageSize(1); + if (UtilValidate.isNotEmpty(pageSize)) { + pageVO.setPageSize(pageSize); + } + pageVO.setStartTimestamp(TimeUtil.toDayStart()); + pageVO.setStopTimestamp(TimeUtil.toDayStop()); + apiAlarmVO.setPage(pageVO); + try { + ApiVO warningVO = (ApiVO) httpUtil.post(link + ApiUrlEnum.ALARM_POSTURL.getUrl(), apiAlarmVO, ApiVO.class); +// BayonetReturnVO bayonetReturnVO = new BayonetReturnVO(); + BayoneReturnListVO bayoneReturnListVO = new BayoneReturnListVO(); + if (!UtilValidate.isEmpty(warningVO) && !UtilValidate.isEmpty(warningVO.getData())) { + WarningBayonetReturnVO wvo = gson.fromJson(gson.toJson(warningVO.getData()), WarningBayonetReturnVO.class); + //因为数据没有 + if (!UtilValidate.isEmpty(wvo.getResult()) && wvo.getResult().size() > 0) { + + wvo.getResult().forEach(a -> + { + a.getFaces().forEach(ea -> + { + try { + if (redisUtils.exists(RedisKeys.getCameraSize(a.getCameraId()))) { + BgImageSize bgImageSize = gson.fromJson(redisUtils.get(RedisKeys.getCameraSize(a.getCameraId())).toString(), BgImageSize.class); + PositionVO positionVo = Base64ImageUtils.deelPostion(ea.getFaceRect(), bgImageSize.getBgWidth(), bgImageSize.getBgHeight()); + positionVo.setBgHeight(bgImageSize.getBgWidth()); + positionVo.setBgWidth(bgImageSize.getBgHeight()); + ea.setFaceRect(positionVo); + } else { + BufferedImage bufferedImage = Base64ImageUtils.urlToBufferImage(new URL(a.getFaceBgUrl())); + PositionVO positionVo = Base64ImageUtils.deelPostion(ea.getFaceRect(), bufferedImage.getWidth(), bufferedImage.getHeight()); + positionVo.setBgHeight(bufferedImage.getHeight()); + positionVo.setBgWidth(bufferedImage.getWidth()); + ea.setFaceRect(positionVo); + redisUtils.set(RedisKeys.getCameraSize(a.getCameraId()), gson.toJson(new BgImageSize(a.getCameraId(), bufferedImage.getWidth(), bufferedImage.getHeight()))); + bufferedImage = null; + } + } catch (MalformedURLException e1) { + } + }); + }); + + bayoneReturnListVO.setResult(wvo.getResult()); + bayoneReturnListVO.setToDaySnapShot(wvo.getPage().getTotal()); + //累计抓拍 + pageVO.setStartTimestamp(null); + pageVO.setStopTimestamp(null); + //统计总数 + apiAlarmVO.setPage(pageVO); + ApiVO wo = (ApiVO) httpUtil.post(link + ApiUrlEnum.ALARM_POSTURL.getUrl(), apiAlarmVO, ApiVO.class); + WarningBayonetReturnVO woVo = gson.fromJson(gson.toJson(wo.getData()), WarningBayonetReturnVO.class); + if (UtilValidate.isEmpty(woVo)) { + bayoneReturnListVO.setTotalSnapShot(0L); + } else { + bayoneReturnListVO.setTotalSnapShot(woVo.getPage().getTotal()); + } + } else { + bayoneReturnListVO.setToDaySnapShot(0L); + bayoneReturnListVO.setResult(new ArrayList<>()); + } + } + //累计抓拍 + pageVO.setStartTimestamp(null); + pageVO.setStopTimestamp(null); + //统计总数 + apiAlarmVO.setPage(pageVO); + ApiVO wo = (ApiVO) httpUtil.post(link + ApiUrlEnum.ALARM_POSTURL.getUrl(), apiAlarmVO, ApiVO.class); + WarningBayonetReturnVO wovo = gson.fromJson(gson.toJson(wo.getData()), WarningBayonetReturnVO.class); + if (UtilValidate.isEmpty(wovo)) { + bayoneReturnListVO.setTotalSnapShot(0L); + } else { + bayoneReturnListVO.setTotalSnapShot(wovo.getPage().getTotal()); + } + return successResult(bayoneReturnListVO); + } catch (Exception e) { + e.printStackTrace(); + return failResult("查询异常:" + e.getMessage()); + } + } + + + @Autowired + private IControlBayonetMidService iControlBayonetMidService; + + + @ApiOperation(value = "卡口功能-打开卡口页面获取最新布控的一个摄像头id") + @GetMapping("/bayonet") + public CommonResult bayonetIndex() { + //根据es查询当前数据 + ApiAlarmVO apiAlarmVO = new ApiAlarmVO(); + PageVO pageVO = new PageVO(); + pageVO.setPageSize(1); + pageVO.setStartTimestamp(TimeUtil.toDayStart()); + pageVO.setStopTimestamp(TimeUtil.toDayStop()); + apiAlarmVO.setPage(pageVO); + String cameraId = ""; + Map myMap = new HashMap<>(); + try { + ApiVO warningVO = (ApiVO) httpUtil.post(link + ApiUrlEnum.ALARM_POSTURL.getUrl(), apiAlarmVO, ApiVO.class); + if (!UtilValidate.isEmpty(warningVO) && !UtilValidate.isEmpty(warningVO.getData())) { + WarningBayonetReturnVO wvo = gson.fromJson(gson.toJson(warningVO.getData()), WarningBayonetReturnVO.class); + //因为数据没有 + if (!UtilValidate.isEmpty(wvo.getResult()) && wvo.getResult().size() > 0) { + cameraId = wvo.getResult().get(0).getCameraId(); + } + } + if (UtilValidate.isEmpty(cameraId)) { + ControlBayonetMid controlBayonetMid = iControlBayonetMidService.selectFaceCameraByTime(); + if (UtilValidate.isEmpty(controlBayonetMid)) { + return failResult(SystemCode.NO_DATA.code, SystemCode.NO_DATA.des, null); + } + cameraId = controlBayonetMid.getIdFaceCamera().toString(); + } + FaceCameraInfo faceCameraInfo = faceCameraService.findById(new Long(cameraId)); + myMap.put("camera_region_firstlevel", faceCameraInfo.getCameraRegionFirstlevel()); + myMap.put("cameraId", cameraId); + String name = faceCameraInfo.getCameraName(); + myMap.put("cameraName", (UtilValidate.isEmpty(name)) ? "摄像头" : name + "(摄像头)"); + } catch (Exception e) { + return failResult("查询异常"); + } + return successResult(myMap); + } + + @ApiOperation(value = "卡口功能-查看全部") + @PostMapping("/bayonet") + public CommonResult bayonet(@ApiParam(required = true, name = "apiAlarmVO", value = "{\n" + + " \"cameraId\": \"摄像头id(可以空)\",\n" + + " \"page\": {\n" + + " \"order\": \"排序默认DESC\",\n" + + " \"pageNo\": 0,\n" + + " \"pageSize\": 0,\n" + + " \"startTimestamp\": 抓拍时间开始,\n" + + " \"stopTimestamp\": 抓拍时间结束\n" + + " }\n" + + "}") @RequestBody ApiAlarmVO apiAlarmVO) { + try { +// System.out.println("----------"); + ApiVO warningVO = (ApiVO) httpUtil.post(link + ApiUrlEnum.ALARM_POSTURL.getUrl(), apiAlarmVO, ApiVO.class); + if (UtilValidate.isEmpty(warningVO) || warningVO.getCode().intValue() == ErrEnum.NOT_FOUND.getCode().intValue()) { + WarningPageVO warningPageVO = new WarningPageVO(); + return successResult(warningPageVO); + } + + if (warningVO.getCode().intValue() != ErrEnum.OK.getCode().intValue()) { + return failResult("服务器返回错误:" + warningVO.getMessage()); + } + WarningBayonetReturnVO wvo = gson.fromJson(gson.toJson(warningVO.getData()), WarningBayonetReturnVO.class); + //因为数据没有 + + if (UtilValidate.isEmpty(wvo) || UtilValidate.isEmpty(wvo.getResult())) { + return successResult(wvo); + } + + try { + wvo.getResult().forEach(a -> + { + //更改为摄像头名称 + FaceCameraInfo faceCameraInfo = faceCameraService.findById(new Long(a.getCameraId())); + String cameraId = a.getCameraId(); + a.setCameraId(cameraId); + a.setCameraName((!UtilValidate.isEmpty(faceCameraInfo) ? faceCameraInfo.getCameraName() : cameraId)); + a.setTimestamp(null); + a.getFaces().forEach(ea -> + { + if (UtilValidate.isEmpty(ea.getFeature())) { + ea.setFeature(new FeatureVO(-1, "")); + } + try { + if (redisUtils.exists(RedisKeys.getCameraSize(a.getCameraId()))) { + BgImageSize bgImageSize = gson.fromJson(redisUtils.get(RedisKeys.getCameraSize(a.getCameraId())).toString(), BgImageSize.class); + PositionVO positionVo = Base64ImageUtils.deelPostion(ea.getFaceRect(), bgImageSize.getBgWidth(), bgImageSize.getBgHeight()); + positionVo.setBgHeight(bgImageSize.getBgWidth()); + positionVo.setBgWidth(bgImageSize.getBgHeight()); + ea.setFaceRect(positionVo); + } else { + BufferedImage bufferedImage = Base64ImageUtils.urlToBufferImage(new URL(a.getFaceBgUrl())); + PositionVO positionVo = Base64ImageUtils.deelPostion(ea.getFaceRect(), bufferedImage.getWidth(), bufferedImage.getHeight()); + positionVo.setBgHeight(bufferedImage.getHeight()); + positionVo.setBgWidth(bufferedImage.getWidth()); + ea.setFaceRect(positionVo); + redisUtils.set(RedisKeys.getCameraSize(a.getCameraId()), gson.toJson(new BgImageSize(a.getCameraId(), bufferedImage.getWidth(), bufferedImage.getHeight()))); + bufferedImage = null; + } + } catch (MalformedURLException e1) { + } + }); + }); + + } catch (Exception ee) { + log.error("卡口功能-查看全部:{}", ee.getMessage()); + } + return successResult(wvo); + } catch (Exception e) { + return failResult("查询异常:" + e.getMessage()); + } + } + + @Autowired + private IControlTaskService iControlTaskService; + + @Autowired + private IPortraitService iPortraitService; + + + @Autowired + private IFaceLibraryService iFaceLibraryService; + + + @Autowired + private RedisUtils redisUtils; + + @ApiOperation(value = "查看-预警信息") + @PostMapping("/alarm") + public CommonResult alarm(@ApiParam(required = true, name = "apiAlarmVO", value = "{\n" + + " \"page\": {\n" + + " \"order\": \"排序 默认DESC(默认可以不填)\",\n" + + " \"pageNo\": 0(默认1可以不填),\n" + + " \"pageSize\": 0(默认10可以不填),\n" + + " \"startTimestamp\": 0(默认可以不填查询所有),\n" + + " \"stopTimestamp\": 0(默认可以不填查询所有)\n" + + " },\n" + + " \"taskIds\": [任务id列表],\n" + + " \"cameraIds\": [摄像头列表],\n" + + " taskType:[任务类别:0 报警任务,1是视频任务不传默认为0]" + + "}") @RequestBody ApiAlarmVO apiAlarmVO) { + try { +// Long time=System.currentTimeMillis(); + List ararmList = new ArrayList<>(); + ApiVO warningVO = (ApiVO) httpUtil.post(link + ApiUrlEnum.ALARMS_POSTURL.getUrl(), apiAlarmVO, ApiVO.class); + if (UtilValidate.isEmpty(warningVO) || warningVO.getCode().intValue() == ErrEnum.NOT_FOUND.getCode().intValue()) { + Page pages = new Page<>(); + pages.setRecords(ararmList); + pages.setTotal(0); + return successResult(pages); + } + if (warningVO.getCode().intValue() != ErrEnum.OK.getCode().intValue()) { + return failResult("服务器返回错误:" + warningVO.getMessage()); + } + + WarningBayonetReturnVO wvo = gson.fromJson(gson.toJson(warningVO.getData()), WarningBayonetReturnVO.class); + if (UtilValidate.isEmpty(wvo)) { + return failResult("没有查询到数据"); + } + wvo.getResult().forEach(a -> + { +// a.getFaces() 存储时候进行拆分 + if (!UtilValidate.isEmpty(a.getFaces()) && a.getFaces().size() > 0) { + ApiFaceVO apiFaceVO = a.getFaces().get(0); + try { + if (redisUtils.exists(RedisKeys.getCameraSize(a.getCameraId()))) { + BgImageSize bgImageSize = gson.fromJson(redisUtils.get(RedisKeys.getCameraSize(a.getCameraId())).toString(), BgImageSize.class); + PositionVO positionVo = Base64ImageUtils.deelPostion(apiFaceVO.getFaceRect(), bgImageSize.getBgWidth(), bgImageSize.getBgHeight()); + positionVo.setBgHeight(bgImageSize.getBgHeight()); + positionVo.setBgWidth(bgImageSize.getBgWidth()); + apiFaceVO.setFaceRect(positionVo); + } else { + BufferedImage bufferedImage = Base64ImageUtils.urlToBufferImage(new URL(a.getFaceBgUrl())); + PositionVO positionVo = Base64ImageUtils.deelPostion(apiFaceVO.getFaceRect(), bufferedImage.getWidth(), bufferedImage.getHeight()); + positionVo.setBgHeight(bufferedImage.getHeight()); + positionVo.setBgWidth(bufferedImage.getWidth()); + apiFaceVO.setFaceRect(positionVo); + redisUtils.set(RedisKeys.getCameraSize(a.getCameraId()), gson.toJson(new BgImageSize(a.getCameraId(), bufferedImage.getWidth(), bufferedImage.getHeight()))); + bufferedImage = null; + } + } catch (MalformedURLException e1) { + } + + + WarningPageVO warningPageVO = new WarningPageVO(); + //根据任务区查询3 + //测试后期需要删除 TODO +// a.setTaskId("1204968766411169794"); + QueryWrapper queryWrapper = new QueryWrapper<>(); + ControlTask controlTask = new ControlTask(); + controlTask.setTaskNo(a.getTaskId()); + queryWrapper.setEntity(controlTask); + List controlTaskList = iControlTaskService.getBaseMapper().selectList(queryWrapper); + warningPageVO.setTaskId(a.getTaskId()); + if (!UtilValidate.isEmpty(controlTaskList) && controlTaskList.size() >= 1) { + controlTask = controlTaskList.get(0); + warningPageVO.setTaskName(controlTask.getTaskName()); +// warningPageVO.setTaskType(ContralEnums.getTypeByValue(Integer.parseInt(controlTask.getDisposalType())).getMessage()); + warningPageVO.setTaskType(controlTask.getDisposalType()); + } else { + warningPageVO.setTaskName("任务已删除"); + warningPageVO.setTaskType(""); + } + //基本展示信息4-4 + warningPageVO.setBgImg(a.getFaceBgUrl()); + + if (!UtilValidate.isEmpty(apiFaceVO.getCompare()) && apiFaceVO.getCompare().size() > 0) { + ComparisonVO comparisonVO = apiFaceVO.getCompare().get(0); + //库名称和库id0-2 + FaceLibrary faceLibrary = iFaceLibraryService.getBaseMapper().selectById(comparisonVO.getLibraryId()); + warningPageVO.setLibId(comparisonVO.getLibraryId()); + if (!UtilValidate.isEmpty(faceLibrary)) { + warningPageVO.setLibName(faceLibrary.getFactoryName()); + } else { + warningPageVO.setLibName(comparisonVO.getLibraryId()); + } + warningPageVO.setScore(comparisonVO.getHitSimilarity()); + //查询人员信息 5-5 +// comparisonVO.setComparisonFaceId("1204598824872067073"); + Portrait portrait = iPortraitService.getById(comparisonVO.getComparisonFaceId()); + if (!UtilValidate.isEmpty(portrait)) { + if (UtilValidate.isNotEmpty(portrait.getName())) { + warningPageVO.setName(portrait.getName()); + } + if (UtilValidate.isNotEmpty(portrait.getBirthDate())) { + warningPageVO.setAge(DateUtils.getAge(portrait.getBirthDate())); + } + if (UtilValidate.isNotEmpty(portrait.getUrl())) { + warningPageVO.setFaceUrl(portrait.getUrl()); + } + if (UtilValidate.isNotEmpty(portrait.getSex())) { + warningPageVO.setSex(SEXEnums.getTypeByValue(portrait.getSex().toString()).name); + } + if (UtilValidate.isNotEmpty(portrait.getIdCard())) { + warningPageVO.setIdCard(portrait.getIdCard()); + } + } + } else { + warningPageVO.setScore(0.0); + } + warningPageVO.setPositionVO(apiFaceVO.getFaceRect()); + warningPageVO.setTime(a.getDate()); + //查询摄像头信息2-2 + if (!a.getCameraId().toString().equals("0")) { + FaceCameraInfo faceCameraInfo = faceCameraService.findById(new Long(a.getCameraId())); + String cameraId = a.getCameraId(); + warningPageVO.setCameraId(cameraId); + warningPageVO.setCameraRegion((!UtilValidate.isEmpty(faceCameraInfo) ? faceCameraInfo.getCameraName() : cameraId)); + } + ararmList.add(warningPageVO); + } + }); + Page pages = new Page<>(); + pages.setRecords(ararmList); + pages.setTotal(wvo.getPage().getTotal()); + wvo = null; + warningVO = null; +// System.out.println("耗时:"+(System.currentTimeMillis()-time)); + return successResult(pages); + } catch (Exception e) { + e.printStackTrace(); + return failResult("查询异常:" + e.getMessage()); + } + } + + + @ApiOperation(value = "获取全部布控任务中的摄像头信息和最近一条预警信息") + @GetMapping(value = "/getCameraWarningByTask") + public CommonResult findCameraByTask() { + List all = faceCameraService.findCameraByTask(); + if (UtilValidate.isEmpty(all)) { + return successResult(new ArrayList<>()); + } +// CameraWarningVO + List myList = new ArrayList<>(); + all.forEach(e -> + { + CameraWarningVO cameraWarningVO = new CameraWarningVO(); + CameraVO cameraVO = new CameraVO(); + BeanUtils.copyProperties(e, cameraVO); + cameraWarningVO.setCamera(cameraVO); + cameraWarningVO.setWarning(getWarningByCameraId(e)); + myList.add(cameraWarningVO); + }); + return successResult(myList); + } + + /** + * 根據攝像頭获取最新的摄像头id + * + * @param + * @return + */ + private WarningPageVO getWarningByCameraId(FaceCameraEntity faceCameraEntity) { + ApiAlarmVO apiAlarmVO = new ApiAlarmVO(); + PageVO page = new PageVO(); + page.setPageSize(1); + apiAlarmVO.setPage(page); + apiAlarmVO.setCameraIds(Arrays.asList(faceCameraEntity.getIdFaceCamera().toString())); + ApiVO warningVO = (ApiVO) httpUtil.post(link + ApiUrlEnum.ALARMS_POSTURL.getUrl(), apiAlarmVO, ApiVO.class); + if (UtilValidate.isEmpty(warningVO) || warningVO.getCode().intValue() == ErrEnum.NOT_FOUND.getCode().intValue()) { + return new WarningPageVO(); + } + if (warningVO.getCode().intValue() != ErrEnum.OK.getCode().intValue()) { + return new WarningPageVO(); + } + WarningBayonetReturnVO wvo = gson.fromJson(gson.toJson(warningVO.getData()), WarningBayonetReturnVO.class); + if (UtilValidate.isEmpty(wvo)) { + return new WarningPageVO(); + } + List ararmList = new ArrayList<>(); + wvo.getResult().forEach(a -> + { + if (!UtilValidate.isEmpty(a.getFaces()) && a.getFaces().size() > 0) { + ApiFaceVO apiFaceVO = a.getFaces().get(0); + try { + if (redisUtils.exists(RedisKeys.getCameraSize(a.getCameraId()))) { + BgImageSize bgImageSize = gson.fromJson(redisUtils.get(RedisKeys.getCameraSize(a.getCameraId())).toString(), BgImageSize.class); + PositionVO positionVo = Base64ImageUtils.deelPostion(apiFaceVO.getFaceRect(), bgImageSize.getBgWidth(), bgImageSize.getBgHeight()); + positionVo.setBgHeight(bgImageSize.getBgWidth()); + positionVo.setBgWidth(bgImageSize.getBgHeight()); + apiFaceVO.setFaceRect(positionVo); + } else { + + Integer width = 1080; + Integer height = 607; + Boolean mark = true; + try { + BufferedImage bufferedImage = Base64ImageUtils.urlToBufferImage(new URL(a.getFaceBgUrl())); + if (UtilValidate.isNotEmpty(bufferedImage)) { + width = bufferedImage.getWidth(); + height = bufferedImage.getHeight(); + } + } catch (Exception e2) { + mark = false; + } + // "{\"cameraId\":\"1211828378753777666\",\"bgWidth\":1080,\"bgHeight\":607}" + PositionVO positionVo = Base64ImageUtils.deelPostion(apiFaceVO.getFaceRect(), width, height); + positionVo.setBgHeight(height); + positionVo.setBgWidth(width); + apiFaceVO.setFaceRect(positionVo); + if (mark) { + redisUtils.set(RedisKeys.getCameraSize(a.getCameraId()), gson.toJson(new BgImageSize(a.getCameraId(), width, height))); + } + } + } catch (Exception e1) { + } + WarningPageVO warningPageVO = new WarningPageVO(); + //根据任务区查询3 + //测试后期需要删除 TODO + QueryWrapper queryWrapper = new QueryWrapper<>(); + ControlTask controlTask = new ControlTask(); + controlTask.setTaskNo(a.getTaskId()); + queryWrapper.setEntity(controlTask); + List controlTaskList = iControlTaskService.getBaseMapper().selectList(queryWrapper); + warningPageVO.setTaskId(a.getTaskId()); + if (!UtilValidate.isEmpty(controlTaskList) && controlTaskList.size() >= 1) { + controlTask = controlTaskList.get(0); + warningPageVO.setTaskName(controlTask.getTaskName()); + warningPageVO.setTaskType(controlTask.getDisposalType()); + } else { + warningPageVO.setTaskName("任务已删除"); + warningPageVO.setTaskType(""); + } + //基本展示信息4-4 + warningPageVO.setBgImg(a.getFaceBgUrl()); + + if (!UtilValidate.isEmpty(apiFaceVO.getCompare()) && apiFaceVO.getCompare().size() > 0) { + ComparisonVO comparisonVO = apiFaceVO.getCompare().get(0); + //库名称和库id0-2 + FaceLibrary faceLibrary = iFaceLibraryService.getBaseMapper().selectById(comparisonVO.getLibraryId()); + warningPageVO.setLibId(comparisonVO.getLibraryId()); + if (!UtilValidate.isEmpty(faceLibrary)) { + warningPageVO.setLibName(faceLibrary.getFactoryName()); + } else { + warningPageVO.setLibName(comparisonVO.getLibraryId()); + } + warningPageVO.setScore(comparisonVO.getHitSimilarity()); + //查询人员信息 5-5 + Portrait portrait = iPortraitService.getById(comparisonVO.getComparisonFaceId()); + if (!UtilValidate.isEmpty(portrait)) { + if (UtilValidate.isNotEmpty(portrait.getName())) { + warningPageVO.setName(portrait.getName()); + } + if (UtilValidate.isNotEmpty(portrait.getBirthDate())) { + warningPageVO.setAge(DateUtils.getAge(portrait.getBirthDate())); + } + if (UtilValidate.isNotEmpty(portrait.getUrl())) { + warningPageVO.setFaceUrl(portrait.getUrl()); + } + if (UtilValidate.isNotEmpty(portrait.getSex())) { + warningPageVO.setSex(SEXEnums.getTypeByValue(portrait.getSex().toString()).name); + } + if (UtilValidate.isNotEmpty(portrait.getIdCard())) { + warningPageVO.setIdCard(portrait.getIdCard()); + } + } + } else { + warningPageVO.setScore(0.0); + } + warningPageVO.setPositionVO(apiFaceVO.getFaceRect()); + warningPageVO.setTime(a.getDate()); + //查询摄像头信息2-2 + if (!a.getCameraId().toString().equals("0")) { + warningPageVO.setCameraId(faceCameraEntity.getIdFaceCamera().toString()); + warningPageVO.setCameraRegion(faceCameraEntity.getCameraName()); + } + ararmList.add(warningPageVO); + } + }); + if (ararmList.size() > 0) { + return ararmList.get(0); + } + return new WarningPageVO(); + } + + + @GetMapping("/taskStatus/{taskId}") + @ApiParam(required = true, name = "taskStatus", value = "") + @ApiOperation(value = "查看任务状态") + public CommonResult CommonResult(@PathVariable("taskId") String taskId) { + if (UtilValidate.isEmpty(taskId)) { + return failResult(SystemCode.ParaIsNull); + } + +// //开发完成够对接 TODO +// ControlTask controlTask = iControlTaskService.getById(taskId); +// if(UtilValidate.isEmpty(controlTask)) +// { +// return failResult("没有找到对应的任务"); +// } + + ApiVO warningVO = (ApiVO) httpUtil.get(link + ApiUrlEnum.ALARMS_STATUS.getUrl() + "/" + taskId, ApiVO.class); + if (UtilValidate.isEmpty(warningVO) || warningVO.getCode() != ErrEnum.OK.getCode().intValue() || UtilValidate.isEmpty(warningVO.getData())) { + return failResult("查询任务状态出错"); + } + Map myMap = gson.fromJson(gson.toJson(warningVO.getData()), Map.class); +// Map myMap=new HashMap(); +// myMap.put("status","STATUS_OVER"); + return successResult(myMap); + } + + @GetMapping("/taskInfo/{carmeraId}") + @ApiParam(required = true, name = "taskName", value = "") + @ApiOperation(value = "根据摄像头id查看任务信息") + public CommonResult taskInfo(@PathVariable("carmeraId") String carmeraId) { + if (UtilValidate.isEmpty(carmeraId)) { + return failResult(SystemCode.ParaIsNull); + } + ControlTask controlTask = iControlTaskService.getTaskInfoByCameraID(carmeraId); + if (UtilValidate.isEmpty(controlTask)) { + return failResult(SystemCode.NO_DATA); + } + return successResult(controlTask); + } + + +} diff --git a/face-server/src/main/java/com/dkha/server/mappers/ControlBayonetMidMapper.java b/face-server/src/main/java/com/dkha/server/mappers/ControlBayonetMidMapper.java new file mode 100644 index 0000000..a107162 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/mappers/ControlBayonetMidMapper.java @@ -0,0 +1,39 @@ +package com.dkha.server.mappers; + +import com.dkha.common.modules.vo.camera.CameraInfoVO; +import com.dkha.server.modules.entities.ControlBayonetMid; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dkha.server.modules.entities.FaceCameraEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 布控和摄像头中间表 Mapper 接口 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Mapper +public interface ControlBayonetMidMapper extends BaseMapper { + /** + * 根据任务ID删除任务和摄像头的中间表 + * + * @Return Integer >0成功 + */ + Integer deletetaskandcarmerbytaskid(@Param("taskID") String taskID); + + Integer selectexistByCarmeID(@Param("idcamera") String idcamera); + + Integer updateCarmerValidaStateByTaskID(@Param("taskID") String taskID, @Param("State") String State, @Param("UpdateBy") String UpdateBy); + + List selectFaceCameraBytaskID(@Param("taskID") String taskID); + + List selectFaceCameraBytask(); + + List selectFaceCameraBytaskInfo(); + int getControlByRegion(@Param("regionId") long regionId); +} diff --git a/face-server/src/main/java/com/dkha/server/mappers/ControlLibraryMidMapper.java b/face-server/src/main/java/com/dkha/server/mappers/ControlLibraryMidMapper.java new file mode 100644 index 0000000..2fea96d --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/mappers/ControlLibraryMidMapper.java @@ -0,0 +1,25 @@ +package com.dkha.server.mappers; + +import com.dkha.server.modules.entities.ControlLibraryMid; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + *

+ * 布控和库中间表 Mapper 接口 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Mapper +public interface ControlLibraryMidMapper extends BaseMapper { + + /**查看特征库id是否存在或有效*/ + Integer selectexistByLibID(@Param("libid") String libID,@Param("isvalid") String isvalid); + /**根据任务ID删除任务对应的中间特征库*/ + Integer deletetaskLibraryMidbytaskid(@Param("taskID") String taskID); + + Integer selectByLibID(@Param("libid") String libID,@Param("isvalid") String isvalid); +} diff --git a/face-server/src/main/java/com/dkha/server/mappers/ControlTaskMapper.java b/face-server/src/main/java/com/dkha/server/mappers/ControlTaskMapper.java new file mode 100644 index 0000000..cfc094d --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/mappers/ControlTaskMapper.java @@ -0,0 +1,46 @@ +package com.dkha.server.mappers; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dkha.server.modules.entities.ControlTask; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dkha.server.modules.entities.FaceCameraEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @version V1.0 + * @Description: 布控任务Mapper 接口 + * @Title: + * @author: huangyugang + * @date: 2019-12-09 10:25 + * @Copyright: 成都电科慧安 + */ +@Mapper +public interface ControlTaskMapper extends BaseMapper { + + List getTaskList(@Param("page") Page page, + @Param("searchParam") Map searchParam); + + List getviedoTaskList(@Param("page") Page page, + @Param("searchParam") Map searchParam); + + List getCameraByTaskID(@Param("taskid") String taskid); + + List getCameraByTaskNo(@Param("taskno") String taskno); + /** + * 根据摄像头的区域ID转换为区域名称 + */ + List getCameraRegionByReginlist(@Param("regionIds") List regionIds); + /** + * 根据任务ID转换库名称 + */ + List getLibRegionBytaskid(@Param("taskid") String taskid); + + + /**根据摄像头id获取任务信息*/ + List getTaskInfoByCameraID(@Param("taskno") String taskno); +} + diff --git a/face-server/src/main/java/com/dkha/server/mappers/FaceCameraDao.java b/face-server/src/main/java/com/dkha/server/mappers/FaceCameraDao.java new file mode 100644 index 0000000..f579c32 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/mappers/FaceCameraDao.java @@ -0,0 +1,48 @@ +package com.dkha.server.mappers; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + +import com.dkha.common.modules.vo.camera.CameraInfoVO; +import com.dkha.server.modules.entities.FaceCameraEntity; +import com.dkha.server.modules.entities.faceCamera.FaceCameraInfo; +import com.dkha.server.modules.entities.faceCamera.FaceCameraList; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * 摄像头表 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 2019-12-08 + */ +@Mapper +public interface FaceCameraDao extends BaseMapper { + + + List getList(@Param("page") Page page, + @Param("searchParam") Map searchParam, + @Param("cameraRegion") List cameraRegion); + + List> findByRegion(@Param("regionId") String regionId); + + List> getAllCameraByRegionId(@Param("regionIds") List regionIds); + + List> getCameraByRegionId(@Param("regionId") long regionId); + + List> getRegionUnControlCamera(@Param("regionId") long regionId); + + /** + * 判断当前区域及其子区域是否存在布控摄像头 + * @param regionId + * @return + */ + int isCameraInRegion(@Param("regionId") String regionId); + + CameraInfoVO selectFaceCameraID(@Param("idFaceCamera") String idFaceCamera); + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/mappers/FaceCameraMapper.java b/face-server/src/main/java/com/dkha/server/mappers/FaceCameraMapper.java new file mode 100644 index 0000000..981b806 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/mappers/FaceCameraMapper.java @@ -0,0 +1,18 @@ +package com.dkha.server.mappers; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dkha.server.modules.entities.FaceCameraEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 摄像头表 Mapper 接口 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Mapper +public interface FaceCameraMapper extends BaseMapper { + +} diff --git a/face-server/src/main/java/com/dkha/server/mappers/FaceLibraryMapper.java b/face-server/src/main/java/com/dkha/server/mappers/FaceLibraryMapper.java new file mode 100644 index 0000000..945c4cc --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/mappers/FaceLibraryMapper.java @@ -0,0 +1,35 @@ +package com.dkha.server.mappers; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dkha.server.modules.entities.FaceLibrary; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 库表 Mapper 接口 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Mapper +public interface FaceLibraryMapper extends BaseMapper { + /** + * Library 分页查询个 + * @param page + * @param factoryName 库名称 + * @return + */ + List getLibraryPage(@Param("page") Page page, @Param("factoryName") String factoryName); + + /** + * 统计库对应的人脸数 + * @param idFactory + * @return + */ + Integer getLibraryCount(@Param("idFactory") Long idFactory); +} diff --git a/face-server/src/main/java/com/dkha/server/mappers/FaceTrackMapper.java b/face-server/src/main/java/com/dkha/server/mappers/FaceTrackMapper.java new file mode 100644 index 0000000..e4c0637 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/mappers/FaceTrackMapper.java @@ -0,0 +1,64 @@ +package com.dkha.server.mappers; + + + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dkha.common.modules.vo.face.FaceTrackVO; +import com.dkha.server.modules.entities.FaceTrackEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 2020-01-10 + */ +@Mapper +public interface FaceTrackMapper extends BaseMapper { + /** + * 根据摄像头和分组时间查询 + * @param idFaceCamera + * @param packetTime + * @return + */ + List querByidCameraAndTime(@Param("idFaceCamera") Long idFaceCamera, @Param("packetTime") String packetTime); + /** + * 根据摄像头Id和开始,结束时间,人脸ID + * @param faceTrackVO + * @return + */ + List queryByidCamerAndFaceId(@Param("faceTrackVO") FaceTrackVO faceTrackVO); + + /** + * 根據開始時間和結束時間查詢庫id + * @param faceTrackVO + * @return + */ + List findIdFatoryByTime(@Param("faceTrackVO") FaceTrackVO faceTrackVO); + + /** + * 根据图片路径和开始,结束时间 + * @param faceTrackVO + * @return + */ + List queryByurlAndTime(@Param("faceTrackVO") FaceTrackVO faceTrackVO); + /** + * 根据图片路径和开始,结束时间和阈值 + * @param faceTrackVO + * @return + */ + List queryBytrajectoryThreshold(@Param("faceTrackVO")FaceTrackVO faceTrackVO); + + /** + * 根据人脸ID查询 + * @param idPortrait + * @return + */ + FaceTrackEntity queryByIdPortrait(@Param("idPortrait")String idPortrait); + + List findTrackByFaceId(@Param("faceIds") List faceIds); +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/mappers/PortraitMapper.java b/face-server/src/main/java/com/dkha/server/mappers/PortraitMapper.java new file mode 100644 index 0000000..3821b2d --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/mappers/PortraitMapper.java @@ -0,0 +1,79 @@ +package com.dkha.server.mappers; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dkha.common.modules.vo.search.SearchPortraitVo; +import com.dkha.server.modules.entities.Portrait; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + *

+ * 人像表 Mapper 接口 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Mapper +public interface PortraitMapper extends BaseMapper { + /** + * 分页查询人像表信息 + * @param page + * @param searchParams + * @return + */ + List queryPage(@Param("page") Page page, @Param("searchParams") Map searchParams); + + /** + * 人脸检索分页获取总的记录数量 + * @param searchParams 检索参数 + * @param faceIdList 人脸Id集合--如果上传图片进行搜索,则该值不能为空 + * @param libraryIdList 库Id集合 + * @return + */ + Integer findSearchPageCount(@Param("searchParams") Map searchParams, @Param("faceIdList") List faceIdList, @Param("libraryIdList") List libraryIdList); + + /** + * 人脸检索获取某一页对应的详细数据 + * @param searchParams 检索参数 + * @param faceIdList 人脸Id集合--如果上传图片进行搜索,则该值不能为空 + * @param libraryIdList 库Id集合 + * @return + */ + List findSearchPageList(@Param("searchParams") Map searchParams, @Param("faceIdList") List faceIdList, @Param("libraryIdList") List libraryIdList); + + /** + * 人脸检索分页--非api调用 + * @param page + * @param searchParams 检索参数 + * @param faceIdList 人脸Id集合--如果上传图片进行搜索,则该值不能为空 + * @param libraryIdList 库Id集合 + * @return + */ + List findSearchPage(@Param("page") Page page, @Param("searchParams") Map searchParams, @Param("faceIdList") List faceIdList, @Param("libraryIdList") List libraryIdList); + + /** + * 根据id查询 + * @param idPortrait + * @return + */ + Portrait queryPortrait(@Param("idPortrait") Long idPortrait); + + /** + * 根据库id查询 + * @param idFactory + * @return + */ + List queryPortraitByFactory(@Param("idFactory") Long idFactory); + + /** + * 根据id删除 + * @param taskID + * @return + */ + Integer deletePortrait(@Param("taskID") Long taskID) ; +} diff --git a/face-server/src/main/java/com/dkha/server/mappers/WarningInformationMapper.java b/face-server/src/main/java/com/dkha/server/mappers/WarningInformationMapper.java new file mode 100644 index 0000000..0635602 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/mappers/WarningInformationMapper.java @@ -0,0 +1,18 @@ +package com.dkha.server.mappers; + +import com.dkha.server.modules.entities.WarningInformation; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 预警信息 Mapper 接口 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Mapper +public interface WarningInformationMapper extends BaseMapper { + +} diff --git a/face-server/src/main/java/com/dkha/server/modules/entities/ControlBayonetMid.java b/face-server/src/main/java/com/dkha/server/modules/entities/ControlBayonetMid.java new file mode 100644 index 0000000..c1bb81d --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/modules/entities/ControlBayonetMid.java @@ -0,0 +1,62 @@ +package com.dkha.server.modules.entities; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import java.util.Date; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + *

+ * 布控和摄像头中间表 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value="ControlBayonetMid对象", description="布控和摄像头中间表") +public class ControlBayonetMid implements Serializable { + + private static final long serialVersionUID = 1L; + @ApiModelProperty(value = "id") + @TableId(value = "id", type = IdType.ID_WORKER) + private Long id; + + @ApiModelProperty(value = "id布控id") + private Long idControlTask; + + @ApiModelProperty(value = "摄像头id") + private Long idFaceCamera; + + @ApiModelProperty(value = "是否有效 Y有效 N无效") + @TableField(fill = FieldFill.INSERT) + private String isValid; + + @ApiModelProperty(value = "创建时间") + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date createTime; + + @ApiModelProperty(value = "更新时间") + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateTime; + + @ApiModelProperty(value = "创建人") + @TableField(fill = FieldFill.INSERT) + private String createBy; + + @ApiModelProperty(value = "更新人") + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updateBy; + + +} diff --git a/face-server/src/main/java/com/dkha/server/modules/entities/ControlLibraryMid.java b/face-server/src/main/java/com/dkha/server/modules/entities/ControlLibraryMid.java new file mode 100644 index 0000000..5efec47 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/modules/entities/ControlLibraryMid.java @@ -0,0 +1,61 @@ +package com.dkha.server.modules.entities; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import java.util.Date; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + *

+ * 布控和库中间表 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value="ControlLibraryMid对象", description="布控和库中间表") +public class ControlLibraryMid implements Serializable { + + private static final long serialVersionUID = 1L; + @ApiModelProperty(value = "id") + @TableId(value = "id", type = IdType.ID_WORKER) + private Long id; + + @ApiModelProperty(value = "布控id") + private Long idControlTask; + + @ApiModelProperty(value = "库id") + private Long idFactory; + + @ApiModelProperty(value = "是否有效 Y有效 N无效") + private String isValid; + + @ApiModelProperty(value = "创建时间") + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + @ApiModelProperty(value = "更新时间") + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateTime; + + @ApiModelProperty(value = "更新人") + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updateBy; + + @ApiModelProperty(value = "创建人") + @TableField(fill = FieldFill.INSERT) + private String createBy; + + +} diff --git a/face-server/src/main/java/com/dkha/server/modules/entities/ControlTask.java b/face-server/src/main/java/com/dkha/server/modules/entities/ControlTask.java new file mode 100644 index 0000000..72f80ff --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/modules/entities/ControlTask.java @@ -0,0 +1,121 @@ +package com.dkha.server.modules.entities; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import java.util.Date; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import java.io.Serializable; +import java.util.List; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +/** + *

+ * 布控任务 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Data +@EqualsAndHashCode(callSuper = false) + +@ApiModel(value="ControlTask对象", description="布控任务") +public class ControlTask implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @TableId(value = "id_control_task", type = IdType.ID_WORKER) + private Long idControlTask; + + @ApiModelProperty(value = "任务名称") + + private String taskName; + + @ApiModelProperty(value = "任务编号") + @TableId(value = "task_no") + private String taskNo; + + @ApiModelProperty(value = "布控对象(id 人像库id 或者上传图片id)") + private String controlObject; + + @ApiModelProperty(value = "处置类型-码值 视频对比 -1 抓捕类1,监控类2,提示类0 默认选择0") + private String disposalType; + + @ApiModelProperty(value = "布控类型-码值 长期布控 0,临时布控 1 默认选择0 ") + private String controlType; + + @ApiModelProperty(value = "布控开始时间") + private Date controlStartTime; + + @ApiModelProperty(value = "布控结束时间") + private Date controlEndTime; + + @ApiModelProperty(value = "布控区域") + private String controlRegion; + + @ApiModelProperty(value = "布控阈值") + private Double controlThreshold; + + @ApiModelProperty(value = "布控状态-码值") + private String controlStatus; + + @ApiModelProperty(value = "接收人员(人员id逗号隔开)") + private String receive; + + @ApiModelProperty(value = "备注信息") + private String remarks; + + @ApiModelProperty(value = "是否有效 Y有效 N无效") + private String isValid; + + @ApiModelProperty(value = "创建时间") + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + @ApiModelProperty(value = "更新时间") + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateTime; + + @ApiModelProperty(value = "创建人") + @TableField(fill = FieldFill.INSERT) + private String createBy; + + @ApiModelProperty(value = "更新人") + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updateBy; + + @ApiModelProperty(value = "库列表id") + @TableField(exist=false) + private List libIds; + + @ApiModelProperty(value = "视频布控URL") + private String viedourl; + + @ApiModelProperty(value = "任务库的列表") + @TableField(exist=false) + private String tasklibstr; + + @ApiModelProperty(value = "布控的摄像头ID列表") + @TableField(exist=false) + private List listfacecamera; + + @ApiModelProperty(value = "上传图片布控的url") + private String imgurl; + + @ApiModelProperty(value = "视频布控状态") + @TableField(exist=false) + private String taskstatus; + +} + diff --git a/face-server/src/main/java/com/dkha/server/modules/entities/FaceCameraEntity.java b/face-server/src/main/java/com/dkha/server/modules/entities/FaceCameraEntity.java new file mode 100644 index 0000000..866c83c --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/modules/entities/FaceCameraEntity.java @@ -0,0 +1,171 @@ +package com.dkha.server.modules.entities; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.dkha.server.system.common.entity.CommonEntity; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 摄像头表 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 2019-12-08 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("face_camera") +public class FaceCameraEntity extends CommonEntity { + private static final long serialVersionUID = 1L; + + /** + * 主键id + * 分布式全局唯一ID 长整型类型 + */ + @TableId(type = IdType.ID_WORKER, value = "id_face_camera") + @ApiModelProperty(value = "摄像头id") + private Long idFaceCamera; + /** + * 摄像头名称 + */ + @ApiModelProperty(value = "摄像头名称") + private String cameraName; + /** + * 摄像头层级区域-码值 + */ + @ApiModelProperty(value = "摄像头层级区域-码值") + private String cameraRegionFirstlevel; + @ApiModelProperty(value = "摄像头区域-码值") + private String cameraRegion; + + @ApiModelProperty(value = "摄像头层级区域冗余字段") + private String cameraRegionFirstlevelBackUp; + + /** + * 摄像头详细地址 + */ + @ApiModelProperty(value = "摄像头详细地址") + + private String cameraAddress; + /** + * 摄像头经度 + */ + @ApiModelProperty(value = "摄像头经度") + public static final String CAMERA_LONGITUDE="camera_longitude"; + private String cameraLongitude; + /** + * 摄像头纬度 + */ + @ApiModelProperty(value = "摄像头纬度") + public static final String CAMERA_LATITUDE="camera_latitude"; + private String cameraLatitude; + + /** + * 型号名称 + */ + @ApiModelProperty(value = "型号") + private String version; + + /** + * 位置类型-码值 + */ + @ApiModelProperty(value = "位置类型-码值") + private String cameratLocationtypeId; + + @ApiModelProperty(value = "位置类型冗余字段") + + private String cameratLocationtypeIdBackUp; + /** + * 公安机关代码 + */ + @ApiModelProperty(value = "公安机关代码") + + private String publicSecurityCode; + /** + * 公安机关名称 + */ + @ApiModelProperty(value = "公安机关名称") + + private String publicSecurityName; + /** + * 建设单位 + */ + @ApiModelProperty(value = "建设单位") + + private String constructionUnit; + /** + * 管理单位 + */ + @ApiModelProperty(value = "管理单位") + + private String managementUnit; + /** + * 管理人员 + */ + @ApiModelProperty(value = "管理人员") + + private String managementPersonnel; + /** + * 联系电话 + */ + @ApiModelProperty(value = "联系电话") + + private String contactNumber; + /** + * IP + */ + @ApiModelProperty(value = "IP") + private String ip; + + /** + * 端口 + */ + @ApiModelProperty(value = "端口") + private String port; + + /** + * 用户名 + */ + @ApiModelProperty(value = "用户名") + + private String userName; + /** + * 密码 + */ + @ApiModelProperty(value = "密码") + + private String passwd; + /** + * 品牌 + */ + @ApiModelProperty(value = "品牌") + + private String brand; + + /** + * 品牌 + */ + @ApiModelProperty(value = "品牌id") + private String idBrand; + + /** + * rtsp地址 + */ + @ApiModelProperty(value = "rtsp地址") + + private String rtspUrl; + /** + * 备注信息 + */ + @ApiModelProperty(value = "备注信息") + + private String remarks; + /** + * 是否运行 Y启动 N未启动 + */ + @ApiModelProperty(value = "是否运行,Y启动 N未启动") + private String status; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/modules/entities/FaceLibrary.java b/face-server/src/main/java/com/dkha/server/modules/entities/FaceLibrary.java new file mode 100644 index 0000000..bc53b66 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/modules/entities/FaceLibrary.java @@ -0,0 +1,69 @@ +package com.dkha.server.modules.entities; + +import java.util.Date; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + + +/** + *

+ * 库表 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value="FaceLibrary对象", description="库表") +public class FaceLibrary implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @TableId(value = "id_factory") + private Long idFactory; + + @ApiModelProperty(value = "库名称") + private String factoryName; + + @ApiModelProperty(value = "库类型-码值") + private String factoryType; + + @ApiModelProperty(value = "备注信息") + protected String remarks; + + @TableField(exist = false) + @ApiModelProperty(value = "图片数量") + private String number; + + @TableField(exist = false) + @ApiModelProperty(value = "类型名称") + private String factoryTypeName; + + @ApiModelProperty(value = "是否有效 Y有效 N无效") + + private String isValid; + + @ApiModelProperty(value = "创建时间") + private Date createTime; + + @ApiModelProperty(value = "创建人") + private String createBy; + + @ApiModelProperty(value = "更新时间") + private Date updateTime; + + @ApiModelProperty(value = "更新人") + private String updateBy; + + +} diff --git a/face-server/src/main/java/com/dkha/server/modules/entities/FaceTrackEntity.java b/face-server/src/main/java/com/dkha/server/modules/entities/FaceTrackEntity.java new file mode 100644 index 0000000..035e746 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/modules/entities/FaceTrackEntity.java @@ -0,0 +1,84 @@ +package com.dkha.server.modules.entities; + + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +/** + * + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 2020-01-10 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value="FaceTrackEntity对象", description="轨迹对象") +@TableName(value = "face_track") +public class FaceTrackEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 轨迹id + */ + @ApiModelProperty(value = "id_face_track") + @TableId(value = "id_face_track", type = IdType.ID_WORKER) + private Long idFaceTrack; + /** + * 人像id + */ + private Long idPortrait; + /** + * 摄像头id + */ + private Long idFaceCamera; + /** + * 库id + */ + private Long idFactory; + /** + * 人物数据 + */ + private String characterData; + /** + * 关联数据 + */ + private String linkedData; + /** + * 分组时间 + */ + private String packetTime; + /** + * 当月数据关联 + */ + private String monthData; + /** + * 轨迹判定阈值 + */ + private Double trajectoryThreshold; + /** + * 创建人 + */ + private String createBy; + /** + * 创建时间 + */ + private Date createTime; + /** + * 更新人 + */ + private String updateBy; + /** + * 更新时间 + */ + private Date updateTime; +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/modules/entities/Portrait.java b/face-server/src/main/java/com/dkha/server/modules/entities/Portrait.java new file mode 100644 index 0000000..b9324da --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/modules/entities/Portrait.java @@ -0,0 +1,88 @@ +package com.dkha.server.modules.entities; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableField; +import java.io.Serializable; +import java.util.Date; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + *

+ * 人像表 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value="Portrait对象", description="人像表") +public class Portrait implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "人像id") + @TableId(value = "id_portrait") + private Long idPortrait; + + @ApiModelProperty(value = "库id") + private Long idFactory; + + @ApiModelProperty(value = "图片url") + private String url; + + @ApiModelProperty(value = "背景图url") + private String backgroundUrl; + + @ApiModelProperty(value = "姓名") + private String name; + + @ApiModelProperty(value = "性别") + private String sex; + + @ApiModelProperty(value = "出生日期") + + private java.sql.Date birthDate; + + @TableField(exist = false) + @ApiModelProperty(value = "年龄") + private Integer age; + + @ApiModelProperty(value = "身份证") + private String idCard; + + @ApiModelProperty(value = "人脸坐标位置") + private String faceRect; + + @ApiModelProperty(value = "人脸入库id") + @TableField("faceIds") + private String faceIds; + + @ApiModelProperty(value = "人脸特征id") + @TableField("featId") + private String featId; + + @ApiModelProperty(value = "是否有效 Y有效 N无效") + private String isValid; + + @ApiModelProperty(value = "创建时间") + private Date createTime; + + @ApiModelProperty(value = "创建人") + private String createBy; + + @ApiModelProperty(value = "更新时间") + private Date updateTime; + + @ApiModelProperty(value = "更新人") + private String updateBy; + + +} diff --git a/face-server/src/main/java/com/dkha/server/modules/entities/WarningInformation.java b/face-server/src/main/java/com/dkha/server/modules/entities/WarningInformation.java new file mode 100644 index 0000000..316d121 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/modules/entities/WarningInformation.java @@ -0,0 +1,73 @@ +package com.dkha.server.modules.entities; + +import com.baomidou.mybatisplus.annotation.IdType; +import java.util.Date; +import com.baomidou.mybatisplus.annotation.TableId; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + *

+ * 预警信息 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value="WarningInformation对象", description="预警信息") +public class WarningInformation implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @TableId(value = "id_warning_information", type = IdType.ID_WORKER_STR) + private String idWarningInformation; + + @ApiModelProperty(value = "接收参数") + private String receiveJson; + + @ApiModelProperty(value = "布控任务id") + private String idControlTask; + + @ApiModelProperty(value = "人像id/图片id") + private String idPortrait; + + @ApiModelProperty(value = "预警类型-码值") + private String type; + + @ApiModelProperty(value = "卡口id") + private String idFaceBayonet; + + @ApiModelProperty(value = "比对分数") + private Double score; + + @ApiModelProperty(value = "处理结果类型(1盘查 2抓捕)") + private String processResultType; + + @ApiModelProperty(value = "处理结果") + private String processResult; + + @ApiModelProperty(value = "是否有效 Y有效 N无效") + private String isValid; + + @ApiModelProperty(value = "创建时间") + private Date createTime; + + @ApiModelProperty(value = "创建人") + private String createBy; + + @ApiModelProperty(value = "更新时间") + private Date updateTime; + + @ApiModelProperty(value = "更新人") + private String updateBy; + + +} diff --git a/face-server/src/main/java/com/dkha/server/modules/entities/faceCamera/FaceCameraExcel.java b/face-server/src/main/java/com/dkha/server/modules/entities/faceCamera/FaceCameraExcel.java new file mode 100644 index 0000000..5a49936 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/modules/entities/faceCamera/FaceCameraExcel.java @@ -0,0 +1,60 @@ +package com.dkha.server.modules.entities.faceCamera; + +import com.dkha.common.util.UtilValidate; +import com.dkha.common.util.excel.ExcelField; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.apache.commons.lang3.StringUtils; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +@Data +@ApiModel(description = "摄像头excel") +public class FaceCameraExcel { + @ApiModelProperty(value = "摄像头名称") + @ExcelField(title = "摄像头名称") + public String cameraName; + + @ApiModelProperty(value = "摄像头详细地址") + public String cameraAddress; + + @ApiModelProperty(value = "摄像头经度") + @ExcelField(title = "摄像头坐标经度") + public String cameraLongitude; + + @ApiModelProperty(value = "摄像头纬度") + @ExcelField(title = "摄像头坐标纬度") + public String cameraLatitude; + + @ApiModelProperty(value = "型号") + @ExcelField(title = "摄像头厂家") + public String version; + + + @ApiModelProperty(value = "IP") + @ExcelField(title = "摄像头IP") + public String ip; + + @ApiModelProperty(value = "用户名") + @ExcelField(title = "摄像头用户名") + public String userName; + + @ExcelField(title = "摄像头密码") + @ApiModelProperty(value = "密码") + public String passwd; + + @ApiModelProperty(value = "品牌") + @ExcelField(title = "品牌") + public String brand; + + @ExcelField(title = "品牌") + @ApiModelProperty(value = "rtsp地址") + public String rtspUrl; + @ApiModelProperty(value = "提示信息") + @ExcelField(title = "提示信息") + public String message; + + +} diff --git a/face-server/src/main/java/com/dkha/server/modules/entities/faceCamera/FaceCameraInfo.java b/face-server/src/main/java/com/dkha/server/modules/entities/faceCamera/FaceCameraInfo.java new file mode 100644 index 0000000..686d4dc --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/modules/entities/faceCamera/FaceCameraInfo.java @@ -0,0 +1,130 @@ +package com.dkha.server.modules.entities.faceCamera; + +import com.dkha.common.util.UtilValidate; +import com.dkha.server.system.modules.sys.entity.SysDictDataEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.apache.commons.lang3.StringUtils; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +//@Data +@ApiModel(description = "查看摄像头信息") +@Getter +@Setter +@NoArgsConstructor +public class FaceCameraInfo { + + @ApiModelProperty(value = "idFaceCamera") + private Long idFaceCamera; + @NotBlank(message = "摄像头名称不能为空") + @ApiModelProperty(value = "摄像头名称") + private String cameraName; + + @ApiModelProperty(value = "摄像头区域-码值") + private String cameraRegionFirstlevel; + + public String getCameraRegionFirstlevel() { + if (UtilValidate.isNotEmpty(cameraRegionFirstlevel)) { + return cameraRegionFirstlevel; + } + + return StringUtils.join(cameraRegionFirstlevelArrays, ','); + } + + @ApiModelProperty(value = "摄像头层级区域冗余字段") + private String cameraRegionFirstlevelBackUp; + @NotNull(message = "摄像头区域不能为空") + @ApiModelProperty(value = "摄像头区域-码值") + private String[] cameraRegionFirstlevelArrays; + + public String[] getCameraRegionFirstlevelArrays() { + if (UtilValidate.isNotEmpty(this.cameraRegionFirstlevelArrays)) { + return this.cameraRegionFirstlevelArrays; + } + + return this.cameraRegionFirstlevel.split(","); + } + + + @ApiModelProperty(value = "摄像头详细地址") + private String cameraAddress; + + @NotBlank(message = "摄像头经度不能为空") + @Min(value = -180,message = "经度不能小于-180") + @Max(value = 180,message = "经度不能大于180") + @ApiModelProperty(value = "摄像头经度") + private String cameraLongitude; + + @NotBlank(message = "摄像头纬度不能为空") + @ApiModelProperty(value = "摄像头纬度") + @Min(value = -90,message = "纬度不能小于-90") + @Max(value = 90,message = "纬度不能大于90") + private String cameraLatitude; +// @NotBlank(message = "位置类型不能为空") +// @ApiModelProperty(value = "位置类型-码值") +// private String cameratLocationtypeId; + + // @ApiModelProperty(value = "公安机关代码") +// private String publicSecurityCode; +// +// @ApiModelProperty(value = "公安机关名称") +// private String publicSecurityName; + @NotBlank(message = "型号不能为空") + @ApiModelProperty(value = "型号") + private String version; + + @ApiModelProperty(value = "品牌id") + private String idBrand; + + // @ApiModelProperty(value = "建设单位") +// private String constructionUnit; +// +// @ApiModelProperty(value = "管理单位") +// private String managementUnit; +// +// @ApiModelProperty(value = "管理人员") +// private String managementPersonnel; +// +// @ApiModelProperty(value = "联系电话") +// private String contactNumber; +// @NotBlank(message = "ip不能为空") + +// @NotBlank(message = "port不能为空") + @ApiModelProperty(value = "端口") + private String port; + + @ApiModelProperty(value = "IP") + private String ip; +// @NotBlank(message = "用户名不能为空") + + @ApiModelProperty(value = "用户名") + private String userName; +// @NotBlank(message = "密码不能为空") + + @ApiModelProperty(value = "密码") + private String passwd; + @NotBlank(message = "品牌不能为空") + + @ApiModelProperty(value = "品牌") + private String brand; + @NotBlank(message = "rtsp地址不能为空") + + @ApiModelProperty(value = "rtsp地址") + private String rtspUrl; + + @ApiModelProperty(value = "备注信息") + private String remarks; + + @ApiModelProperty(value = "是否运行 Y启动 N未启动") + private String status; + +} diff --git a/face-server/src/main/java/com/dkha/server/modules/entities/faceCamera/FaceCameraList.java b/face-server/src/main/java/com/dkha/server/modules/entities/faceCamera/FaceCameraList.java new file mode 100644 index 0000000..b2d9b4e --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/modules/entities/faceCamera/FaceCameraList.java @@ -0,0 +1,92 @@ +package com.dkha.server.modules.entities.faceCamera; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + + +/** + * 摄像头表 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 2019-12-08 + */ +@Data +@ApiModel(value = "摄像头列表") +public class FaceCameraList implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "idFaceCamera") + private Long idFaceCamera; + + @ApiModelProperty(value = "摄像头名称") + private String cameraName; + + @ApiModelProperty(value = "摄像头区域-码值") + private String cameraRegionFirstlevel; + @ApiModelProperty(value = "摄像头层级区域冗余字段") + private String cameraRegionFirstlevelBackUp; + + @ApiModelProperty(value = "摄像头详细地址") + private String cameraAddress; + + @ApiModelProperty(value = "摄像头经度") + private String cameraLongitude; + + @ApiModelProperty(value = "摄像头纬度") + private String cameraLatitude; + + @ApiModelProperty(value = "位置类型-码值") + private String cameratLocationtypeId; + @ApiModelProperty(value = "位置类型冗余字段") + + private String cameratLocationtypeIdBackUp; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建时间") + private Date createTime; +// +// @ApiModelProperty(value = "公安机关代码") +// private String publicSecurityCode; +// +// @ApiModelProperty(value = "公安机关名称") +// private String publicSecurityName; +// +// @ApiModelProperty(value = "建设单位") +// private String constructionUnit; +// +// @ApiModelProperty(value = "管理单位") +// private String managementUnit; +// +// @ApiModelProperty(value = "管理人员") +// private String managementPersonnel; +// +// @ApiModelProperty(value = "联系电话") +// private String contactNumber; +// +// @ApiModelProperty(value = "IP") +// private String ip; +// +// @ApiModelProperty(value = "用户名") +// private String userName; +// +// @ApiModelProperty(value = "密码") +// private String passwd; +// +// @ApiModelProperty(value = "品牌") +// private String brand; +// +// @ApiModelProperty(value = "rtsp地址") +// private String rtspUrl; +// +// @ApiModelProperty(value = "备注信息") +// private String remarks; + + @ApiModelProperty(value = "是否运行 Y启动 N未启动") + private String status; + + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/modules/entities/faceCamera/InsertFaceCamera.java b/face-server/src/main/java/com/dkha/server/modules/entities/faceCamera/InsertFaceCamera.java new file mode 100644 index 0000000..769bdaa --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/modules/entities/faceCamera/InsertFaceCamera.java @@ -0,0 +1,102 @@ +package com.dkha.server.modules.entities.faceCamera; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.apache.commons.lang3.StringUtils; + +import javax.validation.constraints.*; + +@Data +@ApiModel(description = "新增摄像头") +public class InsertFaceCamera { + @NotBlank(message = "摄像头名称不能为空") + @ApiModelProperty(value = "摄像头名称") + private String cameraName; + + @ApiModelProperty(value = "摄像头区域-码值") + private String cameraRegionFirstlevel; + + public String getCameraRegionFirstlevel() { + StringUtils.join(cameraRegionFirstlevelArrays, ','); + + return StringUtils.join(cameraRegionFirstlevelArrays, ','); + } + + @NotNull(message = "摄像头区域不能为空") + @ApiModelProperty(value = "摄像头区域-码值") + private long[] cameraRegionFirstlevelArrays; + + + @ApiModelProperty(value = "摄像头详细地址") + private String cameraAddress; + + @NotBlank(message = "摄像头经度不能为空") + @Min(value = -180,message = "经度不能小于-180") + @Max(value = 180,message = "经度不能大于180") + @ApiModelProperty(value = "摄像头经度") + private String cameraLongitude; + + @NotBlank(message = "摄像头纬度不能为空") + @Min(value = -90,message = "纬度不能小于-90") + @Max(value = 90,message = "纬度不能大于90") + @ApiModelProperty(value = "摄像头纬度") + private String cameraLatitude; +// +// @NotBlank(message = "位置类型不能为空") +// @ApiModelProperty(value = "位置类型-码值") +// private String cameratLocationtypeId; + +// @ApiModelProperty(value = "公安机关代码") +// private String publicSecurityCode; +// +// @ApiModelProperty(value = "公安机关名称") +// private String publicSecurityName; + +// @ApiModelProperty(value = "建设单位") +// private String constructionUnit; +// +// @ApiModelProperty(value = "管理单位") +// private String managementUnit; +// +// @ApiModelProperty(value = "管理人员") +// private String managementPersonnel; +// @ApiModelProperty(value = "联系电话") +// private String contactNumber; + @NotBlank(message = "ip不能为空") + @ApiModelProperty(value = "IP") + private String ip; + +// @NotBlank(message = "port不能为空") + @ApiModelProperty(value = "端口") + private String port; + +// @NotBlank(message = "用户名不能为空") + @ApiModelProperty(value = "用户名") + private String userName; + +// @NotBlank(message = "密码不能为空") + @ApiModelProperty(value = "密码") + private String passwd; + +// @NotBlank(message = "型号不能为空") + @ApiModelProperty(value = "型号") + private String version; + + @NotBlank(message = "品牌id") + @ApiModelProperty(value = "品牌id") + private String idBrand; + +// @NotBlank(message = "品牌不能为空") + @ApiModelProperty(value = "品牌") + private String brand; + + @NotBlank(message = "rtsp地址不能为空") + @ApiModelProperty(value = "rtsp地址") + private String rtspUrl; + + @ApiModelProperty(value = "备注信息") + private String remarks; + + +} diff --git a/face-server/src/main/java/com/dkha/server/schedule/CheckCameraTimer.java b/face-server/src/main/java/com/dkha/server/schedule/CheckCameraTimer.java new file mode 100644 index 0000000..a276fc5 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/schedule/CheckCameraTimer.java @@ -0,0 +1,68 @@ +package com.dkha.server.schedule; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.dkha.common.enums.YNEnums; +import com.dkha.server.modules.entities.FaceCameraEntity; +import com.dkha.server.services.FaceCameraService; +import lombok.extern.slf4j.Slf4j; +import org.bytedeco.javacv.FFmpegFrameGrabber; +import org.bytedeco.javacv.FrameGrabber; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +/** + * @ClassName: CheckCameraTimer + * @Description: + * @author: yanping + * @date: 2020-01-07 10:25:50 + * @Copyright: 成都电科惠安 + */ + +@Slf4j +@Component +public class CheckCameraTimer { + + @Autowired + private FaceCameraService faceCameraService; + + /** + * 检测摄像头是否可用,项目启动10秒后执行,间隔时间为两小时 + */ + @Scheduled(fixedDelay = 1000 * 3600 * 2, initialDelay = 10000) + public void checkCameras() { + List cameras = faceCameraService.list(new QueryWrapper().eq("is_valid", YNEnums.YES.code)); + List updates = new ArrayList<>(); + for (FaceCameraEntity faceCameraEntity : cameras) { + String rtspUrl = faceCameraEntity.getRtspUrl(); + FFmpegFrameGrabber fFmpegFrameGrabber = null; + try { + fFmpegFrameGrabber = new FFmpegFrameGrabber(rtspUrl); + fFmpegFrameGrabber.start(); + fFmpegFrameGrabber.stop(); + faceCameraEntity.setStatus(YNEnums.YES.code); + updates.add(faceCameraEntity); + } catch (FrameGrabber.Exception e) { + log.error(e.getMessage()); + faceCameraEntity.setStatus(YNEnums.NO.code); + updates.add(faceCameraEntity); + continue; + } finally { + + } + + } + if(updates.size() > 0){ + faceCameraService.updateBatchById(updates); + } + + } + + +} diff --git a/face-server/src/main/java/com/dkha/server/services/FaceCameraService.java b/face-server/src/main/java/com/dkha/server/services/FaceCameraService.java new file mode 100644 index 0000000..d392f34 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/FaceCameraService.java @@ -0,0 +1,129 @@ +package com.dkha.server.services; + + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import com.dkha.common.modules.vo.camera.CameraInfoVO; +import com.dkha.common.page.PageParam; +import com.dkha.server.modules.entities.FaceCameraEntity; +import com.dkha.server.modules.entities.faceCamera.FaceCameraExcel; +import com.dkha.server.modules.entities.faceCamera.FaceCameraInfo; +import com.dkha.server.modules.entities.faceCamera.FaceCameraList; +import com.dkha.server.modules.entities.faceCamera.InsertFaceCamera; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; +import java.util.Map; + +/** + * 摄像头表 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 2019-12-08 + */ +public interface FaceCameraService extends IService { + /** + * 获取摄像头信息 + * + * @param pageParam + * @return + */ + Page getPage(PageParam pageParam); + + /** + * 获取所有摄像头信息 + * @param cameraName + * @return + */ + List getAll(String cameraName); + + /** + * 新增摄像头 + * @param insertFaceCamera + * @return 条数 + */ + Integer insertCamera(InsertFaceCamera insertFaceCamera); + + /** + * /查看摄像头 + * + * @param idCamera + * @return + */ + FaceCameraInfo findById(long idCamera); + + /** + * 获取摄像头卡口树状图 + * 第一级传0 + * @param id + * @return + */ + List> getBayonet(Long id); + + /** + * 获取摄像头区域树状图 + * + * @return + */ + List> getRegion(Long pid); + + /** + * 获取当前区域下的摄像头 + * @param regionId + * @return + */ + List> getCameraByRegionId(long regionId); + + /** + * 获取当前区域下尚未布控的摄像头 + * @param regionId + * @return + */ + List> getRegionUnControlCamera(long regionId); + + /** + * 获取当前区域下的所有摄像头 + * @param regionId + * @return + */ + List> getAllCameraByRegionId(long regionId); + Integer delete(long camera); + + /** + * 修改摄像头状态 + * @param camera + * @param status + * @return + */ + Integer status(long camera, boolean status); + + /** + * Excel导入 + * @param multipartFile + * @return + * @throws Exception + */ + List importExcel(MultipartFile multipartFile) ; + + /** + * 修改摄像头信息 + * @param faceCameraInfo + * @return + */ + Integer update(FaceCameraInfo faceCameraInfo); + + /** + * 根据任务获取所有布控摄像头信息 + * @return + */ + List findCameraByTask(); + + /** + * 经纬度查询摄像头信息 + * @param cameraLongitude + * @param cameraLatitude + * @return + */ + FaceCameraEntity findByCoordinate(String cameraLongitude,String cameraLatitude); + CameraInfoVO selectFaceCameraID(String idFaceCamera); +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/services/FaceTrackService.java b/face-server/src/main/java/com/dkha/server/services/FaceTrackService.java new file mode 100644 index 0000000..f271138 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/FaceTrackService.java @@ -0,0 +1,68 @@ +package com.dkha.server.services; + + + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.dkha.common.modules.vo.face.FaceTrackVO; +import com.dkha.server.modules.entities.FaceTrackEntity; + +import java.util.List; + +/** + * + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 2020-01-10 + */ +public interface FaceTrackService extends IService { + /** + * 新增 + * @param faceTrackEntity + * @return + */ + int addFaceTrackEntity(FaceTrackEntity faceTrackEntity); + /** + * 根据摄像头和分组时间查询 + * @param idFaceCamera + * @param packetTime + * @return + */ + List querByidCameraAndTime(Long idFaceCamera, String packetTime); + + /** + * 根据摄像头Id和开始,结束时间,人脸ID + * @param faceTrackVO + * @return + */ + List queryByidCamerAndFaceId(FaceTrackVO faceTrackVO); + + /** + * 根据图片路径和开始,结束时间 + * @param faceTrackVO + * @return + */ + List queryByurlAndTime(FaceTrackVO faceTrackVO); + + /** + * 根據時間獲取庫id + * @param faceTrackVO + * @return + */ + List findIdFatoryByTime(FaceTrackVO faceTrackVO); + + /** + * 根据图片路径和开始,结束时间和阈值 + * @param faceTrackVO + * @return + */ + List queryBytrajectoryThreshold(FaceTrackVO faceTrackVO); + /** + * 根据人脸ID查询 + * @param idPortrait + * @return + */ + FaceTrackEntity queryByIdPortrait(String idPortrait); + + List findTrackByFaceId(List faceIds); +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/services/ICompareService.java b/face-server/src/main/java/com/dkha/server/services/ICompareService.java new file mode 100644 index 0000000..657835f --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/ICompareService.java @@ -0,0 +1,35 @@ +package com.dkha.server.services; + + +import com.dkha.common.modules.vo.facelib.CompareRequestVo; +import com.dkha.common.modules.vo.facelib.CompareResultVo; +import com.dkha.common.modules.vo.facelib.OneToOneResultVo; + +/** + * @Author Spring + * @Since 2019/12/11 16:12 + * @Description 比对相关业务 + */ +public interface ICompareService { + + /** + * 分组比对接口 + * @param compareRequestVo + * @return + */ + CompareResultVo groupingCompare(CompareRequestVo compareRequestVo); + + /** + * 一比一接口 + * @param compareRequestVo + * @return + */ + OneToOneResultVo oneToOne(CompareRequestVo compareRequestVo); + + /*** + * 图片上传 bease64 + * @param image + * @return + */ + String setFaceCompare(String image); +} diff --git a/face-server/src/main/java/com/dkha/server/services/IControlBayonetMidService.java b/face-server/src/main/java/com/dkha/server/services/IControlBayonetMidService.java new file mode 100644 index 0000000..5faffdd --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/IControlBayonetMidService.java @@ -0,0 +1,59 @@ +package com.dkha.server.services; + +import com.dkha.common.modules.vo.camera.CameraInfoVO; +import com.dkha.server.modules.entities.ControlBayonetMid; +import com.baomidou.mybatisplus.extension.service.IService; +import com.dkha.server.modules.entities.FaceCameraEntity; + +import java.util.List; + +/** + *

+ * 布控和摄像头中间表 服务类 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +public interface IControlBayonetMidService extends IService { + /** + * 根据任务ID删除任务和摄像头的中间表 + */ + Integer deletetaskandcarmerbytaskid(String taskID); + + /** + * 根据摄像头ID判断是否存在任务 + */ + long selectexistByCarmeID(String idcamera); + + /** + * 更新中间库摄像头状态 + */ + Integer updateCarmerValidaStateByTaskID(String taskID, String State, String UpdateBy); + + /** + * 根据任务ID获取摄像头列表 + */ + List selectFaceCameraBytaskID(String taskid); + + /** + * 获取摄像头信息 + * @return + */ + List selectFaceCameraBytask(); + /** + * 获取最新布控的一个摄像头 + */ + ControlBayonetMid selectFaceCameraByTime(); + + /** + * 根据区域获取布控任务 + * + * @param regionId + * @return + */ + int getControlByRegion(long regionId); + + List selectFaceCameraBytaskInfo(); + +} diff --git a/face-server/src/main/java/com/dkha/server/services/IControlLibraryMidService.java b/face-server/src/main/java/com/dkha/server/services/IControlLibraryMidService.java new file mode 100644 index 0000000..e72544e --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/IControlLibraryMidService.java @@ -0,0 +1,19 @@ +package com.dkha.server.services; + +import com.dkha.server.mappers.ControlLibraryMidMapper; +import com.dkha.server.modules.entities.ControlLibraryMid; +import com.baomidou.mybatisplus.extension.service.IService; +import org.springframework.beans.factory.annotation.Autowired; + +/** + *

+ * 布控和库中间表 服务类 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +public interface IControlLibraryMidService extends IService { + + public Integer deletetaskLibraryMidbytaskid(String taskID) ; +} diff --git a/face-server/src/main/java/com/dkha/server/services/IControlTaskService.java b/face-server/src/main/java/com/dkha/server/services/IControlTaskService.java new file mode 100644 index 0000000..2c64566 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/IControlTaskService.java @@ -0,0 +1,54 @@ +package com.dkha.server.services; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dkha.common.modules.vo.control.TaskControlVO; +import com.dkha.common.modules.vo.control.VideoControlVo; +import com.dkha.common.page.PageParam; +import com.dkha.common.result.CommonResult; +import com.dkha.server.modules.entities.ControlTask; +import com.baomidou.mybatisplus.extension.service.IService; +import org.springframework.web.multipart.MultipartFile; + +/** + *

+ * 布控任务 服务类 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +public interface IControlTaskService extends IService { + + /**查询任务列表*/ + Page getList(PageParam pageParam,Integer videotype); + /**添加任务列表*/ + CommonResult addControlTask(TaskControlVO controlTask); + /**修改任务*/ + CommonResult updateControlTask(TaskControlVO controlTask); + /**删除指定任务*/ + CommonResult deleteControlTask(String taskID); + /**根据任务ID获取摄像头列表*/ + CommonResult getCameraListByTaskID(String taskID); + /**根据任务Num获取摄像头列表*/ + CommonResult getCameraListByTaskNO(String taskNO); + /**根据任务ID停止任务*/ + CommonResult stopControlByTaskID(String taskID); + /**根据任务ID暂停任务*/ + CommonResult suspendControlByTaskID(String taskID); + /**根据任务ID恢复任务*/ + CommonResult resumeControlByTaskID(String taskID); + /**人脸信息添加*/ + CommonResult addtaskfaceFile(MultipartFile multipartFile); + /**人脸信息添加base64*/ + CommonResult addtaskfaceFiles(String url); + /**添加视频文件*/ + CommonResult addcomplevideoFile(MultipartFile multipartFile); + /**添加视频比对任务*/ + CommonResult addcomplevideoTask(VideoControlVo controlVO); + /**根据摄像头的区域ID列表转换为区域字符串*/ + String getCameraRegionStringByRegionstr(String Regionstr); + /**根据任务ID获取库字符串*/ + String getLibRegionBytaskid(String taskID); + /**根据摄像头id获取任务信息*/ + ControlTask getTaskInfoByCameraID(String Camera); +} diff --git a/face-server/src/main/java/com/dkha/server/services/IFaceCameraService.java b/face-server/src/main/java/com/dkha/server/services/IFaceCameraService.java new file mode 100644 index 0000000..045053c --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/IFaceCameraService.java @@ -0,0 +1,16 @@ +package com.dkha.server.services; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.dkha.server.modules.entities.FaceCameraEntity; + +/** + *

+ * 摄像头表 服务类 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +public interface IFaceCameraService extends IService { + +} diff --git a/face-server/src/main/java/com/dkha/server/services/IFaceLibraryService.java b/face-server/src/main/java/com/dkha/server/services/IFaceLibraryService.java new file mode 100644 index 0000000..841b4f5 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/IFaceLibraryService.java @@ -0,0 +1,52 @@ +package com.dkha.server.services; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dkha.common.page.PageParam; +import com.dkha.server.modules.entities.FaceLibrary; +import com.baomidou.mybatisplus.extension.service.IService; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + *

+ * 库表 服务类 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +public interface IFaceLibraryService extends IService { + /** + * 新增库 + * @param faceLibrary + * @return + */ + FaceLibrary addLibrary(FaceLibrary faceLibrary); + + /** + * 删除库 + * @param faceLibrary + * @return + */ + FaceLibrary deleteLibrary(Long faceLibrary); + /** + * 修改库 + * @param faceLibrary + * @return + */ + FaceLibrary updateLibrary(FaceLibrary faceLibrary); + + /** + * 查询 + * @return + */ + Page queryLibrary(PageParam pageParam); + + /** + * 人像库查所有 + * @return + */ + List findFaceLibraries(); +} + diff --git a/face-server/src/main/java/com/dkha/server/services/IFileService.java b/face-server/src/main/java/com/dkha/server/services/IFileService.java new file mode 100644 index 0000000..27cd473 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/IFileService.java @@ -0,0 +1,36 @@ +package com.dkha.server.services; + +import com.dkha.common.modules.vo.cut.CutVo; +import com.dkha.common.modules.vo.upload.ImageUploadResult; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; + +/** + * @Author Spring + * @Since 2019/12/11 15:40 + * @Description 文件上传相关 + */ +public interface IFileService { + + /** + * 多图/单图上传,其中一张图可以多人脸/单人脸 + * @param multipartFiles + * @return + */ + ImageUploadResult uploadMultiFaceImages(MultipartFile[] multipartFiles) throws Exception; + + /** + * 单图上传,其中一张图只能有一张人脸 + * @param multipartFiles + * @return + */ + ImageUploadResult uploadSingleFaceImage(MultipartFile[] multipartFiles) throws Exception; + + /** + * 裁剪图片 + * @param cutVo + * @return + */ + String cutPicture(CutVo cutVo) throws Exception; +} diff --git a/face-server/src/main/java/com/dkha/server/services/IPortraitService.java b/face-server/src/main/java/com/dkha/server/services/IPortraitService.java new file mode 100644 index 0000000..7a8cb0e --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/IPortraitService.java @@ -0,0 +1,89 @@ +package com.dkha.server.services; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dkha.common.modules.vo.face.ApiSearchFaceRectVO; +import com.dkha.common.modules.vo.search.SearchRequestVo; +import com.dkha.common.modules.vo.search.SearchResultVo; +import com.dkha.common.page.PageParam; +import com.dkha.server.modules.entities.Portrait; +import com.baomidou.mybatisplus.extension.service.IService; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + *

+ * 人像表 服务类 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +public interface IPortraitService extends IService { + /** + * 人脸入库 + * @param multipartFile + * @return + */ + Portrait addPortrait(String libraryId,MultipartFile multipartFile) ; + /** + * 人脸检测 + * @param multipartFile + * @return + */ + List pictureDetection(MultipartFile multipartFile) throws Exception; + /** + * 布控图片人脸入库 + * @param multipartFile + * @return + */ + Portrait addPortraitPng(String libraryId,MultipartFile multipartFile) ; + /** + * 布控图片人脸入库(地址为base64的编码转url) + * @param multipartFile + * @return + */ + Portrait addPortraitPngs(String libraryId,String multipartFile) ; + + + /** + * 人脸批量入库 + * @param files + * @return + */ + List addPortraits(String libraryId,MultipartFile[] files); + /** + * 修改人脸信息 + * @param portrait + * @return + */ + Portrait updatePortrait(Portrait portrait); + + /** + * 删除人脸 + * @param portrait + * @return + */ + Long deletePortrait(Long portrait); + + /** + * 批量删除人脸 + * @param portraitId + * @return + */ + List deletePortraits(List portraitId); + + /** + * 人脸入库 + * @param pageParam + * @return + */ + Page queryPortrait(PageParam pageParam); + + /** + * 人脸库检索----分页 + * @param searchRequestVo 人脸库检索请求Vo + * @return + */ + SearchResultVo libSearchPage(SearchRequestVo searchRequestVo); +} diff --git a/face-server/src/main/java/com/dkha/server/services/IWarningInformationService.java b/face-server/src/main/java/com/dkha/server/services/IWarningInformationService.java new file mode 100644 index 0000000..efd4e89 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/IWarningInformationService.java @@ -0,0 +1,16 @@ +package com.dkha.server.services; + +import com.dkha.server.modules.entities.WarningInformation; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 预警信息 服务类 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +public interface IWarningInformationService extends IService { + +} diff --git a/face-server/src/main/java/com/dkha/server/services/impl/CompareServiceImpl.java b/face-server/src/main/java/com/dkha/server/services/impl/CompareServiceImpl.java new file mode 100644 index 0000000..7201fc1 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/impl/CompareServiceImpl.java @@ -0,0 +1,203 @@ +package com.dkha.server.services.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.dkha.common.enums.ApiUrlEnum; +import com.dkha.common.exception.DkException; +import com.dkha.common.fileupload.MinioUtil; +import com.dkha.common.http.HttpUtil; +import com.dkha.common.modules.vo.ReturnVO; +import com.dkha.common.modules.vo.face.ApiFaceOneSearchFaceVO; +import com.dkha.common.modules.vo.face.ApiFaceOneSearchReturnFaceVO; +import com.dkha.common.modules.vo.face.ApiFaceSearGroupReturnVO; +import com.dkha.common.modules.vo.face.ApiSearchFaceRectVO; +import com.dkha.common.modules.vo.facelib.*; +import com.dkha.common.modules.vo.search.FaceCheckVO; +import com.dkha.common.modules.vo.search.FaceCompareVO; +import com.dkha.common.util.Base64ImageUtils; +import com.dkha.common.util.JsonUtil; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.services.ICompareService; +import com.dkha.server.services.IFileService; +import com.fasterxml.jackson.core.type.TypeReference; +import org.apache.poi.ss.formula.functions.T; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * @Author Spring + * @Since 2019/12/11 16:12 + * @Description 比对相关业务类 + */ +@Component +public class CompareServiceImpl implements ICompareService { + + @Value("${api.group.max}") + private String apiGroupMaxSize; + @Value("${api.server.prefix}") + private String apiServerPrefix; + @Value("${api.group.min}") + private int apiGroupMinSize; + @Autowired + private HttpUtil httpUtil; +// @Autowired +// private Base64ImageUtils base64ImageUtils; + @Autowired + private MinioUtil minioUtil; + @Autowired + private IFileService iFileService; + @Value("${api.server.prefix}") + private String apiRequestPrefix; + /** + * 比对的图片数量 + */ + public static int comparePicSize = 2; + + @Override + public CompareResultVo groupingCompare(CompareRequestVo compareRequestVo) { + if (UtilValidate.isEmpty(compareRequestVo.getUrlList())) { + throw new DkException("请选择需要比对的图片"); + } + if (compareRequestVo.getUrlList().size() < apiGroupMinSize) { + throw new DkException("请至少选择" + apiGroupMinSize + "张图片进行分组"); + } + if (compareRequestVo.getUrlList().size() > Integer.parseInt(apiGroupMaxSize)) { + throw new DkException("最多只支持"+ apiGroupMaxSize +"张图片分组"); + } + //调用sdk进行分组 + FaceCheckVO faceCheckVO = new FaceCheckVO(); + if (UtilValidate.isNotEmpty(compareRequestVo.getMinScore())) { + faceCheckVO.setMinScore(compareRequestVo.getMinScore()); + } + faceCheckVO.setImgs(compareRequestVo.getUrlList()); + String apiUrl = apiServerPrefix + ApiUrlEnum.FACE_GROUP.getUrl(); + ReturnVO returnVO = (ReturnVO)httpUtil.post(apiUrl, faceCheckVO, ReturnVO.class); + List> resultList = JsonUtil.string2Obj(JsonUtil.obj2String(returnVO.getData()), new TypeReference>>() {}); + //返回结果集 + CompareResultVo compareResultVo = new CompareResultVo(); + if (UtilValidate.isNotEmpty(resultList)) { + for (List apiFaceSearGroupReturnVOList : resultList) { + CompareResultSubVo compareResultSubVo = new CompareResultSubVo(); + //取返回回来的第一张图片作为左侧比对标准 + compareResultSubVo.setResultUrl(apiFaceSearGroupReturnVOList.get(0).getUrl()); + for (int i = 1; i < apiFaceSearGroupReturnVOList.size(); i++) { + CompareResultDetailVo compareResultDetailVo = new CompareResultDetailVo(); + compareResultDetailVo.setScore(apiFaceSearGroupReturnVOList.get(i).getHitSimilarity()); + compareResultDetailVo.setUrl(apiFaceSearGroupReturnVOList.get(i).getUrl()); + compareResultSubVo.getCompareResultSubVoList().add(compareResultDetailVo); + } + compareResultVo.getCompareResultSubVoList().add(compareResultSubVo); + } + } + return compareResultVo; + } + + @Override + public OneToOneResultVo oneToOne(CompareRequestVo compareRequestVo) { + if (UtilValidate.isEmpty(compareRequestVo.getUrlList())) { + throw new DkException("请选择需要比对的图片"); + } + if (compareRequestVo.getUrlList().size() != comparePicSize) { + throw new DkException("请上传1:1比对的两张图片"); + } + String apiUrl = apiServerPrefix + ApiUrlEnum.FACE_COMPARISON.getUrl(); + FaceCompareVO faceCompareVO = new FaceCompareVO(); + faceCompareVO.setImage1(compareRequestVo.getUrlList().get(0)); + faceCompareVO.setImage2(compareRequestVo.getUrlList().get(1)); + ReturnVO returnVO = (ReturnVO)httpUtil.post(apiUrl, faceCompareVO, ReturnVO.class); + ApiFaceOneSearchReturnFaceVO apiFaceOneSearchReturnFaceVO = JsonUtil.string2Obj(JsonUtil.obj2String(returnVO.getData()), new TypeReference() {}); + //返回结果集 + OneToOneResultVo oneToOneResultVo = new OneToOneResultVo(); + if (UtilValidate.isNotEmpty(apiFaceOneSearchReturnFaceVO)) { + if (UtilValidate.isNotEmpty(apiFaceOneSearchReturnFaceVO.getFaces())) { + for (ApiFaceOneSearchFaceVO apiFaceOneSearchFaceVO : apiFaceOneSearchReturnFaceVO.getFaces()) { + oneToOneResultVo.getUrls().add(apiFaceOneSearchFaceVO.getUrl()); + } + oneToOneResultVo.setScore(apiFaceOneSearchReturnFaceVO.getHitSimilarity()); + } + } + return oneToOneResultVo; + } + + @Override + public String setFaceCompare(String image) { + JSONObject map1; + try { + map1 = minioUtil.uploadFiles(Base64ImageUtils.BaseToInputStream(image), String.valueOf(getHash() % 500), String.valueOf(getHash()), ".jpg"); + } catch (Exception e) { + e.printStackTrace(); + throw new DkException("文件上传失败"); + } + String imag = map1.getString("url"); + validateSingleFaceImage(imag); + return imag; + + } + + /** + * 返回hash值 + * @return + */ + public int getHash(){ + String uuid = UUID.randomUUID().toString().replaceAll("-",""); + int hash = uuid.hashCode(); + if(hash<0){ + hash = 0-hash; + } + return hash; + } + /** + * 多图/单图上传,其中一张图可以多人脸/单人脸 校验 + * @param image + */ + private void validateSingleFaceImage(String image) { + //人脸检测url + String faceSearchUrl = apiRequestPrefix + ApiUrlEnum.FACE_SEARCH.getUrl(); + //组装api请求数据 + ReturnVO returnVO; + returnVO = (ReturnVO) httpUtil.post(faceSearchUrl + "?url=" + image, null, ReturnVO.class); + if (returnVO.getCode() != 200) { + throw new DkException(returnVO.getMessage()); + } + //反序列化 + List apiSearchFaceRectVOList = JsonUtil.string2Obj(JsonUtil.obj2String(returnVO.getData()), new TypeReference>() {}); + if (UtilValidate.isEmpty(apiSearchFaceRectVOList)) { + throw new DkException("当前上传中未检测到人脸,请重新上传"); + } + if (apiSearchFaceRectVOList.size() > 1) { + throw new DkException("当前上传图片检测到多张人脸,请重新上传"); + } + } + //上传图片 + public FaceCompareVO setFaceCompare(String image1,String image2) { + FaceCompareVO faceCompareVO = new FaceCompareVO(); + JSONObject map1; + try { + map1 = minioUtil.uploadFiles(Base64ImageUtils.BaseToInputStream(image1), String.valueOf(getHash() % 500), String.valueOf(getHash()), null); + String imag = map1.getString("url"); + validateSingleFaceImage(imag); + faceCompareVO.setImage1(imag); + } catch (Exception e) { + throw new DkException("文件上传失败"); + } + + JSONObject map2; + try { + map2 = minioUtil.uploadFiles(Base64ImageUtils.BaseToInputStream(image2), String.valueOf(getHash() % 500), String.valueOf(getHash()), null); + String image = map2.getString("url"); + validateSingleFaceImage(image); + faceCompareVO.setImage2(image); + } catch (Exception e) { + throw new DkException("文件上传失败"); + } + + return faceCompareVO; + } +} diff --git a/face-server/src/main/java/com/dkha/server/services/impl/ControlBayonetMidServiceImpl.java b/face-server/src/main/java/com/dkha/server/services/impl/ControlBayonetMidServiceImpl.java new file mode 100644 index 0000000..cc72793 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/impl/ControlBayonetMidServiceImpl.java @@ -0,0 +1,72 @@ +package com.dkha.server.services.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.dkha.common.modules.vo.camera.CameraInfoVO; +import com.dkha.server.modules.entities.ControlBayonetMid; +import com.dkha.server.mappers.ControlBayonetMidMapper; +import com.dkha.server.modules.entities.FaceCameraEntity; +import com.dkha.server.services.IControlBayonetMidService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + *

+ * 布控和摄像头中间表 服务实现类 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Service +public class ControlBayonetMidServiceImpl extends ServiceImpl implements IControlBayonetMidService { + + @Autowired + ControlBayonetMidMapper controlBayonetMidMapper; + + @Override + public Integer deletetaskandcarmerbytaskid(String taskID) { + return controlBayonetMidMapper.deletetaskandcarmerbytaskid(taskID); + } + + @Override + public long selectexistByCarmeID(String idcamera) { + long rs = controlBayonetMidMapper.selectexistByCarmeID(idcamera); + return rs; + } + + @Override + public Integer updateCarmerValidaStateByTaskID(String taskID, String State, String UpdateBy) { + return controlBayonetMidMapper.updateCarmerValidaStateByTaskID(taskID, State, UpdateBy); + } + + @Override + public List selectFaceCameraBytaskID(String taskid) { + return controlBayonetMidMapper.selectFaceCameraBytaskID(taskid); + } + + @Override + public List selectFaceCameraBytask() { + return controlBayonetMidMapper.selectFaceCameraBytask(); + } + + @Override + public ControlBayonetMid selectFaceCameraByTime() { + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("is_valid", "Y").orderByDesc("create_time").last("limit 1"); + return controlBayonetMidMapper.selectOne(queryWrapper); + } + + @Override + public int getControlByRegion(long regionId) { + return controlBayonetMidMapper.getControlByRegion(regionId); + } + + @Override + public List selectFaceCameraBytaskInfo() { + return controlBayonetMidMapper.selectFaceCameraBytaskInfo(); + } +} diff --git a/face-server/src/main/java/com/dkha/server/services/impl/ControlLibraryMidServiceImpl.java b/face-server/src/main/java/com/dkha/server/services/impl/ControlLibraryMidServiceImpl.java new file mode 100644 index 0000000..d9dbb61 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/impl/ControlLibraryMidServiceImpl.java @@ -0,0 +1,27 @@ +package com.dkha.server.services.impl; + +import com.dkha.server.modules.entities.ControlLibraryMid; +import com.dkha.server.mappers.ControlLibraryMidMapper; +import com.dkha.server.services.IControlLibraryMidService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + *

+ * 布控和库中间表 服务实现类 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Service +public class ControlLibraryMidServiceImpl extends ServiceImpl implements IControlLibraryMidService { + @Autowired + ControlLibraryMidMapper controlLibraryMidMapper ; + + @Override + public Integer deletetaskLibraryMidbytaskid(String taskID) { + return controlLibraryMidMapper.deletetaskLibraryMidbytaskid(taskID); + } +} diff --git a/face-server/src/main/java/com/dkha/server/services/impl/ControlTaskServiceImpl.java b/face-server/src/main/java/com/dkha/server/services/impl/ControlTaskServiceImpl.java new file mode 100644 index 0000000..4254dbf --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/impl/ControlTaskServiceImpl.java @@ -0,0 +1,734 @@ +package com.dkha.server.services.impl; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.dkha.common.enums.*; +import com.dkha.common.fileupload.MinioUtil; +import com.dkha.common.http.HttpUtil; +import com.dkha.common.modules.vo.control.ControlTaskVedioVO; +import com.dkha.common.modules.vo.control.TaskControlVO; +import com.dkha.common.modules.vo.control.VideoControlVo; +import com.dkha.common.modules.vo.face.ControlTaskVO; +import com.dkha.common.page.PageParam; +import com.dkha.common.result.CommonResult; +import com.dkha.common.systemcode.SystemCode; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.mappers.ControlLibraryMidMapper; +import com.dkha.server.mappers.ControlTaskMapper; +import com.dkha.server.mappers.FaceCameraDao; +import com.dkha.server.modules.entities.*; +import com.dkha.server.services.*; +import com.google.common.base.Joiner; +import com.google.common.base.Splitter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.*; +import java.util.regex.Pattern; + +/** + *

+ * 布控任务 服务实现类 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Service +@Slf4j +public class ControlTaskServiceImpl extends ServiceImpl implements IControlTaskService { + + @Autowired + ControlTaskMapper controlTaskMapper; + @Autowired + FaceCameraDao faceCameraDao; + @Autowired + ControlBayonetMidServiceImpl controlBayonetMidService; + @Autowired + ControlLibraryMidMapper controlLibraryMidMapper; + @Autowired + ControlLibraryMidServiceImpl controlLibraryMidService; + + @Autowired + private IPortraitService iPortraitService; + + @Autowired + private IFaceLibraryService iFaceLibraryService; + @Autowired + private FaceCameraService faceCameraService; + + @Value("${api.server.prefix}") + private String link; + @Value("${videotype}") + private String videoreg = "(mp4|flv|avi|rm|rmvb|wmv)"; + + @Resource + private HttpUtil httpUtil; + + @Autowired + private MinioUtil minioUtil; + + @Override + public Page getList(PageParam pageParam,Integer videotype) { + if (pageParam.getPageNo() < 1) { + pageParam.setPageNo(1); + } + if (pageParam.getPageSize() < 0 || pageParam.getPageSize() > 500) { + pageParam.setPageSize(20); + } + Page page = new Page<>(pageParam.getPageNo(), pageParam.getPageSize()); + //分页查询 + List facetaskLists=null; + if(videotype==-1) { + facetaskLists = controlTaskMapper.getviedoTaskList(page, pageParam.getNote()); + }else + { + facetaskLists = controlTaskMapper.getTaskList(page, pageParam.getNote()); + } + for (ControlTask ct : facetaskLists) { + //生成摄像头列表的区域信息 + ct.setTasklibstr( this.getLibRegionBytaskid(ct.getIdControlTask().toString())); + //摄像头名称 + List faceCameras = controlBayonetMidService.selectFaceCameraBytaskID(ct.getIdControlTask().toString()); + ct.setListfacecamera(faceCameras); + //视频任务列表,需要获取任务状态 + if(-1==videotype){ + try { + ct.setTaskstatus(TaskStatuEnum.STATUS_WORKING.getMessage()); + Map resultMap = (Map) httpUtil.get(link + ApiUrlEnum.ALARMS_STATUS.getUrl() + "/" + ct.getTaskNo(), Map.class); + if (resultMap != null) { + if (ErrEnum.OK.getCode().toString().equalsIgnoreCase(resultMap.get("code").toString())) { + Map data = (Map) resultMap.get("data"); + if (data != null && data.get("status") != null) { + if (TaskStatuEnum.STATUS_OVER.getCode().equalsIgnoreCase(data.get("status").toString())) { + ct.setTaskstatus(TaskStatuEnum.STATUS_OVER.getMessage()); + } + } + } + } + + }catch (Exception ex){ + } + } + } + page.setRecords(facetaskLists); + return page; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public CommonResult addControlTask(TaskControlVO taskvo) { + + List listcamera = taskvo.getListcamera(); + if(listcamera==null||listcamera.size()==0) { + return new CommonResult(null, SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "布控摄像头信息不能为空!"); + } + try { + /*1 校验区域所属的摄像头是否有任务执行 */ + //保存摄像头列表 + List listBayone = new ArrayList<>(); + List listBayonebyUse = new ArrayList<>(); + List camerList = new ArrayList<>(); + //存储摄像头的区域码表 + HashMap cameraRegion=new HashMap<>(); + for (String camerid : listcamera) { + ControlBayonetMid controlBayonetMid = new ControlBayonetMid(); + FaceCameraEntity faceCamera = faceCameraService.getById(camerid); + if (controlBayonetMidService.selectexistByCarmeID(camerid) == 0) { + //依次判断摄像头是否添加到任务中 + controlBayonetMid.setIsValid(YNEnums.YES.code); + controlBayonetMid.setIdFaceCamera(faceCamera.getIdFaceCamera()); + camerList.add(faceCamera.getIdFaceCamera().toString()); + listBayone.add(controlBayonetMid); + cameraRegion.put(faceCamera.getCameraRegionFirstlevel(),1); + } else { + listBayonebyUse.add(faceCamera); + } + } + if (!UtilValidate.isEmpty(listBayonebyUse)) { + return new CommonResult(listBayonebyUse, SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "该区域下摄像头有被其他任务使用!"); + } + //保存库列表 + List listbibray = new ArrayList<>(); + List listbibraybyUse = new ArrayList<>(); + List listlibs = taskvo.getLibIds(); + for (String libid : listlibs) { + if (controlLibraryMidMapper.selectexistByLibID(libid, YNEnums.YES.code) > 0) { + ControlLibraryMid clm = new ControlLibraryMid(); + clm.setIdFactory(Long.parseLong(libid.toString())); + clm.setIsValid(YNEnums.YES.code); + listbibray.add(clm); + } else { + listbibraybyUse.add(libid); + } + } + if (!UtilValidate.isEmpty(listbibraybyUse)) { + return new CommonResult(listbibraybyUse, SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "该任务存在无效库!"); + } + // 调用平台API接口 + ControlTaskVO ctvo = new ControlTaskVO(); + //任务名称 + String strTaskNo = "00000000"; + ctvo.setName(taskvo.getTaskName()); + ctvo.setThreshold(taskvo.getControlThreshold()); + ctvo.setCameraId(camerList); + ctvo.setLibraryId(taskvo.getLibIds()); + Map resultMap = ( Map) httpUtil.post(link+ApiUrlEnum.TASK_POSTURL.getUrl(), ctvo, Map.class); + if(resultMap!=null){ + if(ErrEnum.OK.getCode().toString().equalsIgnoreCase(resultMap.get("code").toString())) + { + Map data= (Map) resultMap.get("data"); + if(data!=null&&data.get("taskId")!=null){ + strTaskNo=data.get("taskId").toString(); + }else + { + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, "远程API保存任务信息失败!没有获取到任务编号"); + } + }else { + return new CommonResult(resultMap, SystemCode.INTERNAL_PROGRAM_ERROR.code, "远程API保存任务信息失败!"); + } + }else { + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, "远程API保存任务信息失败!"); + } + + ControlTask controlTask = new ControlTask(); + controlTask.setTaskNo(strTaskNo); + BeanUtils.copyProperties(taskvo, controlTask); + //设置任务区域 + controlTask.setControlRegion(this.getCameraRegionStringByCameraList(cameraRegion)); + controlTask.setIsValid(TaskStatusEnum.RUN.code); + //保存任务 + if (this.save(controlTask)) { + for (ControlBayonetMid cbm : listBayone) { + //设置任务编号 + cbm.setIdControlTask(controlTask.getIdControlTask()); + } + for (ControlLibraryMid clm : listbibray) { + //设置任务编号 + clm.setIdControlTask(controlTask.getIdControlTask()); + } + //批量 保存摄像头列表 + controlBayonetMidService.saveBatch(listBayone); + //批量 保存库ID列表 + controlLibraryMidService.saveBatch(listbibray); + return new CommonResult(controlTask.getTaskNo(), SystemCode.HANDLER_SUCCESS.code, SystemCode.HANDLER_SUCCESS.des); + } else { + log.error("任务保存:{}", controlTask.getTaskNo()); + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, "保存任务信息失败!"); + } + } catch (Exception ex) { + log.error("保存任务异常:{}", ex.getMessage()); + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, "保存任务信息失败!"+ex.getMessage()); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public CommonResult updateControlTask(TaskControlVO controlTask) { + //根据任务ID查询任务信息 + ControlTask controlOne = this.getById(controlTask.getIdControlTask()); + if (controlOne == null) { + return new CommonResult(null, SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "参数异常,非法的任务ID!查询不到有效任务"); + } else { + try { + controlOne.setTaskName(controlTask.getTaskName()); + controlOne.setDisposalType(controlTask.getDisposalType()); + controlOne.setRemarks(controlTask.getRemarks()); + this.updateById(controlOne); + } catch (Exception ex) { + log.error("修改任务异常:{}", ex.getMessage()); + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, "修改任务信息失败!"); + } + } + return new CommonResult(controlOne, SystemCode.HANDLER_SUCCESS.code, SystemCode.HANDLER_SUCCESS.des); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public CommonResult deleteControlTask(String taskID) { + //根据任务ID查询任务信息 + ControlTask controlOne = this.getById(taskID); + if (controlOne == null) { + return new CommonResult(null, SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "参数异常,非法的任务ID!"); + } else { + try { + boolean isDeleteApi = false; + //1. 调用平台API接口 + Map resultMap = (Map) httpUtil.delete(link + ApiUrlEnum.TASK_POSTURL.getUrl() + "/" + controlOne.getTaskNo(), Map.class); + if (resultMap != null) { + if(ErrEnum.OK.getCode().toString().equalsIgnoreCase(resultMap.get("code").toString())){ + isDeleteApi=true; + } + } else { + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, "远程API删除任务信息失败!"); + } + if (isDeleteApi) { + // 删除任务摄像头中间管理库 + controlBayonetMidService.deletetaskandcarmerbytaskid(taskID); + // 删除任务特征库中间管理库 + controlLibraryMidService.deletetaskLibraryMidbytaskid(taskID); + // 删除本地数据库 + this.removeById(taskID); + } else { + return new CommonResult(taskID, SystemCode.DELETE_FAILED.code, "平台API删除任务信息失败"); + } + } catch (Exception ex) { + log.error("删除任务异常:{}", ex.getMessage()); + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, "删除任务信息失败!"); + } + } + return new CommonResult(taskID, SystemCode.HANDLER_SUCCESS.code, SystemCode.HANDLER_SUCCESS.des); + } + + @Override + public CommonResult getCameraListByTaskID(String taskID) { + List listfaceCamera = controlTaskMapper.getCameraByTaskID(taskID); + if (listfaceCamera != null) { + return new CommonResult(listfaceCamera, SystemCode.HANDLER_SUCCESS.code, SystemCode.HANDLER_SUCCESS.des); + } else { + return new CommonResult(null, SystemCode.HANDLER_FAILED.code, SystemCode.HANDLER_FAILED.des); + } + } + + @Override + public CommonResult getCameraListByTaskNO(String taskNO) { + List listfaceCamera = controlTaskMapper.getCameraByTaskNo(taskNO); + if (listfaceCamera != null) { + return new CommonResult(listfaceCamera, SystemCode.HANDLER_SUCCESS.code, SystemCode.HANDLER_SUCCESS.des); + } else { + return new CommonResult(null, SystemCode.HANDLER_FAILED.code, SystemCode.HANDLER_FAILED.des); + } + } + /** + * 停止订单信息 调用底层删除任务,本地库修改为停止状态 + * @param taskID + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public CommonResult stopControlByTaskID(String taskID) { + ControlTask controlOne = this.getById(taskID); + if (controlOne == null) { + return new CommonResult(null, SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "参数异常,非法的任务ID!"); + } else { + boolean isDeleteApi = false; + try{ + //1. 调用平台API接口 + Map resultMap = (Map) httpUtil.delete(link + ApiUrlEnum.TASK_POSTURL.getUrl() + "/" + controlOne.getTaskNo(), Map.class); + if (resultMap != null) { + if(ErrEnum.OK.getCode().toString().equalsIgnoreCase(resultMap.get("code").toString())) { + isDeleteApi=true; + } + } else { + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, "远程API删除任务信息失败!"); + } + if (isDeleteApi) { + // 更新本地数据库的状态为N + controlOne.setIsValid(TaskStatusEnum.STOP.code); + this.updateById(controlOne); + } else { + return new CommonResult(taskID, SystemCode.DELETE_FAILED.code, "平台API删除任务信息失败"); + }} + catch (Exception ex){ + if(log.isErrorEnabled()){ + log.error("停止任务失败"); + } + return new CommonResult(taskID, SystemCode.DELETE_FAILED.code, "停止任务失败"); + } + } + return new CommonResult(taskID, SystemCode.HANDLER_SUCCESS.code, SystemCode.HANDLER_SUCCESS.des); + } + + /** + * 暂停任务 调用底层删除任务,本地库修改为暂停状态 + * @param taskID + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public CommonResult suspendControlByTaskID(String taskID) { + + ControlTask controlOne = this.getById(taskID); + if (controlOne == null) { + return new CommonResult(null, SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "参数异常,非法的任务ID!"); + } else { + boolean isDeleteApi = false; + try{ + //1. 调用平台API接口 + Map resultMap = (Map) httpUtil.delete(link + ApiUrlEnum.TASK_POSTURL.getUrl() + "/" + controlOne.getTaskNo(), Map.class); + if (resultMap != null) { + if(ErrEnum.OK.getCode().toString().equalsIgnoreCase(resultMap.get("code").toString())){ + isDeleteApi=true; + } + } else { + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, "远程API删除任务信息失败!"); + } + if (isDeleteApi) { + // 更新本地数据库的状态为暂停 + controlOne.setIsValid(TaskStatusEnum.SUSPEND.code); + this.updateById(controlOne); + } else { + return new CommonResult(taskID, SystemCode.DELETE_FAILED.code, "平台API删除任务信息失败"); + }} + catch (Exception ex){ + return new CommonResult(taskID, SystemCode.DELETE_FAILED.code, ex.getMessage()); + } + } + return new CommonResult(taskID, SystemCode.HANDLER_SUCCESS.code, "暂停任务"+controlOne.getTaskName()+"成功"); + + } + + /** + * 恢复任务 调用底层新增任务,本地库修改为运行状态 + * @param taskID + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public CommonResult resumeControlByTaskID(String taskID) { + //1. 构建任务对象 + ControlTask controlOne = this.getById(taskID); + if (controlOne == null) { + return new CommonResult(null, SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "参数异常,非法的任务ID!"); + } else { + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("id_control_task", taskID); + //根据任务ID获取摄像头中间库 + List listBayoneMid = controlBayonetMidService.list(queryWrapper); + //获取摄像头 + if (UtilValidate.isEmpty(listBayoneMid)) { + return new CommonResult(controlOne.getTaskName(), SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "恢复任务失败,该任务下没有查询到有效摄像头列表!"); + } + //根据任务ID获取人像中间库 + List listLibMid = controlLibraryMidService.list(queryWrapper); + //获取人像中间库 + if(UtilValidate.isEmpty(listLibMid)) + { + return new CommonResult(controlOne.getTaskName(), SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "恢复任务失败,该任务下没有查询到有效库列表!"); + } + //摄像头列表ID + List listcamera = new ArrayList<>(); + for (ControlBayonetMid cbm : listBayoneMid) { + listcamera.add(cbm.getIdFaceCamera().toString()); + } + //获取人像中间库ID + List listfacelib= new ArrayList<>(); + for (ControlLibraryMid clb : listLibMid) { + listfacelib.add(clb.getIdFactory().toString()); + } + + ControlTaskVO ctvo = new ControlTaskVO(); + ctvo.setName(controlOne.getTaskName()); + ctvo.setThreshold(controlOne.getControlThreshold()); + ctvo.setCameraId(listcamera); + ctvo.setLibraryId(listfacelib); + //恢复新建时把原来的NO重新发送过去 + ctvo.setTaskId(controlOne.getTaskNo()); + try { + //2. 发送任务到API层 + // 调用平台API接口 + String strTaskNo = "000000"; + Map resultMap = (Map) httpUtil.post(link + ApiUrlEnum.TASK_POSTURL.getUrl(), ctvo, Map.class); + if (resultMap != null) { + if(ErrEnum.OK.getCode().toString().equalsIgnoreCase(resultMap.get("code").toString())){ + Map data = (Map) resultMap.get("data"); + if (data != null && data.get("taskId") != null) { + strTaskNo = data.get("taskId").toString(); + } else { + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, "远程API保存任务信息失败!"); + } + } else { + return new CommonResult(resultMap, SystemCode.INTERNAL_PROGRAM_ERROR.code, "远程API保存任务信息失败!"); + } + } else { + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, "远程API保存任务信息失败!"); + } + //3. 更新本地库任务的状态为RUN状态 + controlOne.setTaskNo(strTaskNo); + controlOne.setIsValid(TaskStatusEnum.RUN.code); + this.updateById(controlOne); + }catch (Exception ex){ + if(log.isErrorEnabled()){ + log.error("恢复任务异常{}:{}",controlOne.getTaskName(),ex.getMessage()); + } + } + } + return new CommonResult(taskID, SystemCode.HANDLER_SUCCESS.code, SystemCode.HANDLER_SUCCESS.des); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public CommonResult addtaskfaceFile(MultipartFile multipartFile) { + FaceLibrary faceLibrary =new FaceLibrary(); + faceLibrary.setIsValid(YNEnums.YES.code); + faceLibrary.setRemarks("任务图片上传临时库"); + Random r= new Random(); + faceLibrary.setFactoryName("任务图片上传库"+r.nextInt()); + faceLibrary.setFactoryType("-1"); + faceLibrary.setCreateTime(new Date()); + faceLibrary.setUpdateTime(new Date()); + faceLibrary.setCreateBy("SYSTASK"); + faceLibrary.setUpdateBy("SYSTASK"); + + FaceLibrary faceLibrar = iFaceLibraryService.addLibrary(faceLibrary); + if(UtilValidate.isEmpty(faceLibrar)) + { + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, "生成特征库识别!"); + } + //2.添加人脸信息特征 + Portrait portrait; + try { + portrait = iPortraitService.addPortraitPng(faceLibrar.getIdFactory().toString(), multipartFile); + } catch (Exception e) { + log.error("上传人像异常"+e.getMessage()); + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, e.getMessage()); + } + Map result=new HashMap<>(); + result.put("libid",faceLibrar.getIdFactory().toString()); + result.put("url",portrait.getBackgroundUrl()); + return new CommonResult(result,SystemCode.HANDLER_SUCCESS.code,"人像文件上传成功!"); + } + + @Override + public CommonResult addtaskfaceFiles(String url) { + FaceLibrary faceLibrary =new FaceLibrary(); + faceLibrary.setIsValid(YNEnums.YES.code); + faceLibrary.setRemarks("任务图片上传临时库"); + Random r= new Random(); + faceLibrary.setFactoryName("任务图片上传库"+r.nextInt()); + faceLibrary.setFactoryType("-1"); + faceLibrary.setCreateTime(new Date()); + faceLibrary.setUpdateTime(new Date()); + faceLibrary.setCreateBy("SYSTASK"); + faceLibrary.setUpdateBy("SYSTASK"); + + FaceLibrary faceLibrar = iFaceLibraryService.addLibrary(faceLibrary); + if(UtilValidate.isEmpty(faceLibrar)) + { + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, "生成特征库识别!"); + } + //2.添加人脸信息特征 + Portrait portrait; + try { + portrait = iPortraitService.addPortraitPngs(faceLibrar.getIdFactory().toString(), url); + } catch (Exception e) { + log.error("上传人像异常"+e.getMessage()); + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, e.getMessage()); + } + Map result=new HashMap<>(); + result.put("libid",faceLibrar.getIdFactory().toString()); + result.put("url",portrait.getBackgroundUrl()); + return new CommonResult(result,SystemCode.HANDLER_SUCCESS.code,"人像文件上传成功!"); + } + + @Override + public CommonResult addcomplevideoFile(MultipartFile multipartFile) { + try { + Pattern p = Pattern.compile(videoreg); + boolean boo = p.matcher(multipartFile.getOriginalFilename()).find(); + if (!boo){ + return new CommonResult( null,SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "上传文件必须是视频文件!"); + } + String suffix = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf(".")); + String newname= UUID.randomUUID().toString().replace("-","").toLowerCase(); + JSONObject map = minioUtil.uploadFile(multipartFile.getInputStream(),newname, suffix); + return new CommonResult(map, SystemCode.HANDLER_SUCCESS.code,SystemCode.HANDLER_SUCCESS.code.toString() ); + }catch (Exception ex){ + log.error("比对视频文件上传异常:{}",ex.getMessage()); + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, ex.getMessage()); + } + } + + @Override + @Transactional + public CommonResult addcomplevideoTask(VideoControlVo controlVO) { + try { + + List listbibray = new ArrayList<>(); + List listbibraybyUse = new ArrayList<>(); + List listlibs = controlVO.getLibIds(); + for (String libid : listlibs) { + if (controlLibraryMidMapper.selectexistByLibID(libid, YNEnums.YES.code) > 0) { + ControlLibraryMid clm = new ControlLibraryMid(); + clm.setIdFactory(Long.parseLong(libid.toString())); + clm.setIsValid(YNEnums.YES.code); + listbibray.add(clm); + } else { + listbibraybyUse.add(libid); + } + } + if (!UtilValidate.isEmpty(listbibraybyUse)) { + return new CommonResult(listbibraybyUse, SystemCode.ILLEGAL_ARGUMENT_EXCEPTION.code, "该任务存在无效库!"); + } + // 调用平台API接口 + ControlTaskVedioVO ctvo = new ControlTaskVedioVO(); + //任务名称 + String strTaskNo = "00000000"; + ctvo.setName("视频比对任务"); + ctvo.setThreshold(controlVO.getControlThreshold()); + ctvo.setUrl(controlVO.getVideourl()); + ctvo.setLibraryId(controlVO.getLibIds()); + + + Map resultMap = ( Map) httpUtil.post(link+ApiUrlEnum.TASK_VEDIO_POSTURL.getUrl(), ctvo, Map.class); + if(resultMap!=null){ + if(ErrEnum.OK.getCode().toString().equalsIgnoreCase(resultMap.get("code").toString())) + { + Map data= (Map) resultMap.get("data"); + if(data!=null&&data.get("taskId")!=null){ + strTaskNo=data.get("taskId").toString(); + }else + { + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, "远程API保存视频比对任务信息失败!未获取到任务ID"); + } + }else { + return new CommonResult(resultMap, SystemCode.INTERNAL_PROGRAM_ERROR.code, "远程API保存视频比对任务信息失败!未获取OK表示"); + } + }else { + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, "远程API保存视频比对任务信息失败!Map返回未空"); + } + + ControlTask controlTask = new ControlTask(); + controlTask.setTaskNo(strTaskNo); + BeanUtils.copyProperties(controlVO, controlTask); + controlTask.setIsValid(TaskStatusEnum.RUN.code); + controlTask.setViedourl(controlVO.getVideourl()); + controlTask.setDisposalType("-1"); //视频对比 + controlTask.setControlType("0"); + controlTask.setControlObject("0"); + //保存任务 + if (this.save(controlTask)) { + + for (ControlLibraryMid clm : listbibray) { + //设置任务编号 + clm.setIdControlTask(controlTask.getIdControlTask()); + } + //批量 保存库ID列表 + controlLibraryMidService.saveBatch(listbibray); + return new CommonResult(controlTask.getTaskNo(), SystemCode.HANDLER_SUCCESS.code, SystemCode.HANDLER_SUCCESS.des); + } else { + log.error("任务保存:{}", controlTask.getTaskNo()); + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, "保存任务信息失败!"); + } + + } catch (Exception ex) { + log.error("保存任务异常:{}", ex.getMessage()); + return new CommonResult(null, SystemCode.INTERNAL_PROGRAM_ERROR.code, "保存任务信息失败!"+ex.getMessage()); + } + + } + + /** + * 根据任务的区域码表字符串获取区域名称 + * @param regionstr + * @return + */ + @Override + public String getCameraRegionStringByRegionstr(String regionstr) { + + Iterable splits = Splitter.on(",").trimResults().omitEmptyStrings().split(regionstr); + List listregion=new ArrayList<>(); + splits.forEach(region -> listregion.add(Long.parseLong(region))); + if(listregion!=null&&listregion.size()>0){ + List regionnames=controlTaskMapper.getCameraRegionByReginlist(listregion); + return Joiner.on("/").skipNulls().join(regionnames); + } + else{ + return ""; + } + } + + /** + * 根据摄像头列表获取区域的的字符串名称 + * @param cameraRegion + * @return + */ + public String getCameraRegionStringByCameraList(HashMap cameraRegion){ + + if(cameraRegion!=null&&cameraRegion.size()>0) { + List cameralist = new ArrayList<>(); + for (Map.Entry mentry : + cameraRegion.entrySet()) { + cameralist.add(mentry.getKey()); + } + if (cameralist != null && cameralist.size() > 0 && cameralist.size() == 1) { + return getCameraRegionStringByRegionstr(cameralist.get(0)); + } else { + + List list = new ArrayList<>(); + for (String str : cameralist) { + String[] splitarray = str.split(","); + list.add(splitarray); + } + Collections.sort(list, new Comparator() { + @Override + public int compare(String[] o1, String[] o2) { + if (o1.length > o2.length) { + return 1; + } else { + if (o1.length < o2.length) { + { + return -1; + } + } else { + return 0; + } + } + } + }); + + StringBuilder sb = new StringBuilder(); + String[] str = list.get(0); + int count = 0; + for (String[] stra : list) { + if (stra.length == str.length) { + count++; + } + } + if (count >= 2) { + for (int i = 0; i < str.length - 1; i++) { + sb.append(str[i]+","); + } + } else { + for (int i = 0; i < str.length; i++) { + sb.append(str[i]+","); + } + } + return getCameraRegionStringByRegionstr(sb.toString()); + } + } + return ""; + } + + + @Override + public String getLibRegionBytaskid(String taskID) { + + List libsnames=controlTaskMapper.getLibRegionBytaskid(taskID); + if(libsnames!=null){ + return Joiner.on(",").skipNulls().join(libsnames);} + else + {return "";} + + } + + @Override + public ControlTask getTaskInfoByCameraID(String Camera) { + List taskList=controlTaskMapper.getTaskInfoByCameraID(Camera); + if(UtilValidate.isEmpty(taskList) || taskList.size()<=0) + { + return null; + } + return taskList.get(0); + } +} diff --git a/face-server/src/main/java/com/dkha/server/services/impl/FaceCameraServiceImpl.java b/face-server/src/main/java/com/dkha/server/services/impl/FaceCameraServiceImpl.java new file mode 100644 index 0000000..3a6e594 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/impl/FaceCameraServiceImpl.java @@ -0,0 +1,478 @@ +package com.dkha.server.services.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.dkha.common.enums.ApiUrlEnum; +import com.dkha.common.enums.ErrEnum; +import com.dkha.common.enums.YNEnums; +import com.dkha.common.exception.DkException; +import com.dkha.common.http.HttpUtil; +import com.dkha.common.modules.vo.ApiVO; +import com.dkha.common.modules.vo.camera.CameraInfoVO; +import com.dkha.common.page.PageParam; +import com.dkha.common.util.UtilValidate; +import com.dkha.common.util.excel.ImportExcel; +import com.dkha.server.mappers.FaceCameraDao; +import com.dkha.server.modules.entities.FaceCameraEntity; +import com.dkha.server.modules.entities.faceCamera.FaceCameraExcel; +import com.dkha.server.modules.entities.faceCamera.FaceCameraInfo; +import com.dkha.server.modules.entities.faceCamera.FaceCameraList; +import com.dkha.server.modules.entities.faceCamera.InsertFaceCamera; +import com.dkha.server.services.FaceCameraService; +import com.dkha.server.services.IControlBayonetMidService; +import com.dkha.server.system.modules.sys.dao.SysDictDataDao; +import com.dkha.server.system.modules.sys.dao.SysRegionDao; +import com.dkha.server.system.modules.sys.entity.SysDictDataEntity; +import com.dkha.server.system.modules.sys.entity.SysRegionEntity; +import com.dkha.server.system.modules.sys.enums.RegionTopEnum; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.io.IOException; +import java.util.*; + +/** + * 摄像头表 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 2019-12-08 + */ +@Service +public class FaceCameraServiceImpl extends ServiceImpl implements FaceCameraService { + + @Resource + private FaceCameraDao faceCameraDaol; + + @Resource + private HttpUtil httpUtil; + + @Resource + private SysRegionDao sysRegionDao; + @Resource + private SysDictDataDao sysDictDataDao; + @Value("${api.server.prefix}") + private String link; + + @Override + public Page getPage(PageParam pageParam) { + Page page = new Page<>(pageParam.getPageNo(), pageParam.getPageSize()); + //设置模糊查询参数 + Map paramsNote = pageParam.paramsToLike(pageParam.getNote(), "cameraName"); + //分页查询 + List cameraRegion = new ArrayList<>(); + //查询当前区域下的所有摄像头 + if (pageParam.getNote().get("cameraRegion") != null && !"".equals(pageParam.getNote().get("cameraRegion").trim())) { + List> region = sysRegionDao.getRegion1(Long.parseLong(pageParam.getNote().get("cameraRegion"))); + for (Map map : region) { + recursionGetRegion(map); + } + for (Map map : region) { + test(cameraRegion, map); + } + cameraRegion.add(Long.parseLong(pageParam.getNote().get("cameraRegion"))); + } + List faceCameraLists = faceCameraDaol.getList(page, paramsNote, cameraRegion); + + page.setRecords(faceCameraLists); + return page; + } + + @Override + public List getAll(String cameraName) { + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("is_valid", YNEnums.YES.code); + queryWrapper.like(UtilValidate.isNotEmpty(cameraName), "camera_name", cameraName); + List all = this.list(queryWrapper); + return all; + } + + /** + * 获取当前区域下的所有子区域id + * + * @param cameraRegion + * @param map + */ + public void test(List cameraRegion, Map map) { + if (map.get("children") != null) { + List> children = (List>) map.get("children"); + for (Map map1 : children) { + test(cameraRegion, map1); + } + } + cameraRegion.add((Long) map.get("value")); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public Integer insertCamera(InsertFaceCamera insertFaceCamera) { + if (insertFaceCamera == null) { + throw new DkException("参数为空"); + } + //校验经纬度是否重复 + FaceCameraEntity faceCameraInfo = this.findByCoordinate(insertFaceCamera.getCameraLongitude(), insertFaceCamera.getCameraLatitude()); + if (UtilValidate.isNotEmpty(faceCameraInfo)) { + throw new DkException("摄像头经纬度坐标重复"); + } + //摄像头名称,ip,rtsp地址重复性校验 + FaceCameraEntity nameEntity = baseMapper.selectOne(new QueryWrapper().eq("camera_name", insertFaceCamera.getCameraName().trim()).eq("is_valid", YNEnums.YES.code)); + FaceCameraEntity ipEntity = baseMapper.selectOne(new QueryWrapper().eq("ip", insertFaceCamera.getIp().trim()).eq("is_valid", YNEnums.YES.code)); + FaceCameraEntity rtspUrlEntity = baseMapper.selectOne(new QueryWrapper().eq("rtsp_url", insertFaceCamera.getRtspUrl().trim()).eq("is_valid", YNEnums.YES.code)); + //版本码表关联 + SysDictDataEntity brand = sysDictDataDao.selectById(insertFaceCamera.getIdBrand()); + + if (UtilValidate.isEmpty(brand)) { + throw new DkException("摄像头型号不能为空"); + } + insertFaceCamera.setBrand(brand.getDictLabel()); + + if (nameEntity != null) { + throw new DkException("摄像头名称不能重复"); + } + if (ipEntity != null) { + throw new DkException("摄像头ip不能重复"); + } + if (rtspUrlEntity != null) { + throw new DkException("摄像头rtsp地址不能重复"); + } + Map map = new HashMap(); + map.put("name", insertFaceCamera.getCameraName()); + map.put("url", insertFaceCamera.getRtspUrl()); + ApiVO result = httpUtil.post(link + ApiUrlEnum.CAMERA.getUrl(), map, ApiVO.class); + if (result == null || !ErrEnum.OK.getCode().equals(result.getCode())) { + throw new DkException("新增摄像头失败"); + } + FaceCameraEntity faceCameraEntity = new FaceCameraEntity(); + BeanUtils.copyProperties(insertFaceCamera, faceCameraEntity); + faceCameraEntity.setStatus(YNEnums.NO.code); + JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(result.getData())); + faceCameraEntity.setIdFaceCamera(Long.parseLong(jsonObject.getString("carmeraId"))); + String[] regions = faceCameraEntity.getCameraRegionFirstlevel().split(","); + faceCameraEntity.setCameraRegion(regions[regions.length - 1]); + faceCameraEntity.setCameraRegionFirstlevelBackUp(""); + //翻译摄像头区域层级冗余字段 + for (String region : regions) { + SysRegionEntity sysRegionEntity = sysRegionDao.getById(Long.parseLong(region)); + faceCameraEntity.setCameraRegionFirstlevelBackUp(faceCameraEntity.getCameraRegionFirstlevelBackUp() + sysRegionEntity.getName()); + } +// //TODO 摄像头位置类型码值翻译 +// SysDictDataEntity sysDictDataEntity = sysDictDataDao.selectById(faceCameraEntity.getCameratLocationtypeId()); +// faceCameraEntity.setCameratLocationtypeIdBackUp(sysDictDataEntity.getDictLabel()); + + return baseMapper.insert(faceCameraEntity); + } + + @Override + public FaceCameraInfo findById(long idCamera) { + FaceCameraEntity faceCameraEntity = baseMapper.selectById(idCamera); + FaceCameraInfo faceCameraInfo = new FaceCameraInfo(); + if(faceCameraEntity != null){ + BeanUtils.copyProperties(faceCameraEntity, faceCameraInfo); + } + return faceCameraInfo; + + } + + @Override + public List> getAllCameraByRegionId(long regionId) { + + List cameraRegion = new ArrayList<>(); + List> region = sysRegionDao.getRegion1(regionId); + for (Map map : region) { + recursionGetRegion(map); + } + for (Map map : region) { + test(cameraRegion, map); + } + cameraRegion.add(regionId); + + + return baseMapper.getAllCameraByRegionId(cameraRegion); + } + + @Override + public List> getCameraByRegionId(long regionId) { + List> result = baseMapper.getCameraByRegionId(regionId); +// return ConvertUtils.sourceToTarget(baseMapper.selectList(new QueryWrapper() +// .eq("is_valid", YNEnums.YES.code) +// .eq("camera_region", regionId)), FaceCameraInfo.class); + return result; + } + + @Override + public List> getRegionUnControlCamera(long regionId) { + + return baseMapper.getRegionUnControlCamera(regionId); + } + + @Override + public List> getRegion(Long pid) { + /** + * 获取所有第一级摄像头区域 + */ + List> region = sysRegionDao.getRegion1(pid); + //遍历获取所有子级摄像头区域 + for (Map map : region) { + recursionGetRegion(map); + } + return region; + } + + @Override + public List> getBayonet(Long pid) { + List> result = new LinkedList<>(); + + //获取当前id下的区域 + List> region = sysRegionDao.getRegion(pid); + //获取当期区域下的所有有布控任务的摄像头 + List> camera = baseMapper.findByRegion(String.valueOf(pid)); + result.addAll(region); + result.addAll(camera); + List> copyRegion = new ArrayList<>(); + copyRegion.addAll(region); + for (int i = 0; i < copyRegion.size(); i++) { + int count = baseMapper.isCameraInRegion("%" + (Long) copyRegion.get(i).get("id") + "%"); + if (count < 1) { + region.remove(copyRegion.get(i)); + continue; + } + if (copyRegion.get(i).get("type") != null && ((String) copyRegion.get(i).get("type")).endsWith("region")) { + region.get(region.indexOf(copyRegion.get(i))).put("label", region.get(region.indexOf(copyRegion.get(i))).get("label") + "(区域)"); + } + recursionGetBayonet(region.get(i)); + } + for (Map map : camera) { + if (map.get("type") != null && ((String) map.get("type")).endsWith("camera")) { + map.put("label", map.get("label") + "(摄像头)"); + } + } + + return result; + } + + /** + * 递归获取所有摄像头区域 + * + * @param resoure + */ + public void recursionGetRegion(Map resoure) { + long id = resoure.get("value") == null ? RegionTopEnum.FATHER.value() : (Long) resoure.get("value"); + + List> region = sysRegionDao.getRegion1(id); + if (region != null && region.size() != 0) { + for (Map map : region) { + recursionGetRegion(map); + } + resoure.put("children", region); + } + } + + /** + * 递归 获取摄像头区域 + * + * @param resoure + */ + public void recursionGetBayonet(Map resoure) { + long id = resoure.get("id") == null ? RegionTopEnum.FATHER.value() : (Long) resoure.get("id"); + + List> result = new LinkedList<>(); + List> region = sysRegionDao.getRegion(id); + List> copyRegion = new ArrayList<>(); + copyRegion.addAll(region); + List> camera = baseMapper.findByRegion(String.valueOf(id)); + if (region != null && region.size() != 0) { + + for (int i = 0; i < copyRegion.size(); i++) { + int count = baseMapper.isCameraInRegion("%" + (Long) copyRegion.get(i).get("id") + "%"); + if (count < 1) { + region.remove(copyRegion.get(i)); + continue; + } + if (copyRegion.get(i).get("type") != null && ((String) copyRegion.get(i).get("type")).endsWith("region")) { + region.get(region.indexOf(copyRegion.get(i))).put("label", region.get(region.indexOf(copyRegion.get(i))).get("label") + "(区域)"); + } + recursionGetBayonet(copyRegion.get(i)); + } + } + for (Map map : camera) { + if (map.get("type") != null && ((String) map.get("type")).endsWith("camera")) { + map.put("label", map.get("label") + "(摄像头)"); + } + } + result.addAll(region); + result.addAll(camera); + resoure.put("children", result); + + } + + @Transactional(rollbackFor = Exception.class) + @Override + public Integer update(FaceCameraInfo faceCameraInfo) { + FaceCameraEntity faceCameraEntity = baseMapper.selectById(faceCameraInfo.getIdFaceCamera()); + if (faceCameraEntity == null) { + throw new DkException("无此摄像头"); + } + FaceCameraEntity old = this.findByCoordinate(faceCameraInfo.getCameraLongitude(), faceCameraInfo.getCameraLatitude()); + if (UtilValidate.isNotEmpty(old) && !faceCameraEntity.getIdFaceCamera().equals(old.getIdFaceCamera())) { + throw new DkException("摄像头经纬度坐标重复"); + } + FaceCameraEntity nameEntity = baseMapper.selectOne(new QueryWrapper().eq("camera_name", faceCameraInfo.getCameraName().trim()).eq("is_valid", YNEnums.YES.code)); + FaceCameraEntity ipEntity = baseMapper.selectOne(new QueryWrapper().eq("ip", faceCameraInfo.getIp().trim()).eq("is_valid", YNEnums.YES.code)); + FaceCameraEntity rtspUrlEntity = baseMapper.selectOne(new QueryWrapper().eq("rtsp_url", faceCameraInfo.getRtspUrl().trim()).eq("is_valid", YNEnums.YES.code)); + //摄像头名称,ip,rtsp地址重复性校验 + if (nameEntity != null && !nameEntity.getIdFaceCamera().equals(faceCameraInfo.getIdFaceCamera())) { + throw new DkException("摄像头名称不能重复"); + } + if (ipEntity != null && !ipEntity.getIdFaceCamera().equals(faceCameraInfo.getIdFaceCamera())) { + throw new DkException("摄像头ip不能重复"); + } + if (rtspUrlEntity != null && !rtspUrlEntity.getIdFaceCamera().equals(faceCameraInfo.getIdFaceCamera())) { + throw new DkException("摄像头rtsp地址不能重复"); + } + //版本码表关联 + SysDictDataEntity brand = sysDictDataDao.selectById(faceCameraInfo.getIdBrand()); + if (UtilValidate.isNotEmpty(brand)) { + faceCameraEntity.setIdBrand(brand.getDictTypeId().toString()); + faceCameraEntity.setBrand(brand.getDictLabel()); + } else { + throw new DkException("摄像头品牌不能为空"); + } + Map map = new HashMap(0); + //判断是否修改了名称,rtsp + if (!faceCameraEntity.getCameraName().equals(faceCameraInfo.getCameraName()) || + !faceCameraEntity.getRtspUrl().equals(faceCameraInfo.getRtspUrl())) { + map.put("name", faceCameraInfo.getCameraName()); + map.put("url", faceCameraInfo.getRtspUrl()); + map.put("carmeraId", faceCameraInfo.getIdFaceCamera()); + ApiVO result = httpUtil.put(link + ApiUrlEnum.CAMERA.getUrl(), map, ApiVO.class); + if (result == null || !ErrEnum.OK.getCode().equals(result.getCode())) { + throw new DkException("修改摄像头失败"); + } + } + BeanUtils.copyProperties(faceCameraInfo, faceCameraEntity); + //摄像头区域类型修改 + faceCameraEntity.setCameraRegionFirstlevel(null); + faceCameraEntity.setCameraRegionFirstlevelBackUp(""); + String[] regionFirstlevelArrays = faceCameraInfo.getCameraRegionFirstlevelArrays(); + faceCameraEntity.setCameraRegion(String.valueOf(regionFirstlevelArrays[regionFirstlevelArrays.length - 1])); + for (String regionId : regionFirstlevelArrays) { + SysRegionEntity sysRegionEntity = sysRegionDao.getById(Long.parseLong(regionId)); + faceCameraEntity.setCameraRegionFirstlevelBackUp(faceCameraEntity.getCameraRegionFirstlevelBackUp() + sysRegionEntity.getName()); + } + faceCameraEntity.setCameraRegionFirstlevel(StringUtils.join(regionFirstlevelArrays, ',')); +// //摄像头位置类型修改 +// SysDictDataEntity sysDictDataEntity = sysDictDataDao.selectById(faceCameraInfo.getCameratLocationtypeId()); +// faceCameraEntity.setCameratLocationtypeIdBackUp(sysDictDataEntity.getDictLabel()); + //TODO 摄像头位置类型码值翻译 + + return baseMapper.updateById(faceCameraEntity); + } + + @Autowired + private IControlBayonetMidService iControlBayonetMidService; + + @Transactional(rollbackFor = Exception.class) + @Override + public List findCameraByTask() { + return iControlBayonetMidService.selectFaceCameraBytask(); + } + + + @Transactional + @Override + public Integer delete(long camera) { + FaceCameraEntity entity = baseMapper.selectById(camera); + if (entity == null) { + throw new DkException("无此摄像头"); + } + + //验证摄像头是否已经布控了任务 + + Long res = iControlBayonetMidService.selectexistByCarmeID(String.valueOf(camera)); + if (res.intValue() > 0) { + throw new DkException("删除摄像头失败,当前摄像头存在布控任务"); + } + + + ApiVO result = httpUtil.delete(link + ApiUrlEnum.CAMERA.getUrl() + "/" + camera, ApiVO.class); + if (result == null || !ErrEnum.OK.getCode().equals(result.getCode())) { + throw new DkException("删除摄像头失败"); + } + entity.setIsValid(YNEnums.NO.code); + return baseMapper.updateById(entity); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public Integer status(long camera, boolean status) { + FaceCameraEntity entity = baseMapper.selectById(camera); + if (status) { + entity.setStatus(YNEnums.YES.code); + } else { + entity.setStatus(YNEnums.NO.code); + } + return baseMapper.updateById(entity); + } + + @Override + public List importExcel(MultipartFile multipartFile) { + List errorList = new ArrayList<>(0); + try { + ImportExcel ei = new ImportExcel(multipartFile, 1, 0); + List cameraExcels = ei.getDataList(FaceCameraExcel.class); + + for (FaceCameraExcel faceCameraExcel : cameraExcels) { + //TODO 数据校验空 + if (checkNull(errorList, faceCameraExcel)) { + continue; + } + //码表关联查询 + + } + } catch (InvalidFormatException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + + return errorList; + } + + private boolean checkNull(List error, FaceCameraExcel faceCameraExcel) { + //空值校验 + if (UtilValidate.isEmpty(faceCameraExcel.getIp())) { + faceCameraExcel.setMessage("ip地址不能为空"); + error.add(faceCameraExcel); + return true; + } + + return false; + } + + @Override + public FaceCameraEntity findByCoordinate(String cameraLongitude, String cameraLatitude) { + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq(FaceCameraEntity.CAMERA_LONGITUDE, cameraLongitude); + queryWrapper.eq(FaceCameraEntity.CAMERA_LATITUDE, cameraLatitude); + FaceCameraEntity faceCameraEntity = baseMapper.selectOne(queryWrapper); + return faceCameraEntity; + } + + @Override + public CameraInfoVO selectFaceCameraID(String idFaceCamera) { + return baseMapper.selectFaceCameraID(idFaceCamera); + } +} diff --git a/face-server/src/main/java/com/dkha/server/services/impl/FaceLibraryServiceImpl.java b/face-server/src/main/java/com/dkha/server/services/impl/FaceLibraryServiceImpl.java new file mode 100644 index 0000000..71085db --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/impl/FaceLibraryServiceImpl.java @@ -0,0 +1,179 @@ +package com.dkha.server.services.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dkha.common.enums.ApiUrlEnum; +import com.dkha.common.enums.YNEnums; +import com.dkha.common.exception.DkException; +import com.dkha.common.fileupload.MinioUtil; +import com.dkha.common.http.HttpUtil; +import com.dkha.common.modules.vo.ApiVO; +import com.dkha.common.modules.vo.dto.FaceLibraryVO; +import com.dkha.common.page.PageParam; +import com.dkha.common.redis.RedisUtils; +import com.dkha.common.systemcode.SystemCode; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.mappers.ControlLibraryMidMapper; +import com.dkha.server.mappers.PortraitMapper; +import com.dkha.server.modules.entities.FaceLibrary; +import com.dkha.server.mappers.FaceLibraryMapper; +import com.dkha.server.modules.entities.Portrait; +import com.dkha.server.services.IFaceLibraryService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.google.gson.Gson; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; + +/** + *

+ * 库表 服务实现类 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Service +public class FaceLibraryServiceImpl extends ServiceImpl implements IFaceLibraryService { + /**库mapper*/ + @Resource + private FaceLibraryMapper faceLibraryMapper; + @Resource + private ControlLibraryMidMapper controlLibraryMidMapper; + @Resource + private PortraitMapper portraitMapper; + + @Value("${api.server.prefix}") + private String link; + @Resource + private HttpUtil httpUtil; + @Autowired + private Gson gson; + @Autowired + private MinioUtil minioUtil; + @Autowired + private RedisUtils redisUtils; + @Value("${api.server.prefix}") + private String apiRequestPrefix; + @Value("${minio.bucketName}") + private String bucketName; + + @Override + @Transactional(rollbackFor = Exception.class) + public FaceLibrary addLibrary(FaceLibrary faceLibrary) { + try { + FaceLibraryVO faceLibraryVO = new FaceLibraryVO(); + faceLibraryVO.setName(faceLibrary.getFactoryName()); + if(UtilValidate.isNotEmpty(faceLibrary.getFactoryType())) { + faceLibraryVO.setType(faceLibrary.getFactoryType()); + } + ApiVO faceLibrary1 = (ApiVO) httpUtil.post(link+ ApiUrlEnum.FACELIB_POSTURL.getUrl(), faceLibraryVO, ApiVO.class); + /**调用API*/ + String json = gson.toJson(faceLibrary1.getData()); + FaceLibraryVO face = gson.fromJson(json, FaceLibraryVO.class); + faceLibrary.setIdFactory(Long.parseLong(face.getLibraryId())); + int insert = faceLibraryMapper.insert(faceLibrary); + if(insert<0){ + throw new DkException("新增库失败"); + } + }catch (Exception e){ + throw new DkException("新增库失败"+e.getMessage()); + } + return faceLibrary; + } + + @Override + public FaceLibrary deleteLibrary(Long libraryId) { + FaceLibrary faceLibrary = new FaceLibrary(); + faceLibrary.setIsValid(YNEnums.NO.code); + faceLibrary.setIdFactory(libraryId); + try { + + ApiVO faceLibrary1 = (ApiVO) httpUtil.delete(link+ ApiUrlEnum.FACELIB_POSTURL.getUrl()+"/"+String.valueOf(libraryId), ApiVO.class); + }catch (Exception e){ + throw new DkException("删除库失败"); + } + /**调用API*/ + Integer integer = controlLibraryMidMapper.selectByLibID(String.valueOf(libraryId), YNEnums.YES.code); + if(integer<=0) { + int count = faceLibraryMapper.deleteById(faceLibrary); + /**删除对应的人像*/ + List portraits = portraitMapper.queryPortraitByFactory(libraryId); + portraitMapper.deletePortrait(libraryId); + if(UtilValidate.isNotEmpty(portraits)){ + for (Portrait p:portraits) { + /**删除文件服务器*/ + try { + minioUtil.removeObject(bucketName,p.getUrl()); + } catch (Exception e) { + log.error(e.getMessage()); + //throw new DkException("文件服务器图片删除失败"); + } + } + } + if (count < 0) { + throw new DkException("删除库失败"); + } + }else{ + throw new DkException(SystemCode.DELETELIB_ERROR.code,"该库有关联的布控信息,不能删除!"); + } + + return faceLibrary; + } + + @Override + public FaceLibrary updateLibrary(FaceLibrary faceLibrary) { + try { + int count = faceLibraryMapper.updateById(faceLibrary); + FaceLibraryVO faceLibraryVO = new FaceLibraryVO(); + faceLibraryVO.setName(faceLibrary.getFactoryName()); + faceLibraryVO.setLibraryId(String.valueOf(faceLibrary.getIdFactory())); + ApiVO face = (ApiVO) httpUtil.put(link+ ApiUrlEnum.FACELIB_POSTURL.getUrl(),faceLibraryVO, ApiVO.class); + if(!face.getMessage().equals("成功")) { + throw new DkException("wy修改库失败"); + } + }catch (Exception e){ + log.error(e.getMessage()); + throw new DkException("修改库失败"); + } + return faceLibrary; + } + + @Override + public Page queryLibrary(PageParam pageParam) { + /**创建page对象*/ + Page page = new Page<>(pageParam.getPageNo(), pageParam.getPageSize()); + /**设置模糊查询参数*/ + Map paramsNote = pageParam.getNote(); + + /**分页查询*/ + List postList = faceLibraryMapper.getLibraryPage(page, paramsNote.get("factoryName")); + if(UtilValidate.isNotEmpty(postList)){ + for (FaceLibrary p: postList) { + Integer libraryCount = faceLibraryMapper.getLibraryCount(p.getIdFactory()); + if(libraryCount>0) { + p.setNumber(String.valueOf(libraryCount)); + }else{ + p.setNumber("0"); + } + } + + } + page.setRecords(postList); + return page; + } + + @Override + public List findFaceLibraries() { + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("is_valid", YNEnums.YES.code); + queryWrapper.orderByDesc("create_time"); + return baseMapper.selectList(queryWrapper); + } + +} diff --git a/face-server/src/main/java/com/dkha/server/services/impl/FaceTrackServiceImpl.java b/face-server/src/main/java/com/dkha/server/services/impl/FaceTrackServiceImpl.java new file mode 100644 index 0000000..dd8089b --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/impl/FaceTrackServiceImpl.java @@ -0,0 +1,93 @@ +package com.dkha.server.services.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.dkha.common.exception.DkException; + +import com.dkha.common.modules.vo.face.FaceTrackVO; +import com.dkha.server.mappers.FaceTrackMapper; +import com.dkha.server.modules.entities.FaceTrackEntity; +import com.dkha.server.services.FaceTrackService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + + +/** + * + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 2020-01-10 + */ +@Service +public class FaceTrackServiceImpl extends ServiceImpl implements FaceTrackService { + + @Resource + private FaceTrackMapper faceTrackMapper; + @Override + public int addFaceTrackEntity(FaceTrackEntity faceTrackEntity) { + int count; + try{ + count = faceTrackMapper.insert(faceTrackEntity); + }catch (Exception e){ + throw new DkException("新增失败"); + } + return count; + } + + /** + *根据摄像头和分组时间查询 + * @param idFaceCamera + * @param packetTime + * @return + */ + @Override + public List querByidCameraAndTime(Long idFaceCamera, String packetTime) { + return faceTrackMapper.querByidCameraAndTime(idFaceCamera,packetTime); + } + + /** + *根据摄像头Id和开始,结束时间,人脸ID + * @param faceTrackVO + * @return + */ + @Override + public List queryByidCamerAndFaceId(FaceTrackVO faceTrackVO) { + return faceTrackMapper.queryByidCamerAndFaceId(faceTrackVO); + } + + /** + *根据图片路径和开始,结束时间 + * @param faceTrackVO + * @return + */ + @Override + public List queryByurlAndTime(FaceTrackVO faceTrackVO) { + return faceTrackMapper.queryByurlAndTime(faceTrackVO); + } + + @Override + public List findIdFatoryByTime(FaceTrackVO faceTrackVO) { + return faceTrackMapper.findIdFatoryByTime(faceTrackVO); + } + + /** + *根据图片路径和开始,结束时间和阈值 + * @param faceTrackVO + * @return + */ + @Override + public List queryBytrajectoryThreshold(FaceTrackVO faceTrackVO) { + return faceTrackMapper.queryBytrajectoryThreshold(faceTrackVO); + } + + @Override + public List findTrackByFaceId(List faceIds) { + return faceTrackMapper.findTrackByFaceId(faceIds); + } + + @Override + public FaceTrackEntity queryByIdPortrait(String idPortrait) { + return faceTrackMapper.queryByIdPortrait(idPortrait); + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/services/impl/FileServiceImpl.java b/face-server/src/main/java/com/dkha/server/services/impl/FileServiceImpl.java new file mode 100644 index 0000000..ae2f160 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/impl/FileServiceImpl.java @@ -0,0 +1,191 @@ +package com.dkha.server.services.impl; + +import com.alibaba.fastjson.JSONObject; +import com.dkha.common.enums.ApiUrlEnum; +import com.dkha.common.exception.DkException; +import com.dkha.common.fileupload.MinioUtil; +import com.dkha.common.http.HttpUtil; +import com.dkha.common.modules.vo.ReturnVO; +import com.dkha.common.modules.vo.cut.CutVo; +import com.dkha.common.modules.vo.face.ApiSearchFaceRectVO; +import com.dkha.common.modules.vo.position.PositionVO; +import com.dkha.common.modules.vo.upload.ImageUploadResult; +import com.dkha.common.util.Base64ImageUtils; +import com.dkha.common.util.IntUUID; +import com.dkha.common.util.JsonUtil; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.services.IFileService; +import com.fasterxml.jackson.core.type.TypeReference; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.InputStream; +import java.net.URL; +import java.util.*; +import java.util.regex.Pattern; + +/** + * @Author Spring + * @Since 2019/12/11 15:41 + * @Description 文件上传相关 + */ +@Component +@Slf4j +public class FileServiceImpl implements IFileService { + + @Value("${api.server.prefix}") + private String apiRequestPrefix; + @Autowired + private HttpUtil httpUtil; + @Autowired + private MinioUtil minioUtil; + @Value("${api.picture.type}") + private String apiPictureType; + + @Override + public ImageUploadResult uploadMultiFaceImages(MultipartFile[] multipartFiles) throws Exception { + if (UtilValidate.isEmpty(multipartFiles)) { + throw new DkException("请上传图片"); + } + List imageUrlList = new ArrayList<>(); + for (MultipartFile file : multipartFiles) { + JSONObject map = minioUtil.uploadFile(file.getInputStream(), this.generateFileName(file.getOriginalFilename()), null); + if (UtilValidate.isNotEmpty(map) && map.get("flag").equals("0")) { + imageUrlList.add(map.get("url").toString()); + } else { + throw new DkException("文件上传异常"); + } + } + return this.validateMultiFaceImages(imageUrlList); + } + + @Override + public ImageUploadResult uploadSingleFaceImage(MultipartFile[] multipartFiles) throws Exception { + if (UtilValidate.isEmpty(multipartFiles)) { + throw new DkException("请上传图片"); + } + if (multipartFiles.length > 1) { + throw new DkException("只能上传单张图片"); + } + + List imageUrlList = new ArrayList<>(); + for (MultipartFile file : multipartFiles) { + //获取文件后缀 + JSONObject map = minioUtil.uploadFile(file.getInputStream(), this.generateFileName(file.getOriginalFilename()) , null); + if (UtilValidate.isNotEmpty(map) && map.get("flag").equals("0")) { + imageUrlList.add(map.get("url").toString()); + } else { + throw new DkException("文件上传异常"); + } + } + this.validateSingleFaceImage(imageUrlList); + ImageUploadResult imageUploadResult = new ImageUploadResult(); + imageUploadResult.setSuccessFiles(imageUrlList.size()); + imageUploadResult.setSuccessFileUrlList(imageUrlList); + return imageUploadResult; + } + + @Override + public String cutPicture(CutVo cutVo) throws Exception { + PositionVO positionVO = new PositionVO(); + positionVO.setH(cutVo.getH()); + positionVO.setW(cutVo.getW()); + positionVO.setX(cutVo.getX()); + positionVO.setY(cutVo.getY()); + BufferedImage bufferedImage = ImageIO.read(new URL(cutVo.getUrl())); +// positionVO = Base64ImageUtils.deelPostion(positionVO, bufferedImage.getWidth(), bufferedImage.getHeight()); + InputStream inputStream = Base64ImageUtils.encodeHeadImage(bufferedImage, positionVO); + String fileName = this.generateFileName(cutVo.getUrl()); + JSONObject map = minioUtil.uploadFile(inputStream, fileName, null); + if (UtilValidate.isNotEmpty(map) && map.get("flag").equals("0")) { + return map.get("url").toString(); + } + throw new DkException("文件上传异常"); + } + + /** + * 单图上传,其中一张图只能有一张人脸 校验 + * @param images 图片路径集合 + */ + private ImageUploadResult validateMultiFaceImages(List images) { + //人脸检测url + String faceSearchUrl = apiRequestPrefix + ApiUrlEnum.FACE_SEARCH.getUrl(); + //组织返回结果集 + ImageUploadResult imageUploadResult = new ImageUploadResult(); + for (String image : images) { + //组装api请求数据 + ReturnVO returnVO = (ReturnVO) httpUtil.post(faceSearchUrl + "?url=" + image, null, ReturnVO.class); + if (returnVO.getCode() != 200) { + throw new DkException(returnVO.getMessage()); + } + //反序列化 + List apiSearchFaceRectVOList = JsonUtil.string2Obj(JsonUtil.obj2String(returnVO.getData()), new TypeReference>() {}); + if (UtilValidate.isEmpty(apiSearchFaceRectVOList)) { + throw new DkException("当前上传中未检测到人脸,请重新上传"); + } + //检测成功集合 + List successUrlList = new ArrayList<>(); + for (ApiSearchFaceRectVO apiSearchFaceRectVO : apiSearchFaceRectVOList) { + successUrlList.add(apiSearchFaceRectVO.getUrl()); + } + imageUploadResult.setSuccessFileUrlList(successUrlList); + imageUploadResult.setSuccessFiles(successUrlList.size()); + imageUploadResult.setFailFiles(images.size() - successUrlList.size()); + imageUploadResult.setTotalFiles(images.size()); + } + return imageUploadResult; + } + + /** + * 多图/单图上传,其中一张图可以多人脸/单人脸 校验 + * @param images + */ + private void validateSingleFaceImage(List images) { + //人脸检测url + String faceSearchUrl = apiRequestPrefix + ApiUrlEnum.FACE_SEARCH.getUrl(); + for (String image : images) { + //组装api请求数据 + ReturnVO returnVO = (ReturnVO) httpUtil.post(faceSearchUrl + "?url=" + image, null, ReturnVO.class); + if (returnVO.getCode() != 200) { + throw new DkException(returnVO.getMessage()); + } + //反序列化 + List apiSearchFaceRectVOList = JsonUtil.string2Obj(JsonUtil.obj2String(returnVO.getData()), new TypeReference>() {}); + if (UtilValidate.isEmpty(apiSearchFaceRectVOList)) { + throw new DkException("当前上传中未检测到人脸,请重新上传"); + } + if (apiSearchFaceRectVOList.size() > 1) { + throw new DkException("当前上传图片检测到多张人脸,请重新上传"); + } + } + } + + /** + * 生成唯一文件名 + * @param originFileName + * @return + */ + private String generateFileName(String originFileName) { + // todo 迁移到资源文件中 + //当前时间 + long timeMillis = System.currentTimeMillis(); + int shortUUID = IntUUID.getShortUUID(); + if (!originFileName.contains(".")) { + throw new DkException("文件名格式错误"); + } + String[] originalFileNameCompose = originFileName.split("\\."); + //获取原文件后缀 + String originalFileNameSuffix = originalFileNameCompose[originalFileNameCompose.length - 1]; + Pattern p = Pattern.compile(apiPictureType); + boolean flag = p.matcher(originalFileNameSuffix).find(); + if (!flag) { + throw new DkException("请上传.jpg .png .jpeg类型的图片"); + } + return timeMillis + "-" + shortUUID + "." + originalFileNameSuffix; + } +} diff --git a/face-server/src/main/java/com/dkha/server/services/impl/PortraitServiceImpl.java b/face-server/src/main/java/com/dkha/server/services/impl/PortraitServiceImpl.java new file mode 100644 index 0000000..952b915 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/impl/PortraitServiceImpl.java @@ -0,0 +1,700 @@ +package com.dkha.server.services.impl; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dkha.common.enums.ApiUrlEnum; +import com.dkha.common.enums.YNEnums; +import com.dkha.common.exception.DkException; +import com.dkha.common.fileupload.MinioUtil; +import com.dkha.common.http.HttpUtil; +import com.dkha.common.modules.vo.ApiVO; +import com.dkha.common.modules.vo.ReturnVO; +import com.dkha.common.modules.vo.face.*; +import com.dkha.common.modules.vo.search.SearchPortraitVo; +import com.dkha.common.modules.vo.search.SearchRequestVo; +import com.dkha.common.modules.vo.search.SearchResultVo; +import com.dkha.common.page.PageParam; +import com.dkha.common.systemcode.SystemCode; +import com.dkha.common.util.DateUtils; +import com.dkha.common.util.IdCardUtil; +import com.dkha.common.util.JsonUtil; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.modules.entities.Portrait; +import com.dkha.server.mappers.PortraitMapper; +import com.dkha.server.services.IPortraitService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fasterxml.jackson.core.type.TypeReference; +import com.google.gson.Gson; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Collections; +import java.util.Date; +import java.util.*; + +/** + *

+ * 人像表 服务实现类 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Service +public class PortraitServiceImpl extends ServiceImpl implements IPortraitService { + @Autowired + private MinioUtil minioUtil; + + @Resource + private PortraitMapper portraitMapper; + @Value("${api.server.prefix}") + private String link; + @Resource + private HttpUtil httpUtil; + @Autowired + private Gson gson; + @Value("${api.server.prefix}") + private String apiRequestPrefix; + @Value("${api.max.result}") + private String apiMaxResult; + @Value("${minio.bucketName}") + private String bucketName; + + @Override + @Transactional(rollbackFor = Exception.class) + public Portrait addPortrait(String libraryId, MultipartFile multipartFile) { + /**保存数据*/ + Portrait portrait; + String[] identityMessage = new String[2]; + String multipartFileName = multipartFile.getOriginalFilename(); + if (UtilValidate.isNotEmpty(multipartFileName)) { + boolean status = multipartFileName.contains("_"); + if (status) { + String filename = multipartFileName.substring(0, multipartFileName.lastIndexOf(".")); + identityMessage = filename.split("_"); + } else { + throw new DkException(SystemCode.FILE_ERROR.code, multipartFileName + "文件名格式不正确"); + } + } + ImagesVO imageVO = new ImagesVO(); + setimageVO(imageVO, identityMessage); + try { + String card = imageVO.getIdCard(); + int hash = card.hashCode(); + if (hash < 0) { + hash = 0 - hash; + } + JSONObject map = minioUtil.uploadFiles(multipartFile.getInputStream(), String.valueOf(hash % 500), multipartFile.getOriginalFilename(), null); + map.get("url"); + imageVO.setNation(""); + imageVO.setUrl(map.get("url").toString()); + imageVO.setLibraryId(libraryId); + } catch (Exception e) { + throw new DkException(multipartFileName + "文件上传失败"); + } + //imagesVO.setFaces(faces); + /**调用微云新增人像*/ + ApiVO face = (ApiVO) httpUtil.post(link + ApiUrlEnum.FACE_POSTURL.getUrl(), imageVO, ApiVO.class); + String json = gson.toJson(face.getData()); + ImageReturnVO imageReturnVO = null; + if (UtilValidate.isNotEmpty(json)) { + imageReturnVO = gson.fromJson(json, ImageReturnVO.class); + } + if (UtilValidate.isNotEmpty(imageReturnVO)) { + portrait = save(imageReturnVO, imageVO); + } else { + throw new DkException(SystemCode.FACESRH_ERROR.code, face.getMessage()); + } + return portrait; + } + + @Override + public List pictureDetection(MultipartFile multipartFile) throws Exception { + //人脸检测url + String faceSearchUrl = apiRequestPrefix + ApiUrlEnum.FACE_SEARCH.getUrl(); + //组织返回结果集 + String uuid = UUID.randomUUID().toString().replaceAll("-", ""); + int hash = uuid.hashCode(); + if (hash < 0) { + hash = 0 - hash; + } + JSONObject map; + try { + map = minioUtil.uploadFiles(multipartFile.getInputStream(), String.valueOf(hash % 500), uuid, null); + } catch (Exception e) { + throw new DkException(multipartFile.getOriginalFilename() + "文件上传失败"); + } + //组装api请求数据 + ReturnVO returnVO = (ReturnVO) httpUtil.post(faceSearchUrl + "?url=" + map.getString("url"), null, ReturnVO.class); + if (returnVO.getCode() != 200) { + throw new DkException(returnVO.getMessage()); + } + //反序列化 + List apiSearchFaceRectVOList = JsonUtil.string2Obj(JsonUtil.obj2String(returnVO.getData()), new TypeReference>() { + }); + if (UtilValidate.isEmpty(apiSearchFaceRectVOList)) { + try { + minioUtil.removeObject(bucketName, map.getString("url")); + } catch (Exception e) { + throw new DkException("删除人脸失败"); + } + throw new DkException("当前上传中未检测到人脸,请重新上传"); + } + + return apiSearchFaceRectVOList; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Portrait addPortraitPng(String libraryId, MultipartFile multipartFile) { + /**保存数据*/ + Portrait portrait; + String multipartFileName = multipartFile.getOriginalFilename(); + ImagesVO imageVO = new ImagesVO(); + try { + JSONObject map = minioUtil.uploadFile(multipartFile.getInputStream(), multipartFile.getOriginalFilename(), null); + imageVO.setNation(""); + imageVO.setUrl(map.get("url").toString()); + imageVO.setLibraryId(libraryId); + } catch (Exception e) { + throw new DkException(multipartFileName + "文件上传失败"); + } + //setimageVO(imageVO, s); + //imagesVO.setFaces(faces); + /**调用微云新增人像*/ + ApiVO face = (ApiVO) httpUtil.post(link + ApiUrlEnum.FACE_POSTURL.getUrl(), imageVO, ApiVO.class); + String json = gson.toJson(face.getData()); + ImageReturnVO imageReturnVO = null; + if (UtilValidate.isNotEmpty(json)) { + imageReturnVO = gson.fromJson(json, ImageReturnVO.class); + } + if (UtilValidate.isNotEmpty(imageReturnVO)) { + portrait = save(imageReturnVO, imageVO); + } else { + throw new DkException(SystemCode.FACESRH_ERROR.code, face.getMessage()); + } + return portrait; + } + + @Override + public Portrait addPortraitPngs(String libraryId, String multipartFile) { + /**保存数据*/ + Portrait portrait; + ImagesVO imageVO = new ImagesVO(); + imageVO.setNation(""); + imageVO.setUrl(multipartFile); + imageVO.setLibraryId(libraryId); + /**调用微云新增人像*/ + ApiVO face = (ApiVO) httpUtil.post(link + ApiUrlEnum.FACE_POSTURL.getUrl(), imageVO, ApiVO.class); + String json = gson.toJson(face.getData()); + ImageReturnVO imageReturnVO = null; + if (UtilValidate.isNotEmpty(json)) { + imageReturnVO = gson.fromJson(json, ImageReturnVO.class); + } + if (UtilValidate.isNotEmpty(imageReturnVO)) { + portrait = save(imageReturnVO, imageVO); + } else { + throw new DkException(SystemCode.FACESRH_ERROR.code, face.getMessage()); + } + return portrait; + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public List addPortraits(String libraryId, MultipartFile[] files) { + List list = new ArrayList<>(); + try { + //判断file数组不能为空并且长度大于0 + if (files != null && files.length > 0) { + for (int i = 0; i < files.length; i++) { + JSONObject map = minioUtil.uploadFile(files[i].getInputStream(), files[i].getOriginalFilename(), null); + map.get("path"); + String[] message = new String[4]; + String multipartFileName = files[i].getOriginalFilename(); + if (UtilValidate.isNotEmpty(multipartFileName)) { + String filename = multipartFileName.substring(0, multipartFileName.lastIndexOf(".")); + message = filename.split("_"); + } + /**文件名:身份证_姓名*/ + ImagesVO imageVO = new ImagesVO(); + setimageVO(imageVO, message); + imageVO.setUrl(map.get("url").toString()); + List faces = new ArrayList<>(); + //faces.add(imageVO); + imageVO.setLibraryId(libraryId); + //imagesVO.setFaces(faces); + /**调用微云新增人像*/ + ApiVO face = (ApiVO) httpUtil.post(link + ApiUrlEnum.FACE_POSTURL.getUrl(), imageVO, ApiVO.class); + String json = gson.toJson(face.getData()); + ImageReturnVO imageReturnVO = null; + if (UtilValidate.isNotEmpty(json)) { + imageReturnVO = gson.fromJson(json, ImageReturnVO.class); + } + if (UtilValidate.isNotEmpty(imageReturnVO)) { + Portrait portrait = save(imageReturnVO, imageVO); + list.add(portrait); + } else { + throw new DkException(face.getMessage()); + } + } + } + return list; + /**调用微云新增人像*/ + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + @Override + public Portrait updatePortrait(Portrait portrait) { + try { + if (UtilValidate.isNotEmpty(portrait)) { + ImagesVO imageVO = new ImagesVO(); + setSex(imageVO, portrait.getIdCard()); + portrait.setSex(imageVO.getGender()); + java.sql.Date birthDate = getBirthDate(portrait.getIdCard()); + portrait.setBirthDate(birthDate); + portrait.setAge(DateUtils.getAge(portrait.getBirthDate())); + } + portraitMapper.updateById(portrait); + } catch (Exception e) { + throw new DkException("修改人像失败"); + } + return portrait; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Long deletePortrait(Long idPortrait) { + try { + Portrait portrait = new Portrait(); + portrait.setIdPortrait(idPortrait); + Portrait portrait1 = portraitMapper.queryPortrait(idPortrait); + /**调用API*/ + if (UtilValidate.isNotEmpty(portrait1)) { + /**调用微云删除人像*/ + ApiVO face = (ApiVO) httpUtil.delete(link + ApiUrlEnum.FACE_POSTURL.getUrl() + "/" + portrait1.getIdFactory() + "/" + idPortrait, ApiVO.class); + + if (face.getMessage().equals("成功")) { + minioUtil.removeObject(bucketName, portrait1.getUrl()); + } else { + log.error("wy删除失败"); + } + int i = portraitMapper.deleteById(portrait); + } + } catch (Exception e) { + throw new DkException("删除人像失败"); + } + return idPortrait; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public List deletePortraits(List idPortrait) { + try { + if (UtilValidate.isNotEmpty(idPortrait)) { + for (int i = 0; i < idPortrait.size(); i++) { + Portrait portrait1 = portraitMapper.queryPortrait(idPortrait.get(i)); + if (UtilValidate.isEmpty(portrait1)) { + continue; + } + /**调用微云删除人像*/ + ApiVO face = (ApiVO) httpUtil.delete(link + ApiUrlEnum.FACE_POSTURL.getUrl() + "/" + portrait1.getIdFactory() + "/" + portrait1.getIdPortrait(), ApiVO.class); + if (face.getMessage().equals("成功")) { + minioUtil.removeObject(bucketName, portrait1.getUrl()); + } else { + log.error("wy删除失败"); + } + portraitMapper.deleteById(idPortrait.get(i)); + } + } + } catch (Exception e) { + throw new DkException("删除人像失败"); + } + return idPortrait; + } + + @Override + //public ReturnVO queryPortrait(PageParam pageParam) { + public Page queryPortrait(PageParam pageParam) { + /* PagePortraitVO pagePortraitVO = new PagePortraitVO(); + pagePortraitVO.setLibraryId(pageParam.getNote().get("libraryId")); + PageVO pageVO = new PageVO(); + pageVO.setPageNo(pageParam.getPageNo()); + pageVO.setPageSize(pageParam.getPageSize()); + pagePortraitVO.setPage(pageVO); + ReturnVO faceLibrary1 = (ReturnVO) httpUtil.post(link+ ApiUrlEnum.FACELIBS_POSTURL.getUrl(), pagePortraitVO, ReturnVO.class);*/ + /**创建page对象*/ + Page page = new Page<>(pageParam.getPageNo(), pageParam.getPageSize()); + /**设置模糊查询参数*/ + Map paramsNote = pageParam.getNote(); + + /**分页查询*/ + //List postList = portraitMapper.selectPage(page, paramsNote.get("factoryName")); + List postList = portraitMapper.queryPage(page, paramsNote); + if (UtilValidate.isNotEmpty(postList)) { + for (Portrait portrait : postList) { + /**年龄*/ + if (UtilValidate.isNotEmpty(portrait.getBirthDate())) { + portrait.setAge(DateUtils.getAge(portrait.getBirthDate())); + } + } + } + page.setRecords(postList); + return page; + + // return faceLibrary1; + } + + /** + * 获取出生年月 + * + * @param idCard + * @return + */ + public java.sql.Date getBirthDate(String idCard) { + if (null != idCard && !idCard.equals("") && idCard.length() == 18) { + LocalDate date = LocalDate.of(Integer.parseInt(idCard.substring(6, 10)), Integer.parseInt(idCard.substring(10, 12)), Integer.parseInt(idCard.substring(12, 14))); + try { + ZonedDateTime zonedDateTime = date.atStartOfDay(ZoneId.systemDefault()); + return new java.sql.Date(Date.from(zonedDateTime.toInstant()).getTime()); + } catch (Exception e) { + throw new DkException("身份信息有误"); + } + } + return null; + } + + /** + * 保存数据 + * + * @return + */ + public Portrait save(ImageReturnVO imageReturnVO, ImagesVO imageVO) { + Portrait portrait = new Portrait(); + /**id*/ + if (UtilValidate.isNotEmpty(imageReturnVO.getFaceId())) { + portrait.setIdPortrait(Long.parseLong(imageReturnVO.getFaceId())); + } + //人脸ID + if (UtilValidate.isNotEmpty(imageReturnVO.getIdFaceid())) { + portrait.setFeatId(imageReturnVO.getIdFaceid()); + } + if (UtilValidate.isNotEmpty(imageReturnVO.getFace())) { + /**背景地址*/ + if (UtilValidate.isNotEmpty(imageReturnVO.getFace().getUrl())) { + portrait.setBackgroundUrl(imageReturnVO.getFace().getUrl()); + } + /**人脸地址*/ + if (UtilValidate.isNotEmpty(imageReturnVO.getFace().getFaceUrl())) { + portrait.setUrl(imageReturnVO.getFace().getFaceUrl()); + } + } + + if (UtilValidate.isNotEmpty(imageReturnVO.getLibraryId())) { + portrait.setIdFactory(Long.parseLong(imageReturnVO.getLibraryId())); + } + /**出生年月*/ + if (UtilValidate.isNotEmpty(imageVO.getIdCard())) { + portrait.setBirthDate(getBirthDate(imageVO.getIdCard())); + } + /**身份证信息*/ + if (UtilValidate.isNotEmpty(imageReturnVO.getFace().getIdCard())) { + portrait.setIdCard(imageReturnVO.getFace().getIdCard()); + } + if (UtilValidate.isNotEmpty(imageVO.getName())) { + portrait.setName(imageVO.getName()); + } + if (UtilValidate.isNotEmpty(imageReturnVO.getFaceId())) { + portrait.setFaceIds(imageReturnVO.getFaceId()); + } + if (UtilValidate.isNotEmpty(imageVO.getGender())) { + portrait.setSex(imageVO.getGender()); + } + portrait.setIsValid(YNEnums.YES.code); + portrait.setCreateTime(new Date()); + portrait.setUpdateTime(new Date()); + try { + int insert = portraitMapper.insert(portrait); + } catch (Exception e) { + throw new DkException("保存人像信息错误"); + } + return portrait; + } + + /** + * 设置性别 + * + * @param imageVO + * @param idCard + */ + public void setSex(ImagesVO imageVO, String idCard) { + if (UtilValidate.isNotEmpty(idCard)) { + if (idCard.length() == 15) { + String sex = idCard.substring(13, 14); //取指定位置的值(16位之后,17位结束;) + int b = Integer.parseInt(sex);//强制类型转换 + if (b % 2 == 0) { + imageVO.setGender("1");//女 + } else { + imageVO.setGender("0"); + } + } + if (idCard.length() == 18) { + String sex = idCard.substring(16, 17); //取指定位置的值(16位之后,17位结束;) + int b = Integer.parseInt(sex);//强制类型转换 + if (b % 2 == 0) { + imageVO.setGender("1");//女 + } else { + imageVO.setGender("0"); + } + } + imageVO.setIdCard(idCard); + } + } + + public void setimageVO(ImagesVO imageVO, String[] identityMessage) { + if (identityMessage.length > 0) { + /**文件名:身份证_姓名_性别*/ + if (!IdCardUtil.isValidatedAllIdcard(identityMessage[0])) { + throw new DkException(SystemCode.IDCARD_ERROR.code, "身份证号码输入不正确"); + } + if (UtilValidate.isNotEmpty(identityMessage[0])) { + setSex(imageVO, identityMessage[0]); + imageVO.setIdCard(identityMessage[0]); + } + if (UtilValidate.isNotEmpty(identityMessage[1])) { + imageVO.setName(identityMessage[1]); + } + } + } + + @Override + public SearchResultVo libSearchPage(SearchRequestVo searchRequestVo) { + //用户传输图片过来进行检索,调用人脸API + if (UtilValidate.isNotEmpty(searchRequestVo.getFaceImageRequestList())) { + return this.libSearPageByApi(searchRequestVo); + } else { + //调用数据库查询接口进行查询,不涉及人脸检索 + Page searchPage = this.findSearchPage(searchRequestVo.getPageParam(), null, searchRequestVo.getLibIdList(), null); + SearchResultVo searchResultVo = new SearchResultVo(); + searchResultVo.setResultPage(searchPage); + //将部分请求参数返回前端,方便前端进行数据绑定 + searchResultVo.setRequestLibIdList(searchRequestVo.getLibIdList()); + if (UtilValidate.isNotEmpty(searchRequestVo.getPageParam().getNote().get("search"))) { + searchResultVo.setRequestSearch(searchRequestVo.getPageParam().getNote().get("search").replaceAll("%", "")); + } + return searchResultVo; + } + } + + /** + * 人脸检索--api调用渠道 + * + * @param searchRequestVo + * @return + */ + private SearchResultVo libSearPageByApi(SearchRequestVo searchRequestVo) { + String requestUrl = apiRequestPrefix + ApiUrlEnum.FACE_SEARCH_LIB.getUrl(); + /** + * 返回结果集 + */ + SearchResultVo searchResultVo = new SearchResultVo(); + /** + * 图片搜索,如果当前为第一页,则调用sdk查询,反之利用第一页sdk返回的数据 + * 进行操作 + */ + if (searchRequestVo.getPageParam().getPageNo() == 1) { + //人脸ID,分数集合,及其对应分数--由sdk返回 + Map faceApiResultMap = new LinkedHashMap<>(); + for (String faceImage : searchRequestVo.getFaceImageRequestList()) { + /** + * 构建请求对象 + */ + ApiFaceSearchVO apiFaceSearchVO = new ApiFaceSearchVO(); + //设置图片url + apiFaceSearchVO.setUrl(faceImage); + //设置检索库 + apiFaceSearchVO.setLibraryIds(searchRequestVo.getLibIdList()); + //设置阀值 + if (UtilValidate.isNotEmpty(searchRequestVo.getMinScore())) { + apiFaceSearchVO.setMinScore(Double.parseDouble(searchRequestVo.getMinScore())); + } + //设置分页 + PageVO pageVO = new PageVO(); + pageVO.setPageSize(Integer.parseInt(apiMaxResult)); + apiFaceSearchVO.setPageVO(pageVO); + //获取解析结果 + ReturnVO returnVO = (ReturnVO) httpUtil.post(requestUrl, apiFaceSearchVO, ReturnVO.class); + if (returnVO.getCode() != 200) { + throw new DkException(returnVO.getMessage()); + } + //解析结果 + ApiFaceSearchReturnVO apiFaceSearchReturnVO = JsonUtil.string2Obj(JsonUtil.obj2String(returnVO.getData()), new TypeReference() { + }); + if (UtilValidate.isNotEmpty(apiFaceSearchReturnVO)) { + for (ApiFaceSearchFacesVO apiFaceSearchFacesVO : apiFaceSearchReturnVO.getFaces()) { + List faceList = apiFaceSearchFacesVO.getFaceList(); + if (UtilValidate.isNotEmpty(faceList)) { + for (ApiFaceSearchFaceVO apiFaceSearchFaceVO : faceList) { + faceApiResultMap.put(apiFaceSearchFaceVO.getFaceId(), apiFaceSearchFaceVO.getHitSimilarity()); + } + } + } + } + if (UtilValidate.isEmpty(faceApiResultMap)) { + /** + * 为空的时候组织数据,便于前端组织数据 + */ + Page page = new Page<>(); + searchResultVo.setResultPage(page); + searchResultVo.setFaceImageRequestList(new ArrayList<>()); + searchResultVo.setFaceApiResultMap(new HashMap<>()); + //将部分请求参数返回前端,方便前端进行数据绑定 + searchResultVo.setRequestLibIdList(searchRequestVo.getLibIdList()); + if (UtilValidate.isNotEmpty(searchRequestVo.getPageParam().getNote().get("search"))) { + searchResultVo.setRequestSearch(searchRequestVo.getPageParam().getNote().get("search").replaceAll("%", "")); + } + return searchResultVo; + } else { + // 对API调用返回的数据进行排序 + faceApiResultMap = this.sort(faceApiResultMap); + } + } + //获取分页数据 + Page searchPage = this.findSearchPage(searchRequestVo.getPageParam(), new ArrayList<>(faceApiResultMap.keySet()), searchRequestVo.getLibIdList(), faceApiResultMap); + searchResultVo.setResultPage(searchPage); + searchResultVo.setFaceApiResultMap(faceApiResultMap); + searchResultVo.setFaceImageRequestList(searchRequestVo.getFaceImageRequestList()); + //将部分请求参数返回前端,方便前端进行数据绑定 + searchResultVo.setRequestLibIdList(searchRequestVo.getLibIdList()); + if (UtilValidate.isNotEmpty(searchRequestVo.getPageParam().getNote().get("search"))) { + searchResultVo.setRequestSearch(searchRequestVo.getPageParam().getNote().get("search").replaceAll("%", "")); + } + return searchResultVo; + } else { + //获取分页数据 + Page searchPage = this.findSearchPage(searchRequestVo.getPageParam(), new ArrayList<>(searchRequestVo.getFaceApiResultMap().keySet()), searchRequestVo.getLibIdList(), searchRequestVo.getFaceApiResultMap()); + searchResultVo.setResultPage(searchPage); + searchResultVo.setFaceApiResultMap(searchRequestVo.getFaceApiResultMap()); + searchResultVo.setFaceImageRequestList(searchRequestVo.getFaceImageRequestList()); + //将部分请求参数返回前端,方便前端进行数据绑定 + searchResultVo.setRequestLibIdList(searchRequestVo.getLibIdList()); + if (UtilValidate.isNotEmpty(searchRequestVo.getPageParam().getNote().get("search"))) { + searchResultVo.setRequestSearch(searchRequestVo.getPageParam().getNote().get("search").replaceAll("%", "")); + } + return searchResultVo; + } + } + + /** + * 人脸检索分页 + * + * @param pageParam + * @param faceIdList 人脸Id集合 + * @param libraryIdList 库Id集合 + * @param faceApiResultMap 人脸分数集合 + * @return + */ + private Page findSearchPage(PageParam pageParam, List faceIdList, List libraryIdList, Map faceApiResultMap) { + Page page = new Page<>(pageParam.getPageNo(), pageParam.getPageSize()); + Map searchParams = pageParam.paramsToLike(pageParam.getNote(), "search"); + /** + * 查询出来的数据为乱序,即使对入参做了排序,也没有用,故此处的查询的唯一作用是用于判断有效的记录条数 + * 然后再根据当前页,以及当前页面的入参数据进行一次有效的查询,查询出来的结果依然为乱序,然后再根据、 + * faceApiResultMap 与Id的对应关系再进行一次排序作为返回值 + */ + // 获取总的有效数量, + Integer pageCount = baseMapper.findSearchPageCount(searchParams, faceIdList, libraryIdList); + page.setTotal(pageCount); + List pageList; + // 通过API调用 + if (UtilValidate.isNotEmpty(faceIdList) && UtilValidate.isNotEmpty(libraryIdList) && UtilValidate.isNotEmpty(faceApiResultMap)) { + pageList = baseMapper.findSearchPageList(searchParams, this.getSubFaceIdList(faceIdList, page), libraryIdList); + // 获取当前页有效数据 + // 设置人脸分数 + if (UtilValidate.isNotEmpty(faceApiResultMap)) { + for (SearchPortraitVo searchPortraitVo : pageList) { + if (faceApiResultMap.containsKey(searchPortraitVo.getIdPortrait())) { + searchPortraitVo.setSimilarityDegree(faceApiResultMap.get(searchPortraitVo.getIdPortrait())); + } + } + } + //对返回的数据进行排序 + Collections.sort(pageList); + page.setRecords(pageList); + return page; + } else { + // 非API调用 + pageList = baseMapper.findSearchPage(page, searchParams, null, libraryIdList); + page.setRecords(pageList); + return page; + } + + } + + /** + * 对返回的人脸结果集进行排序 + * + * @param sortMap + * @return + */ + private Map sort(Map sortMap) { + // 通过ArrayList构造函数把map.entrySet()转换成list + List> sortList = new ArrayList<>(sortMap.entrySet()); + Collections.sort(sortList, new Comparator>() { + @Override + public int compare(Map.Entry o1, Map.Entry o2) { + return o2.getValue().compareTo(o1.getValue()); + } + }); + Map resultMap = new LinkedHashMap<>(); + Iterator> iterator = sortList.iterator(); + while (iterator.hasNext()) { + Map.Entry next = iterator.next(); + resultMap.put(next.getKey(), next.getValue()); + } + return resultMap; + } + + /** + * 截取人脸Id子集合 + * + * @param faceIdList 需要剪裁的集合 + * @param page page对象 + * @return + */ + private List getSubFaceIdList(List faceIdList, Page page) { + if (UtilValidate.isEmpty(faceIdList)) { + return null; + } + // 每页数量 + long pageSize = page.getSize(); + // 当前页 + long current = page.getCurrent(); + // 总记录数量 + long total = page.getTotal(); + long start = (current - 1) * pageSize; + long end = current * pageSize; + if (end > total) { + end = total; + } + if (start > end) { + return null; + } + return faceIdList.subList(new Long(start).intValue(), new Long(end).intValue()); + } + + public static void main(String[] args) { + String s = "513902199202293979"; + System.out.println(s.hashCode() % 500); + } +} diff --git a/face-server/src/main/java/com/dkha/server/services/impl/TrackTaskImpl.java b/face-server/src/main/java/com/dkha/server/services/impl/TrackTaskImpl.java new file mode 100644 index 0000000..e52e1e1 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/impl/TrackTaskImpl.java @@ -0,0 +1,276 @@ +package com.dkha.server.services.impl; + +import com.dkha.common.enums.ApiUrlEnum; +import com.dkha.common.http.HttpUtil; +import com.dkha.common.modules.vo.camera.BayOnetCameraVO; +import com.dkha.common.modules.vo.camera.CameraInfoVO; +import com.dkha.common.modules.vo.camera.PeopleComparableVO; +import com.dkha.common.modules.vo.camera.PeopleVO; +import com.dkha.common.modules.vo.face.ApiFaceSearchReturnVO; +import com.dkha.common.modules.vo.face.ApiFaceSearchVO; +import com.dkha.common.modules.vo.face.PageVO; +import com.dkha.common.redis.RedisKeys; +import com.dkha.common.redis.RedisUtils; +import com.dkha.common.util.TimeUtil; +import com.dkha.common.util.UrlUtil; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.services.IControlBayonetMidService; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: TrackTaskImpl + * @Package com.dkha.server.services.impl + * @author: panhui + * @date: 2020/1/14 12:39 + * @Copyright: 成都电科慧安 + */ +@Component +@Slf4j +public class TrackTaskImpl { + + + @Autowired + private HttpUtil httpUtil; + + @Value("${api.server.prefix}") + private String link; + + /** + * 调用api进行人脸检测 获取到人脸的id + * @param faceUrl + * @param libs + * @param minScore + */ + public List faceCheck(String faceUrl, List libs, Double minScore) + { + List faceList =new ArrayList<>(); + ApiFaceSearchVO apiFaceSearchVO = new ApiFaceSearchVO(); + apiFaceSearchVO.setUrl(faceUrl); + apiFaceSearchVO.setLibraryIds(libs); + apiFaceSearchVO.setMinScore(minScore); + PageVO pageVO = new PageVO(); + pageVO.setPageSize(1); + apiFaceSearchVO.setPageVO(pageVO); + String json= UrlUtil.postApiData(link+ ApiUrlEnum.FACE_SEARCH_LIB.getUrl(),apiFaceSearchVO, httpUtil,gson); +// log.error("获取数据{}",json); + if(UtilValidate.isEmpty(json)){return faceList; } + ApiFaceSearchReturnVO apiFaceSearchReturnVO=gson.fromJson(json,ApiFaceSearchReturnVO.class); + if(UtilValidate.isEmpty(apiFaceSearchReturnVO) || UtilValidate.isEmpty(apiFaceSearchReturnVO.getFaces())) + { + return faceList; + } + apiFaceSearchReturnVO.getFaces().forEach(e-> + { + if(UtilValidate.isEmpty(e.getFaceList())) + { + return; + } + e.getFaceList().forEach(a-> + { + faceList.add(a.getFaceId()); + }); + }); + return faceList; + } + + @Autowired + private RedisUtils redisUtils; + @Autowired + private Gson gson; + + @Autowired + IControlBayonetMidService iControlBayonetMidService; + /** + * redis获取libid + * @param nowTime + * @return + */ + public List getRedisLibId(String nowTime) + { + List list=new ArrayList<>(); + List cameraList = iControlBayonetMidService.selectFaceCameraBytaskInfo(); + if (!UtilValidate.isEmpty(cameraList)) { + cameraList.forEach(e-> + { + //去API比对 + if(redisUtils.exists(RedisKeys.getCameraByTrack(nowTime,e.getIdFaceCamera()))) + { + BayOnetCameraVO bayOnetCameraVO=gson.fromJson(redisUtils.get(RedisKeys.getCameraByTrack(nowTime,e.getIdFaceCamera())).toString(), BayOnetCameraVO.class); + list.add(bayOnetCameraVO.getAssociationLibraryId().toString()); + //获取lib信息 + } + }); + } + return list; + } + + + /** + * redis临时调用设置redis中属性的id + * @param nowTime + * @return + */ + public void setBingDataCamerID(String nowTime) + { + + + List cameraList = iControlBayonetMidService.selectFaceCameraBytaskInfo(); + if (!UtilValidate.isEmpty(cameraList)) { + cameraList.forEach(e-> + { + //去API比对 + if(redisUtils.exists(RedisKeys.getCameraByTrack(nowTime,e.getIdFaceCamera()))) + { + BayOnetCameraVO bayOnetCameraVO=gson.fromJson(redisUtils.get(RedisKeys.getCameraByTrack(nowTime,e.getIdFaceCamera())).toString(), BayOnetCameraVO.class); + bayOnetCameraVO.getFeatIds().forEach(a-> + { + xxx(nowTime,a); + }); + + } + }); + } + + } + + private void xxx(String nowTime,String faceId) + { + List myList=getRedisCameraId(nowTime); + myList.forEach(a-> + { + //去API比对 + if(redisUtils.exists(RedisKeys.getCameraByFaceId(nowTime,a,faceId))) + { + List list=gson.fromJson(redisUtils.get(RedisKeys.getCameraByFaceId(nowTime,a,faceId)).toString(), new TypeToken>() {}.getType()); + if(UtilValidate.isNotEmpty(list)) { + list.forEach(e-> + { + e.setCameraId(a); + }); + } + redisUtils.set(RedisKeys.getCameraByFaceId(nowTime,a,faceId),gson.toJson(list)); + } + }); + } + + /** + * redis获取CameraId + * @param nowTime + * @return + */ + public List getRedisCameraId(String nowTime) + { + List list=new ArrayList<>(); + List cameraList = iControlBayonetMidService.selectFaceCameraBytaskInfo(); + if (!UtilValidate.isEmpty(cameraList)) { + cameraList.forEach(e-> + { + //去API比对 + if(redisUtils.exists(RedisKeys.getCameraByTrack(nowTime,e.getIdFaceCamera()))) + { + BayOnetCameraVO bayOnetCameraVO=gson.fromJson(redisUtils.get(RedisKeys.getCameraByTrack(nowTime,e.getIdFaceCamera())).toString(), BayOnetCameraVO.class); + list.add(bayOnetCameraVO.getCameraId().toString()); + //获取lib信息 + } + }); + } + return list; + } + + /** + * 筛选数据 + * @return + */ + public Map> filterPeople(List peopleVOList) + { + Map> myMap=new HashMap<>(); + peopleVOList.forEach(e-> + { + if(UtilValidate.isEmpty(e.getTime())) + { + e.setTime( new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(e.getTimestamp()) ); + } + String key=e.getTime().substring(0,10); + if(myMap.containsKey(key)) + { + PeopleComparableVO pvo= new PeopleComparableVO(); + BeanUtils.copyProperties(e,pvo); + myMap.get(key).add(pvo); + }else + { + List lp=new ArrayList<>(); + PeopleComparableVO pvo= new PeopleComparableVO(); + BeanUtils.copyProperties(e,pvo); + lp.add(pvo); + myMap.put(key,lp); + } + }); + //对数据进行排序处理 把所有摄像头的数据整合后进行排序 + //时间和所有数据 + Map> newMyMap=new HashMap<>(); + myMap.forEach((a,b)-> + { + if(UtilValidate.isNotEmpty(b)) + { + //按照时间戳就行排序 + Collections.sort(b); + String lastCarmerId=""; + for(PeopleComparableVO p:b) + { + //相等就不需要这个数据了 + if(UtilValidate.isNotEmpty(p.getCameraId())) { + if (!p.getCameraId().equals(lastCarmerId)) { + if (newMyMap.containsKey(a)) { + newMyMap.get(a).add(p); + } else { + List pList = new ArrayList<>(); + pList.add(p); + newMyMap.put(a, pList); + } + lastCarmerId = p.getCameraId(); + } + } + //筛选有用的 + } + } + }); + return newMyMap; + } + + + + /** + * redis获取用户信息 + * @param faceId + * @return + */ + public List getRedisPeopleInfo(String nowTime,String faceId) + { + List peopleVOList=new ArrayList<>(); + List myList=getRedisCameraId(nowTime); + myList.forEach(a-> + { + //去API比对 + if(redisUtils.exists(RedisKeys.getCameraByFaceId(nowTime,a,faceId))) + { + List list=gson.fromJson(redisUtils.get(RedisKeys.getCameraByFaceId(nowTime,a,faceId)).toString(), new TypeToken>() {}.getType()); + if(UtilValidate.isNotEmpty(list)) { + peopleVOList.addAll(list); + } + } + }); + return peopleVOList; + } +} diff --git a/face-server/src/main/java/com/dkha/server/services/impl/WarningInformationServiceImpl.java b/face-server/src/main/java/com/dkha/server/services/impl/WarningInformationServiceImpl.java new file mode 100644 index 0000000..d07b2fa --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/services/impl/WarningInformationServiceImpl.java @@ -0,0 +1,20 @@ +package com.dkha.server.services.impl; + +import com.dkha.server.modules.entities.WarningInformation; +import com.dkha.server.mappers.WarningInformationMapper; +import com.dkha.server.services.IWarningInformationService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 预警信息 服务实现类 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Service +public class WarningInformationServiceImpl extends ServiceImpl implements IWarningInformationService { + +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/annotation/DataFilter.java b/face-server/src/main/java/com/dkha/server/system/common/annotation/DataFilter.java new file mode 100644 index 0000000..0c0b1e2 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/annotation/DataFilter.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.annotation; + +import java.lang.annotation.*; + +/** + * 数据过滤注解 + * + * @author Mark sunlightcs@gmail.com + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface DataFilter { + /** + * 表的别名 + */ + String tableAlias() default ""; + + /** + * 查询条件前缀,可选值有:[where、and] + */ + String prefix() default ""; + + /** + * 用户ID + */ + String userId() default "creator"; + + /** + * 部门ID + */ + String deptId() default "dept_id"; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/annotation/LogOperation.java b/face-server/src/main/java/com/dkha/server/system/common/annotation/LogOperation.java new file mode 100644 index 0000000..e82735f --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/annotation/LogOperation.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.annotation; + +import java.lang.annotation.*; + +/** + * 操作日志注解 + * + * @author Mark sunlightcs@gmail.com + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface LogOperation { + + String value() default ""; +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/aspect/DataFilterAspect.java b/face-server/src/main/java/com/dkha/server/system/common/aspect/DataFilterAspect.java new file mode 100644 index 0000000..c0e9ea2 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/aspect/DataFilterAspect.java @@ -0,0 +1,113 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.aspect; + +import com.dkha.common.util.UtilValidate; +import com.dkha.server.system.common.annotation.DataFilter; +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.exception.ErrorCode; +import com.dkha.server.system.common.interceptor.DataScope; +import com.dkha.server.system.modules.security.user.SecurityUser; +import com.dkha.server.system.modules.security.user.UserDetail; +import com.dkha.server.system.modules.sys.enums.SuperAdminEnum; +import org.apache.commons.lang3.StringUtils; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; + +/** + * 数据过滤,切面处理类 + * + * @author Mark sunlightcs@gmail.com + */ +@Aspect +@Component +public class DataFilterAspect { + + @Pointcut("@annotation(com.dkha.server.system.common.annotation.DataFilter)") + public void dataFilterCut() { + + } + + @Before("dataFilterCut()") + public void dataFilter(JoinPoint point) { + Object params = point.getArgs()[0]; + if(params != null && params instanceof Map){ + UserDetail user = SecurityUser.getUser(); + + //如果是超级管理员,则不进行数据过滤 + if(user.getSuperAdmin() == SuperAdminEnum.YES.value()) { + return ; + } + + try { + //否则进行数据过滤 + Map map = (Map)params; + String sqlFilter = getSqlFilter(user, point); + map.put(Constant.SQL_FILTER, new DataScope(sqlFilter)); + }catch (Exception e){ + + } + + return ; + } + + throw new com.dkha.server.system.common.exception.RenException(ErrorCode.DATA_SCOPE_PARAMS_ERROR); + } + + /** + * 获取数据过滤的SQL + */ + private String getSqlFilter(UserDetail user, JoinPoint point) throws Exception { + MethodSignature signature = (MethodSignature) point.getSignature(); + Method method = point.getTarget().getClass().getDeclaredMethod(signature.getName(), signature.getParameterTypes()); + DataFilter dataFilter = method.getAnnotation(DataFilter.class); + + //获取表的别名 + String tableAlias = dataFilter.tableAlias(); + if(StringUtils.isNotBlank(tableAlias)){ + tableAlias += "."; + } + + StringBuilder sqlFilter = new StringBuilder(); + + //查询条件前缀 + String prefix = dataFilter.prefix(); + if(StringUtils.isNotBlank(prefix)){ + sqlFilter.append(" ").append(prefix); + } + + sqlFilter.append(" ("); + + //部门ID列表 + List deptIdList = user.getDeptIdList(); + if(UtilValidate.isNotEmpty(deptIdList)){ + sqlFilter.append(tableAlias).append(dataFilter.deptId()); + + sqlFilter.append(" in(").append(StringUtils.join(deptIdList, ",")).append(")"); + } + + //查询本人数据 + if(UtilValidate.isNotEmpty(deptIdList)){ + sqlFilter.append(" or "); + } + sqlFilter.append(tableAlias).append(dataFilter.userId()).append("=").append(user.getId()); + + sqlFilter.append(")"); + + return sqlFilter.toString(); + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/aspect/LogOperationAspect.java b/face-server/src/main/java/com/dkha/server/system/common/aspect/LogOperationAspect.java new file mode 100644 index 0000000..979ec89 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/aspect/LogOperationAspect.java @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.aspect; + +import com.alibaba.fastjson.JSON; +import com.dkha.common.util.IpUtils; +import com.dkha.server.system.common.annotation.LogOperation; +import com.dkha.server.system.common.utils.HttpContextUtils; +import com.dkha.server.system.modules.log.entity.SysLogOperationEntity; +import com.dkha.server.system.modules.log.enums.OperationStatusEnum; +import com.dkha.server.system.modules.log.service.SysLogOperationService; +import com.dkha.server.system.modules.security.user.SecurityUser; +import com.dkha.server.system.modules.security.user.UserDetail; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Method; + +/** + * 操作日志,切面处理类 + * + * @author Mark sunlightcs@gmail.com + */ +@Aspect +@Component +public class LogOperationAspect { + @Autowired + private SysLogOperationService sysLogOperationService; + + @Pointcut("@annotation(com.dkha.server.system.common.annotation.LogOperation)") + public void logPointCut() { + + } + + @Around("logPointCut()") + public Object around(ProceedingJoinPoint point) throws Throwable { + long beginTime = System.currentTimeMillis(); + try { + //执行方法 + Object result = point.proceed(); + + //执行时长(毫秒) + long time = System.currentTimeMillis() - beginTime; + //保存日志 + saveLog(point, time, OperationStatusEnum.SUCCESS.value()); + + return result; + }catch(Exception e) { + //执行时长(毫秒) + long time = System.currentTimeMillis() - beginTime; + //保存日志 + saveLog(point, time, OperationStatusEnum.FAIL.value()); + + throw e; + } + } + + private void saveLog(ProceedingJoinPoint joinPoint, long time, Integer status) throws Exception { + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = joinPoint.getTarget().getClass().getDeclaredMethod(signature.getName(), signature.getParameterTypes()); + LogOperation annotation = method.getAnnotation(LogOperation.class); + + SysLogOperationEntity log = new SysLogOperationEntity(); + if(annotation != null){ + //注解上的描述 + log.setOperation(annotation.value()); + } + + //登录用户信息 + UserDetail user = SecurityUser.getUser(); + if(user != null){ + log.setCreatorName(user.getUsername()); + } + + log.setStatus(status); + log.setRequestTime((int)time); + + //请求相关信息 + HttpServletRequest request = HttpContextUtils.getHttpServletRequest(); + log.setIp(IpUtils.getIpAddr(request)); + log.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT)); + log.setRequestUri(request.getRequestURI()); + log.setRequestMethod(request.getMethod()); + + //请求参数 + Object[] args = joinPoint.getArgs(); + try{ + String params = JSON.toJSONString(args[0]); + log.setRequestParams(params); + }catch (Exception e){ + + } + + //保存到DB + sysLogOperationService.save(log); + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/config/MybatisPlusConfig.java b/face-server/src/main/java/com/dkha/server/system/common/config/MybatisPlusConfig.java new file mode 100644 index 0000000..f588253 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/config/MybatisPlusConfig.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.config; + +import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; +import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor; +import com.dkha.server.system.common.interceptor.DataFilterInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; + +/** + * mybatis-plus配置 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Configuration +public class MybatisPlusConfig { + + /** + * 配置数据权限 + */ + @Bean + @Order(1) + public DataFilterInterceptor dataFilterInterceptor() { + return new DataFilterInterceptor(); + } + + /** + * 配置分页 + */ + @Bean + @Order(0) + public PaginationInterceptor paginationInterceptor() { + return new PaginationInterceptor(); + } + + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/constant/Constant.java b/face-server/src/main/java/com/dkha/server/system/common/constant/Constant.java new file mode 100644 index 0000000..c8b58e9 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/constant/Constant.java @@ -0,0 +1,189 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.constant; + +/** + * 常量 + * + * @author Mark sunlightcs@gmail.com + */ +public interface Constant { + /** + * 成功 + */ + int SUCCESS = 1; + /** + * 岗位发布平台登录默认初始化密码 + */ + int COMPANY_INITIALIZATION_PASSWORD = 123456; + /** + * 失败 + */ + int FAIL = 0; + /** + * OK + */ + String OK = "OK"; + /** + * 用户标识 + */ + String USER_KEY = "userId"; + /** + * 菜单根节点标识 + */ + Long MENU_ROOT = 0L; + /** + * 部门根节点标识 + */ + Long DEPT_ROOT = 0L; + /** + * 数据字典根节点标识 + */ + Long DICT_ROOT = 0L; + /** + * 升序 + */ + String ASC = "asc"; + /** + * 降序 + */ + String DESC = "desc"; + /** + * 创建时间字段名 + */ + String CREATE_DATE = "create_date"; + + /** + * 创建时间字段名 + */ + String ID = "id"; + + /** + * 数据权限过滤 + */ + String SQL_FILTER = "sqlFilter"; + + /** + * 当前页码 + */ + String PAGE = "page"; + /** + * 每页显示记录数 + */ + String LIMIT = "limit"; + /** + * 排序字段 + */ + String ORDER_FIELD = "orderField"; + /** + * 排序方式 + */ + String ORDER = "order"; + /** + * token header + */ + String TOKEN_HEADER = "token"; + + /** + * 云存储配置KEY + */ + String CLOUD_STORAGE_CONFIG_KEY = "CLOUD_STORAGE_CONFIG_KEY"; + /** + * 短信配置KEY + */ + String SMS_CONFIG_KEY = "SMS_CONFIG_KEY"; + /** + * 邮件配置KEY + */ + String MAIL_CONFIG_KEY = "MAIL_CONFIG_KEY"; + + /** + * 定时任务状态 + */ + enum ScheduleStatus { + /** + * 暂停 + */ + PAUSE(0), + /** + * 正常 + */ + NORMAL(1); + + private int value; + + ScheduleStatus(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } + + /** + * 云服务商 + */ + enum CloudService { + /** + * 七牛云 + */ + QINIU(1), + /** + * 阿里云 + */ + ALIYUN(2), + /** + * 腾讯云 + */ + QCLOUD(3), + /** + * FASTDFS + */ + FASTDFS(4), + /** + * 本地 + */ + LOCAL(5); + + private int value; + + CloudService(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } + + /** + * 短信服务商 + */ + enum SmsService { + /** + * 阿里云 + */ + ALIYUN(1), + /** + * 腾讯云 + */ + QCLOUD(2); + + private int value; + + SmsService(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/convert/DateConverter.java b/face-server/src/main/java/com/dkha/server/system/common/convert/DateConverter.java new file mode 100644 index 0000000..2acda8c --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/convert/DateConverter.java @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.convert; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.convert.converter.Converter; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 日期转换 + * + * @author Mark sunlightcs@gmail.com + */ +@Component +public class DateConverter implements Converter { + private static final Logger logger = LoggerFactory.getLogger(DateConverter.class); + private static List formatList = new ArrayList<>(5); + static { + formatList.add("yyyy-MM"); + formatList.add("yyyy-MM-dd"); + formatList.add("yyyy-MM-dd hh:mm"); + formatList.add("yyyy-MM-dd hh:mm:ss"); + formatList.add("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); + } + + @Override + public Date convert(String source) { + String value = source.trim(); + if (StringUtils.isEmpty(value)) { + return null; + } + + if(source.matches("^\\d{4}-\\d{1,2}$")){ + return parseDate(source, formatList.get(0)); + }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")){ + return parseDate(source, formatList.get(1)); + }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}$")){ + return parseDate(source, formatList.get(2)); + }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")){ + return parseDate(source, formatList.get(3)); + }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}.*T.*\\d{1,2}:\\d{1,2}:\\d{1,2}.*..*$")){ + return parseDate(source, formatList.get(4)); + } else { + throw new IllegalArgumentException("Invalid boolean value '" + source + "'"); + } + } + + /** + * 格式化日期 + * @param dateStr String 字符型日期 + * @param format String 格式 + * @return Date 日期 + */ + public Date parseDate(String dateStr, String format) { + Date date = null; + try { + DateFormat dateFormat = new SimpleDateFormat(format); + date = dateFormat.parse(dateStr); + } catch (Exception e) { + logger.error("Formatted date with date: {} and format : {} ", dateStr, format); + } + return date; + } + +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/dao/BaseDao.java b/face-server/src/main/java/com/dkha/server/system/common/dao/BaseDao.java new file mode 100644 index 0000000..9aeb96f --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/dao/BaseDao.java @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 基础Dao + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface BaseDao extends BaseMapper { + +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/entity/BaseEntity.java b/face-server/src/main/java/com/dkha/server/system/common/entity/BaseEntity.java new file mode 100644 index 0000000..71ec4cd --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/entity/BaseEntity.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 基础实体类,所有实体都需要继承 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +public abstract class BaseEntity implements Serializable { + /** + * id + */ + @TableId(value = "id", type = IdType.ID_WORKER) + private Long id; + /** + * 创建者 + */ + @TableField(fill = FieldFill.INSERT) + private Long creator; + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + private Date createDate; + + + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/entity/CommonEntity.java b/face-server/src/main/java/com/dkha/server/system/common/entity/CommonEntity.java new file mode 100644 index 0000000..2987358 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/entity/CommonEntity.java @@ -0,0 +1,32 @@ +package com.dkha.server.system.common.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; +@Data +public class CommonEntity implements Serializable { + + @TableField(fill = FieldFill.INSERT) + @ApiModelProperty(value = "是否有效 Y有效 N无效 作逻辑删除使用") + private String isValid; + @TableField(fill = FieldFill.INSERT) + @ApiModelProperty(value = "创建人") + private String createBy; + @TableField(fill = FieldFill.INSERT_UPDATE) + @ApiModelProperty(value = "更新人") + private String updateBy; + + @TableField(fill = FieldFill.INSERT) + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建时间") + private Date createTime; + @TableField(fill = FieldFill.INSERT_UPDATE) + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "更新时间") + private Date updateTime; +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/exception/ErrorCode.java b/face-server/src/main/java/com/dkha/server/system/common/exception/ErrorCode.java new file mode 100644 index 0000000..c9f2da7 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/exception/ErrorCode.java @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.exception; + +/** + * 错误编码,由5位数字组成,前2位为模块编码,后3位为业务编码 + *

+ * 如:10001(10代表系统模块,001代表业务代码) + *

+ * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface ErrorCode { + int INTERNAL_SERVER_ERROR = 500; + int UNAUTHORIZED = 401; + int FORBIDDEN = 403; + + int NOT_NULL = 10001; + int DB_RECORD_EXISTS = 10002; + int PARAMS_GET_ERROR = 10003; + int ACCOUNT_PASSWORD_ERROR = 10004; + int ACCOUNT_DISABLE = 10005; + int IDENTIFIER_NOT_NULL = 10006; + int CAPTCHA_ERROR = 10007; + int SUB_MENU_EXIST = 10008; + int PASSWORD_ERROR = 10009; + int ACCOUNT_NOT_EXIST = 10010; + int SUPERIOR_DEPT_ERROR = 10011; + int SUPERIOR_MENU_ERROR = 10012; + int DATA_SCOPE_PARAMS_ERROR = 10013; + int DEPT_SUB_DELETE_ERROR = 10014; + int DEPT_USER_DELETE_ERROR = 10015; + int ACT_DEPLOY_ERROR = 10016; + int ACT_MODEL_IMG_ERROR = 10017; + int ACT_MODEL_EXPORT_ERROR = 10018; + int UPLOAD_FILE_EMPTY = 10019; + int TOKEN_NOT_EMPTY = 10020; + int TOKEN_INVALID = 10021; + int ACCOUNT_LOCK = 10022; + int ACT_DEPLOY_FORMAT_ERROR = 10023; + int OSS_UPLOAD_FILE_ERROR = 10024; + int SEND_SMS_ERROR = 10025; + int MAIL_TEMPLATE_NOT_EXISTS = 10026; + int REDIS_ERROR = 10027; + int JOB_ERROR = 10028; + int INVALID_SYMBOL = 10029; + int JSON_FORMAT_ERROR = 10030; + int SMS_CONFIG = 10031; + int TASK_CLIME_FAIL = 10032; + int NONE_EXIST_PROCESS = 10033; + int SUPERIOR_NOT_EXIST = 10034; + int REJECT_MESSAGE = 10035; + int ROLLBACK_MESSAGE = 10036; + int UNCLAIM_ERROR_MESSAGE = 10037; + int SUPERIOR_REGION_ERROR = 10038; + int REGION_SUB_DELETE_ERROR = 10039; + int PROCESS_START_ERROR = 10040; + int REJECT_PROCESS_PARALLEL_ERROR = 10041; + int REJECT_PROCESS_HANDLEING_ERROR = 10042; + int END_PROCESS_PARALLEL_ERROR = 10043; + int END_PROCESS_HANDLEING_ERROR = 10044; + int END_PROCESS_MESSAGE = 10045; + int BACK_PROCESS_PARALLEL_ERROR = 10046; + int BACK_PROCESS_HANDLEING_ERROR = 10047; + +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/exception/ExceptionUtils.java b/face-server/src/main/java/com/dkha/server/system/common/exception/ExceptionUtils.java new file mode 100644 index 0000000..b044152 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/exception/ExceptionUtils.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.exception; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * Exception工具类 + * + * @author Mark sunlightcs@gmail.com + */ +public class ExceptionUtils { + + /** + * 获取异常信息 + * @param ex 异常 + * @return 返回异常信息 + */ + public static String getErrorStackTrace(Exception ex){ + StringWriter sw = null; + PrintWriter pw = null; + try { + sw = new StringWriter(); + pw = new PrintWriter(sw, true); + ex.printStackTrace(pw); + }finally { + try { + if(pw != null) { + pw.close(); + } + } catch (Exception e) { + + } + try { + if(sw != null) { + sw.close(); + } + } catch (IOException e) { + + } + } + + return sw.toString(); + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/exception/RenException.java b/face-server/src/main/java/com/dkha/server/system/common/exception/RenException.java new file mode 100644 index 0000000..4229d95 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/exception/RenException.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.exception; + + +import com.dkha.server.system.common.utils.MessageUtils; + +/** + * 自定义异常 + * + * @author Mark sunlightcs@gmail.com + */ +public class RenException extends RuntimeException { + private static final long serialVersionUID = 1L; + + private int code; + private String msg; + + public RenException(int code) { + this.code = code; + this.msg = MessageUtils.getMessage(code); + } + + public RenException(int code, String... params) { + this.code = code; + this.msg = MessageUtils.getMessage(code, params); + } + + public RenException(int code, Throwable e) { + super(e); + this.code = code; + this.msg = MessageUtils.getMessage(code); + } + + public RenException(int code, Throwable e, String... params) { + super(e); + this.code = code; + this.msg = MessageUtils.getMessage(code, params); + } + + public RenException(String msg) { + super(msg); + this.code = ErrorCode.INTERNAL_SERVER_ERROR; + this.msg = msg; + } + + public RenException(String msg, Throwable e) { + super(msg, e); + this.code = ErrorCode.INTERNAL_SERVER_ERROR; + this.msg = msg; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/exception/RenExceptionHandler.java b/face-server/src/main/java/com/dkha/server/system/common/exception/RenExceptionHandler.java new file mode 100644 index 0000000..14b0bdb --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/exception/RenExceptionHandler.java @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.exception; + +import com.alibaba.fastjson.JSON; +import com.dkha.common.exception.EmployeeException; +import com.dkha.common.result.CommonResult; +import com.dkha.common.systemcode.SystemCode; +import com.dkha.common.util.IpUtils; +import com.dkha.server.system.common.utils.HttpContextUtils; +import com.dkha.server.system.common.utils.Result; +import com.dkha.server.system.modules.log.entity.SysLogErrorEntity; +import com.dkha.server.system.modules.log.service.SysLogErrorService; +import org.apache.commons.collections.MapUtils; +import org.apache.shiro.authz.UnauthorizedException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DuplicateKeyException; +import org.springframework.http.HttpHeaders; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + + +/** + * 异常处理器 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@RestControllerAdvice +public class RenExceptionHandler { + private static final Logger logger = LoggerFactory.getLogger(RenExceptionHandler.class); + + @Autowired + private SysLogErrorService sysLogErrorService; + + /** + * 处理自定义异常 + */ + @ExceptionHandler(RenException.class) + public Result handleRenException(RenException ex){ + Result result = new Result(); + result.error(ex.getCode(), ex.getMsg()); + + return result; + } + + @ExceptionHandler(DuplicateKeyException.class) + public Result handleDuplicateKeyException(DuplicateKeyException ex){ + Result result = new Result(); + result.error(ErrorCode.DB_RECORD_EXISTS); + + return result; + } + + @ExceptionHandler(UnauthorizedException.class) + public CommonResult handUnauthorizedException(UnauthorizedException exception) { + return new CommonResult().failResult(SystemCode.NOT_AUTHORIZATION.code, SystemCode.NOT_AUTHORIZATION.des, null); + } + + /** + * 保存异常日志 + */ + private void saveLog(Exception ex){ + SysLogErrorEntity log = new SysLogErrorEntity(); + + //请求相关信息 + HttpServletRequest request = HttpContextUtils.getHttpServletRequest(); + log.setIp(IpUtils.getIpAddr(request)); + log.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT)); + log.setRequestUri(request.getRequestURI()); + log.setRequestMethod(request.getMethod()); + Map params = HttpContextUtils.getParameterMap(request); + if(MapUtils.isNotEmpty(params)){ + log.setRequestParams(JSON.toJSONString(params)); + } + + //异常信息 + log.setErrorInfo(ExceptionUtils.getErrorStackTrace(ex)); + + //保存 + sysLogErrorService.save(log); + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/interceptor/DataFilterInterceptor.java b/face-server/src/main/java/com/dkha/server/system/common/interceptor/DataFilterInterceptor.java new file mode 100644 index 0000000..e60577c --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/interceptor/DataFilterInterceptor.java @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.interceptor; + +import com.baomidou.mybatisplus.core.toolkit.PluginUtils; +import com.baomidou.mybatisplus.extension.handlers.AbstractSqlParserHandler; +import org.apache.ibatis.executor.statement.StatementHandler; +import org.apache.ibatis.mapping.BoundSql; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.SqlCommandType; +import org.apache.ibatis.plugin.*; +import org.apache.ibatis.reflection.MetaObject; +import org.apache.ibatis.reflection.SystemMetaObject; + +import java.sql.Connection; +import java.util.Map; +import java.util.Properties; + +/** + * 数据过滤 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})}) +public class DataFilterInterceptor extends AbstractSqlParserHandler implements Interceptor { + + @Override + public Object intercept(Invocation invocation) throws Throwable { + StatementHandler statementHandler = (StatementHandler) PluginUtils.realTarget(invocation.getTarget()); + MetaObject metaObject = SystemMetaObject.forObject(statementHandler); + + // SQL解析 + this.sqlParser(metaObject); + + // 先判断是不是SELECT操作 + MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement"); + if (!SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) { + return invocation.proceed(); + } + + // 针对定义了rowBounds,做为mapper接口方法的参数 + BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql"); + String originalSql = boundSql.getSql(); + Object paramObj = boundSql.getParameterObject(); + + // 判断参数里是否有DataScope对象 + DataScope scope = null; + if (paramObj instanceof DataScope) { + scope = (DataScope) paramObj; + } else if (paramObj instanceof Map) { + for (Object arg : ((Map) paramObj).values()) { + if (arg instanceof DataScope) { + scope = (DataScope) arg; + break; + } + } + } + + // 不用数据过滤 + if(scope == null){ + return invocation.proceed(); + } + + // 拼接新SQL + originalSql = originalSql + scope.getSqlFilter(); + + // 重写SQL + metaObject.setValue("delegate.boundSql.sql", originalSql); + return invocation.proceed(); + } + + @Override + public Object plugin(Object target) { + if (target instanceof StatementHandler) { + return Plugin.wrap(target, this); + } + return target; + } + + @Override + public void setProperties(Properties properties) { + + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/interceptor/DataScope.java b/face-server/src/main/java/com/dkha/server/system/common/interceptor/DataScope.java new file mode 100644 index 0000000..54c75d1 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/interceptor/DataScope.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.interceptor; + +/** + * 数据范围 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class DataScope { + private String sqlFilter; + + public DataScope(String sqlFilter) { + this.sqlFilter = sqlFilter; + } + + public String getSqlFilter() { + return sqlFilter; + } + + public void setSqlFilter(String sqlFilter) { + this.sqlFilter = sqlFilter; + } + + @Override + public String toString() { + return this.sqlFilter; + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/page/PageData.java b/face-server/src/main/java/com/dkha/server/system/common/page/PageData.java new file mode 100644 index 0000000..43da0d1 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/page/PageData.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.page; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 分页工具类 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@ApiModel(value = "分页数据") +public class PageData implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "总记录数") + private int total; + + @ApiModelProperty(value = "列表数据") + private List list; + + /** + * 分页 + * @param list 列表数据 + * @param total 总记录数 + */ + public PageData(List list, long total) { + this.list = list; + this.total = (int)total; + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/service/BaseService.java b/face-server/src/main/java/com/dkha/server/system/common/service/BaseService.java new file mode 100644 index 0000000..5883728 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/service/BaseService.java @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.service; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; + +import java.io.Serializable; +import java.util.Collection; + +/** + * 基础服务接口,所有Service接口都要继承 + * + * @author Mark sunlightcs@gmail.com + */ +public interface BaseService { + + /** + *

+ * 插入一条记录(选择字段,策略插入) + *

+ * + * @param entity 实体对象 + */ + boolean insert(T entity); + + /** + *

+ * 插入(批量),该方法不支持 Oracle、SQL Server + *

+ * + * @param entityList 实体对象集合 + */ + boolean insertBatch(Collection entityList); + + /** + *

+ * 插入(批量),该方法不支持 Oracle、SQL Server + *

+ * + * @param entityList 实体对象集合 + * @param batchSize 插入批次数量 + */ + boolean insertBatch(Collection entityList, int batchSize); + + /** + *

+ * 根据 ID 选择修改 + *

+ * + * @param entity 实体对象 + */ + boolean updateById(T entity); + + /** + *

+ * 根据 whereEntity 条件,更新记录 + *

+ * + * @param entity 实体对象 + * @param updateWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper} + */ + boolean update(T entity, Wrapper updateWrapper); + + /** + *

+ * 根据ID 批量更新 + *

+ * + * @param entityList 实体对象集合 + */ + boolean updateBatchById(Collection entityList); + + /** + *

+ * 根据ID 批量更新 + *

+ * + * @param entityList 实体对象集合 + * @param batchSize 更新批次数量 + */ + boolean updateBatchById(Collection entityList, int batchSize); + + /** + *

+ * 根据 ID 查询 + *

+ * + * @param id 主键ID + */ + T selectById(Serializable id); + + /** + *

+ * 根据 ID 删除 + *

+ * + * @param id 主键ID + */ + boolean deleteById(Serializable id); + + /** + *

+ * 删除(根据ID 批量删除) + *

+ * + * @param idList 主键ID列表 + */ + boolean deleteBatchIds(Collection idList); +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/service/CrudService.java b/face-server/src/main/java/com/dkha/server/system/common/service/CrudService.java new file mode 100644 index 0000000..a1ebcf0 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/service/CrudService.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.service; + + + +import com.dkha.server.system.common.page.PageData; + +import java.util.List; +import java.util.Map; + +/** + * CRUD基础服务接口 + * + * @author Mark sunlightcs@gmail.com + */ +public interface CrudService extends BaseService { + + PageData page(Map params); + + List list(Map params); + + D get(Long id); + + void save(D dto); + + void update(D dto); + + void delete(Long[] ids); + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/service/impl/BaseServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/common/service/impl/BaseServiceImpl.java new file mode 100644 index 0000000..2e5abbe --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/service/impl/BaseServiceImpl.java @@ -0,0 +1,257 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.enums.SqlMethod; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.*; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.service.BaseService; +import com.dkha.server.system.common.utils.ConvertUtils; +import org.apache.ibatis.binding.MapperMethod; +import org.apache.ibatis.session.SqlSession; +import org.mybatis.spring.SqlSessionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +import java.io.Serializable; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * 基础服务类,所有Service都要继承 + * + * @author Mark sunlightcs@gmail.com + */ +public abstract class BaseServiceImpl, T> implements BaseService { + @Autowired + protected M baseDao; + + /** + * 获取分页对象 + * @param params 分页查询参数 + * @param defaultOrderField 默认排序字段 + * @param isAsc 排序方式 + */ + protected IPage getPage(Map params, String defaultOrderField, boolean isAsc) { + //分页参数 + long curPage = 1; + long limit = 10; + + if(params.get(Constant.PAGE) != null){ + curPage = Long.parseLong((String)params.get(Constant.PAGE)); + } + if(params.get(Constant.LIMIT) != null){ + limit = Long.parseLong((String)params.get(Constant.LIMIT)); + } + + //分页对象 + Page page = new Page<>(curPage, limit); + + //分页参数 + params.put(Constant.PAGE, page); + + //排序字段 + String orderField = (String)params.get(Constant.ORDER_FIELD); + String order = (String)params.get(Constant.ORDER); + + //前端字段排序 + if(StringUtils.isNotEmpty(orderField) && StringUtils.isNotEmpty(order)){ + if(Constant.ASC.equalsIgnoreCase(order)) { + return page.setAsc(orderField); + }else { + return page.setDesc(orderField); + } + } + + //没有排序字段,则不排序 + if(StringUtils.isEmpty(defaultOrderField)){ + return page; + } + + //默认排序 + if(isAsc) { + page.setAsc(defaultOrderField); + }else { + page.setDesc(defaultOrderField); + } + + return page; + } + + protected PageData getPageData(List list, long total, Class target){ + List targetList = ConvertUtils.sourceToTarget(list, target); + + return new PageData<>(targetList, total); + } + + protected PageData getPageData(IPage page, Class target){ + return getPageData(page.getRecords(), page.getTotal(), target); + } + + protected Map paramsToLike(Map params, String... likes){ + for (String like : likes){ + String val = (String)params.get(like); + if (StringUtils.isNotEmpty(val)){ + params.put(like, "%" + val + "%"); + }else { + params.put(like, null); + } + } + return params; + } + + /** + *

+ * 判断数据库操作是否成功 + *

+ *

+ * 注意!! 该方法为 Integer 判断,不可传入 int 基本类型 + *

+ * + * @param result 数据库操作返回影响条数 + * @return boolean + */ + protected static boolean retBool(Integer result) { + return SqlHelper.retBool(result); + } + + protected Class currentModelClass() { + return (Class) ReflectionKit.getSuperClassGenericType(getClass(), 1); + } + + /** + *

+ * 批量操作 SqlSession + *

+ */ + protected SqlSession sqlSessionBatch() { + return SqlHelper.sqlSessionBatch(currentModelClass()); + } + + /** + * 释放sqlSession + * @param sqlSession session + */ + protected void closeSqlSession(SqlSession sqlSession){ + SqlSessionUtils.closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(currentModelClass())); + } + + /** + * 获取SqlStatement + * + * @param sqlMethod + * @return + */ + protected String sqlStatement(SqlMethod sqlMethod) { + return SqlHelper.table(currentModelClass()).getSqlStatement(sqlMethod.getMethod()); + } + + @Override + public boolean insert(T entity) { + return BaseServiceImpl.retBool(baseDao.insert(entity)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean insertBatch(Collection entityList) { + return insertBatch(entityList, 100); + } + + /** + * 批量插入 + * + * @param entityList + * @param batchSize + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean insertBatch(Collection entityList, int batchSize) { + SqlSession batchSqlSession = sqlSessionBatch(); + int i = 0; + String sqlStatement = sqlStatement(SqlMethod.INSERT_ONE); + try { + for (T anEntityList : entityList) { + batchSqlSession.insert(sqlStatement, anEntityList); + if (i >= 1 && i % batchSize == 0) { + batchSqlSession.flushStatements(); + } + i++; + } + batchSqlSession.flushStatements(); + }finally { + closeSqlSession(batchSqlSession); + } + return true; + } + + @Override + public boolean updateById(T entity) { + return BaseServiceImpl.retBool(baseDao.updateById(entity)); + } + + @Override + public boolean update(T entity, Wrapper updateWrapper) { + return BaseServiceImpl.retBool(baseDao.update(entity, updateWrapper)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean updateBatchById(Collection entityList) { + return updateBatchById(entityList, 30); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean updateBatchById(Collection entityList, int batchSize) { + if (CollectionUtils.isEmpty(entityList)) { + throw new IllegalArgumentException("Error: entityList must not be empty"); + } + SqlSession batchSqlSession = sqlSessionBatch(); + int i = 0; + String sqlStatement = sqlStatement(SqlMethod.UPDATE_BY_ID); + try { + for (T anEntityList : entityList) { + MapperMethod.ParamMap param = new MapperMethod.ParamMap<>(); + param.put(Constants.ENTITY, anEntityList); + batchSqlSession.update(sqlStatement, param); + if (i >= 1 && i % batchSize == 0) { + batchSqlSession.flushStatements(); + } + i++; + } + batchSqlSession.flushStatements(); + }finally { + closeSqlSession(batchSqlSession); + } + return true; + } + + @Override + public T selectById(Serializable id) { + return baseDao.selectById(id); + } + + @Override + public boolean deleteById(Serializable id) { + return SqlHelper.delBool(baseDao.deleteById(id)); + } + + @Override + public boolean deleteBatchIds(Collection idList) { + return SqlHelper.delBool(baseDao.deleteBatchIds(idList)); + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/service/impl/CrudServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/common/service/impl/CrudServiceImpl.java new file mode 100644 index 0000000..2bde4c3 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/service/impl/CrudServiceImpl.java @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.ReflectionKit; +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.service.CrudService; +import com.dkha.server.system.common.utils.ConvertUtils; +import org.springframework.beans.BeanUtils; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * CRUD基础服务类 + * + * @author Mark sunlightcs@gmail.com + */ +public abstract class CrudServiceImpl, T, D> extends BaseServiceImpl implements CrudService { + + protected Class currentDtoClass() { + return (Class) ReflectionKit.getSuperClassGenericType(getClass(), 2); + } + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, null, false), + getWrapper(params) + ); + + return getPageData(page, currentDtoClass()); + } + + @Override + public List list(Map params) { + List entityList = baseDao.selectList(getWrapper(params)); + + return ConvertUtils.sourceToTarget(entityList, currentDtoClass()); + } + + public abstract QueryWrapper getWrapper(Map params); + + @Override + public D get(Long id) { + T entity = baseDao.selectById(id); + + return ConvertUtils.sourceToTarget(entity, currentDtoClass()); + } + + @Override + public void save(D dto) { + T entity = ConvertUtils.sourceToTarget(dto, currentModelClass()); + insert(entity); + + //copy主键值到dto + BeanUtils.copyProperties(entity, dto); + } + + @Override + public void update(D dto) { + T entity = ConvertUtils.sourceToTarget(dto, currentModelClass()); + updateById(entity); + } + + @Override + public void delete(Long[] ids) { + baseDao.deleteBatchIds(Arrays.asList(ids)); + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/utils/ConvertUtils.java b/face-server/src/main/java/com/dkha/server/system/common/utils/ConvertUtils.java new file mode 100644 index 0000000..914616d --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/utils/ConvertUtils.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.utils; + +import com.dkha.common.util.UtilValidate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * 转换工具类 + * + * @author Mark sunlightcs@gmail.com + */ +public class ConvertUtils { + private static Logger logger = LoggerFactory.getLogger(ConvertUtils.class); + + public static T sourceToTarget(Object source, Class target){ + if(source == null){ + return null; + } + T targetObject = null; + try { + targetObject = target.newInstance(); + BeanUtils.copyProperties(source, targetObject); + } catch (Exception e) { + logger.error("convert error ", e); + } + + return targetObject; + } + + public static List sourceToTarget(Collection sourceList, Class target){ + if(sourceList == null){ + return null; + } + + List targetList = new ArrayList<>(sourceList.size()); + try { + for(Object source : sourceList){ + T targetObject = target.newInstance(); + if (UtilValidate.isNotEmpty(source)) { + BeanUtils.copyProperties(source, targetObject); + } + targetList.add(targetObject); + } + }catch (Exception e){ + logger.error("convert error ", e); + } + + return targetList; + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/utils/DateUtils.java b/face-server/src/main/java/com/dkha/server/system/common/utils/DateUtils.java new file mode 100644 index 0000000..d297611 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/utils/DateUtils.java @@ -0,0 +1,182 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.utils; + +import org.apache.commons.lang3.StringUtils; +import org.joda.time.DateTime; +import org.joda.time.LocalDate; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * 日期处理 + * + * @author Mark sunlightcs@gmail.com + */ +public class DateUtils { + /** 时间格式(yyyy-MM-dd) */ + public final static String DATE_PATTERN = "yyyy-MM-dd"; + /** 时间格式(yyyy-MM-dd HH:mm:ss) */ + public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; + + /** + * 日期格式化 日期格式为:yyyy-MM-dd + * @param date 日期 + * @return 返回yyyy-MM-dd格式日期 + */ + public static String format(Date date) { + return format(date, DATE_PATTERN); + } + + /** + * 日期格式化 日期格式为:yyyy-MM-dd + * @param date 日期 + * @param pattern 格式,如:DateUtils.DATE_TIME_PATTERN + * @return 返回yyyy-MM-dd格式日期 + */ + public static String format(Date date, String pattern) { + if(date != null){ + SimpleDateFormat df = new SimpleDateFormat(pattern); + return df.format(date); + } + return null; + } + + /** + * 日期解析 + * @param date 日期 + * @param pattern 格式,如:DateUtils.DATE_TIME_PATTERN + * @return 返回Date + */ + public static Date parse(String date, String pattern) { + try { + return new SimpleDateFormat(pattern).parse(date); + } catch (ParseException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 字符串转换成日期 + * @param strDate 日期字符串 + * @param pattern 日期的格式,如:DateUtils.DATE_TIME_PATTERN + */ + public static Date stringToDate(String strDate, String pattern) { + if (StringUtils.isBlank(strDate)){ + return null; + } + + DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern); + return fmt.parseLocalDateTime(strDate).toDate(); + } + + /** + * 根据周数,获取开始日期、结束日期 + * @param week 周期 0本周,-1上周,-2上上周,1下周,2下下周 + * @return 返回date[0]开始日期、date[1]结束日期 + */ + public static Date[] getWeekStartAndEnd(int week) { + DateTime dateTime = new DateTime(); + LocalDate date = new LocalDate(dateTime.plusWeeks(week)); + + date = date.dayOfWeek().withMinimumValue(); + Date beginDate = date.toDate(); + Date endDate = date.plusDays(6).toDate(); + return new Date[]{beginDate, endDate}; + } + + /** + * 对日期的【秒】进行加/减 + * + * @param date 日期 + * @param seconds 秒数,负数为减 + * @return 加/减几秒后的日期 + */ + public static Date addDateSeconds(Date date, int seconds) { + DateTime dateTime = new DateTime(date); + return dateTime.plusSeconds(seconds).toDate(); + } + + /** + * 对日期的【分钟】进行加/减 + * + * @param date 日期 + * @param minutes 分钟数,负数为减 + * @return 加/减几分钟后的日期 + */ + public static Date addDateMinutes(Date date, int minutes) { + DateTime dateTime = new DateTime(date); + return dateTime.plusMinutes(minutes).toDate(); + } + + /** + * 对日期的【小时】进行加/减 + * + * @param date 日期 + * @param hours 小时数,负数为减 + * @return 加/减几小时后的日期 + */ + public static Date addDateHours(Date date, int hours) { + DateTime dateTime = new DateTime(date); + return dateTime.plusHours(hours).toDate(); + } + + /** + * 对日期的【天】进行加/减 + * + * @param date 日期 + * @param days 天数,负数为减 + * @return 加/减几天后的日期 + */ + public static Date addDateDays(Date date, int days) { + DateTime dateTime = new DateTime(date); + return dateTime.plusDays(days).toDate(); + } + + /** + * 对日期的【周】进行加/减 + * + * @param date 日期 + * @param weeks 周数,负数为减 + * @return 加/减几周后的日期 + */ + public static Date addDateWeeks(Date date, int weeks) { + DateTime dateTime = new DateTime(date); + return dateTime.plusWeeks(weeks).toDate(); + } + + /** + * 对日期的【月】进行加/减 + * + * @param date 日期 + * @param months 月数,负数为减 + * @return 加/减几月后的日期 + */ + public static Date addDateMonths(Date date, int months) { + DateTime dateTime = new DateTime(date); + return dateTime.plusMonths(months).toDate(); + } + + /** + * 对日期的【年】进行加/减 + * + * @param date 日期 + * @param years 年数,负数为减 + * @return 加/减几年后的日期 + */ + public static Date addDateYears(Date date, int years) { + DateTime dateTime = new DateTime(date); + return dateTime.plusYears(years).toDate(); + } +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/utils/ExcelUtils.java b/face-server/src/main/java/com/dkha/server/system/common/utils/ExcelUtils.java new file mode 100644 index 0000000..93ab162 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/utils/ExcelUtils.java @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.utils; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.Workbook; +import org.springframework.beans.BeanUtils; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; + +/** + * excel工具类 + * + * @author Mark sunlightcs@gmail.com + */ +public class ExcelUtils { + + /** + * Excel导出 + * + * @param response response + * @param fileName 文件名 + * @param list 数据List + * @param pojoClass 对象Class + */ + public static void exportExcel(HttpServletResponse response, String fileName, Collection list, + Class pojoClass) throws IOException { + if(StringUtils.isBlank(fileName)){ + //当前日期 + fileName = DateUtils.format(new Date()); + } + + Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), pojoClass, list); + response.setCharacterEncoding("UTF-8"); + response.setHeader("content-Type", "application/vnd.ms-excel"); + response.setHeader("Content-Disposition", + "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xls"); + ServletOutputStream out = response.getOutputStream(); + workbook.write(out); + out.flush(); + } + + /** + * Excel导出,先sourceList转换成List,再导出 + * + * @param response response + * @param fileName 文件名 + * @param sourceList 原数据List + * @param targetClass 目标对象Class + */ + public static void exportExcelToTarget(HttpServletResponse response, String fileName, Collection sourceList, + Class targetClass) throws Exception { + List targetList = new ArrayList<>(sourceList.size()); + for(Object source : sourceList){ + Object target = targetClass.newInstance(); + BeanUtils.copyProperties(source, target); + targetList.add(target); + } + + exportExcel(response, fileName, targetList, targetClass); + } +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/utils/HttpContextUtils.java b/face-server/src/main/java/com/dkha/server/system/common/utils/HttpContextUtils.java new file mode 100644 index 0000000..10fa084 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/utils/HttpContextUtils.java @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.utils; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpHeaders; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +/** + * Http + * + * @author Mark sunlightcs@gmail.com + */ +public class HttpContextUtils { + + public static HttpServletRequest getHttpServletRequest() { + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); + if(requestAttributes == null){ + return null; + } + + return ((ServletRequestAttributes) requestAttributes).getRequest(); + } + + public static Map getParameterMap(HttpServletRequest request) { + Enumeration parameters = request.getParameterNames(); + + Map params = new HashMap<>(); + while (parameters.hasMoreElements()) { + String parameter = parameters.nextElement(); + String value = request.getParameter(parameter); + if (StringUtils.isNotBlank(value)) { + params.put(parameter, value); + } + } + + return params; + } + + public static String getDomain(){ + HttpServletRequest request = getHttpServletRequest(); + StringBuffer url = request.getRequestURL(); + return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString(); + } + + public static String getOrigin(){ + HttpServletRequest request = getHttpServletRequest(); + return request.getHeader(HttpHeaders.ORIGIN); + } + + public static String getLanguage() { + //默认语言 + String defaultLanguage = "zh-CN"; + //request + HttpServletRequest request = getHttpServletRequest(); + if(request == null){ + return defaultLanguage; + } + + //请求语言 + defaultLanguage = request.getHeader(HttpHeaders.ACCEPT_LANGUAGE); + + return defaultLanguage; + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/utils/IpUtils.java b/face-server/src/main/java/com/dkha/server/system/common/utils/IpUtils.java new file mode 100644 index 0000000..0a9bae1 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/utils/IpUtils.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.utils; + +import com.dkha.common.util.UtilValidate; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; + +/** + * IP地址 + * + * @author Mark sunlightcs@gmail.com + */ +public class IpUtils { + private static Logger logger = LoggerFactory.getLogger(IpUtils.class); + + /** + * 获取IP地址 + * + * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址 + * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址 + */ + public static String getIpAddr(HttpServletRequest request) { + String unknown = "unknown"; + String ip = null; + try { + ip = request.getHeader("x-forwarded-for"); + //nginx代理存在的情况下 + if (UtilValidate.isNotEmpty(ip) && ip.contains(",")) { + ip = ip.split(",")[0]; + } + if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (StringUtils.isEmpty(ip) || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } + if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + } catch (Exception e) { + logger.error("IPUtils ERROR ", e); + } + + return ip; + } + +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/utils/MessageUtils.java b/face-server/src/main/java/com/dkha/server/system/common/utils/MessageUtils.java new file mode 100644 index 0000000..ed30d43 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/utils/MessageUtils.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.utils; + +import com.dkha.common.util.SpringContextUtils; +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; + +/** + * 国际化 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class MessageUtils { + private static MessageSource messageSource; + static { + messageSource = (MessageSource) SpringContextUtils.getBean("messageSource"); + } + + public static String getMessage(int code){ + return getMessage(code, new String[0]); + } + + public static String getMessage(int code, String... params){ + return messageSource.getMessage(code+"", params, LocaleContextHolder.getLocale()); + } +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/utils/Result.java b/face-server/src/main/java/com/dkha/server/system/common/utils/Result.java new file mode 100644 index 0000000..b349824 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/utils/Result.java @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.utils; + +import com.dkha.server.system.common.exception.ErrorCode; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + +/** + * 响应数据 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@ApiModel(value = "响应") +public class Result implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 编码:0表示成功,其他值表示失败 + */ + @ApiModelProperty(value = "编码:0表示成功,其他值表示失败") + private int code = 0; + /** + * 消息内容 + */ + @ApiModelProperty(value = "消息内容") + private String msg = "success"; + /** + * 响应数据 + */ + @ApiModelProperty(value = "响应数据") + private T data; + + public Result ok(T data) { + this.setData(data); + return this; + } + + public boolean success(){ + return code == 0 ? true : false; + } + + public Result error() { + this.code = ErrorCode.INTERNAL_SERVER_ERROR; + this.msg = MessageUtils.getMessage(this.code); + return this; + } + + public Result error(int code) { + this.code = code; + this.msg = MessageUtils.getMessage(this.code); + return this; + } + + public Result error(int code, String msg) { + this.code = code; + this.msg = msg; + return this; + } + + public Result error(String msg) { + this.code = ErrorCode.INTERNAL_SERVER_ERROR; + this.msg = msg; + return this; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/utils/TreeNode.java b/face-server/src/main/java/com/dkha/server/system/common/utils/TreeNode.java new file mode 100644 index 0000000..65c1382 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/utils/TreeNode.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.utils; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * 树节点,所有需要实现树节点的,都需要继承该类 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class TreeNode implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 主键 + */ + private Long id; + /** + * 上级ID + */ + private Long pid; + /** + * 子节点列表 + */ + private List children = new ArrayList<>(); + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getPid() { + return pid; + } + + public void setPid(Long pid) { + this.pid = pid; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/utils/TreeUtils.java b/face-server/src/main/java/com/dkha/server/system/common/utils/TreeUtils.java new file mode 100644 index 0000000..960ba0d --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/utils/TreeUtils.java @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.utils; + + +import com.dkha.common.util.UtilValidate; +import com.dkha.server.system.common.validator.AssertUtils; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * 树形结构工具类,如:菜单、部门等 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class TreeUtils { + + /** + * 根据pid,构建树节点 + */ + public static List build(List treeNodes, Long pid) { + //pid不能为空 + AssertUtils.isNull(pid, "pid"); + + List treeList = new ArrayList<>(); + for(T treeNode : treeNodes) { + if (pid.equals(treeNode.getPid())) { + treeList.add(findChildren(treeNodes, treeNode)); + } + } + + return treeList; + } + + /** + * 查找子节点 + */ + private static T findChildren(List treeNodes, T rootNode) { + for(T treeNode : treeNodes) { + if(rootNode.getId().equals(treeNode.getPid())) { + rootNode.getChildren().add(findChildren(treeNodes, treeNode)); + } + } + return rootNode; + } + + /** + * 构建树节点 + */ + public static List build(List treeNodes) { + List result = new ArrayList<>(); + + //list转map + Map nodeMap = new LinkedHashMap<>(treeNodes.size()); + for(T treeNode : treeNodes){ + nodeMap.put(treeNode.getId(), treeNode); + } + + for(T node : nodeMap.values()) { + T parent = nodeMap.get(node.getPid()); + if(parent != null && UtilValidate.isNotEmpty(node.getId()) && !(node.getId().equals(parent.getId()))){ + parent.getChildren().add(node); + continue; + } + if (UtilValidate.isNotEmpty(node.getId())) { + result.add(node); + } + } + + return result; + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/validator/AssertUtils.java b/face-server/src/main/java/com/dkha/server/system/common/validator/AssertUtils.java new file mode 100644 index 0000000..ad87b0a --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/validator/AssertUtils.java @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.validator; + +import com.dkha.common.util.UtilValidate; +import com.dkha.server.system.common.exception.ErrorCode; +import com.dkha.server.system.common.exception.RenException; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * 校验工具类 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class AssertUtils { + + public static void isBlank(String str, String... params) { + isBlank(str, ErrorCode.NOT_NULL, params); + } + + public static void isBlank(String str, Integer code, String... params) { + if(code == null){ + throw new RenException(ErrorCode.NOT_NULL, "code"); + } + + if (StringUtils.isBlank(str)) { + throw new RenException(code, params); + } + } + + public static void isNull(Object object, String... params) { + isNull(object, ErrorCode.NOT_NULL, params); + } + + public static void isNull(Object object, Integer code, String... params) { + if(code == null){ + throw new RenException(ErrorCode.NOT_NULL, "code"); + } + + if (object == null) { + throw new RenException(code, params); + } + } + + public static void isArrayEmpty(Object[] array, String... params) { + isArrayEmpty(array, ErrorCode.NOT_NULL, params); + } + + public static void isArrayEmpty(Object[] array, Integer code, String... params) { + if(code == null){ + throw new RenException(ErrorCode.NOT_NULL, "code"); + } + + if(UtilValidate.isEmpty(array)){ + throw new RenException(code, params); + } + } + + public static void isListEmpty(List list, String... params) { + isListEmpty(list, ErrorCode.NOT_NULL, params); + } + + public static void isListEmpty(List list, Integer code, String... params) { + if(code == null){ + throw new RenException(ErrorCode.NOT_NULL, "code"); + } + + if(UtilValidate.isEmpty(list)){ + throw new RenException(code, params); + } + } + + public static void isMapEmpty(Map map, String... params) { + isMapEmpty(map, ErrorCode.NOT_NULL, params); + } + + public static void isMapEmpty(Map map, Integer code, String... params) { + if(code == null){ + throw new RenException(ErrorCode.NOT_NULL, "code"); + } + + if(UtilValidate.isEmpty(map)){ + throw new RenException(code, params); + } + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/validator/ValidatorUtils.java b/face-server/src/main/java/com/dkha/server/system/common/validator/ValidatorUtils.java new file mode 100644 index 0000000..d4a3d7a --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/validator/ValidatorUtils.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.validator; + +import com.dkha.server.system.common.exception.RenException; +import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.context.support.ResourceBundleMessageSource; +import org.springframework.validation.beanvalidation.MessageSourceResourceBundleLocator; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import java.util.Locale; +import java.util.Set; + +/** + * hibernate-validator校验工具类 + * 参考文档:http://docs.jboss.org/hibernate/validator/6.0/reference/en-US/html_single/ + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class ValidatorUtils { + + private static ResourceBundleMessageSource getMessageSource() { + ResourceBundleMessageSource bundleMessageSource = new ResourceBundleMessageSource(); + bundleMessageSource.setDefaultEncoding("UTF-8"); + bundleMessageSource.setBasenames("i18n/validation"); + return bundleMessageSource; + } + + /** + * 校验对象 + * @param object 待校验对象 + * @param groups 待校验的组 + */ + public static void validateEntity(Object object, Class... groups) + throws RenException { + Locale.setDefault(LocaleContextHolder.getLocale()); + Validator validator = Validation.byDefaultProvider().configure().messageInterpolator( + new ResourceBundleMessageInterpolator(new MessageSourceResourceBundleLocator(getMessageSource()))) + .buildValidatorFactory().getValidator(); + + Set> constraintViolations = validator.validate(object, groups); + if (!constraintViolations.isEmpty()) { + ConstraintViolation constraint = constraintViolations.iterator().next(); + throw new RenException(constraint.getMessage()); + } + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/validator/group/AddGroup.java b/face-server/src/main/java/com/dkha/server/system/common/validator/group/AddGroup.java new file mode 100644 index 0000000..bfc7ea1 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/validator/group/AddGroup.java @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.validator.group; + +/** + * 新增 Group + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface AddGroup { + +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/validator/group/AliyunGroup.java b/face-server/src/main/java/com/dkha/server/system/common/validator/group/AliyunGroup.java new file mode 100644 index 0000000..4666b48 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/validator/group/AliyunGroup.java @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.validator.group; + +/** + * 阿里云 + * + * @author Mark sunlightcs@gmail.com + */ +public interface AliyunGroup { +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/validator/group/DefaultGroup.java b/face-server/src/main/java/com/dkha/server/system/common/validator/group/DefaultGroup.java new file mode 100644 index 0000000..2a90285 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/validator/group/DefaultGroup.java @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.validator.group; + +/** + * 默认 Group + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface DefaultGroup { + +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/validator/group/FastDFSGroup.java b/face-server/src/main/java/com/dkha/server/system/common/validator/group/FastDFSGroup.java new file mode 100644 index 0000000..c3f2f9c --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/validator/group/FastDFSGroup.java @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.validator.group; + +/** + * FastDFS + * + * @author Mark sunlightcs@gmail.com + */ +public interface FastDFSGroup { +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/validator/group/Group.java b/face-server/src/main/java/com/dkha/server/system/common/validator/group/Group.java new file mode 100644 index 0000000..533cc52 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/validator/group/Group.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.validator.group; + +import javax.validation.GroupSequence; + +/** + * 定义校验顺序,如果AddGroup组失败,则UpdateGroup组不会再校验 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@GroupSequence({AddGroup.class, UpdateGroup.class}) +public interface Group { + +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/validator/group/LocalGroup.java b/face-server/src/main/java/com/dkha/server/system/common/validator/group/LocalGroup.java new file mode 100644 index 0000000..4b6991c --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/validator/group/LocalGroup.java @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.validator.group; + +/** + * 本地上传 + * + * @author Mark sunlightcs@gmail.com + */ +public interface LocalGroup { +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/validator/group/QcloudGroup.java b/face-server/src/main/java/com/dkha/server/system/common/validator/group/QcloudGroup.java new file mode 100644 index 0000000..dafee40 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/validator/group/QcloudGroup.java @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.validator.group; + +/** + * 腾讯云 + * + * @author Mark sunlightcs@gmail.com + */ +public interface QcloudGroup { +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/validator/group/QiniuGroup.java b/face-server/src/main/java/com/dkha/server/system/common/validator/group/QiniuGroup.java new file mode 100644 index 0000000..de9611c --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/validator/group/QiniuGroup.java @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.validator.group; + +/** + * 七牛 + * + * @author Mark sunlightcs@gmail.com + */ +public interface QiniuGroup { +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/validator/group/TreeNode.java b/face-server/src/main/java/com/dkha/server/system/common/validator/group/TreeNode.java new file mode 100644 index 0000000..6db399a --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/validator/group/TreeNode.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.validator.group; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * 树节点,所有需要实现树节点的,都需要继承该类 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class TreeNode implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 主键 + */ + private Long id; + /** + * 上级ID + */ + private Long pid; + /** + * 子节点列表 + */ + private List children = new ArrayList<>(); + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getPid() { + return pid; + } + + public void setPid(Long pid) { + this.pid = pid; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/validator/group/UpdateGroup.java b/face-server/src/main/java/com/dkha/server/system/common/validator/group/UpdateGroup.java new file mode 100644 index 0000000..6526524 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/validator/group/UpdateGroup.java @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.validator.group; + +/** + * 修改 Group + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface UpdateGroup { + +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/xss/SqlFilter.java b/face-server/src/main/java/com/dkha/server/system/common/xss/SqlFilter.java new file mode 100644 index 0000000..c8dc6c3 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/xss/SqlFilter.java @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.xss; + +import com.dkha.server.system.common.exception.ErrorCode; +import com.dkha.server.system.common.exception.RenException; +import org.apache.commons.lang3.StringUtils; + +/** + * SQL过滤 + * @author Mark sunlightcs@gmail.com + */ +public class SqlFilter { + + /** + * SQL注入过滤 + * @param str 待验证的字符串 + */ + public static String sqlInject(String str){ + if(StringUtils.isBlank(str)){ + return null; + } + //去掉'|"|;|\字符 + str = StringUtils.replace(str, "'", ""); + str = StringUtils.replace(str, "\"", ""); + str = StringUtils.replace(str, ";", ""); + str = StringUtils.replace(str, "\\", ""); + + //转换成小写 + str = str.toLowerCase(); + + //非法字符 + String[] keywords = {"master", "truncate", "insert", "select", "delete", "update", "declare", "alter", "drop"}; + + //判断是否包含非法字符 + for(String keyword : keywords){ + if(str.indexOf(keyword) != -1){ + throw new RenException(ErrorCode.INVALID_SYMBOL); + } + } + + return str; + } +} diff --git a/face-server/src/main/java/com/dkha/server/system/common/xss/XssFilter.java b/face-server/src/main/java/com/dkha/server/system/common/xss/XssFilter.java new file mode 100644 index 0000000..323cff9 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/xss/XssFilter.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.xss; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; + +/** + * XSS过滤 + * @author Mark sunlightcs@gmail.com + */ +public class XssFilter implements Filter { + + @Override + public void init(FilterConfig config) throws ServletException { + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper( + (HttpServletRequest) request); + chain.doFilter(xssRequest, response); + } + + @Override + public void destroy() { + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/xss/XssHttpServletRequestWrapper.java b/face-server/src/main/java/com/dkha/server/system/common/xss/XssHttpServletRequestWrapper.java new file mode 100644 index 0000000..c094111 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/xss/XssHttpServletRequestWrapper.java @@ -0,0 +1,147 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.xss; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.LinkedHashMap; +import java.util.Map; + + +/** + * XSS过滤处理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { + HttpServletRequest orgRequest; + + public XssHttpServletRequestWrapper(HttpServletRequest request) { + super(request); + orgRequest = request; + } + + @Override + public ServletInputStream getInputStream() throws IOException { + //非json类型,直接返回 + if(!MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(super.getHeader(HttpHeaders.CONTENT_TYPE))){ + return super.getInputStream(); + } + + //为空,直接返回 + String json = IOUtils.toString(super.getInputStream(), StandardCharsets.UTF_8); + if (StringUtils.isBlank(json)) { + return super.getInputStream(); + } + + //xss过滤 + json = xssEncode(json); + final ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8)); + return new ServletInputStream() { + @Override + public boolean isFinished() { + return true; + } + + @Override + public boolean isReady() { + return true; + } + + @Override + public void setReadListener(ReadListener readListener) { + + } + + @Override + public int read() { + return bis.read(); + } + }; + } + + @Override + public String getParameter(String name) { + String value = super.getParameter(xssEncode(name)); + if (StringUtils.isNotBlank(value)) { + value = xssEncode(value); + } + return value; + } + + @Override + public String[] getParameterValues(String name) { + String[] parameters = super.getParameterValues(name); + if (parameters == null || parameters.length == 0) { + return null; + } + + for (int i = 0; i < parameters.length; i++) { + parameters[i] = xssEncode(parameters[i]); + } + return parameters; + } + + @Override + public Map getParameterMap() { + Map map = new LinkedHashMap<>(); + Map parameters = super.getParameterMap(); + for (String key : parameters.keySet()) { + String[] values = parameters.get(key); + for (int i = 0; i < values.length; i++) { + values[i] = xssEncode(values[i]); + } + map.put(key, values); + } + return map; + } + + @Override + public String getHeader(String name) { + String value = super.getHeader(xssEncode(name)); + if (StringUtils.isNotBlank(value)) { + value = xssEncode(value); + } + return value; + } + + private String xssEncode(String input) { + return XssUtils.filter(input); + } + + /** + * 获取最原始的request + */ + public HttpServletRequest getOrgRequest() { + return orgRequest; + } + + /** + * 获取最原始的request + */ + public static HttpServletRequest getOrgRequest(HttpServletRequest request) { + if (request instanceof XssHttpServletRequestWrapper) { + return ((XssHttpServletRequestWrapper) request).getOrgRequest(); + } + + return request; + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/common/xss/XssUtils.java b/face-server/src/main/java/com/dkha/server/system/common/xss/XssUtils.java new file mode 100644 index 0000000..92f8155 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/common/xss/XssUtils.java @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.common.xss; + +import org.jsoup.Jsoup; +import org.jsoup.safety.Whitelist; + +/** + * XSS过滤工具类 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class XssUtils extends Whitelist { + + /** + * XSS过滤 + */ + public static String filter(String html){ + return Jsoup.clean(html, xssWhitelist()); + } + + /** + * XSS过滤白名单 + */ + private static Whitelist xssWhitelist(){ + return new Whitelist() + //支持的标签 + .addTags("a", "b", "blockquote", "br", "caption", "cite", "code", "col", "colgroup", "dd", "div", "dl", + "dt", "em", "h1", "h2", "h3", "h4", "h5", "h6", "i", "img", "li", "ol", "p", "pre", "q", "small", + "strike", "strong","sub", "sup", "table", "tbody", "td","tfoot", "th", "thead", "tr", "u","ul", + "embed","object","param","span") + + //支持的标签属性 + .addAttributes("a", "href", "class", "style", "target", "rel", "nofollow") + .addAttributes("blockquote", "cite") + .addAttributes("code", "class", "style") + .addAttributes("col", "span", "width") + .addAttributes("colgroup", "span", "width") + .addAttributes("img", "align", "alt", "height", "src", "title", "width", "class", "style") + .addAttributes("ol", "start", "type") + .addAttributes("q", "cite") + .addAttributes("table", "summary", "width", "class", "style") + .addAttributes("tr", "abbr", "axis", "colspan", "rowspan", "width", "style") + .addAttributes("td", "abbr", "axis", "colspan", "rowspan", "width", "style") + .addAttributes("th", "abbr", "axis", "colspan", "rowspan", "scope","width", "style") + .addAttributes("ul", "type", "style") + .addAttributes("pre", "class", "style") + .addAttributes("div", "class", "id", "style") + .addAttributes("embed", "src", "wmode", "flashvars", "pluginspage", "allowFullScreen", "allowfullscreen", + "quality", "width", "height", "align", "allowScriptAccess", "allowscriptaccess", "allownetworking", "type") + .addAttributes("object", "type", "id", "name", "data", "width", "height", "style", "classid", "codebase") + .addAttributes("param", "name", "value") + .addAttributes("span", "class", "style") + + //标签属性对应的协议 + .addProtocols("a", "href", "ftp", "http", "https", "mailto") + .addProtocols("img", "src", "http", "https") + .addProtocols("blockquote", "cite", "http", "https") + .addProtocols("cite", "cite", "http", "https") + .addProtocols("q", "cite", "http", "https") + .addProtocols("embed", "src", "http", "https"); + } + + public static void main(String[] args) { + StringBuilder html = new StringBuilder(); + html.append("人人开源"); + + System.out.println(filter(html.toString())); + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/controller/SysLogErrorController.java b/face-server/src/main/java/com/dkha/server/system/modules/log/controller/SysLogErrorController.java new file mode 100644 index 0000000..0835177 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/controller/SysLogErrorController.java @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.controller; + +import com.dkha.server.system.common.annotation.LogOperation; +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.utils.ExcelUtils; +import com.dkha.server.system.common.utils.Result; +import com.dkha.server.system.modules.log.dto.SysLogErrorDTO; +import com.dkha.server.system.modules.log.excel.SysLogErrorExcel; +import com.dkha.server.system.modules.log.service.SysLogErrorService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +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.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + + +/** + * 异常日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@RestController +@RequestMapping("sys/log/error") +@Api(tags="异常日志") +public class SysLogErrorController { + @Autowired + private SysLogErrorService sysLogErrorService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") + }) + @RequiresPermissions("sys:log:error") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = sysLogErrorService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @RequiresPermissions("sys:log:error") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = sysLogErrorService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, SysLogErrorExcel.class); + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/controller/SysLogLoginController.java b/face-server/src/main/java/com/dkha/server/system/modules/log/controller/SysLogLoginController.java new file mode 100644 index 0000000..13e571a --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/controller/SysLogLoginController.java @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.controller; + +import com.dkha.server.system.common.annotation.LogOperation; +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.utils.ExcelUtils; +import com.dkha.server.system.common.utils.Result; +import com.dkha.server.system.modules.log.dto.SysLogLoginDTO; +import com.dkha.server.system.modules.log.excel.SysLogLoginExcel; +import com.dkha.server.system.modules.log.service.SysLogLoginService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +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.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + + +/** + * 登录日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@RestController +@RequestMapping("sys/log/login") +@Api(tags="登录日志") +public class SysLogLoginController { + @Autowired + private SysLogLoginService sysLogLoginService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") , + @ApiImplicitParam(name = "status", value = "状态 0:失败 1:成功 2:账号已锁定", paramType = "query", dataType="int"), + @ApiImplicitParam(name = "creatorName", value = "用户名", paramType = "query", dataType="String") + }) + @RequiresPermissions("sys:log:login") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = sysLogLoginService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @ApiImplicitParams({ + @ApiImplicitParam(name = "status", value = "状态 0:失败 1:成功 2:账号已锁定", paramType = "query", dataType="int"), + @ApiImplicitParam(name = "creatorName", value = "用户名", paramType = "query", dataType="String") + }) + @RequiresPermissions("sys:log:login") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = sysLogLoginService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, SysLogLoginExcel.class); + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/controller/SysLogOperationController.java b/face-server/src/main/java/com/dkha/server/system/modules/log/controller/SysLogOperationController.java new file mode 100644 index 0000000..5376cc9 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/controller/SysLogOperationController.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.controller; + +import com.dkha.server.system.common.annotation.LogOperation; +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.utils.ExcelUtils; +import com.dkha.server.system.common.utils.Result; +import com.dkha.server.system.modules.log.dto.SysLogOperationDTO; +import com.dkha.server.system.modules.log.excel.SysLogOperationExcel; +import com.dkha.server.system.modules.log.service.SysLogOperationService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +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.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + + +/** + * 操作日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@RestController +@RequestMapping("sys/log/operation") +@Api(tags="操作日志") +public class SysLogOperationController { + @Autowired + private SysLogOperationService sysLogOperationService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") , + @ApiImplicitParam(name = "status", value = "状态 0:失败 1:成功", paramType = "query", dataType="int") + }) + @RequiresPermissions("sys:log:operation") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = sysLogOperationService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @RequiresPermissions("sys:log:operation") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = sysLogOperationService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, SysLogOperationExcel.class); + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/dao/SysLogErrorDao.java b/face-server/src/main/java/com/dkha/server/system/modules/log/dao/SysLogErrorDao.java new file mode 100644 index 0000000..a7e1161 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/dao/SysLogErrorDao.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.dao; + +import com.dkha.server.system.common.dao.BaseDao; +import com.dkha.server.system.modules.log.entity.SysLogErrorEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 异常日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Mapper +public interface SysLogErrorDao extends BaseDao { + +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/dao/SysLogLoginDao.java b/face-server/src/main/java/com/dkha/server/system/modules/log/dao/SysLogLoginDao.java new file mode 100644 index 0000000..5ef5b3b --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/dao/SysLogLoginDao.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.dao; + +import com.dkha.server.system.common.dao.BaseDao; +import com.dkha.server.system.modules.log.entity.SysLogLoginEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 登录日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Mapper +public interface SysLogLoginDao extends BaseDao { + +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/dao/SysLogOperationDao.java b/face-server/src/main/java/com/dkha/server/system/modules/log/dao/SysLogOperationDao.java new file mode 100644 index 0000000..f4d9c7a --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/dao/SysLogOperationDao.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.dao; + +import com.dkha.server.system.common.dao.BaseDao; +import com.dkha.server.system.modules.log.entity.SysLogOperationEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 操作日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Mapper +public interface SysLogOperationDao extends BaseDao { + +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/dto/SysLogErrorDTO.java b/face-server/src/main/java/com/dkha/server/system/modules/log/dto/SysLogErrorDTO.java new file mode 100644 index 0000000..4fabea9 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/dto/SysLogErrorDTO.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 异常日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@ApiModel(value = "异常日志") +public class SysLogErrorDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + private Long id; + @ApiModelProperty(value = "请求URI") + private String requestUri; + @ApiModelProperty(value = "请求方式") + private String requestMethod; + @ApiModelProperty(value = "请求参数") + private String requestParams; + @ApiModelProperty(value = "用户代理") + private String userAgent; + @ApiModelProperty(value = "操作IP") + private String ip; + @ApiModelProperty(value = "异常信息") + private String errorInfo; + @ApiModelProperty(value = "创建时间") + private Date createDate; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/dto/SysLogLoginDTO.java b/face-server/src/main/java/com/dkha/server/system/modules/log/dto/SysLogLoginDTO.java new file mode 100644 index 0000000..28cd591 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/dto/SysLogLoginDTO.java @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 登录日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@ApiModel(value = "登录日志") +public class SysLogLoginDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + private Long id; + + @ApiModelProperty(value = "用户操作 0:用户登录 1:用户退出") + private Integer operation; + + @ApiModelProperty(value = "状态 0:失败 1:成功 2:账号已锁定") + private Integer status; + + @ApiModelProperty(value = "用户代理") + private String userAgent; + + @ApiModelProperty(value = "操作IP") + private String ip; + + @ApiModelProperty(value = "用户名") + private String creatorName; + + @ApiModelProperty(value = "创建时间") + private Date createDate; + +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/dto/SysLogOperationDTO.java b/face-server/src/main/java/com/dkha/server/system/modules/log/dto/SysLogOperationDTO.java new file mode 100644 index 0000000..3678a7b --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/dto/SysLogOperationDTO.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 操作日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@ApiModel(value = "操作日志") +public class SysLogOperationDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + private Long id; + + @ApiModelProperty(value = "用户操作") + private String operation; + + @ApiModelProperty(value = "请求URI") + private String requestUri; + + @ApiModelProperty(value = "请求方式") + private String requestMethod; + + @ApiModelProperty(value = "请求参数") + private String requestParams; + + @ApiModelProperty(value = "请求时长(毫秒)") + private Integer requestTime; + + @ApiModelProperty(value = "用户代理") + private String userAgent; + + @ApiModelProperty(value = "操作IP") + private String ip; + + @ApiModelProperty(value = "状态 0:失败 1:成功") + private Integer status; + + @ApiModelProperty(value = "用户名") + private String creatorName; + + @ApiModelProperty(value = "创建时间") + private Date createDate; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/entity/SysLogErrorEntity.java b/face-server/src/main/java/com/dkha/server/system/modules/log/entity/SysLogErrorEntity.java new file mode 100644 index 0000000..7368651 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/entity/SysLogErrorEntity.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.dkha.server.system.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 异常日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_log_error") +public class SysLogErrorEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 请求URI + */ + private String requestUri; + /** + * 请求方式 + */ + private String requestMethod; + /** + * 请求参数 + */ + private String requestParams; + /** + * 用户代理 + */ + private String userAgent; + /** + * 操作IP + */ + private String ip; + /** + * 异常信息 + */ + private String errorInfo; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/entity/SysLogLoginEntity.java b/face-server/src/main/java/com/dkha/server/system/modules/log/entity/SysLogLoginEntity.java new file mode 100644 index 0000000..eb1211d --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/entity/SysLogLoginEntity.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.dkha.server.system.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 登录日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_log_login") +public class SysLogLoginEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 用户操作 0:用户登录 1:用户退出 + */ + private Integer operation; + /** + * 状态 0:失败 1:成功 2:账号已锁定 + */ + private Integer status; + /** + * 用户代理 + */ + private String userAgent; + /** + * 操作IP + */ + private String ip; + /** + * 用户名 + */ + private String creatorName; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/entity/SysLogOperationEntity.java b/face-server/src/main/java/com/dkha/server/system/modules/log/entity/SysLogOperationEntity.java new file mode 100644 index 0000000..66f0fad --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/entity/SysLogOperationEntity.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.dkha.server.system.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 操作日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_log_operation") +public class SysLogOperationEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 用户操作 + */ + private String operation; + /** + * 请求URI + */ + private String requestUri; + /** + * 请求方式 + */ + private String requestMethod; + /** + * 请求参数 + */ + private String requestParams; + /** + * 请求时长(毫秒) + */ + private Integer requestTime; + /** + * 用户代理 + */ + private String userAgent; + /** + * 操作IP + */ + private String ip; + /** + * 状态 0:失败 1:成功 + */ + private Integer status; + /** + * 用户名 + */ + private String creatorName; +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/enums/LoginOperationEnum.java b/face-server/src/main/java/com/dkha/server/system/modules/log/enums/LoginOperationEnum.java new file mode 100644 index 0000000..1ca0967 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/enums/LoginOperationEnum.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.enums; + +/** + * 登录操作枚举 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public enum LoginOperationEnum { + /** + * 用户登录 + */ + LOGIN(0), + /** + * 用户退出 + */ + LOGOUT(1); + + private int value; + + LoginOperationEnum(int value) { + this.value = value; + } + + public int value() { + return this.value; + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/enums/LoginStatusEnum.java b/face-server/src/main/java/com/dkha/server/system/modules/log/enums/LoginStatusEnum.java new file mode 100644 index 0000000..bb7ec23 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/enums/LoginStatusEnum.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.enums; + +/** + * 登录状态枚举 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public enum LoginStatusEnum { + /** + * 失败 + */ + FAIL(0), + /** + * 成功 + */ + SUCCESS(1), + /** + * 账号已锁定 + */ + LOCK(2); + + private int value; + + LoginStatusEnum(int value) { + this.value = value; + } + + public int value() { + return this.value; + } +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/enums/OperationStatusEnum.java b/face-server/src/main/java/com/dkha/server/system/modules/log/enums/OperationStatusEnum.java new file mode 100644 index 0000000..3b4ee66 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/enums/OperationStatusEnum.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.enums; + +/** + * 操作状态枚举 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public enum OperationStatusEnum { + /** + * 失败 + */ + FAIL(0), + /** + * 成功 + */ + SUCCESS(1); + + private int value; + + OperationStatusEnum(int value) { + this.value = value; + } + + public int value() { + return this.value; + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/excel/SysLogErrorExcel.java b/face-server/src/main/java/com/dkha/server/system/modules/log/excel/SysLogErrorExcel.java new file mode 100644 index 0000000..d194d36 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/excel/SysLogErrorExcel.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.util.Date; + +/** + * 异常日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +public class SysLogErrorExcel { + @Excel(name = "请求URI") + private String requestUri; + @Excel(name = "请求方式") + private String requestMethod; + @Excel(name = "请求参数") + private String requestParams; + @Excel(name = "User-Agent") + private String userAgent; + @Excel(name = "操作IP") + private String ip; + @Excel(name = "创建时间", format = "yyyy-MM-dd HH:mm:ss") + private Date createDate; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/excel/SysLogLoginExcel.java b/face-server/src/main/java/com/dkha/server/system/modules/log/excel/SysLogLoginExcel.java new file mode 100644 index 0000000..cca6afb --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/excel/SysLogLoginExcel.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.util.Date; + +/** + * 登录日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +public class SysLogLoginExcel { + @Excel(name = "用户操作") + private String operation; + @Excel(name = "状态", replace = {"失败_0", "成功_1", "账号已锁定_1"}) + private Integer status; + @Excel(name = "User-Agent") + private String userAgent; + @Excel(name = "操作IP") + private String ip; + @Excel(name = "用户名") + private String creatorName; + @Excel(name = "创建时间", format = "yyyy-MM-dd HH:mm:ss") + private Date createDate; + +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/excel/SysLogOperationExcel.java b/face-server/src/main/java/com/dkha/server/system/modules/log/excel/SysLogOperationExcel.java new file mode 100644 index 0000000..43fecf6 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/excel/SysLogOperationExcel.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.util.Date; + +/** + * 操作日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +public class SysLogOperationExcel { + @Excel(name = "用户操作") + private String operation; + @Excel(name = "请求URI") + private String requestUri; + @Excel(name = "请求方式") + private String requestMethod; + @Excel(name = "请求参数") + private String requestParams; + @Excel(name = "请求时长(毫秒)") + private Integer requestTime; + @Excel(name = "User-Agent") + private String userAgent; + @Excel(name = "操作IP") + private String ip; + @Excel(name = "状态", replace = {"失败_0", "成功_1"}) + private Integer status; + @Excel(name = "用户名") + private String creatorName; + @Excel(name = "创建时间", format = "yyyy-MM-dd HH:mm:ss") + private Date createDate; + +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/service/SysLogErrorService.java b/face-server/src/main/java/com/dkha/server/system/modules/log/service/SysLogErrorService.java new file mode 100644 index 0000000..e0ff1b3 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/service/SysLogErrorService.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.service; + + + +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.service.BaseService; +import com.dkha.server.system.modules.log.dto.SysLogErrorDTO; +import com.dkha.server.system.modules.log.entity.SysLogErrorEntity; + +import java.util.List; +import java.util.Map; + +/** + * 异常日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface SysLogErrorService extends BaseService { + + PageData page(Map params); + + List list(Map params); + + void save(SysLogErrorEntity entity); + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/service/SysLogLoginService.java b/face-server/src/main/java/com/dkha/server/system/modules/log/service/SysLogLoginService.java new file mode 100644 index 0000000..6e63ca8 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/service/SysLogLoginService.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.service; + + +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.service.BaseService; +import com.dkha.server.system.modules.log.dto.SysLogLoginDTO; +import com.dkha.server.system.modules.log.entity.SysLogLoginEntity; + +import java.util.List; +import java.util.Map; + +/** + * 登录日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface SysLogLoginService extends BaseService { + + PageData page(Map params); + + List list(Map params); + + void save(SysLogLoginEntity entity); +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/service/SysLogOperationService.java b/face-server/src/main/java/com/dkha/server/system/modules/log/service/SysLogOperationService.java new file mode 100644 index 0000000..1c514ca --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/service/SysLogOperationService.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.service; + + +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.service.BaseService; +import com.dkha.server.system.modules.log.dto.SysLogOperationDTO; +import com.dkha.server.system.modules.log.entity.SysLogOperationEntity; + +import java.util.List; +import java.util.Map; + +/** + * 操作日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface SysLogOperationService extends BaseService { + + PageData page(Map params); + + List list(Map params); + + void save(SysLogOperationEntity entity); +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/service/impl/SysLogErrorServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/modules/log/service/impl/SysLogErrorServiceImpl.java new file mode 100644 index 0000000..f052957 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/service/impl/SysLogErrorServiceImpl.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.service.impl.BaseServiceImpl; +import com.dkha.server.system.common.utils.ConvertUtils; +import com.dkha.server.system.modules.log.dao.SysLogErrorDao; +import com.dkha.server.system.modules.log.dto.SysLogErrorDTO; +import com.dkha.server.system.modules.log.entity.SysLogErrorEntity; +import com.dkha.server.system.modules.log.service.SysLogErrorService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +/** + * 异常日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Service +public class SysLogErrorServiceImpl extends BaseServiceImpl implements SysLogErrorService { + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, Constant.CREATE_DATE, false), + getWrapper(params) + ); + + return getPageData(page, SysLogErrorDTO.class); + } + + @Override + public List list(Map params) { + List entityList = baseDao.selectList(getWrapper(params)); + + return ConvertUtils.sourceToTarget(entityList, SysLogErrorDTO.class); + } + + private QueryWrapper getWrapper(Map params){ + QueryWrapper wrapper = new QueryWrapper<>(); + return wrapper; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysLogErrorEntity entity) { + insert(entity); + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/service/impl/SysLogLoginServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/modules/log/service/impl/SysLogLoginServiceImpl.java new file mode 100644 index 0000000..28a98d1 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/service/impl/SysLogLoginServiceImpl.java @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.service.impl.BaseServiceImpl; +import com.dkha.server.system.common.utils.ConvertUtils; +import com.dkha.server.system.modules.log.dao.SysLogLoginDao; +import com.dkha.server.system.modules.log.dto.SysLogLoginDTO; +import com.dkha.server.system.modules.log.entity.SysLogLoginEntity; +import com.dkha.server.system.modules.log.service.SysLogLoginService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +/** + * 登录日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Service +public class SysLogLoginServiceImpl extends BaseServiceImpl implements SysLogLoginService { + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, Constant.CREATE_DATE, false), + getWrapper(params) + ); + + return getPageData(page, SysLogLoginDTO.class); + } + + @Override + public List list(Map params) { + List entityList = baseDao.selectList(getWrapper(params)); + + return ConvertUtils.sourceToTarget(entityList, SysLogLoginDTO.class); + } + + private QueryWrapper getWrapper(Map params){ + String status = (String) params.get("status"); + String creatorName = (String) params.get("creatorName"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(UtilValidate.isNotEmpty(status), "status", status); + wrapper.like(UtilValidate.isNotEmpty(creatorName), "creator_name", creatorName); + + return wrapper; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysLogLoginEntity entity) { + insert(entity); + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/log/service/impl/SysLogOperationServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/modules/log/service/impl/SysLogOperationServiceImpl.java new file mode 100644 index 0000000..67fbc55 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/log/service/impl/SysLogOperationServiceImpl.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.log.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.service.impl.BaseServiceImpl; +import com.dkha.server.system.common.utils.ConvertUtils; +import com.dkha.server.system.modules.log.dao.SysLogOperationDao; +import com.dkha.server.system.modules.log.dto.SysLogOperationDTO; +import com.dkha.server.system.modules.log.entity.SysLogOperationEntity; +import com.dkha.server.system.modules.log.service.SysLogOperationService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +/** + * 操作日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Service +public class SysLogOperationServiceImpl extends BaseServiceImpl implements SysLogOperationService { + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, Constant.CREATE_DATE, false), + getWrapper(params) + ); + + return getPageData(page, SysLogOperationDTO.class); + } + + @Override + public List list(Map params) { + List entityList = baseDao.selectList(getWrapper(params)); + + return ConvertUtils.sourceToTarget(entityList, SysLogOperationDTO.class); + } + + private QueryWrapper getWrapper(Map params){ + String status = (String) params.get("status"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(StringUtils.isNotBlank(status), "status", status); + + return wrapper; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysLogOperationEntity entity) { + insert(entity); + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/config/FilterConfig.java b/face-server/src/main/java/com/dkha/server/system/modules/security/config/FilterConfig.java new file mode 100644 index 0000000..a6ff96d --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/config/FilterConfig.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.security.config; + +import com.dkha.server.system.common.xss.XssFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.filter.DelegatingFilterProxy; + +import javax.servlet.DispatcherType; + +/** + * Filter配置 + * + * @author Mark sunlightcs@gmail.com + */ +@Configuration +public class FilterConfig { + + @Bean + public FilterRegistrationBean shiroFilterRegistration() { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setFilter(new DelegatingFilterProxy("shiroFilter")); + //该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 + registration.addInitParameter("targetFilterLifecycle", "true"); + registration.setEnabled(true); + registration.setOrder(Integer.MAX_VALUE - 1); + registration.addUrlPatterns("/*"); + return registration; + } + + @Bean + public FilterRegistrationBean xssFilterRegistration() { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setDispatcherTypes(DispatcherType.REQUEST); + registration.setFilter(new XssFilter()); + registration.addUrlPatterns("/*"); + registration.setName("xssFilter"); + registration.setOrder(Integer.MAX_VALUE); + return registration; + } +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/config/ShiroConfig.java b/face-server/src/main/java/com/dkha/server/system/modules/security/config/ShiroConfig.java new file mode 100644 index 0000000..820a53a --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/config/ShiroConfig.java @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.security.config; + +import com.dkha.server.system.modules.security.oauth2.Oauth2Filter; +import com.dkha.server.system.modules.security.oauth2.Oauth2Realm; +import org.apache.shiro.mgt.SecurityManager; +import org.apache.shiro.session.mgt.SessionManager; +import org.apache.shiro.spring.LifecycleBeanPostProcessor; +import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; +import org.apache.shiro.spring.web.ShiroFilterFactoryBean; +import org.apache.shiro.web.mgt.DefaultWebSecurityManager; +import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.servlet.Filter; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Shiro的配置文件 + * + * @author Mark sunlightcs@gmail.com + */ +@Configuration +public class ShiroConfig { + + @Bean + public DefaultWebSessionManager sessionManager() { + DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); + sessionManager.setSessionValidationSchedulerEnabled(false); + sessionManager.setSessionIdUrlRewritingEnabled(false); + + return sessionManager; + } + + @Bean("securityManager") + public SecurityManager securityManager(Oauth2Realm oAuth2Realm, SessionManager sessionManager) { + DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); + securityManager.setRealm(oAuth2Realm); + securityManager.setSessionManager(sessionManager); + securityManager.setRememberMeManager(null); + return securityManager; + } + + @Bean + public Oauth2Filter oauth2Filter() { + return new Oauth2Filter(); + } + + @Bean("shiroFilter") + public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) { + ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); + shiroFilter.setSecurityManager(securityManager); + + //oauth过滤 + Map filters = new HashMap<>(); + filters.put("oauth2", new Oauth2Filter()); + shiroFilter.setFilters(filters); + + Map filterMap = new LinkedHashMap<>(); + filterMap.put("/faces/callback", "anon"); + filterMap.put("/webjars/**", "anon"); + filterMap.put("/druid/**", "anon"); + filterMap.put("/login", "anon"); + filterMap.put("/swagger/**", "anon"); + filterMap.put("/v2/api-docs", "anon"); + filterMap.put("/swagger-ui.html", "anon"); + filterMap.put("/swagger-resources/**", "anon"); + filterMap.put("/service/**", "anon"); + filterMap.put("/editor-app/**", "anon"); + filterMap.put("/diagram-viewer/**", "anon"); + filterMap.put("/modeler.html", "anon"); + filterMap.put("/captcha", "anon"); + filterMap.put("/favicon.ico", "anon"); + filterMap.put("/warning/**", "anon"); + filterMap.put("/warning/alarm", "anon"); + filterMap.put("/**", "oauth2"); + shiroFilter.setFilterChainDefinitionMap(filterMap); + + return shiroFilter; + } + + @Bean("lifecycleBeanPostProcessor") + public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { + return new LifecycleBeanPostProcessor(); + } + + @Bean + public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { + AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); + advisor.setSecurityManager(securityManager); + return advisor; + } +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/config/WebMvcConfig.java b/face-server/src/main/java/com/dkha/server/system/modules/security/config/WebMvcConfig.java new file mode 100644 index 0000000..14aa49e --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/config/WebMvcConfig.java @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.security.config; + +import com.dkha.server.system.common.utils.DateUtils; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.ByteArrayHttpMessageConverter; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.ResourceHttpMessageConverter; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.TimeZone; + +@Configuration +public class WebMvcConfig implements WebMvcConfigurer { + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + .allowedOrigins("*") + .allowCredentials(true) + .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") + .maxAge(3600); + } + + @Override + public void configureMessageConverters(List> converters) { + converters.add(new ByteArrayHttpMessageConverter()); + converters.add(new StringHttpMessageConverter()); + converters.add(new ResourceHttpMessageConverter()); + converters.add(new AllEncompassingFormHttpMessageConverter()); + converters.add(new StringHttpMessageConverter()); + converters.add(jackson2HttpMessageConverter()); + } + + @Bean + public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() { + MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); + ObjectMapper mapper = new ObjectMapper(); + + //日期格式转换 + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.setDateFormat(new SimpleDateFormat(DateUtils.DATE_TIME_PATTERN)); + mapper.setTimeZone(TimeZone.getTimeZone("GMT+8")); + + //Long类型转String类型 + SimpleModule simpleModule = new SimpleModule(); + simpleModule.addSerializer(Long.class, ToStringSerializer.instance); + simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); + mapper.registerModule(simpleModule); + + /** + * null 转 "" + * @param builder + * @return + */ + mapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer() { + @Override + public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeString(""); + } + }); + + converter.setObjectMapper(mapper); + return converter; + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/controller/LoginController.java b/face-server/src/main/java/com/dkha/server/system/modules/security/controller/LoginController.java new file mode 100644 index 0000000..16270b2 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/controller/LoginController.java @@ -0,0 +1,166 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.security.controller; + +import com.dkha.common.util.IpUtils; +import com.dkha.server.system.common.exception.ErrorCode; +import com.dkha.server.system.common.exception.RenException; +import com.dkha.server.system.common.utils.Result; +import com.dkha.server.system.common.validator.AssertUtils; +import com.dkha.server.system.common.validator.ValidatorUtils; +import com.dkha.server.system.modules.log.entity.SysLogLoginEntity; +import com.dkha.server.system.modules.log.enums.LoginOperationEnum; +import com.dkha.server.system.modules.log.enums.LoginStatusEnum; +import com.dkha.server.system.modules.log.service.SysLogLoginService; +import com.dkha.server.system.modules.security.dto.LoginDTO; +import com.dkha.server.system.modules.security.password.PasswordUtils; +import com.dkha.server.system.modules.security.service.CaptchaService; +import com.dkha.server.system.modules.security.service.SysUserTokenService; +import com.dkha.server.system.modules.security.user.SecurityUser; +import com.dkha.server.system.modules.security.user.UserDetail; +import com.dkha.server.system.modules.sys.dto.SysUserDTO; +import com.dkha.server.system.modules.sys.enums.UserStatusEnum; +import com.dkha.server.system.modules.sys.service.SysUserService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.Date; + +/** + * 登录 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@Api(tags="登录管理") +public class LoginController { + @Autowired + private SysUserService sysUserService; + @Autowired + private SysUserTokenService sysUserTokenService; + @Autowired + private CaptchaService captchaService; + @Autowired + private SysLogLoginService sysLogLoginService; + + @GetMapping("/captcha") + @ApiOperation(value = "验证码", produces="application/octet-stream") + @ApiImplicitParam(paramType = "query", dataType="string", name = "uuid", required = true) + public void captcha(HttpServletResponse response, String uuid)throws IOException { + //uuid不能为空 + AssertUtils.isBlank(uuid, ErrorCode.IDENTIFIER_NOT_NULL); + + //生成图片验证码 + BufferedImage image = captchaService.create(uuid); + + response.setHeader("Cache-Control", "no-store, no-cache"); + response.setContentType("image/jpeg"); + ServletOutputStream out = response.getOutputStream(); + ImageIO.write(image, "jpg", out); + + out.close(); + } + + @PostMapping("login") + @ApiOperation(value = "登录") + public Result login(HttpServletRequest request, @RequestBody LoginDTO login) { + //效验数据 + ValidatorUtils.validateEntity(login); + + //验证码是否正确 + boolean flag = captchaService.validate(login.getUuid(), login.getCaptcha()); + if(!flag){ + return new Result().error(ErrorCode.CAPTCHA_ERROR); + } + + //用户信息 + SysUserDTO user = sysUserService.getByUsername(login.getUsername()); + + SysLogLoginEntity log = new SysLogLoginEntity(); + log.setOperation(LoginOperationEnum.LOGIN.value()); + log.setCreateDate(new Date()); + log.setIp(IpUtils.getIpAddr(request)); + log.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT)); + log.setIp(IpUtils.getIpAddr(request)); + + //用户不存在 + if(user == null){ + log.setStatus(LoginStatusEnum.FAIL.value()); + log.setCreatorName(login.getUsername()); + sysLogLoginService.save(log); + + throw new RenException(ErrorCode.ACCOUNT_PASSWORD_ERROR); + } + + //密码错误 + if(!PasswordUtils.matches(login.getPassword(), user.getPassword())){ + log.setStatus(LoginStatusEnum.FAIL.value()); + log.setCreator(user.getId()); + log.setCreatorName(user.getUsername()); + sysLogLoginService.save(log); + + throw new RenException(ErrorCode.ACCOUNT_PASSWORD_ERROR); + } + + //账号停用 + if(user.getStatus() == UserStatusEnum.DISABLE.value()){ + log.setStatus(LoginStatusEnum.LOCK.value()); + log.setCreator(user.getId()); + log.setCreatorName(user.getUsername()); + sysLogLoginService.save(log); + + throw new RenException(ErrorCode.ACCOUNT_DISABLE); + } + + //登录成功 + log.setStatus(LoginStatusEnum.SUCCESS.value()); + log.setCreator(user.getId()); + log.setCreatorName(user.getUsername()); + sysLogLoginService.save(log); + + return sysUserTokenService.createToken(user.getId()); + } + + @PostMapping("logout") + @ApiOperation(value = "退出") + public Result logout(HttpServletRequest request) { + UserDetail user = SecurityUser.getUser(); + + //退出 + sysUserTokenService.logout(user.getId()); + + //用户信息 + SysLogLoginEntity log = new SysLogLoginEntity(); + log.setOperation(LoginOperationEnum.LOGOUT.value()); + log.setIp(IpUtils.getIpAddr(request)); + log.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT)); + log.setIp(IpUtils.getIpAddr(request)); + log.setStatus(LoginStatusEnum.SUCCESS.value()); + log.setCreator(user.getId()); + log.setCreatorName(user.getUsername()); + log.setCreateDate(new Date()); + sysLogLoginService.save(log); + + return new Result(); + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/dto/LoginDTO.java b/face-server/src/main/java/com/dkha/server/system/modules/security/dto/LoginDTO.java new file mode 100644 index 0000000..7073653 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/dto/LoginDTO.java @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.security.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + * 登录表单 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@ApiModel(value = "登录表单") +public class LoginDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "用户名", required = true) + @NotBlank(message="{sysuser.username.require}") + private String username; + + @ApiModelProperty(value = "密码") + @NotBlank(message="{sysuser.password.require}") + private String password; + + @ApiModelProperty(value = "验证码") + @NotBlank(message="{sysuser.captcha.require}") + private String captcha; + + @ApiModelProperty(value = "唯一标识") + @NotBlank(message="{sysuser.uuid.require}") + private String uuid; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/oauth2/Oauth2Filter.java b/face-server/src/main/java/com/dkha/server/system/modules/security/oauth2/Oauth2Filter.java new file mode 100644 index 0000000..4e9baf8 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/oauth2/Oauth2Filter.java @@ -0,0 +1,114 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.security.oauth2; + +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.exception.ErrorCode; +import com.dkha.server.system.common.utils.HttpContextUtils; +import com.dkha.server.system.common.utils.Result; +import com.google.gson.Gson; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpStatus; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.AuthenticationToken; +import org.apache.shiro.web.filter.authc.AuthenticatingFilter; +import org.springframework.web.bind.annotation.RequestMethod; + +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * oauth2过滤器 + * + * @author Mark sunlightcs@gmail.com + */ +public class Oauth2Filter extends AuthenticatingFilter { + + @Override + protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception { + //获取请求token + String token = getRequestToken((HttpServletRequest) request); + + if (StringUtils.isBlank(token)) { + return null; + } + + return new Oauth2Token(token); + } + + @Override + protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { + if (((HttpServletRequest) request).getMethod().equals(RequestMethod.OPTIONS.name())) { + return true; + } + + return false; + } + + @Override + protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { + //获取请求token,如果token不存在,直接返回401 + //TODO + String token = getRequestToken((HttpServletRequest) request); + if (StringUtils.isBlank(token)) { + HttpServletResponse httpResponse = (HttpServletResponse) response; + httpResponse.setContentType("application/json;charset=utf-8"); + httpResponse.setHeader("Access-Control-Allow-Credentials", "true"); + httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin()); + + // todo 应该到拦截器里面配置路径,将下面代码解注释,前端所有请求带上token + String json = new Gson().toJson(new Result().error(ErrorCode.UNAUTHORIZED)); + httpResponse.getWriter().print(json); + return false; + +// return true; + } + + return executeLogin(request, response); + } + + @Override + protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) { + HttpServletResponse httpResponse = (HttpServletResponse) response; + httpResponse.setContentType("application/json;charset=utf-8"); + httpResponse.setHeader("Access-Control-Allow-Credentials", "true"); + httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin()); + try { + //处理登录失败的异常 + Throwable throwable = e.getCause() == null ? e : e.getCause(); + Result r = new Result().error(HttpStatus.SC_UNAUTHORIZED, throwable.getMessage()); + + String json = new Gson().toJson(r); + httpResponse.getWriter().print(json); + } catch (IOException e1) { + + } + + return false; + } + + /** + * 获取请求的token + */ + private String getRequestToken(HttpServletRequest httpRequest) { + //从header中获取token + String token = httpRequest.getHeader(Constant.TOKEN_HEADER); + + //如果header中不存在token,则从参数中获取token + if (StringUtils.isBlank(token)) { + token = httpRequest.getParameter(Constant.TOKEN_HEADER); + } + + return token; + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/oauth2/Oauth2Realm.java b/face-server/src/main/java/com/dkha/server/system/modules/security/oauth2/Oauth2Realm.java new file mode 100644 index 0000000..4afe295 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/oauth2/Oauth2Realm.java @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.security.oauth2; + +import com.dkha.server.system.common.exception.ErrorCode; +import com.dkha.server.system.common.utils.ConvertUtils; +import com.dkha.server.system.common.utils.MessageUtils; +import com.dkha.server.system.modules.sys.entity.SysUserTokenEntity; +import com.dkha.server.system.modules.security.service.ShiroService; +import com.dkha.server.system.modules.security.user.UserDetail; +import com.dkha.server.system.modules.sys.entity.SysUserEntity; +import org.apache.shiro.authc.*; +import org.apache.shiro.authz.AuthorizationInfo; +import org.apache.shiro.authz.SimpleAuthorizationInfo; +import org.apache.shiro.realm.AuthorizingRealm; +import org.apache.shiro.subject.PrincipalCollection; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Set; + +/** + * 认证 + * + * @author Mark sunlightcs@gmail.com + */ +@Component +public class Oauth2Realm extends AuthorizingRealm { + @Autowired + private ShiroService shiroService; + + @Override + public boolean supports(AuthenticationToken token) { + return token instanceof Oauth2Token; + } + + /** + * 授权(验证权限时调用) + */ + @Override + protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { + UserDetail user = (UserDetail)principals.getPrimaryPrincipal(); + + //用户权限列表 + Set permsSet = shiroService.getUserPermissions(user); + + SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); + info.setStringPermissions(permsSet); + return info; + } + + /** + * 认证(登录时调用) + */ + @Override + protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { + String accessToken = (String) token.getPrincipal(); + + //根据accessToken,查询用户信息 + SysUserTokenEntity tokenEntity = shiroService.getByToken(accessToken); + //token失效 + if(tokenEntity == null || tokenEntity.getExpireDate().getTime() < System.currentTimeMillis()){ + throw new IncorrectCredentialsException(MessageUtils.getMessage(ErrorCode.TOKEN_INVALID)); + } + + //查询用户信息 + SysUserEntity userEntity = shiroService.getUser(tokenEntity.getUserId()); + + //转换成UserDetail对象 + UserDetail userDetail = ConvertUtils.sourceToTarget(userEntity, UserDetail.class); + + //获取用户对应的部门数据权限 + List deptIdList = shiroService.getDataScopeList(userDetail.getId()); + userDetail.setDeptIdList(deptIdList); + + //账号锁定 + if(userDetail.getStatus() == 0){ + throw new LockedAccountException(MessageUtils.getMessage(ErrorCode.ACCOUNT_LOCK)); + } + + SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userDetail, accessToken, getName()); + return info; + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/oauth2/Oauth2Token.java b/face-server/src/main/java/com/dkha/server/system/modules/security/oauth2/Oauth2Token.java new file mode 100644 index 0000000..6753a8b --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/oauth2/Oauth2Token.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.security.oauth2; + +import org.apache.shiro.authc.AuthenticationToken; + +/** + * token + * + * @author Mark sunlightcs@gmail.com + */ +public class Oauth2Token implements AuthenticationToken { + private String token; + + public Oauth2Token(String token){ + this.token = token; + } + + @Override + public String getPrincipal() { + return token; + } + + @Override + public Object getCredentials() { + return token; + } +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/oauth2/TokenGenerator.java b/face-server/src/main/java/com/dkha/server/system/modules/security/oauth2/TokenGenerator.java new file mode 100644 index 0000000..7b65d50 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/oauth2/TokenGenerator.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.security.oauth2; + + +import com.dkha.server.system.common.exception.RenException; + +import java.security.MessageDigest; +import java.util.UUID; + +/** + * 生成token + * + * @author Mark sunlightcs@gmail.com + */ +public class TokenGenerator { + + public static String generateValue() { + return generateValue(UUID.randomUUID().toString()); + } + + private static final char[] HEX_CODE = "0123456789abcdef".toCharArray(); + + public static String toHexString(byte[] data) { + if(data == null) { + return null; + } + StringBuilder r = new StringBuilder(data.length*2); + for ( byte b : data) { + r.append(HEX_CODE[(b >> 4) & 0xF]); + r.append(HEX_CODE[(b & 0xF)]); + } + return r.toString(); + } + + public static String generateValue(String param) { + try { + MessageDigest algorithm = MessageDigest.getInstance("MD5"); + algorithm.reset(); + algorithm.update(param.getBytes()); + byte[] messageDigest = algorithm.digest(); + return toHexString(messageDigest); + } catch (Exception e) { + throw new RenException("token invalid", e); + } + } +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/password/BCrypt.java b/face-server/src/main/java/com/dkha/server/system/modules/security/password/BCrypt.java new file mode 100644 index 0000000..9cdea8a --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/password/BCrypt.java @@ -0,0 +1,662 @@ +package com.dkha.server.system.modules.security.password; + +import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; +import java.security.SecureRandom; + +/** + * BCrypt implements OpenBSD-style Blowfish password hashing using the scheme described in + * "A Future-Adaptable Password Scheme" by Niels Provos and David Mazieres. + *

+ * This password hashing system tries to thwart off-line password cracking using a + * computationally-intensive hashing algorithm, based on Bruce Schneier's Blowfish cipher. + * The work factor of the algorithm is parameterised, so it can be increased as computers + * get faster. + *

+ * Usage is really simple. To hash a password for the first time, call the hashpw method + * with a random salt, like this: + *

+ * + * String pw_hash = BCrypt.hashpw(plain_password, BCrypt.gensalt());
+ *
+ *

+ * To check whether a plaintext password matches one that has been hashed previously, use + * the checkpw method: + *

+ * + * if (BCrypt.checkpw(candidate_password, stored_hash))
+ *     System.out.println("It matches");
+ * else
+ *     System.out.println("It does not match");
+ *
+ *

+ * The gensalt() method takes an optional parameter (log_rounds) that determines the + * computational complexity of the hashing: + *

+ * + * String strong_salt = BCrypt.gensalt(10)
+ * String stronger_salt = BCrypt.gensalt(12)
+ *
+ *

+ * The amount of work increases exponentially (2**log_rounds), so each increment is twice + * as much work. The default log_rounds is 10, and the valid range is 4 to 31. + * + * @author Damien Miller + */ +public class BCrypt { + // BCrypt parameters + + private static final int GENSALT_DEFAULT_LOG2_ROUNDS = 10; + private static final int BCRYPT_SALT_LEN = 16; + // Blowfish parameters + private static final int BLOWFISH_NUM_ROUNDS = 16; + // Initial contents of key schedule + private static final int P_orig[] = { 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, + 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, + 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, + 0x9216d5d9, 0x8979fb1b }; + private static final int S_orig[] = { 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, + 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, + 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, + 0x9c30d539, 0x2af26013, 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, + 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, + 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, + 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, + 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, + 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, + 0x0f6d6ff3, 0x83f44239, 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, + 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, + 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, + 0x7d84a5c3, 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, + 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, + 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, + 0x5e5c9ec2, 0x196a2463, 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, + 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, + 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, + 0x8ea5e9f8, 0xdb3222f8, 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, + 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, + 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, + 0x4afcb56c, 0x2dd1d35b, 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, + 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, + 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, + 0x8888b812, 0x900df01c, 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, + 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, + 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, + 0xc75442f5, 0xfb9d35cf, 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, + 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, + 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, + 0x1b510052, 0x9a532915, 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, + 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, + 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, + 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, + 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, + 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, + 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, + 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, + 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, + 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, + 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, + 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, + 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, + 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, + 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, + 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, + 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, + 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, + 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, + 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, + 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, + 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, + 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, + 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7, 0xe93d5a68, 0x948140f7, + 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, + 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, + 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, 0x96eb27b3, 0x55fd3941, + 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, + 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, + 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, 0x1dc9faf7, 0x4b6d1856, + 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, + 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, + 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, 0xfdf8e802, 0x04272f70, + 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, + 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, + 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1, + 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, + 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, + 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, 0xc67b5510, 0x6d672c37, + 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, + 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, + 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, 0x6a124237, 0xb79251e7, + 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, + 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, + 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, 0x83426b33, 0xf01eab71, + 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, + 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, + 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, 0xb90bace1, 0xbb8205d0, + 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, + 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, + 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, 0x9af88c27, 0x773f8641, + 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, + 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, + 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, + 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, + 0x670efa8e, 0x406000e0, 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, + 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, + 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, + 0xd5730a1d, 0x4cd04dc6, 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, + 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, + 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, + 0x3f046f69, 0x77fa0a59, 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, + 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, + 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, + 0xf8d56629, 0x79132e28, 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, + 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, + 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, + 0xabcc5167, 0xccad925f, 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, + 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, + 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, + 0xccd2017f, 0x6bb4e3bb, 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, + 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, + 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, + 0x06b89fb4, 0xce6ea048, 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, + 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, + 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, + 0x8df9317c, 0xe0b12b4f, 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, + 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, + 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, + 0xd3a0342b, 0x8971f21e, 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, + 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, + 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, + 0x6e163697, 0x88d273cc, 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, + 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, + 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, + 0x77afa1c5, 0x20756060, 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, + 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, + 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 }; + // bcrypt IV: "OrpheanBeholderScryDoubt" + static private final int bf_crypt_ciphertext[] = { 0x4f727068, 0x65616e42, + 0x65686f6c, 0x64657253, 0x63727944, 0x6f756274 }; + // Table for Base64 encoding + static private final char base64_code[] = { '.', '/', 'A', 'B', 'C', 'D', 'E', 'F', + 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', + 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', + 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; + // Table for Base64 decoding + static private final byte index_64[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + -1, -1, -1, -1, -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, -1, -1, -1, -1, -1 }; + static final int MIN_LOG_ROUNDS = 4; + static final int MAX_LOG_ROUNDS = 31; + // Expanded Blowfish key + private int P[]; + private int S[]; + + /** + * Encode a byte array using bcrypt's slightly-modified base64 encoding scheme. Note + * that this is not compatible with the standard MIME-base64 + * encoding. + * + * @param d the byte array to encode + * @param len the number of bytes to encode + * @param rs the destination buffer for the base64-encoded string + * @exception IllegalArgumentException if the length is invalid + */ + static void encode_base64(byte d[], int len, StringBuilder rs) + throws IllegalArgumentException { + int off = 0; + int c1, c2; + + if (len <= 0 || len > d.length) { + throw new IllegalArgumentException("Invalid len"); + } + + while (off < len) { + c1 = d[off++] & 0xff; + rs.append(base64_code[(c1 >> 2) & 0x3f]); + c1 = (c1 & 0x03) << 4; + if (off >= len) { + rs.append(base64_code[c1 & 0x3f]); + break; + } + c2 = d[off++] & 0xff; + c1 |= (c2 >> 4) & 0x0f; + rs.append(base64_code[c1 & 0x3f]); + c1 = (c2 & 0x0f) << 2; + if (off >= len) { + rs.append(base64_code[c1 & 0x3f]); + break; + } + c2 = d[off++] & 0xff; + c1 |= (c2 >> 6) & 0x03; + rs.append(base64_code[c1 & 0x3f]); + rs.append(base64_code[c2 & 0x3f]); + } + } + + /** + * Look up the 3 bits base64-encoded by the specified character, range-checking + * against conversion table + * @param x the base64-encoded value + * @return the decoded value of x + */ + private static byte char64(char x) { + if (x > index_64.length) { + return -1; + } + return index_64[x]; + } + + /** + * Decode a string encoded using bcrypt's base64 scheme to a byte array. Note that + * this is *not* compatible with the standard MIME-base64 encoding. + * @param s the string to decode + * @param maxolen the maximum number of bytes to decode + * @return an array containing the decoded bytes + * @throws IllegalArgumentException if maxolen is invalid + */ + static byte[] decode_base64(String s, int maxolen) throws IllegalArgumentException { + ByteArrayOutputStream out = new ByteArrayOutputStream(maxolen); + int off = 0, slen = s.length(), olen = 0; + byte c1, c2, c3, c4, o; + + if (maxolen <= 0) { + throw new IllegalArgumentException("Invalid maxolen"); + } + + while (off < slen - 1 && olen < maxolen) { + c1 = char64(s.charAt(off++)); + c2 = char64(s.charAt(off++)); + if (c1 == -1 || c2 == -1) { + break; + } + o = (byte) (c1 << 2); + o |= (c2 & 0x30) >> 4; + out.write(o); + if (++olen >= maxolen || off >= slen) { + break; + } + c3 = char64(s.charAt(off++)); + if (c3 == -1) { + break; + } + o = (byte) ((c2 & 0x0f) << 4); + o |= (c3 & 0x3c) >> 2; + out.write(o); + if (++olen >= maxolen || off >= slen) { + break; + } + c4 = char64(s.charAt(off++)); + o = (byte) ((c3 & 0x03) << 6); + o |= c4; + out.write(o); + ++olen; + } + + return out.toByteArray(); + } + + /** + * Blowfish encipher a single 64-bit block encoded as two 32-bit halves + * @param lr an array containing the two 32-bit half blocks + * @param off the position in the array of the blocks + */ + private final void encipher(int lr[], int off) { + int i, n, l = lr[off], r = lr[off + 1]; + + l ^= P[0]; + for (i = 0; i <= BLOWFISH_NUM_ROUNDS - 2;) { + // Feistel substitution on left word + n = S[(l >> 24) & 0xff]; + n += S[0x100 | ((l >> 16) & 0xff)]; + n ^= S[0x200 | ((l >> 8) & 0xff)]; + n += S[0x300 | (l & 0xff)]; + r ^= n ^ P[++i]; + + // Feistel substitution on right word + n = S[(r >> 24) & 0xff]; + n += S[0x100 | ((r >> 16) & 0xff)]; + n ^= S[0x200 | ((r >> 8) & 0xff)]; + n += S[0x300 | (r & 0xff)]; + l ^= n ^ P[++i]; + } + lr[off] = r ^ P[BLOWFISH_NUM_ROUNDS + 1]; + lr[off + 1] = l; + } + + /** + * Cycically extract a word of key material + * @param data the string to extract the data from + * @param offp a "pointer" (as a one-entry array) to the current offset into data + * @return the next word of material from data + */ + private static int streamtoword(byte data[], int offp[]) { + int i; + int word = 0; + int off = offp[0]; + + for (i = 0; i < 4; i++) { + word = (word << 8) | (data[off] & 0xff); + off = (off + 1) % data.length; + } + + offp[0] = off; + return word; + } + + /** + * Initialise the Blowfish key schedule + */ + private void init_key() { + P = (int[]) P_orig.clone(); + S = (int[]) S_orig.clone(); + } + + /** + * Key the Blowfish cipher + * @param key an array containing the key + */ + private void key(byte key[]) { + int i; + int koffp[] = { 0 }; + int lr[] = { 0, 0 }; + int plen = P.length, slen = S.length; + + for (i = 0; i < plen; i++) { + P[i] = P[i] ^ streamtoword(key, koffp); + } + + for (i = 0; i < plen; i += 2) { + encipher(lr, 0); + P[i] = lr[0]; + P[i + 1] = lr[1]; + } + + for (i = 0; i < slen; i += 2) { + encipher(lr, 0); + S[i] = lr[0]; + S[i + 1] = lr[1]; + } + } + + /** + * Perform the "enhanced key schedule" step described by Provos and Mazieres in + * "A Future-Adaptable Password Scheme" http://www.openbsd.org/papers/bcrypt-paper.ps + * @param data salt information + * @param key password information + */ + private void ekskey(byte data[], byte key[]) { + int i; + int koffp[] = { 0 }, doffp[] = { 0 }; + int lr[] = { 0, 0 }; + int plen = P.length, slen = S.length; + + for (i = 0; i < plen; i++) { + P[i] = P[i] ^ streamtoword(key, koffp); + } + + for (i = 0; i < plen; i += 2) { + lr[0] ^= streamtoword(data, doffp); + lr[1] ^= streamtoword(data, doffp); + encipher(lr, 0); + P[i] = lr[0]; + P[i + 1] = lr[1]; + } + + for (i = 0; i < slen; i += 2) { + lr[0] ^= streamtoword(data, doffp); + lr[1] ^= streamtoword(data, doffp); + encipher(lr, 0); + S[i] = lr[0]; + S[i + 1] = lr[1]; + } + } + + static long roundsForLogRounds(int log_rounds) { + if (log_rounds < 4 || log_rounds > 31) { + throw new IllegalArgumentException("Bad number of rounds"); + } + return 1L << log_rounds; + } + + /** + * Perform the central password hashing step in the bcrypt scheme + * @param password the password to hash + * @param salt the binary salt to hash with the password + * @param log_rounds the binary logarithm of the number of rounds of hashing to apply + * @return an array containing the binary hashed password + */ + private byte[] crypt_raw(byte password[], byte salt[], int log_rounds) { + int cdata[] = (int[]) bf_crypt_ciphertext.clone(); + int clen = cdata.length; + byte ret[]; + + long rounds = roundsForLogRounds(log_rounds); + + init_key(); + ekskey(salt, password); + for (long i = 0; i < rounds; i++) { + key(password); + key(salt); + } + + for (int i = 0; i < 64; i++) { + for (int j = 0; j < (clen >> 1); j++) { + encipher(cdata, j << 1); + } + } + + ret = new byte[clen * 4]; + for (int i = 0, j = 0; i < clen; i++) { + ret[j++] = (byte) ((cdata[i] >> 24) & 0xff); + ret[j++] = (byte) ((cdata[i] >> 16) & 0xff); + ret[j++] = (byte) ((cdata[i] >> 8) & 0xff); + ret[j++] = (byte) (cdata[i] & 0xff); + } + return ret; + } + + /** + * Hash a password using the OpenBSD bcrypt scheme + * @param password the password to hash + * @param salt the salt to hash with (perhaps generated using BCrypt.gensalt) + * @return the hashed password + * @throws IllegalArgumentException if invalid salt is passed + */ + public static String hashpw(String password, String salt) throws IllegalArgumentException { + BCrypt B; + String real_salt; + byte passwordb[], saltb[], hashed[]; + char minor = (char) 0; + int rounds, off = 0; + StringBuilder rs = new StringBuilder(); + + if (salt == null) { + throw new IllegalArgumentException("salt cannot be null"); + } + + int saltLength = salt.length(); + + if (saltLength < 28) { + throw new IllegalArgumentException("Invalid salt"); + } + + if (salt.charAt(0) != '$' || salt.charAt(1) != '2') { + throw new IllegalArgumentException("Invalid salt version"); + } + if (salt.charAt(2) == '$') { + off = 3; + } + else { + minor = salt.charAt(2); + if (minor != 'a' || salt.charAt(3) != '$') { + throw new IllegalArgumentException("Invalid salt revision"); + } + off = 4; + } + + if (saltLength - off < 25) { + throw new IllegalArgumentException("Invalid salt"); + } + + // Extract number of rounds + if (salt.charAt(off + 2) > '$') { + throw new IllegalArgumentException("Missing salt rounds"); + } + rounds = Integer.parseInt(salt.substring(off, off + 2)); + + real_salt = salt.substring(off + 3, off + 25); + try { + passwordb = (password + (minor >= 'a' ? "\000" : "")).getBytes("UTF-8"); + } + catch (UnsupportedEncodingException uee) { + throw new AssertionError("UTF-8 is not supported"); + } + + saltb = decode_base64(real_salt, BCRYPT_SALT_LEN); + + B = new BCrypt(); + hashed = B.crypt_raw(passwordb, saltb, rounds); + + rs.append("$2"); + if (minor >= 'a') { + rs.append(minor); + } + rs.append("$"); + if (rounds < 10) { + rs.append("0"); + } + rs.append(rounds); + rs.append("$"); + encode_base64(saltb, saltb.length, rs); + encode_base64(hashed, bf_crypt_ciphertext.length * 4 - 1, rs); + return rs.toString(); + } + + /** + * Generate a salt for use with the BCrypt.hashpw() method + * @param log_rounds the log2 of the number of rounds of hashing to apply - the work + * factor therefore increases as 2**log_rounds. Minimum 4, maximum 31. + * @param random an instance of SecureRandom to use + * @return an encoded salt value + */ + public static String gensalt(int log_rounds, SecureRandom random) { + if (log_rounds < MIN_LOG_ROUNDS || log_rounds > MAX_LOG_ROUNDS) { + throw new IllegalArgumentException("Bad number of rounds"); + } + StringBuilder rs = new StringBuilder(); + byte rnd[] = new byte[BCRYPT_SALT_LEN]; + + random.nextBytes(rnd); + + rs.append("$2a$"); + if (log_rounds < 10) { + rs.append("0"); + } + rs.append(log_rounds); + rs.append("$"); + encode_base64(rnd, rnd.length, rs); + return rs.toString(); + } + + /** + * Generate a salt for use with the BCrypt.hashpw() method + * @param log_rounds the log2 of the number of rounds of hashing to apply - the work + * factor therefore increases as 2**log_rounds. Minimum 4, maximum 31. + * @return an encoded salt value + */ + public static String gensalt(int log_rounds) { + return gensalt(log_rounds, new SecureRandom()); + } + + /** + * Generate a salt for use with the BCrypt.hashpw() method, selecting a reasonable + * default for the number of hashing rounds to apply + * @return an encoded salt value + */ + public static String gensalt() { + return gensalt(GENSALT_DEFAULT_LOG2_ROUNDS); + } + + /** + * Check that a plaintext password matches a previously hashed one + * @param plaintext the plaintext password to verify + * @param hashed the previously-hashed password + * @return true if the passwords match, false otherwise + */ + public static boolean checkpw(String plaintext, String hashed) { + return equalsNoEarlyReturn(hashed, hashpw(plaintext, hashed)); + } + + static boolean equalsNoEarlyReturn(String a, String b) { + char[] caa = a.toCharArray(); + char[] cab = b.toCharArray(); + + if (caa.length != cab.length) { + return false; + } + + byte ret = 0; + for (int i = 0; i < caa.length; i++) { + ret |= caa[i] ^ cab[i]; + } + return ret == 0; + } +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/password/BCryptPasswordEncoder.java b/face-server/src/main/java/com/dkha/server/system/modules/security/password/BCryptPasswordEncoder.java new file mode 100644 index 0000000..eb6e174 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/password/BCryptPasswordEncoder.java @@ -0,0 +1,82 @@ +package com.dkha.server.system.modules.security.password; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.security.SecureRandom; +import java.util.regex.Pattern; + +/** + * Implementation of PasswordEncoder that uses the BCrypt strong hashing function. Clients + * can optionally supply a "strength" (a.k.a. log rounds in BCrypt) and a SecureRandom + * instance. The larger the strength parameter the more work will have to be done + * (exponentially) to hash the passwords. The default value is 10. + * + * @author Dave Syer + * + */ +public class BCryptPasswordEncoder implements PasswordEncoder { + private Pattern BCRYPT_PATTERN = Pattern + .compile("\\A\\$2a?\\$\\d\\d\\$[./0-9A-Za-z]{53}"); + private final Log logger = LogFactory.getLog(getClass()); + + private final int strength; + + private final SecureRandom random; + + public BCryptPasswordEncoder() { + this(-1); + } + + /** + * @param strength the log rounds to use, between 4 and 31 + */ + public BCryptPasswordEncoder(int strength) { + this(strength, null); + } + + /** + * @param strength the log rounds to use, between 4 and 31 + * @param random the secure random instance to use + * + */ + public BCryptPasswordEncoder(int strength, SecureRandom random) { + if (strength != -1 && (strength < BCrypt.MIN_LOG_ROUNDS || strength > BCrypt.MAX_LOG_ROUNDS)) { + throw new IllegalArgumentException("Bad strength"); + } + this.strength = strength; + this.random = random; + } + + @Override + public String encode(CharSequence rawPassword) { + String salt; + if (strength > 0) { + if (random != null) { + salt = BCrypt.gensalt(strength, random); + } + else { + salt = BCrypt.gensalt(strength); + } + } + else { + salt = BCrypt.gensalt(); + } + return BCrypt.hashpw(rawPassword.toString(), salt); + } + + @Override + public boolean matches(CharSequence rawPassword, String encodedPassword) { + if (encodedPassword == null || encodedPassword.length() == 0) { + logger.warn("Empty encoded password"); + return false; + } + + if (!BCRYPT_PATTERN.matcher(encodedPassword).matches()) { + logger.warn("Encoded password does not look like BCrypt"); + return false; + } + + return BCrypt.checkpw(rawPassword.toString(), encodedPassword); + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/password/PasswordEncoder.java b/face-server/src/main/java/com/dkha/server/system/modules/security/password/PasswordEncoder.java new file mode 100644 index 0000000..0deb715 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/password/PasswordEncoder.java @@ -0,0 +1,30 @@ +package com.dkha.server.system.modules.security.password; + +/** + * Service interface for encoding passwords. + * + * The preferred implementation is {@code BCryptPasswordEncoder}. + * + * @author Keith Donald + */ +public interface PasswordEncoder { + + /** + * Encode the raw password. Generally, a good encoding algorithm applies a SHA-1 or + * greater hash combined with an 8-byte or greater randomly generated salt. + */ + String encode(CharSequence rawPassword); + + /** + * Verify the encoded password obtained from storage matches the submitted raw + * password after it too is encoded. Returns true if the passwords match, false if + * they do not. The stored password itself is never decoded. + * + * @param rawPassword the raw password to encode and match + * @param encodedPassword the encoded password from storage to compare with + * @return true if the raw password, after encoding, matches the encoded password from + * storage + */ + boolean matches(CharSequence rawPassword, String encodedPassword); + +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/password/PasswordUtils.java b/face-server/src/main/java/com/dkha/server/system/modules/security/password/PasswordUtils.java new file mode 100644 index 0000000..9c7d85f --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/password/PasswordUtils.java @@ -0,0 +1,58 @@ +/** + * Copyright 2018 人人开源 https://www.renren.io + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.dkha.server.system.modules.security.password; + +/** + * 密码工具类 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class PasswordUtils { + private static PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + + /** + * 加密 + * @param str 字符串 + * @return 返回加密字符串 + */ + public static String encode(String str){ + return passwordEncoder.encode(str); + } + + + /** + * 比较密码是否相等 + * @param str 明文密码 + * @param password 加密后密码 + * @return true:成功 false:失败 + */ + public static boolean matches(String str, String password){ + return passwordEncoder.matches(str, password); + } + + + public static void main(String[] args) { + String str = "admin"; + String password = encode(str); + + System.out.println(password); + System.out.println(matches(str, password)); + } + +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/service/CaptchaService.java b/face-server/src/main/java/com/dkha/server/system/modules/security/service/CaptchaService.java new file mode 100644 index 0000000..e7535a5 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/service/CaptchaService.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.security.service; + +import java.awt.image.BufferedImage; + +/** + * 验证码 + * + * @author Mark sunlightcs@gmail.com + */ +public interface CaptchaService { + + /** + * 图片验证码 + */ + BufferedImage create(String uuid); + + /** + * 验证码效验 + * @param uuid uuid + * @param code 验证码 + * @return true:成功 false:失败 + */ + boolean validate(String uuid, String code); +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/service/ShiroService.java b/face-server/src/main/java/com/dkha/server/system/modules/security/service/ShiroService.java new file mode 100644 index 0000000..365e56e --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/service/ShiroService.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.security.service; + +import com.dkha.server.system.modules.sys.entity.SysUserTokenEntity; +import com.dkha.server.system.modules.security.user.UserDetail; +import com.dkha.server.system.modules.sys.entity.SysUserEntity; + +import java.util.List; +import java.util.Set; + +/** + * shiro相关接口 + * + * @author Mark sunlightcs@gmail.com + */ +public interface ShiroService { + /** + * 获取用户权限列表 + */ + Set getUserPermissions(UserDetail user); + + SysUserTokenEntity getByToken(String token); + + /** + * 根据用户ID,查询用户 + * @param userId + */ + SysUserEntity getUser(Long userId); + + /** + * 获取用户对应的部门数据权限 + * @param userId 用户ID + * @return 返回部门ID列表 + */ + List getDataScopeList(Long userId); +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/service/SysUserTokenService.java b/face-server/src/main/java/com/dkha/server/system/modules/security/service/SysUserTokenService.java new file mode 100644 index 0000000..8d44dcb --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/service/SysUserTokenService.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.security.service; + + +import com.dkha.server.system.common.service.BaseService; +import com.dkha.server.system.common.utils.Result; +import com.dkha.server.system.modules.sys.entity.SysUserTokenEntity; + +/** + * 用户Token + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysUserTokenService extends BaseService { + + /** + * 生成token + * @param userId 用户ID + */ + Result createToken(Long userId); + + /** + * 退出,修改token值 + * @param userId 用户ID + */ + void logout(Long userId); + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/service/impl/CaptchaServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/modules/security/service/impl/CaptchaServiceImpl.java new file mode 100644 index 0000000..83895e0 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/service/impl/CaptchaServiceImpl.java @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.security.service.impl; + +import com.dkha.common.redis.RedisKeys; +import com.dkha.common.redis.RedisUtils; +import com.dkha.server.system.modules.security.service.CaptchaService; +import com.google.code.kaptcha.Producer; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.awt.image.BufferedImage; +import java.util.concurrent.TimeUnit; + +/** + * 验证码 + * + * @author Mark sunlightcs@gmail.com + */ +@Service +public class CaptchaServiceImpl implements CaptchaService { + @Autowired + private Producer producer; + @Autowired + private RedisUtils redisUtils; + @Value("${renren.redis.open: false}") + private boolean open; + /** + * Local Cache 5分钟过期 + */ + Cache localCache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterAccess(5, TimeUnit.MINUTES).build(); + + @Override + public BufferedImage create(String uuid) { + //生成文字验证码 + String code = producer.createText(); + + //保存到缓存 + setCache(uuid, code); + + return producer.createImage(code); + } + + @Override + public boolean validate(String uuid, String code) { + //获取验证码 + String captcha = getCache(uuid); + + //效验成功 + if(code.equalsIgnoreCase(captcha)){ + return true; + } + + return false; + } + + private void setCache(String key, String value){ + if(open){ + key = RedisKeys.getCaptchaKey(key); + redisUtils.set(key, value, 300); + }else{ + localCache.put(key, value); + } + } + + private String getCache(String key){ + if(open){ + key = RedisKeys.getCaptchaKey(key); + String captcha = (String)redisUtils.get(key); + //删除验证码 + if(captcha != null){ + redisUtils.delete(key); + } + + return captcha; + } + + String captcha = localCache.getIfPresent(key); + //删除验证码 + if(captcha != null){ + localCache.invalidate(key); + } + return captcha; + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/service/impl/ShiroServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/modules/security/service/impl/ShiroServiceImpl.java new file mode 100644 index 0000000..bb14672 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/service/impl/ShiroServiceImpl.java @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.security.service.impl; + +import com.dkha.server.system.modules.sys.dao.SysUserTokenDao; +import com.dkha.server.system.modules.sys.entity.SysUserTokenEntity; +import com.dkha.server.system.modules.security.service.ShiroService; +import com.dkha.server.system.modules.security.user.UserDetail; +import com.dkha.server.system.modules.sys.dao.SysMenuDao; +import com.dkha.server.system.modules.sys.dao.SysRoleDataScopeDao; +import com.dkha.server.system.modules.sys.dao.SysUserDao; +import com.dkha.server.system.modules.sys.entity.SysUserEntity; +import com.dkha.server.system.modules.sys.enums.SuperAdminEnum; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; + +@Service +public class ShiroServiceImpl implements ShiroService { + @Autowired + private SysMenuDao sysMenuDao; + @Autowired + private SysUserDao sysUserDao; + @Autowired + private SysUserTokenDao sysUserTokenDao; + @Autowired + private SysRoleDataScopeDao sysRoleDataScopeDao; + + @Override + public Set getUserPermissions(UserDetail user) { + //系统管理员,拥有最高权限 + List permissionsList; + if(user.getSuperAdmin() == SuperAdminEnum.YES.value()) { + permissionsList = sysMenuDao.getPermissionsList(); + }else{ + permissionsList = sysMenuDao.getUserPermissionsList(user.getId()); + } + + //用户权限列表 + Set permsSet = new HashSet<>(); + for(String permissions : permissionsList){ + if(StringUtils.isBlank(permissions)){ + continue; + } + permsSet.addAll(Arrays.asList(permissions.trim().split(","))); + } + + return permsSet; + } + + @Override + public SysUserTokenEntity getByToken(String token) { + return sysUserTokenDao.getByToken(token); + } + + @Override + public SysUserEntity getUser(Long userId) { + return sysUserDao.selectById(userId); + } + + @Override + public List getDataScopeList(Long userId) { + return sysRoleDataScopeDao.getDataScopeList(userId); + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/service/impl/SysUserTokenServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/modules/security/service/impl/SysUserTokenServiceImpl.java new file mode 100644 index 0000000..4bd1c7b --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/service/impl/SysUserTokenServiceImpl.java @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.security.service.impl; + +import com.dkha.common.redis.RedisKeys; +import com.dkha.common.redis.RedisUtils; +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.service.impl.BaseServiceImpl; +import com.dkha.server.system.common.utils.Result; +import com.dkha.server.system.modules.sys.dao.SysUserTokenDao; +import com.dkha.server.system.modules.sys.entity.SysUserTokenEntity; +import com.dkha.server.system.modules.security.oauth2.TokenGenerator; +import com.dkha.server.system.modules.security.service.SysUserTokenService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +@Service +public class SysUserTokenServiceImpl extends BaseServiceImpl implements SysUserTokenService { + /** + * 12小时后过期 + */ + private final static int EXPIRE = 3600 * 24 * 3; + @Autowired + private RedisUtils redisUtils; + + @Override + public Result createToken(Long userId) { + //用户token + String token; + + //当前时间 + Date now = new Date(); + //过期时间 + Date expireTime = new Date(now.getTime() + EXPIRE * 1000); + + //判断是否生成过token + SysUserTokenEntity tokenEntity = baseDao.getByUserId(userId); + if (tokenEntity == null) { + //生成一个token + token = TokenGenerator.generateValue(); + + tokenEntity = new SysUserTokenEntity(); + tokenEntity.setUserId(userId); + tokenEntity.setToken(token); + tokenEntity.setUpdateDate(now); + tokenEntity.setExpireDate(expireTime); + + //保存token + this.insert(tokenEntity); + } else { + //判断token是否过期 + if (tokenEntity.getExpireDate().getTime() < System.currentTimeMillis()) { + //token过期,重新生成token + token = TokenGenerator.generateValue(); + } else { + token = tokenEntity.getToken(); + } + + tokenEntity.setToken(token); + tokenEntity.setUpdateDate(now); + tokenEntity.setExpireDate(expireTime); + + //更新token + this.updateById(tokenEntity); + } + Map map = new HashMap<>(2); + map.put(Constant.TOKEN_HEADER, token); + map.put("expire", EXPIRE); + return new Result().ok(map); + } + + @Override + public void logout(Long userId) { + //生成一个token + String token = TokenGenerator.generateValue(); + + //修改token + baseDao.updateToken(userId, token); + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/user/SecurityUser.java b/face-server/src/main/java/com/dkha/server/system/modules/security/user/SecurityUser.java new file mode 100644 index 0000000..652ee64 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/user/SecurityUser.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.security.user; + +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.Subject; + +/** + * 用户 + * + * @author Mark sunlightcs@gmail.com + */ +public class SecurityUser { + + public static Subject getSubject() { + try { + return SecurityUtils.getSubject(); + }catch (Exception e){ + return null; + } + } + + /** + * 获取用户信息 + */ + public static UserDetail getUser() { + Subject subject = getSubject(); + if(subject == null){ + return new UserDetail(); + } + + UserDetail user = (UserDetail)subject.getPrincipal(); + if(user == null){ + return new UserDetail(); + } + + return user; + } + + /** + * 获取用户ID + */ + public static Long getUserId() { + return getUser().getId(); + } + + /** + * 获取部门ID + */ + public static Long getDeptId() { + return getUser().getDeptId(); + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/security/user/UserDetail.java b/face-server/src/main/java/com/dkha/server/system/modules/security/user/UserDetail.java new file mode 100644 index 0000000..d1dc4ff --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/security/user/UserDetail.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.security.user; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 登录用户信息 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +public class UserDetail implements Serializable { + private static final long serialVersionUID = 1L; + + private Long id; + private String username; + private String realName; + private String headUrl; + private Integer gender; + private String email; + private String mobile; + private Long deptId; + private String password; + private Integer status; + private Integer superAdmin; + /** + * 部门数据权限 + */ + private List deptIdList; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysDeptController.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysDeptController.java new file mode 100644 index 0000000..22e4fab --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysDeptController.java @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.controller; + +import com.dkha.server.system.common.annotation.LogOperation; +import com.dkha.server.system.common.utils.Result; +import com.dkha.server.system.common.validator.AssertUtils; +import com.dkha.server.system.common.validator.ValidatorUtils; +import com.dkha.server.system.common.validator.group.AddGroup; +import com.dkha.server.system.common.validator.group.DefaultGroup; +import com.dkha.server.system.common.validator.group.UpdateGroup; +import com.dkha.server.system.modules.sys.dto.SysDeptDTO; +import com.dkha.server.system.modules.sys.service.SysDeptService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.List; + +/** + * 部门管理 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/sys/dept") +@Api(tags="部门管理") +public class SysDeptController { + @Autowired + private SysDeptService sysDeptService; + + @GetMapping("list") + @ApiOperation("列表") + @RequiresPermissions("sys:dept:list") + public Result> list(){ + List list = sysDeptService.list(new HashMap<>(1)); + + return new Result>().ok(list); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("sys:dept:info") + public Result get(@PathVariable("id") Long id){ + SysDeptDTO data = sysDeptService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("sys:dept:save") + public Result save(@RequestBody SysDeptDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + sysDeptService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("sys:dept:update") + public Result update(@RequestBody SysDeptDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + sysDeptService.update(dto); + + return new Result(); + } + + @DeleteMapping("{id}") + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("sys:dept:delete") + public Result delete(@PathVariable("id") Long id){ + //效验数据 + AssertUtils.isNull(id, "id"); + + sysDeptService.delete(id); + + return new Result(); + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysDictDataController.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysDictDataController.java new file mode 100644 index 0000000..795c95d --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysDictDataController.java @@ -0,0 +1,120 @@ +package com.dkha.server.system.modules.sys.controller; + +import com.dkha.server.system.common.annotation.LogOperation; +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.utils.Result; +import com.dkha.server.system.common.validator.AssertUtils; +import com.dkha.server.system.common.validator.ValidatorUtils; +import com.dkha.server.system.common.validator.group.DefaultGroup; +import com.dkha.server.system.common.validator.group.UpdateGroup; +import com.dkha.server.system.modules.sys.dto.SysDictDataDTO; +import com.dkha.server.system.modules.sys.dto.SysDictTypeDTO; +import com.dkha.server.system.modules.sys.entity.SysDictDataEntity; +import com.dkha.server.system.modules.sys.service.SysDictDataService; +import com.dkha.server.system.modules.sys.service.SysDictTypeService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.validation.constraints.NotNull; +import java.util.List; +import java.util.Map; + +/** + * 字典数据 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("sys/dict/data") +@Api(tags="字典数据") +public class SysDictDataController { + @Autowired + private SysDictTypeService sysDictTypeService; + @Autowired + private SysDictDataService sysDictDataService; + + @GetMapping("page") + @ApiOperation("字典数据") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") , + @ApiImplicitParam(name = "dictLabel", value = "字典标签", paramType = "query", dataType="String"), + @ApiImplicitParam(name = "dictValue", value = "字典值", paramType = "query", dataType="String") + }) + @RequiresPermissions("sys:dict:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + //字典类型 + PageData page = sysDictDataService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("sys:dict:info") + public Result get(@PathVariable("id") Long id){ + SysDictDataDTO data = sysDictDataService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("sys:dict:save") + public Result save(@RequestBody SysDictDataDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, DefaultGroup.class); + + sysDictDataService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("sys:dict:update") + public Result update(@RequestBody SysDictDataDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + sysDictDataService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("sys:dict:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + sysDictDataService.delete(ids); + + return new Result(); + } + + + + @GetMapping(value = "/findByType/{type}") + @ApiOperation("类型查询") + @LogOperation("类型查询") +// @RequiresPermissions("sys:dict:list") + public Result getAllByTypeNotFirst( @PathVariable(required = true) String type){ + //效验数据 + return new Result>().ok(sysDictTypeService.getByType(type)); + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysDictTypeController.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysDictTypeController.java new file mode 100644 index 0000000..bc5e3c0 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysDictTypeController.java @@ -0,0 +1,119 @@ +package com.dkha.server.system.modules.sys.controller; + +import com.dkha.server.system.common.annotation.LogOperation; +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.utils.Result; +import com.dkha.server.system.common.validator.AssertUtils; +import com.dkha.server.system.common.validator.ValidatorUtils; +import com.dkha.server.system.common.validator.group.DefaultGroup; +import com.dkha.server.system.common.validator.group.UpdateGroup; +import com.dkha.server.system.modules.sys.dto.SysDictTypeDTO; +import com.dkha.server.system.modules.sys.entity.DictType; +import com.dkha.server.system.modules.sys.service.SysDictTypeService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import java.util.List; +import java.util.Map; + +/** + * 字典类型 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("sys/dict/type") +@Api(tags="字典类型") +@Slf4j +public class SysDictTypeController { + @Autowired + private SysDictTypeService sysDictTypeService; + + @GetMapping("page") + @ApiOperation("字典类型") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") , + @ApiImplicitParam(name = "dictType", value = "字典类型", paramType = "query", dataType="String"), + @ApiImplicitParam(name = "dictName", value = "字典名称", paramType = "query", dataType="String") + }) + @RequiresPermissions("sys:dict:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + //字典类型 + PageData page = sysDictTypeService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("sys:dict:info") + public Result get(@PathVariable("id") Long id){ + SysDictTypeDTO data = sysDictTypeService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("sys:dict:save") + public Result save(@RequestBody SysDictTypeDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, DefaultGroup.class); + + try { + sysDictTypeService.save(dto); + } catch (Exception e) { + log.error("添加字典类型码表异常",e.getMessage()); + return new Result().error("添加失败"); + } + + return new Result().ok("添加成功"); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("sys:dict:update") + public Result update(@RequestBody SysDictTypeDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + sysDictTypeService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("sys:dict:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + sysDictTypeService.delete(ids); + + return new Result(); + } + + @GetMapping("all") + @ApiOperation("所有字典数据") + public Result> all(){ + List list = sysDictTypeService.getAllList(); + + return new Result>().ok(list); + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysMenuController.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysMenuController.java new file mode 100644 index 0000000..d09f8df --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysMenuController.java @@ -0,0 +1,138 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.controller; + +import com.dkha.server.system.common.annotation.LogOperation; +import com.dkha.server.system.common.exception.ErrorCode; +import com.dkha.server.system.common.utils.Result; +import com.dkha.server.system.common.validator.AssertUtils; +import com.dkha.server.system.common.validator.ValidatorUtils; +import com.dkha.server.system.common.validator.group.DefaultGroup; +import com.dkha.server.system.modules.security.service.ShiroService; +import com.dkha.server.system.modules.security.user.SecurityUser; +import com.dkha.server.system.modules.security.user.UserDetail; +import com.dkha.server.system.modules.sys.dto.SysMenuDTO; +import com.dkha.server.system.modules.sys.enums.MenuTypeEnum; +import com.dkha.server.system.modules.sys.service.SysMenuService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Set; + +/** + * 菜单管理 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/sys/menu") +@Api(tags="菜单管理") +public class SysMenuController { + @Autowired + private SysMenuService sysMenuService; + @Autowired + private ShiroService shiroService; + + @GetMapping("nav") + @ApiOperation("导航") + public Result> nav(){ + UserDetail user = SecurityUser.getUser(); + List list = sysMenuService.getUserMenuList(user, MenuTypeEnum.MENU.value()); + + return new Result>().ok(list); + } + + @GetMapping("permissions") + @ApiOperation("权限标识") + public Result> permissions(){ + UserDetail user = SecurityUser.getUser(); + Set set = shiroService.getUserPermissions(user); + + return new Result>().ok(set); + } + + @GetMapping("list") + @ApiOperation("列表") + @ApiImplicitParam(name = "type", value = "菜单类型 0:菜单 1:按钮 null:全部", paramType = "query", dataType="int") + @RequiresPermissions("sys:menu:list") + public Result> list(Integer type){ + List list = sysMenuService.getAllMenuList(type); + + return new Result>().ok(list); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("sys:menu:info") + public Result get(@PathVariable("id") Long id){ + SysMenuDTO data = sysMenuService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("sys:menu:save") + public Result save(@RequestBody SysMenuDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, DefaultGroup.class); + + sysMenuService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("sys:menu:update") + public Result update(@RequestBody SysMenuDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, DefaultGroup.class); + + sysMenuService.update(dto); + + return new Result(); + } + + @DeleteMapping("{id}") + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("sys:menu:delete") + public Result delete(@PathVariable("id") Long id){ + //效验数据 + AssertUtils.isNull(id, "id"); + + //判断是否有子菜单或按钮 + List list = sysMenuService.getListPid(id); + if(list.size() > 0){ + return new Result().error(ErrorCode.SUB_MENU_EXIST); + } + + sysMenuService.delete(id); + + return new Result(); + } + + @GetMapping("select") + @ApiOperation("角色菜单权限") + @RequiresPermissions("sys:menu:select") + public Result> select(){ + UserDetail user = SecurityUser.getUser(); + List list = sysMenuService.getUserMenuList(user, null); + + return new Result>().ok(list); + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysParamsController.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysParamsController.java new file mode 100644 index 0000000..634aeb9 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysParamsController.java @@ -0,0 +1,126 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.controller; + +import com.dkha.server.system.common.annotation.LogOperation; +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.utils.ExcelUtils; +import com.dkha.server.system.common.utils.Result; +import com.dkha.server.system.common.validator.AssertUtils; +import com.dkha.server.system.common.validator.ValidatorUtils; +import com.dkha.server.system.common.validator.group.AddGroup; +import com.dkha.server.system.common.validator.group.DefaultGroup; +import com.dkha.server.system.common.validator.group.UpdateGroup; +import com.dkha.server.system.modules.sys.dto.SysParamsDTO; +import com.dkha.server.system.modules.sys.excel.SysParamsExcel; +import com.dkha.server.system.modules.sys.service.SysParamsService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + + +/** + * 参数管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@RestController +@RequestMapping("sys/params") +@Api(tags="参数管理") +public class SysParamsController { + @Autowired + private SysParamsService sysParamsService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") , + @ApiImplicitParam(name = "paramCode", value = "参数编码", paramType = "query", dataType="String") + }) + @RequiresPermissions("sys:params:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = sysParamsService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("sys:params:info") + public Result get(@PathVariable("id") Long id){ + SysParamsDTO data = sysParamsService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("sys:params:save") + public Result save(@RequestBody SysParamsDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + sysParamsService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("sys:params:update") + public Result update(@RequestBody SysParamsDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + sysParamsService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("sys:params:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + sysParamsService.delete(ids); + + return new Result(); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @RequiresPermissions("sys:params:export") + @ApiImplicitParam(name = "paramCode", value = "参数编码", paramType = "query", dataType="String") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = sysParamsService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, SysParamsExcel.class); + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysRegionController.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysRegionController.java new file mode 100644 index 0000000..2cfc6af --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysRegionController.java @@ -0,0 +1,137 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.controller; + +import com.dkha.common.exception.DkException; +import com.dkha.server.system.common.annotation.LogOperation; +import com.dkha.server.system.common.exception.ErrorCode; +import com.dkha.server.system.common.exception.RenException; +import com.dkha.server.system.common.utils.Result; +import com.dkha.server.system.common.validator.AssertUtils; +import com.dkha.server.system.common.validator.ValidatorUtils; +import com.dkha.server.system.common.validator.group.AddGroup; +import com.dkha.server.system.common.validator.group.DefaultGroup; +import com.dkha.server.system.common.validator.group.UpdateGroup; +import com.dkha.server.system.modules.sys.dto.SysRegionDTO; +import com.dkha.server.system.modules.sys.dto.region.RegionProvince; +import com.dkha.server.system.modules.sys.service.SysRegionService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 行政区域 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/sys/region") +@Api(tags="行政区域") +public class SysRegionController { + @Autowired + private SysRegionService sysRegionService; + + @GetMapping("list") + @ApiOperation("列表") + @ApiImplicitParams({ + @ApiImplicitParam(name = "pid", value = "上级ID", paramType = "query", dataType="String") + }) + @RequiresPermissions("sys:region:list") + public Result> list(@RequestParam Map params){ + List list = sysRegionService.list(params); + + return new Result>().ok(list); + } + + @GetMapping("tree") + @ApiOperation("树形数据") + public Result>> tree(){ + List> list = sysRegionService.getTreeList(); + + return new Result>>().ok(list); + } + + @GetMapping("trees") + @ApiOperation("树形数据--正确版本") + public Result> trees(){ + List list = sysRegionService.allList(); + return new Result>().ok(list); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("sys:region:info") + public Result get(@PathVariable("id") Long id){ + SysRegionDTO data = sysRegionService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("sys:region:save") + public Result save(@RequestBody SysRegionDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + sysRegionService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("sys:region:update") + public Result update(@RequestBody SysRegionDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + sysRegionService.update(dto); + + return new Result(); + } + + @DeleteMapping("{id}") + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("sys:region:delete") + public Result delete(@PathVariable("id") Long id){ + //效验数据 + AssertUtils.isNull(id, "id"); + + int count = sysRegionService.getCountByPid(id); + if(count > 0){ + throw new DkException("该区域存在下级区域,无法删除"); + } + + sysRegionService.delete(id); + + return new Result(); + } + + @GetMapping("region") + @ApiOperation("地区列表") + @ApiImplicitParam(name = "threeLevel", value = "是否显示3级 true显示 false不显示", paramType = "query", dataType="boolean") + public Result> region(@RequestParam(value = "threeLevel", defaultValue = "true") boolean threeLevel){ + List list = sysRegionService.getRegion(threeLevel); + + return new Result>().ok(list); + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysRoleController.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysRoleController.java new file mode 100644 index 0000000..cc82a2b --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysRoleController.java @@ -0,0 +1,133 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.controller; + +import com.dkha.server.system.common.annotation.LogOperation; +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.utils.Result; +import com.dkha.server.system.common.validator.AssertUtils; +import com.dkha.server.system.common.validator.ValidatorUtils; +import com.dkha.server.system.common.validator.group.AddGroup; +import com.dkha.server.system.common.validator.group.DefaultGroup; +import com.dkha.server.system.common.validator.group.UpdateGroup; +import com.dkha.server.system.modules.sys.dto.SysRoleDTO; +import com.dkha.server.system.modules.sys.service.SysRoleDataScopeService; +import com.dkha.server.system.modules.sys.service.SysRoleMenuService; +import com.dkha.server.system.modules.sys.service.SysRoleService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 角色管理 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/sys/role") +@Api(tags="角色管理") +public class SysRoleController { + @Autowired + private SysRoleService sysRoleService; + @Autowired + private SysRoleMenuService sysRoleMenuService; + @Autowired + private SysRoleDataScopeService sysRoleDataScopeService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") , + @ApiImplicitParam(name = "name", value = "角色名", paramType = "query", dataType="String") + }) + @RequiresPermissions("sys:role:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = sysRoleService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("list") + @ApiOperation("列表") + @RequiresPermissions("sys:role:list") + public Result> list(){ + List data = sysRoleService.list(new HashMap<>(1)); + + return new Result>().ok(data); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("sys:role:info") + public Result get(@PathVariable("id") Long id){ + SysRoleDTO data = sysRoleService.get(id); + + //查询角色对应的菜单 + List menuIdList = sysRoleMenuService.getMenuIdList(id); + data.setMenuIdList(menuIdList); + + //查询角色对应的数据权限 + List deptIdList = sysRoleDataScopeService.getDeptIdList(id); + data.setDeptIdList(deptIdList); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("sys:role:save") + public Result save(@RequestBody SysRoleDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + sysRoleService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("sys:role:update") + public Result update(@RequestBody SysRoleDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + sysRoleService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("sys:role:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + sysRoleService.delete(ids); + + return new Result(); + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysUserController.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysUserController.java new file mode 100644 index 0000000..10d2558 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SysUserController.java @@ -0,0 +1,165 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.controller; + +import com.dkha.server.system.common.annotation.LogOperation; +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.exception.ErrorCode; +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.utils.ConvertUtils; +import com.dkha.server.system.common.utils.ExcelUtils; +import com.dkha.server.system.common.utils.Result; +import com.dkha.server.system.common.validator.AssertUtils; +import com.dkha.server.system.common.validator.ValidatorUtils; +import com.dkha.server.system.common.validator.group.AddGroup; +import com.dkha.server.system.common.validator.group.DefaultGroup; +import com.dkha.server.system.common.validator.group.UpdateGroup; +import com.dkha.server.system.modules.security.password.PasswordUtils; +import com.dkha.server.system.modules.security.user.SecurityUser; +import com.dkha.server.system.modules.security.user.UserDetail; +import com.dkha.server.system.modules.sys.dto.PasswordDTO; +import com.dkha.server.system.modules.sys.dto.SysUserDTO; +import com.dkha.server.system.modules.sys.excel.SysUserExcel; +import com.dkha.server.system.modules.sys.service.SysRoleUserService; +import com.dkha.server.system.modules.sys.service.SysUserService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * 用户管理 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/sys/user") +@Api(tags="用户管理") +public class SysUserController { + @Autowired + private SysUserService sysUserService; + @Autowired + private SysRoleUserService sysRoleUserService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") , + @ApiImplicitParam(name = "username", value = "用户名", paramType = "query", dataType="String"), + @ApiImplicitParam(name = "gender", value = "性别", paramType = "query", dataType="String"), + @ApiImplicitParam(name = "deptId", value = "部门ID", paramType = "query", dataType="String") + }) + @RequiresPermissions("sys:user:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = sysUserService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("sys:user:info") + public Result get(@PathVariable("id") Long id){ + SysUserDTO data = sysUserService.get(id); + + //用户角色列表 + List roleIdList = sysRoleUserService.getRoleIdList(id); + data.setRoleIdList(roleIdList); + + return new Result().ok(data); + } + + @GetMapping("info") + @ApiOperation("登录用户信息") + public Result info(){ + SysUserDTO data = ConvertUtils.sourceToTarget(SecurityUser.getUser(), SysUserDTO.class); + return new Result().ok(data); + } + + @PutMapping("password") + @ApiOperation("修改密码") + @LogOperation("修改密码") + public Result password(@RequestBody PasswordDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto); + + UserDetail user = SecurityUser.getUser(); + + //原密码不正确 + if(!PasswordUtils.matches(dto.getPassword(), user.getPassword())){ + return new Result().error(ErrorCode.PASSWORD_ERROR); + } + + sysUserService.updatePassword(user.getId(), dto.getNewPassword()); + + return new Result(); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("sys:user:save") + public Result save(@RequestBody SysUserDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + sysUserService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("sys:user:update") + public Result update(@RequestBody SysUserDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + sysUserService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("sys:user:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + sysUserService.deleteBatchIds(Arrays.asList(ids)); + + return new Result(); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @RequiresPermissions("sys:user:export") + @ApiImplicitParam(name = "username", value = "用户名", paramType = "query", dataType="String") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = sysUserService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, SysUserExcel.class); + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SystemController.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SystemController.java new file mode 100644 index 0000000..b1c8863 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/controller/SystemController.java @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.controller; + +import com.dkha.server.system.common.utils.Result; +import com.dkha.server.system.modules.sys.dto.SystemDTO; +import com.sun.management.OperatingSystemMXBean; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.lang.management.ManagementFactory; +import java.math.BigDecimal; +import java.math.RoundingMode; + +/** + * 系统接口 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@Api(tags="系统接口") +public class SystemController { + + @GetMapping("sys/info") + @ApiOperation("系统信息") + public Result info(){ + OperatingSystemMXBean osmx = (OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean(); + + SystemDTO dto = new SystemDTO(); + dto.setSysTime(System.currentTimeMillis()); + dto.setOsName(System.getProperty("os.name")); + dto.setOsArch(System.getProperty("os.arch")); + dto.setOsVersion(System.getProperty("os.version")); + dto.setUserLanguage(System.getProperty("user.language")); + dto.setUserDir(System.getProperty("user.dir")); + dto.setTotalPhysical(osmx.getTotalPhysicalMemorySize()/1024/1024); + dto.setFreePhysical(osmx.getFreePhysicalMemorySize()/1024/1024); + dto.setMemoryRate(BigDecimal.valueOf((1-osmx.getFreePhysicalMemorySize()*1.0/osmx.getTotalPhysicalMemorySize())*100).setScale(2, RoundingMode.HALF_UP)); + dto.setProcessors(osmx.getAvailableProcessors()); + dto.setJvmName(System.getProperty("java.vm.name")); + dto.setJavaVersion(System.getProperty("java.version")); + dto.setJavaHome(System.getProperty("java.home")); + dto.setJavaTotalMemory(Runtime.getRuntime().totalMemory()/1024/1024); + dto.setJavaFreeMemory(Runtime.getRuntime().freeMemory()/1024/1024); + dto.setJavaMaxMemory(Runtime.getRuntime().maxMemory()/1024/1024); + dto.setUserName(System.getProperty("user.name")); + dto.setSystemCpuLoad(BigDecimal.valueOf(osmx.getSystemCpuLoad()*100).setScale(2, RoundingMode.HALF_UP)); + dto.setUserTimezone(System.getProperty("user.timezone")); + + return new Result().ok(dto); + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysDeptDao.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysDeptDao.java new file mode 100644 index 0000000..5d73bf1 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysDeptDao.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dao; + +import com.dkha.server.system.common.dao.BaseDao; +import com.dkha.server.system.modules.sys.entity.SysDeptEntity; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; +import java.util.Map; + +/** + * 部门管理 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysDeptDao extends BaseDao { + + List getList(Map params); + + SysDeptEntity getById(Long id); + + /** + * 获取所有部门的id、pid列表 + */ + List getIdAndPidList(); + + /** + * 根据部门ID,获取所有子部门ID列表 + * @param id 部门ID + */ + List getSubDeptIdList(String id); + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysDictDataDao.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysDictDataDao.java new file mode 100644 index 0000000..7b9f60e --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysDictDataDao.java @@ -0,0 +1,31 @@ +package com.dkha.server.system.modules.sys.dao; + +import com.dkha.server.system.common.dao.BaseDao; +import com.dkha.server.system.modules.sys.dto.SysDictDataDTO; +import com.dkha.server.system.modules.sys.entity.DictData; +import com.dkha.server.system.modules.sys.entity.SysDictDataEntity; +import com.dkha.server.system.modules.sys.entity.SysDictTypeEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 字典数据 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysDictDataDao extends BaseDao { + + /** + * 字典数据列表 + */ + List getDictDataList(); + + +// /** +// * 字典数据列表 +// */ +// DictData selectById(); +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysDictTypeDao.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysDictTypeDao.java new file mode 100644 index 0000000..904c99e --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysDictTypeDao.java @@ -0,0 +1,23 @@ +package com.dkha.server.system.modules.sys.dao; + +import com.dkha.server.system.common.dao.BaseDao; +import com.dkha.server.system.modules.sys.entity.DictType; +import com.dkha.server.system.modules.sys.entity.SysDictTypeEntity; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 字典类型 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysDictTypeDao extends BaseDao { + + /** + * 字典类型列表 + */ + List getDictTypeList(); + +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysLanguageDao.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysLanguageDao.java new file mode 100644 index 0000000..533b760 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysLanguageDao.java @@ -0,0 +1,26 @@ +package com.dkha.server.system.modules.sys.dao; + +import com.dkha.server.system.common.dao.BaseDao; +import com.dkha.server.system.modules.sys.entity.SysLanguageEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * 国际化 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysLanguageDao extends BaseDao { + + SysLanguageEntity getLanguage(SysLanguageEntity entity); + + void updateLanguage(SysLanguageEntity entity); + + /** + * 删除国际化 + * @param tableName 表名 + * @param tableId 表主键 + */ + void deleteLanguage(@Param("tableName") String tableName, @Param("tableId") Long tableId); +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysMenuDao.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysMenuDao.java new file mode 100644 index 0000000..491574d --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysMenuDao.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dao; + +import com.dkha.server.system.common.dao.BaseDao; +import com.dkha.server.system.modules.sys.entity.SysMenuEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 菜单管理 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysMenuDao extends BaseDao { + + SysMenuEntity getById(@Param("id") Long id, @Param("language") String language); + + /** + * 查询所有菜单列表 + * + * @param type 菜单类型 + * @param language 语言 + */ + List getMenuList(@Param("type") Integer type, @Param("language") String language); + + /** + * 查询用户菜单列表 + * + * @param userId 用户ID + * @param type 菜单类型 + * @param language 语言 + */ + List getUserMenuList(@Param("userId") Long userId, @Param("type") Integer type, @Param("language") String language); + + /** + * 查询用户权限列表 + * @param userId 用户ID + */ + List getUserPermissionsList(Long userId); + + /** + * 查询所有权限列表 + */ + List getPermissionsList(); + + /** + * 根据父菜单,查询子菜单 + * @param pid 父菜单ID + */ + List getListPid(Long pid); + +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysParamsDao.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysParamsDao.java new file mode 100644 index 0000000..53171ef --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysParamsDao.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dao; + +import com.dkha.server.system.common.dao.BaseDao; +import com.dkha.server.system.modules.sys.entity.SysParamsEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 参数管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Mapper +public interface SysParamsDao extends BaseDao { + /** + * 根据参数编码,查询value + * @param paramCode 参数编码 + * @return 参数值 + */ + String getValueByCode(String paramCode); + + /** + * 获取参数编码列表 + * @param ids ids + * @return 返回参数编码列表 + */ + List getParamCodeList(Long[] ids); + + /** + * 根据参数编码,更新value + * @param paramCode 参数编码 + * @param paramValue 参数值 + */ + int updateValueByCode(@Param("paramCode") String paramCode, @Param("paramValue") String paramValue); +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRegionDao.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRegionDao.java new file mode 100644 index 0000000..86a6d56 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRegionDao.java @@ -0,0 +1,47 @@ +package com.dkha.server.system.modules.sys.dao; + +import com.alibaba.druid.sql.ast.statement.SQLForeignKeyImpl; +import com.dkha.server.system.common.dao.BaseDao; +import com.dkha.server.system.modules.sys.entity.SysRegionEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * 行政区域 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysRegionDao extends BaseDao { + + List getList(Map params); + + List getListByLevel(Integer treeLevel); + + List> getTreeList(); + + SysRegionEntity getById(Long id); + + int getCountByPid(Long pid); + + /** + * 摄像头卡口 + * + * @param pid + * @return + */ + List> getRegion(@Param("pid") long pid); + + /** + * 获取当前区域下的摄像头 + * + * @param pid + * @param + * @return + */ + List> getRegion1(@Param("pid") long pid); + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRoleDao.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRoleDao.java new file mode 100644 index 0000000..b0f5829 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRoleDao.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dao; + +import com.dkha.server.system.common.dao.BaseDao; +import com.dkha.server.system.modules.sys.entity.SysRoleEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 角色管理 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysRoleDao extends BaseDao { + + +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRoleDataScopeDao.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRoleDataScopeDao.java new file mode 100644 index 0000000..14616a0 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRoleDataScopeDao.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dao; + +import com.dkha.server.system.common.dao.BaseDao; +import com.dkha.server.system.modules.sys.entity.SysRoleDataScopeEntity; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 角色数据权限 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Mapper +public interface SysRoleDataScopeDao extends BaseDao { + + /** + * 根据角色ID,获取部门ID列表 + */ + List getDeptIdList(Long roleId); + + /** + * 获取用户的部门数据权限列表 + */ + List getDataScopeList(Long userId); + + /** + * 根据角色id,删除角色数据权限关系 + * @param roleIds 角色ids + */ + void deleteByRoleIds(Long[] roleIds); +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRoleMenuDao.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRoleMenuDao.java new file mode 100644 index 0000000..c5a5140 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRoleMenuDao.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dao; + +import com.dkha.server.system.common.dao.BaseDao; +import com.dkha.server.system.modules.sys.entity.SysRoleMenuEntity; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 角色与菜单对应关系 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysRoleMenuDao extends BaseDao { + + /** + * 根据角色ID,获取菜单ID列表 + */ + List getMenuIdList(Long roleId); + + /** + * 根据角色id,删除角色菜单关系 + * @param roleIds 角色ids + */ + void deleteByRoleIds(Long[] roleIds); + + /** + * 根据菜单id,删除角色菜单关系 + * @param menuId 菜单id + */ + void deleteByMenuId(Long menuId); +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRoleUserDao.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRoleUserDao.java new file mode 100644 index 0000000..966fc5d --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysRoleUserDao.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dao; + +import com.dkha.server.system.common.dao.BaseDao; +import com.dkha.server.system.modules.sys.entity.SysRoleUserEntity; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 角色用户关系 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Mapper +public interface SysRoleUserDao extends BaseDao { + + /** + * 根据角色ids,删除角色用户关系 + * @param roleIds 角色ids + */ + void deleteByRoleIds(Long[] roleIds); + + /** + * 根据用户id,删除角色用户关系 + * @param userIds 用户ids + */ + void deleteByUserIds(Long[] userIds); + + /** + * 角色ID列表 + * @param userId 用户ID + * + * @return + */ + List getRoleIdList(Long userId); +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysUserDao.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysUserDao.java new file mode 100644 index 0000000..9764823 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysUserDao.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dao; + +import com.dkha.server.system.common.dao.BaseDao; +import com.dkha.server.system.modules.sys.entity.SysUserEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * 系统用户 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysUserDao extends BaseDao { + + List getList(Map params); + + SysUserEntity getById(Long id); + + SysUserEntity getByUsername(String username); + + int updatePassword(@Param("id") Long id, @Param("newPassword") String newPassword); + + /** + * 根据部门ID,查询用户数 + */ + int getCountByDeptId(Long deptId); + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysUserTokenDao.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysUserTokenDao.java new file mode 100644 index 0000000..93004f0 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dao/SysUserTokenDao.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dao; + +import com.dkha.server.system.common.dao.BaseDao; +import com.dkha.server.system.modules.sys.entity.SysUserTokenEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * 系统用户Token + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysUserTokenDao extends BaseDao { + + SysUserTokenEntity getByToken(String token); + + SysUserTokenEntity getByUserId(Long userId); + + void updateToken(@Param("userId") Long userId, @Param("token") String token); +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/PasswordDTO.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/PasswordDTO.java new file mode 100644 index 0000000..0dc188e --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/PasswordDTO.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + * 修改密码 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@ApiModel(value = "修改密码") +public class PasswordDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "原密码") + @NotBlank(message="{sysuser.password.require}") + private String password; + + @ApiModelProperty(value = "新密码") + @NotBlank(message="{sysuser.password.require}") + private String newPassword; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysDeptDTO.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysDeptDTO.java new file mode 100644 index 0000000..b70f7c3 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysDeptDTO.java @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dto; + +import com.dkha.server.system.common.utils.TreeNode; +import com.dkha.server.system.common.validator.group.AddGroup; +import com.dkha.server.system.common.validator.group.DefaultGroup; +import com.dkha.server.system.common.validator.group.UpdateGroup; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import java.io.Serializable; +import java.util.Date; + +/** + * 部门管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@ApiModel(value = "部门管理") +public class SysDeptDTO extends TreeNode implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @Null(message="{id.null}", groups = AddGroup.class) + @NotNull(message="{id.require}", groups = UpdateGroup.class) + private Long id; + + @ApiModelProperty(value = "上级ID") + @NotNull(message="{sysdept.pid.require}", groups = DefaultGroup.class) + private Long pid; + + @ApiModelProperty(value = "部门名称") + @NotBlank(message="{sysdept.name.require}", groups = DefaultGroup.class) + private String name; + + @ApiModelProperty(value = "排序") + @Min(value = 0, message = "{sort.number}", groups = DefaultGroup.class) + private Integer sort; + + @ApiModelProperty(value = "创建时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date createDate; + + @ApiModelProperty(value = "上级部门名称") + private String parentName; + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + @Override + public Long getPid() { + return pid; + } + + @Override + public void setPid(Long pid) { + this.pid = pid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getSort() { + return sort; + } + + public void setSort(Integer sort) { + this.sort = sort; + } + + public Date getCreateDate() { + return createDate; + } + + public void setCreateDate(Date createDate) { + this.createDate = createDate; + } + + public String getParentName() { + return parentName; + } + + public void setParentName(String parentName) { + this.parentName = parentName; + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysDictDTO.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysDictDTO.java new file mode 100644 index 0000000..1654dd9 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysDictDTO.java @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dto; + +import com.dkha.server.system.common.validator.group.AddGroup; +import com.dkha.server.system.common.validator.group.DefaultGroup; +import com.dkha.server.system.common.validator.group.UpdateGroup; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import java.io.Serializable; +import java.util.Date; + +/** + * 字典数据 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@ApiModel(value = "字典数据") +public class SysDictDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "父id") + private Long pid; + + @ApiModelProperty(value = "码表值类型ID") + @NotNull(message = "码表值类型ID不能为空") + private String dictType; + + @ApiModelProperty(value = "码表名称") + @NotBlank(message = "码表名称不能为空") + private String dictName; +// @NotBlank(message = "码表值不能为空") +// @ApiModelProperty(value = "码表值") +// private String dictValue; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "排序") + private Integer sort; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysDictDataDTO.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysDictDataDTO.java new file mode 100644 index 0000000..83cf41b --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysDictDataDTO.java @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dto; + +import com.dkha.server.system.common.validator.group.AddGroup; +import com.dkha.server.system.common.validator.group.DefaultGroup; +import com.dkha.server.system.common.validator.group.UpdateGroup; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import java.io.Serializable; +import java.util.Date; + +/** + * 字典数据 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@ApiModel(value = "字典数据") +public class SysDictDataDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @Null(message="{id.null}", groups = AddGroup.class) + @NotNull(message="{id.require}", groups = UpdateGroup.class) + private Long id; + + @ApiModelProperty(value = "字典类型ID") + @NotNull(message="{sysdict.type.require}", groups = DefaultGroup.class) + private Long dictTypeId; + + @ApiModelProperty(value = "字典标签") + @NotBlank(message="{sysdict.label.require}", groups = DefaultGroup.class) + private String dictLabel; + + @ApiModelProperty(value = "字典值") + private String dictValue; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "排序") + @Min(value = 0, message = "{sort.number}", groups = DefaultGroup.class) + private Integer sort; + + @ApiModelProperty(value = "创建时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date createDate; + + @ApiModelProperty(value = "更新时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date updateDate; +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysDictTypeDTO.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysDictTypeDTO.java new file mode 100644 index 0000000..c63b4cb --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysDictTypeDTO.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dto; + +import com.dkha.server.system.common.validator.group.AddGroup; +import com.dkha.server.system.common.validator.group.DefaultGroup; +import com.dkha.server.system.common.validator.group.UpdateGroup; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import java.io.Serializable; +import java.util.Date; + +/** + * 字典类型 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@ApiModel(value = "字典类型") +public class SysDictTypeDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @Null(message="{id.null}", groups = AddGroup.class) + @NotNull(message="{id.require}", groups = UpdateGroup.class) + private Long id; + + @ApiModelProperty(value = "字典类型") + @NotBlank(message="{sysdict.type.require}", groups = DefaultGroup.class) + private String dictType; + + @ApiModelProperty(value = "字典名称") + @NotBlank(message="{sysdict.name.require}", groups = DefaultGroup.class) + private String dictName; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "排序") + @Min(value = 0, message = "{sort.number}", groups = DefaultGroup.class) + private Integer sort; + + @ApiModelProperty(value = "创建时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date createDate; + + @ApiModelProperty(value = "更新时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date updateDate; +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysMenuDTO.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysMenuDTO.java new file mode 100644 index 0000000..e35a545 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysMenuDTO.java @@ -0,0 +1,157 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dto; + +import com.dkha.server.system.common.utils.TreeNode; +import com.dkha.server.system.common.validator.group.AddGroup; +import com.dkha.server.system.common.validator.group.DefaultGroup; +import com.dkha.server.system.common.validator.group.UpdateGroup; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.hibernate.validator.constraints.Range; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import java.io.Serializable; +import java.util.Date; + +/** + * 菜单管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@ApiModel(value = "菜单管理") +public class SysMenuDTO extends TreeNode implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @Null(message="{id.null}", groups = AddGroup.class) + @NotNull(message="{id.require}", groups = UpdateGroup.class) + private Long id; + + @ApiModelProperty(value = "上级ID") + @NotNull(message="{sysmenu.pid.require}", groups = DefaultGroup.class) + private Long pid; + + @ApiModelProperty(value = "菜单名称") + @NotBlank(message="{sysmenu.name.require}", groups = DefaultGroup.class) + private String name; + + @ApiModelProperty(value = "菜单URL") + private String url; + + @ApiModelProperty(value = "类型 0:菜单 1:按钮") + @Range(min=0, max=1, message = "{sysmenu.type.range}", groups = DefaultGroup.class) + private Integer type; + + @ApiModelProperty(value = "菜单图标") + private String icon; + + @ApiModelProperty(value = "授权(多个用逗号分隔,如:sys:user:list,sys:user:save)") + private String permissions; + + @ApiModelProperty(value = "排序") + @Min(value = 0, message = "{sort.number}", groups = DefaultGroup.class) + private Integer sort; + + @ApiModelProperty(value = "创建时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date createDate; + + @ApiModelProperty(value = "上级菜单名称") + private String parentName; + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + @Override + public Long getPid() { + return pid; + } + + @Override + public void setPid(Long pid) { + this.pid = pid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public Integer getType() { + return type; + } + + public void setType(Integer type) { + this.type = type; + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public String getPermissions() { + return permissions; + } + + public void setPermissions(String permissions) { + this.permissions = permissions; + } + + public Integer getSort() { + return sort; + } + + public void setSort(Integer sort) { + this.sort = sort; + } + + public Date getCreateDate() { + return createDate; + } + + public void setCreateDate(Date createDate) { + this.createDate = createDate; + } + + public String getParentName() { + return parentName; + } + + public void setParentName(String parentName) { + this.parentName = parentName; + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysParamsDTO.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysParamsDTO.java new file mode 100644 index 0000000..a5ccaaf --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysParamsDTO.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dto; + +import com.dkha.server.system.common.validator.group.AddGroup; +import com.dkha.server.system.common.validator.group.DefaultGroup; +import com.dkha.server.system.common.validator.group.UpdateGroup; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import java.io.Serializable; +import java.util.Date; + +/** + * 参数管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@ApiModel(value = "参数管理") +public class SysParamsDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @Null(message="{id.null}", groups = AddGroup.class) + @NotNull(message="{id.require}", groups = UpdateGroup.class) + private Long id; + + @ApiModelProperty(value = "参数编码") + @NotBlank(message="{sysparams.paramcode.require}", groups = DefaultGroup.class) + private String paramCode; + + @ApiModelProperty(value = "参数值") + @NotBlank(message="{sysparams.paramvalue.require}", groups = DefaultGroup.class) + private String paramValue; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "创建时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date createDate; + + @ApiModelProperty(value = "更新时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date updateDate; + +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysRegionDTO.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysRegionDTO.java new file mode 100644 index 0000000..eb2d3b5 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysRegionDTO.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dto; + +import com.dkha.server.system.common.utils.TreeNode; +import com.dkha.server.system.common.validator.group.DefaultGroup; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Date; + + +/** + * 行政区域 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@ApiModel(value = "行政区域") +public class SysRegionDTO extends TreeNode implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "区域标识") +// @NotNull(message="{id.require}", groups = DefaultGroup.class) + private Long id; + + @ApiModelProperty(value = "上级区域ID") + @NotNull(message="{region.pid.require}", groups = DefaultGroup.class) + private Long pid; + + @ApiModelProperty(value = "区域名称") + @NotBlank(message="{region.name.require}", groups = DefaultGroup.class) + private String name; + + @ApiModelProperty(value = "排序") + @Min(value = 0, message = "{sort.number}", groups = DefaultGroup.class) + private Long sort; + + @ApiModelProperty(value = "上级区域名称") + private String parentName; + @NotBlank() + @ApiModelProperty(value = "是否有子节点") + private Boolean hasChildren; + + @ApiModelProperty(value = "层级") + private Integer treeLevel; + + @ApiModelProperty(value = "更新时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date updateDate; +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysRoleDTO.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysRoleDTO.java new file mode 100644 index 0000000..25a3bde --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysRoleDTO.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dto; + +import com.dkha.server.system.common.validator.group.AddGroup; +import com.dkha.server.system.common.validator.group.DefaultGroup; +import com.dkha.server.system.common.validator.group.UpdateGroup; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * 角色管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@ApiModel(value = "角色管理") +public class SysRoleDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @Null(message="{id.null}", groups = AddGroup.class) + @NotNull(message="{id.require}", groups = UpdateGroup.class) + private Long id; + + @ApiModelProperty(value = "角色名称") + @NotBlank(message="{sysrole.name.require}", groups = DefaultGroup.class) + private String name; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "创建时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date createDate; + + @ApiModelProperty(value = "菜单ID列表") + private List menuIdList; + + @ApiModelProperty(value = "部门ID列表") + private List deptIdList; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysUserDTO.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysUserDTO.java new file mode 100644 index 0000000..14db317 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SysUserDTO.java @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dto; + +import com.dkha.server.system.common.validator.group.AddGroup; +import com.dkha.server.system.common.validator.group.DefaultGroup; +import com.dkha.server.system.common.validator.group.UpdateGroup; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Range; + +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * 用户管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@ApiModel(value = "用户管理") +public class SysUserDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @Null(message="{id.null}", groups = AddGroup.class) + @NotNull(message="{id.require}", groups = UpdateGroup.class) + private Long id; + + @ApiModelProperty(value = "用户名", required = true) + @NotBlank(message="{sysuser.username.require}", groups = DefaultGroup.class) + private String username; + + @ApiModelProperty(value = "密码") + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + @NotBlank(message="{sysuser.password.require}", groups = AddGroup.class) + private String password; + + @ApiModelProperty(value = "姓名", required = true) + @NotBlank(message="{sysuser.realname.require}", groups = DefaultGroup.class) + private String realName; + + @ApiModelProperty(value = "头像") + private String headUrl; + + @ApiModelProperty(value = "性别 0:男 1:女 2:保密", required = true) + @Range(min=0, max=2, message = "{sysuser.gender.range}", groups = DefaultGroup.class) + private Integer gender; + + @ApiModelProperty(value = "邮箱") + @Email(message="{sysuser.email.error}", groups = DefaultGroup.class) + private String email; + + @ApiModelProperty(value = "手机号") + private String mobile; + + @ApiModelProperty(value = "部门ID", required = true) + @NotNull(message="{sysuser.deptId.require}", groups = DefaultGroup.class) + private Long deptId; + + @ApiModelProperty(value = "状态 0:停用 1:正常", required = true) + @Range(min=0, max=1, message = "{sysuser.status.range}", groups = DefaultGroup.class) + private Integer status; + + @ApiModelProperty(value = "创建时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date createDate; + + @ApiModelProperty(value = "超级管理员 0:否 1:是") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Integer superAdmin; + + @ApiModelProperty(value = "角色ID列表") + private List roleIdList; + + @ApiModelProperty(value = "部门名称") + private String deptName; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SystemDTO.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SystemDTO.java new file mode 100644 index 0000000..5b6ae2e --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/SystemDTO.java @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dto; + +import io.swagger.annotations.ApiModel; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 系统数据 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@ApiModel(value = "系统数据") +public class SystemDTO implements Serializable { + private static final long serialVersionUID = 1L; + + private Long sysTime; + private String osName; + private String osArch; + private String osVersion; + private String userLanguage; + private String userDir; + private Long totalPhysical; + private Long freePhysical; + private BigDecimal memoryRate; + private Integer processors; + private String jvmName; + private String javaVersion; + private String javaHome; + private Long javaTotalMemory; + private Long javaFreeMemory; + private Long javaMaxMemory; + private String userName; + private BigDecimal systemCpuLoad; + private String userTimezone; + +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/region/Region.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/region/Region.java new file mode 100644 index 0000000..20d1099 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/region/Region.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2019 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dto.region; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * 地区管理 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@ApiModel(value = "地区管理") +public class Region implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "地区ID") + private Long id; + + @JsonIgnore + private Long pid; + + @ApiModelProperty(value = "名称") + private String name; +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/region/RegionCity.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/region/RegionCity.java new file mode 100644 index 0000000..c386f57 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/region/RegionCity.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2019 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dto.region; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.ArrayList; +import java.util.List; + +/** + * 市 + * + * @author Mark sunlightcs@gmail.com + */ +@ApiModel(value = "市") +@Data +@EqualsAndHashCode(callSuper = true) +public class RegionCity extends Region { + @ApiModelProperty(value = "区、县列表") + private List counties = new ArrayList<>(); +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/region/RegionProvince.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/region/RegionProvince.java new file mode 100644 index 0000000..9964f05 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/dto/region/RegionProvince.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2019 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.dto.region; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.ArrayList; +import java.util.List; + +/** + * 省 + * + * @author Mark sunlightcs@gmail.com + */ +@ApiModel(value = "省") +@Data +@EqualsAndHashCode(callSuper = true) +public class RegionProvince extends Region { + @ApiModelProperty(value = "市列表") + private List cities = new ArrayList<>(); +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/DictData.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/DictData.java new file mode 100644 index 0000000..9b7dcc7 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/DictData.java @@ -0,0 +1,16 @@ +package com.dkha.server.system.modules.sys.entity; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; + +/** + * 字典数据 + * + */ +@Data +public class DictData { + @JsonIgnore + private Long dictTypeId; + private String dictLabel; + private String dictValue; +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/DictType.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/DictType.java new file mode 100644 index 0000000..f83f85e --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/DictType.java @@ -0,0 +1,19 @@ +package com.dkha.server.system.modules.sys.entity; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 字典类型 + * + */ +@Data +public class DictType { + @JsonIgnore + private Long id; + private String dictType; + private List dataList = new ArrayList<>(); +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysDeptEntity.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysDeptEntity.java new file mode 100644 index 0000000..81d09ef --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysDeptEntity.java @@ -0,0 +1,52 @@ +package com.dkha.server.system.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.dkha.server.system.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 部门管理 + * + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_dept") +public class SysDeptEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 上级ID + */ + private Long pid; + /** + * 所有上级ID,用逗号分开 + */ + private String pids; + /** + * 部门名称 + */ + private String name; + /** + * 排序 + */ + private Integer sort; + /** + * 更新者 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateDate; + /** + * 上级部门名称 + */ + @TableField(exist = false) + private String parentName; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysDictDataEntity.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysDictDataEntity.java new file mode 100644 index 0000000..96c12ec --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysDictDataEntity.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.dkha.server.system.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 数据字典 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_dict_data") +public class SysDictDataEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + /** + * 字典类型ID + */ + private Long dictTypeId; + /** + * 字典标签 + */ + private String dictLabel; + /** + * 字典值 + */ + private String dictValue; + /** + * 备注 + */ + private String remark; + /** + * 排序 + */ + private Integer sort; + /** + * 更新者 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateDate; +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysDictEntity.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysDictEntity.java new file mode 100644 index 0000000..6857d47 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysDictEntity.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.dkha.server.system.common.entity.CommonEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 数据字典 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("sys_dict") +public class SysDictEntity extends CommonEntity { + private static final long serialVersionUID = 1L; + /** + * id + */ + @TableId(type = IdType.ID_WORKER) + private Long id; + /** + * 上级ID,一级为0 + */ + private Long pid; + /** + * 字典类型 + */ + private String dictType; + /** + * 字典名称 + */ + private String dictName; + /** + * 字典值 + */ + private String dictValue; + /** + * 备注 + */ + private String remark; + /** + * 排序 + */ + private Integer sort; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysDictTypeEntity.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysDictTypeEntity.java new file mode 100644 index 0000000..d15fa53 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysDictTypeEntity.java @@ -0,0 +1,48 @@ +package com.dkha.server.system.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.dkha.server.system.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 字典类型 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_dict_type") +public class SysDictTypeEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + /** + * 字典类型 + */ + private String dictType; + /** + * 字典名称 + */ + private String dictName; + /** + * 备注 + */ + private String remark; + /** + * 排序 + */ + private Integer sort; + /** + * 更新者 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateDate; +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysLanguageEntity.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysLanguageEntity.java new file mode 100644 index 0000000..84a5456 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysLanguageEntity.java @@ -0,0 +1,39 @@ +package com.dkha.server.system.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + * 国际化 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@TableName("sys_language") +public class SysLanguageEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 表名 + */ + private String tableName; + /** + * 表主键 + */ + private Long tableId; + /** + * 字段名 + */ + private String fieldName; + /** + * 字段值 + */ + private String fieldValue; + /** + * 语言 + */ + private String language; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysMenuEntity.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysMenuEntity.java new file mode 100644 index 0000000..cfc2dd6 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysMenuEntity.java @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.dkha.server.system.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 菜单管理 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_menu") +public class SysMenuEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 父菜单ID,一级菜单为0 + */ + private Long pid; + /** + * 菜单名称 + */ + @TableField(exist = false) + private String name; + /** + * 菜单URL + */ + private String url; + /** + * 授权(多个用逗号分隔,如:sys:user:list,sys:user:save) + */ + private String permissions; + /** + * 类型 0:菜单 1:按钮 + */ + private Integer type; + /** + * 菜单图标 + */ + private String icon; + /** + * 排序 + */ + private Integer sort; + /** + * 更新者 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateDate; + /** + * 上级菜单名称 + */ + @TableField(exist = false) + private String parentName; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysParamsEntity.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysParamsEntity.java new file mode 100644 index 0000000..555d2fc --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysParamsEntity.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.dkha.server.system.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 参数管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_params") +public class SysParamsEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 参数编码 + */ + private String paramCode; + /** + * 参数值 + */ + private String paramValue; + /** + * 类型 0:系统参数 1:非系统参数 + */ + private Integer paramType; + /** + * 备注 + */ + private String remark; + /** + * 更新者 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateDate; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRegionEntity.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRegionEntity.java new file mode 100644 index 0000000..bd9c1e0 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRegionEntity.java @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 行政区域 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@TableName("sys_region") +public class SysRegionEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(type = IdType.ID_WORKER,value = "id") + private Long id; + /** + * 上级ID,一级为0 + */ + private Long pid; + /** + * 名称 + */ + private String name; + /** + * 层级 + */ + private Integer treeLevel; + /** + * 排序 + */ + private Long sort; + /** + * 是否叶子节点 0:否 1:是 + */ + private Integer leaf; + /** + * 创建者 + */ + @TableField(fill = FieldFill.INSERT) + private Long creator; + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + private Date createDate; + /** + * 更新者 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateDate; + /** + * 上级名称 + */ + @TableField(exist = false) + private String parentName; +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRoleDataScopeEntity.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRoleDataScopeEntity.java new file mode 100644 index 0000000..8f778ee --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRoleDataScopeEntity.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.dkha.server.system.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 角色数据权限 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_role_data_scope") +public class SysRoleDataScopeEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 角色ID + */ + private Long roleId; + /** + * 部门ID + */ + private Long deptId; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRoleEntity.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRoleEntity.java new file mode 100644 index 0000000..f5f1273 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRoleEntity.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.dkha.server.system.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 角色 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_role") +public class SysRoleEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 角色名称 + */ + private String name; + /** + * 备注 + */ + private String remark; + /** + * 部门ID + */ + @TableField(fill = FieldFill.INSERT) + private Long deptId; + /** + * 更新者 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateDate; +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRoleMenuEntity.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRoleMenuEntity.java new file mode 100644 index 0000000..64bb825 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRoleMenuEntity.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.dkha.server.system.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 角色菜单关系 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_role_menu") +public class SysRoleMenuEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + /** + * 角色ID + */ + private Long roleId; + /** + * 菜单ID + */ + private Long menuId; + +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRoleUserEntity.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRoleUserEntity.java new file mode 100644 index 0000000..04f7eee --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysRoleUserEntity.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.dkha.server.system.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 角色用户关系 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_role_user") +public class SysRoleUserEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 角色ID + */ + private Long roleId; + /** + * 用户ID + */ + private Long userId; + +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysUserEntity.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysUserEntity.java new file mode 100644 index 0000000..aba2b78 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysUserEntity.java @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.dkha.server.system.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 系统用户 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_user") +public class SysUserEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + /** + * 用户名 + */ + private String username; + /** + * 密码 + */ + private String password; + /** + * 姓名 + */ + private String realName; + /** + * 头像 + */ + private String headUrl; + /** + * 性别 0:男 1:女 2:保密 + */ + private Integer gender; + /** + * 邮箱 + */ + private String email; + /** + * 手机号 + */ + private String mobile; + /** + * 部门ID + */ + private Long deptId; + /** + * 超级管理员 0:否 1:是 + */ + private Integer superAdmin; + /** + * 状态 0:停用 1:正常 + */ + private Integer status; + /** + * 更新者 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateDate; + /** + * 部门名称 + */ + @TableField(exist=false) + private String deptName; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysUserTokenEntity.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysUserTokenEntity.java new file mode 100644 index 0000000..054ca36 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/entity/SysUserTokenEntity.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 系统用户Token + */ +@Data +@TableName("sys_user_token") +public class SysUserTokenEntity implements Serializable { + private static final long serialVersionUID = 1L; + /** + * id + */ + @TableId + private Long id; + /** + * 用户ID + */ + private Long userId; + /** + * 用户token + */ + private String token; + /** + * 过期时间 + */ + private Date expireDate; + /** + * 更新时间 + */ + private Date updateDate; + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + private Date createDate; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/enums/MenuTypeEnum.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/enums/MenuTypeEnum.java new file mode 100644 index 0000000..76930fe --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/enums/MenuTypeEnum.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.enums; + +/** + * 菜单类型枚举 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public enum MenuTypeEnum { + /** + * 菜单 + */ + MENU(0), + /** + * 按钮 + */ + BUTTON(1); + + private int value; + + MenuTypeEnum(int value) { + this.value = value; + } + + public int value() { + return this.value; + } +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/enums/RegionLeafEnum.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/enums/RegionLeafEnum.java new file mode 100644 index 0000000..0915005 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/enums/RegionLeafEnum.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2019 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.enums; + +/** + * 叶子节点枚举 + * + * @author Mark sunlightcs@gmail.com + */ +public enum RegionLeafEnum { + YES(1), + NO(0); + + private int value; + + RegionLeafEnum(int value) { + this.value = value; + } + + public int value() { + return this.value; + } +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/enums/RegionLevelEnum.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/enums/RegionLevelEnum.java new file mode 100644 index 0000000..1ddfcf9 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/enums/RegionLevelEnum.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2019 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.enums; + +/** + * 行政区域 级别枚举 + * + * @author Mark sunlightcs@gmail.com + */ +public enum RegionLevelEnum { + ONE(1), + TWO(2), + THREE(3); + + private int value; + + RegionLevelEnum(int value) { + this.value = value; + } + + public int value() { + return this.value; + } +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/enums/RegionTopEnum.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/enums/RegionTopEnum.java new file mode 100644 index 0000000..4bbd8cc --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/enums/RegionTopEnum.java @@ -0,0 +1,18 @@ +package com.dkha.server.system.modules.sys.enums; + +/** + * 顶级区域 + */ +public enum RegionTopEnum { + FATHER(0); + + private long value; + + RegionTopEnum(int value) { + this.value = value; + } + + public long value() { + return this.value; + } +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/enums/SuperAdminEnum.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/enums/SuperAdminEnum.java new file mode 100644 index 0000000..5080b60 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/enums/SuperAdminEnum.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.enums; + +/** + * 超级管理员枚举 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public enum SuperAdminEnum { + YES(1), + NO(0); + + private int value; + + SuperAdminEnum(int value) { + this.value = value; + } + + public int value() { + return this.value; + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/enums/UserStatusEnum.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/enums/UserStatusEnum.java new file mode 100644 index 0000000..46bbfe7 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/enums/UserStatusEnum.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.enums; + +/** + * 用户状态 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public enum UserStatusEnum { + DISABLE(0), + ENABLED(1); + + private int value; + + UserStatusEnum(int value) { + this.value = value; + } + + public int value() { + return this.value; + } +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/excel/SysParamsExcel.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/excel/SysParamsExcel.java new file mode 100644 index 0000000..c80b098 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/excel/SysParamsExcel.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +/** + * 参数管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +public class SysParamsExcel { + @Excel(name = "参数编码") + private String paramCode; + @Excel(name = "参数值") + private String paramValue; + @Excel(name = "备注") + private String remark; + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/excel/SysUserExcel.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/excel/SysUserExcel.java new file mode 100644 index 0000000..bd28b4e --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/excel/SysUserExcel.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.util.Date; + +/** + * 用户管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +public class SysUserExcel { + @Excel(name = "用户名") + private String username; + @Excel(name = "姓名") + private String realName; + @Excel(name = "性别", replace = {"男_0", "女_1", "保密_2"}) + private Integer gender; + @Excel(name = "邮箱") + private String email; + @Excel(name = "手机号") + private String mobile; + @Excel(name = "部门名称") + private String deptName; + @Excel(name = "状态", replace = {"停用_0", "正常_1"}) + private Integer status; + @Excel(name = "备注") + private String remark; + @Excel(name = "创建时间", format = "yyyy-MM-dd HH:mm:ss") + private Date createDate; + +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/redis/SysParamsRedis.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/redis/SysParamsRedis.java new file mode 100644 index 0000000..25db847 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/redis/SysParamsRedis.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.redis; + +import com.dkha.common.redis.RedisKeys; +import com.dkha.common.redis.RedisUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * 参数管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Component +public class SysParamsRedis { + @Autowired + private RedisUtils redisUtils; + + public void delete(Object[] paramCodes) { + String key = RedisKeys.getSysParamsKey(); + redisUtils.hDel(key, paramCodes); + } + + public void set(String paramCode, String paramValue){ + if(paramValue == null){ + return ; + } + String key = RedisKeys.getSysParamsKey(); + redisUtils.hSet(key, paramCode, paramValue); + } + + public String get(String paramCode){ + String key = RedisKeys.getSysParamsKey(); + return (String)redisUtils.hGet(key, paramCode); + } + +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysDeptService.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysDeptService.java new file mode 100644 index 0000000..34a661b --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysDeptService.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service; + +import com.dkha.server.system.common.service.BaseService; +import com.dkha.server.system.modules.sys.dto.SysDeptDTO; +import com.dkha.server.system.modules.sys.entity.SysDeptEntity; + +import java.util.List; +import java.util.Map; + +/** + * 部门管理 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysDeptService extends BaseService { + + List list(Map params); + + SysDeptDTO get(Long id); + + void save(SysDeptDTO dto); + + void update(SysDeptDTO dto); + + void delete(Long id); + + /** + * 根据部门ID,获取本部门及子部门ID列表 + * @param id 部门ID + */ + List getSubDeptIdList(Long id); +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysDictDataService.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysDictDataService.java new file mode 100644 index 0000000..47f5233 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysDictDataService.java @@ -0,0 +1,27 @@ +package com.dkha.server.system.modules.sys.service; + +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.service.BaseService; +import com.dkha.server.system.modules.sys.dto.SysDictDataDTO; +import com.dkha.server.system.modules.sys.entity.SysDictDataEntity; + +import java.util.Map; + +/** + * 数据字典 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysDictDataService extends BaseService { + + PageData page(Map params); + + SysDictDataDTO get(Long id); + + void save(SysDictDataDTO dto); + + void update(SysDictDataDTO dto); + + void delete(Long[] ids); + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysDictTypeService.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysDictTypeService.java new file mode 100644 index 0000000..2977e83 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysDictTypeService.java @@ -0,0 +1,37 @@ +package com.dkha.server.system.modules.sys.service; + +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.service.BaseService; +import com.dkha.server.system.modules.sys.dto.SysDictTypeDTO; +import com.dkha.server.system.modules.sys.entity.DictType; +import com.dkha.server.system.modules.sys.entity.SysDictDataEntity; +import com.dkha.server.system.modules.sys.entity.SysDictTypeEntity; + +import java.util.List; +import java.util.Map; + +public interface SysDictTypeService extends BaseService { + + PageData page(Map params); + + SysDictTypeDTO get(Long id); + + void save(SysDictTypeDTO dto); + + void update(SysDictTypeDTO dto); + + void delete(Long[] ids); + + /** + * 获取所有字典 + */ + List getAllList(); + + /** + * 按类型获取 + * @param type + * @return + */ + List getByType(String type); + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysLanguageService.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysLanguageService.java new file mode 100644 index 0000000..dbf4bda --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysLanguageService.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service; + + +import com.dkha.server.system.common.service.BaseService; +import com.dkha.server.system.modules.sys.entity.SysLanguageEntity; + +/** + * 国际化 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysLanguageService extends BaseService { + + /** + * 保存或更新 + * @param tableName 表名 + * @param tableId 表主键 + * @param fieldName 字段名 + * @param fieldValue 字段值 + * @param language 语言 + */ + void saveOrUpdate(String tableName, Long tableId, String fieldName, String fieldValue, String language); + + /** + * 删除国际化 + * @param tableName 表名 + * @param tableId 表主键 + */ + void deleteLanguage(String tableName, Long tableId); +} + diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysMenuService.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysMenuService.java new file mode 100644 index 0000000..4f7eb69 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysMenuService.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service; + +import com.dkha.server.system.common.service.BaseService; +import com.dkha.server.system.modules.security.user.UserDetail; +import com.dkha.server.system.modules.sys.dto.SysMenuDTO; +import com.dkha.server.system.modules.sys.entity.SysMenuEntity; +import java.util.List; + + +/** + * 菜单管理 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysMenuService extends BaseService { + + SysMenuDTO get(Long id); + + void save(SysMenuDTO dto); + + void update(SysMenuDTO dto); + + void delete(Long id); + + /** + * 菜单列表 + * + * @param type 菜单类型 + */ + List getAllMenuList(Integer type); + + /** + * 用户菜单列表 + * + * @param user 用户 + * @param type 菜单类型 + */ + List getUserMenuList(UserDetail user, Integer type); + + /** + * 根据父菜单,查询子菜单 + * @param pid 父菜单ID + */ + List getListPid(Long pid); +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysParamsService.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysParamsService.java new file mode 100644 index 0000000..f03c9ac --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysParamsService.java @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service; + + + +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.service.BaseService; +import com.dkha.server.system.modules.sys.dto.SysParamsDTO; +import com.dkha.server.system.modules.sys.entity.SysParamsEntity; + +import java.util.List; +import java.util.Map; + +/** + * 参数管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface SysParamsService extends BaseService { + + PageData page(Map params); + + List list(Map params); + + SysParamsDTO get(Long id); + + void save(SysParamsDTO dto); + + void update(SysParamsDTO dto); + + void delete(Long[] ids); + + /** + * 根据参数编码,获取参数的value值 + * + * @param paramCode 参数编码 + */ + String getValue(String paramCode); + + /** + * 根据参数编码,获取value的Object对象 + * @param paramCode 参数编码 + * @param clazz Object对象 + */ + T getValueObject(String paramCode, Class clazz); + + /** + * 根据参数编码,更新value + * @param paramCode 参数编码 + * @param paramValue 参数值 + */ + int updateValueByCode(String paramCode, String paramValue); +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRegionService.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRegionService.java new file mode 100644 index 0000000..9acfbc4 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRegionService.java @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service; + +import com.dkha.server.system.common.service.BaseService; +import com.dkha.server.system.modules.sys.dto.SysRegionDTO; +import com.dkha.server.system.modules.sys.dto.region.RegionProvince; +import com.dkha.server.system.modules.sys.entity.SysRegionEntity; + +import java.util.List; +import java.util.Map; + +/** + * 行政区域 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysRegionService extends BaseService { + + List list(Map params); + + /** + * 获取树形结构地区码表 + * @return + */ + List allList(); + List> getTreeList(); + + SysRegionDTO get(Long id); + + void save(SysRegionDTO dto); + + void update(SysRegionDTO dto); + + void delete(Long id); + + int getCountByPid(Long pid); + + List getRegion(boolean threeLevel); + + /** + * 根据地区登记查询码值 + * @param level + * @return + */ + List getRegionByLevel(Integer level); + + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRoleDataScopeService.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRoleDataScopeService.java new file mode 100644 index 0000000..e8b1af6 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRoleDataScopeService.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service; + + +import com.dkha.server.system.common.service.BaseService; +import com.dkha.server.system.modules.sys.entity.SysRoleDataScopeEntity; + +import java.util.List; + +/** + * 角色数据权限 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface SysRoleDataScopeService extends BaseService { + + /** + * 根据角色ID,获取部门ID列表 + */ + List getDeptIdList(Long roleId); + + /** + * 保存或修改 + * @param roleId 角色ID + * @param deptIdList 部门ID列表 + */ + void saveOrUpdate(Long roleId, List deptIdList); + + /** + * 根据角色id,删除角色数据权限关系 + * @param roleId 角色ids + */ + void deleteByRoleIds(Long[] roleId); +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRoleMenuService.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRoleMenuService.java new file mode 100644 index 0000000..095a92b --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRoleMenuService.java @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service; + + +import com.dkha.server.system.common.service.BaseService; +import com.dkha.server.system.modules.sys.entity.SysRoleMenuEntity; + +import java.util.List; + + +/** + * 角色与菜单对应关系 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysRoleMenuService extends BaseService { + + /** + * 根据角色ID,获取菜单ID列表 + */ + List getMenuIdList(Long roleId); + + /** + * 保存或修改 + * @param roleId 角色ID + * @param menuIdList 菜单ID列表 + */ + void saveOrUpdate(Long roleId, List menuIdList); + + /** + * 根据角色id,删除角色菜单关系 + * @param roleIds 角色ids + */ + void deleteByRoleIds(Long[] roleIds); + + /** + * 根据菜单id,删除角色菜单关系 + * @param menuId 菜单id + */ + void deleteByMenuId(Long menuId); +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRoleService.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRoleService.java new file mode 100644 index 0000000..b02a4da --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRoleService.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service; + + + +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.service.BaseService; +import com.dkha.server.system.modules.sys.dto.SysRoleDTO; +import com.dkha.server.system.modules.sys.entity.SysRoleEntity; + +import java.util.List; +import java.util.Map; + + +/** + * 角色 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysRoleService extends BaseService { + + PageData page(Map params); + + List list(Map params); + + SysRoleDTO get(Long id); + + void save(SysRoleDTO dto); + + void update(SysRoleDTO dto); + + void delete(Long[] ids); + +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRoleUserService.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRoleUserService.java new file mode 100644 index 0000000..dada4da --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysRoleUserService.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service; + + +import com.dkha.server.system.common.service.BaseService; +import com.dkha.server.system.modules.sys.entity.SysRoleUserEntity; + +import java.util.List; + +/** + * 角色用户关系 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface SysRoleUserService extends BaseService { + + /** + * 保存或修改 + * @param userId 用户ID + * @param roleIdList 角色ID列表 + */ + void saveOrUpdate(Long userId, List roleIdList); + + /** + * 根据角色ids,删除角色用户关系 + * @param roleIds 角色ids + */ + void deleteByRoleIds(Long[] roleIds); + + /** + * 根据用户id,删除角色用户关系 + * @param userIds 用户ids + */ + void deleteByUserIds(Long[] userIds); + + /** + * 角色ID列表 + * @param userId 用户ID + */ + List getRoleIdList(Long userId); +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysUserService.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysUserService.java new file mode 100644 index 0000000..d074ecf --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/SysUserService.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service; + + +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.service.BaseService; +import com.dkha.server.system.modules.sys.dto.SysUserDTO; +import com.dkha.server.system.modules.sys.entity.SysUserEntity; + +import java.util.List; +import java.util.Map; + + +/** + * 系统用户 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysUserService extends BaseService { + + PageData page(Map params); + + List list(Map params); + + SysUserDTO get(Long id); + + SysUserDTO getByUsername(String username); + + void save(SysUserDTO dto); + + void update(SysUserDTO dto); + + void delete(Long[] ids); + + /** + * 修改密码 + * @param id 用户ID + * @param newPassword 新密码 + */ + void updatePassword(Long id, String newPassword); + + /** + * 根据部门ID,查询用户数 + */ + int getCountByDeptId(Long deptId); +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysDeptServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysDeptServiceImpl.java new file mode 100644 index 0000000..1d8c3cd --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysDeptServiceImpl.java @@ -0,0 +1,162 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service.impl; + +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.exception.ErrorCode; +import com.dkha.server.system.common.exception.RenException; +import com.dkha.server.system.common.service.impl.BaseServiceImpl; +import com.dkha.server.system.common.utils.ConvertUtils; +import com.dkha.server.system.common.utils.TreeUtils; +import com.dkha.server.system.modules.security.user.SecurityUser; +import com.dkha.server.system.modules.security.user.UserDetail; +import com.dkha.server.system.modules.sys.dao.SysDeptDao; +import com.dkha.server.system.modules.sys.dto.SysDeptDTO; +import com.dkha.server.system.modules.sys.entity.SysDeptEntity; +import com.dkha.server.system.modules.sys.enums.SuperAdminEnum; +import com.dkha.server.system.modules.sys.service.SysDeptService; +import com.dkha.server.system.modules.sys.service.SysUserService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; + + +@Service +public class SysDeptServiceImpl extends BaseServiceImpl implements SysDeptService { + @Autowired + private SysUserService sysUserService; + + @Override + public List list(Map params) { + //普通管理员,只能查询所属部门及子部门的数据 + UserDetail user = SecurityUser.getUser(); + if(user.getSuperAdmin() == SuperAdminEnum.NO.value()) { + params.put("deptIdList", getSubDeptIdList(user.getDeptId())); + } + + //查询部门列表 + List entityList = baseDao.getList(params); + + List dtoList = ConvertUtils.sourceToTarget(entityList, SysDeptDTO.class); + + return TreeUtils.build(dtoList); + } + + @Override + public SysDeptDTO get(Long id) { + //超级管理员,部门ID为null + if(id == null){ + return null; + } + + SysDeptEntity entity = baseDao.getById(id); + + return ConvertUtils.sourceToTarget(entity, SysDeptDTO.class); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysDeptDTO dto) { + SysDeptEntity entity = ConvertUtils.sourceToTarget(dto, SysDeptEntity.class); + + entity.setPids(getPidList(entity.getPid())); + insert(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(SysDeptDTO dto) { + SysDeptEntity entity = ConvertUtils.sourceToTarget(dto, SysDeptEntity.class); + + //上级部门不能为自身 + if(entity.getId().equals(entity.getPid())){ + throw new RenException(ErrorCode.SUPERIOR_DEPT_ERROR); + } + + //上级部门不能为下级部门 + List subDeptList = getSubDeptIdList(entity.getId()); + if(subDeptList.contains(entity.getPid())){ + throw new RenException(ErrorCode.SUPERIOR_DEPT_ERROR); + } + + entity.setPids(getPidList(entity.getPid())); + updateById(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Long id) { + //判断是否有子部门 + List subList = getSubDeptIdList(id); + if(subList.size() > 1){ + throw new RenException(ErrorCode.DEPT_SUB_DELETE_ERROR); + } + + //判断部门下面是否有用户 + int count = sysUserService.getCountByDeptId(id); + if(count > 0){ + throw new RenException(ErrorCode.DEPT_USER_DELETE_ERROR); + } + + //删除 + baseDao.deleteById(id); + } + + @Override + public List getSubDeptIdList(Long id) { + List deptIdList = baseDao.getSubDeptIdList("%" + id + "%"); + deptIdList.add(id); + + return deptIdList; + } + + /** + * 获取所有上级部门ID + * @param pid 上级ID + */ + private String getPidList(Long pid){ + //顶级部门,无上级部门 + if(Constant.DEPT_ROOT.equals(pid)){ + return Constant.DEPT_ROOT + ""; + } + + //所有部门的id、pid列表 + List deptList = baseDao.getIdAndPidList(); + + //list转map + Map map = new HashMap<>(deptList.size()); + for(SysDeptEntity entity : deptList){ + map.put(entity.getId(), entity); + } + + //递归查询所有上级部门ID列表 + List pidList = new ArrayList<>(); + getPidTree(pid, map, pidList); + + return StringUtils.join(pidList, ","); + } + + private void getPidTree(Long pid, Map map, List pidList) { + //顶级部门,无上级部门 + if(Constant.DEPT_ROOT.equals(pid)){ + return ; + } + + //上级部门存在 + SysDeptEntity parent = map.get(pid); + if(parent != null){ + getPidTree(parent.getPid(), map, pidList); + } + + pidList.add(pid); + } +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysDictDataServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysDictDataServiceImpl.java new file mode 100644 index 0000000..9526566 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysDictDataServiceImpl.java @@ -0,0 +1,80 @@ +package com.dkha.server.system.modules.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.service.impl.BaseServiceImpl; +import com.dkha.server.system.common.utils.ConvertUtils; +import com.dkha.server.system.modules.sys.dao.SysDictDataDao; +import com.dkha.server.system.modules.sys.dto.SysDictDataDTO; +import com.dkha.server.system.modules.sys.entity.SysDictDataEntity; +import com.dkha.server.system.modules.sys.service.SysDictDataService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.Map; + +/** + * 字典类型 + * + * @author Mark sunlightcs@gmail.com + */ +@Service +public class SysDictDataServiceImpl extends BaseServiceImpl implements SysDictDataService { + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, "sort", true), + getWrapper(params) + ); + + return getPageData(page, SysDictDataDTO.class); + } + + private QueryWrapper getWrapper(Map params){ + String dictTypeId = (String) params.get("dictTypeId"); + String dictLabel = (String) params.get("dictLabel"); + String dictValue = (String) params.get("dictValue"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq("dict_type_id", dictTypeId); + wrapper.like(StringUtils.isNotBlank(dictLabel), "dict_label", dictLabel); + wrapper.like(StringUtils.isNotBlank(dictValue), "dict_value", dictValue); + + return wrapper; + } + + @Override + public SysDictDataDTO get(Long id) { + SysDictDataEntity entity = baseDao.selectById(id); + + return ConvertUtils.sourceToTarget(entity, SysDictDataDTO.class); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysDictDataDTO dto) { + SysDictDataEntity entity = ConvertUtils.sourceToTarget(dto, SysDictDataEntity.class); + + insert(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(SysDictDataDTO dto) { + SysDictDataEntity entity = ConvertUtils.sourceToTarget(dto, SysDictDataEntity.class); + + updateById(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Long[] ids) { + //删除 + deleteBatchIds(Arrays.asList(ids)); + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysDictTypeServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysDictTypeServiceImpl.java new file mode 100644 index 0000000..b94d5c7 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysDictTypeServiceImpl.java @@ -0,0 +1,111 @@ +package com.dkha.server.system.modules.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.service.impl.BaseServiceImpl; +import com.dkha.server.system.common.utils.ConvertUtils; +import com.dkha.server.system.modules.sys.dao.SysDictDataDao; +import com.dkha.server.system.modules.sys.dao.SysDictTypeDao; +import com.dkha.server.system.modules.sys.dto.SysDictTypeDTO; +import com.dkha.server.system.modules.sys.entity.DictData; +import com.dkha.server.system.modules.sys.entity.DictType; +import com.dkha.server.system.modules.sys.entity.SysDictDataEntity; +import com.dkha.server.system.modules.sys.entity.SysDictTypeEntity; +import com.dkha.server.system.modules.sys.service.SysDictTypeService; +import org.apache.commons.lang3.StringUtils; +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.Arrays; +import java.util.List; +import java.util.Map; + +/** + * 字典类型 + * + * @author Mark sunlightcs@gmail.com + */ +@Service +public class SysDictTypeServiceImpl extends BaseServiceImpl implements SysDictTypeService { + @Autowired + private SysDictDataDao sysDictDataDao; + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, "sort", true), + getWrapper(params) + ); + + return getPageData(page, SysDictTypeDTO.class); + } + + private QueryWrapper getWrapper(Map params){ + String dictType = (String) params.get("dictType"); + String dictName = (String) params.get("dictName"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.like(StringUtils.isNotBlank(dictType), "dict_type", dictType); + wrapper.like(StringUtils.isNotBlank(dictName), "dict_name", dictName); + + return wrapper; + } + + @Override + public SysDictTypeDTO get(Long id) { + SysDictTypeEntity entity = baseDao.selectById(id); + + return ConvertUtils.sourceToTarget(entity, SysDictTypeDTO.class); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysDictTypeDTO dto) { + SysDictTypeEntity entity = ConvertUtils.sourceToTarget(dto, SysDictTypeEntity.class); + + insert(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(SysDictTypeDTO dto) { + SysDictTypeEntity entity = ConvertUtils.sourceToTarget(dto, SysDictTypeEntity.class); + + updateById(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Long[] ids) { + //删除 + deleteBatchIds(Arrays.asList(ids)); + } + + @Override + public List getAllList() { + List typeList = baseDao.getDictTypeList(); + List dataList = sysDictDataDao.getDictDataList(); + for(DictType type : typeList){ + for(DictData data : dataList){ + if(type.getId().equals(data.getDictTypeId())){ + type.getDataList().add(data); + } + } + } + return typeList; + } + + @Override + public List getByType(String type) { + SysDictTypeEntity entity = baseDao.selectOne(new QueryWrapper().eq("dict_type",type)); + List entities = new ArrayList<>(); + if (UtilValidate.isNotEmpty(entity)) { + entities= sysDictDataDao.selectList(new QueryWrapper().eq("dict_type_id",entity.getId())); + } + return entities; + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysLanguageServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysLanguageServiceImpl.java new file mode 100644 index 0000000..193c7fa --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysLanguageServiceImpl.java @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service.impl; + +import com.dkha.server.system.common.service.impl.BaseServiceImpl; +import com.dkha.server.system.modules.sys.dao.SysLanguageDao; +import com.dkha.server.system.modules.sys.entity.SysLanguageEntity; +import com.dkha.server.system.modules.sys.service.SysLanguageService; +import org.springframework.stereotype.Service; + + +/** + * 国际化 + * + * @author Mark sunlightcs@gmail.com + */ +@Service +public class SysLanguageServiceImpl extends BaseServiceImpl implements SysLanguageService { + + @Override + public void saveOrUpdate(String tableName, Long tableId, String fieldName, String fieldValue, String language) { + SysLanguageEntity entity = new SysLanguageEntity(); + entity.setTableName(tableName); + entity.setTableId(tableId); + entity.setFieldName(fieldName); + entity.setFieldValue(fieldValue); + entity.setLanguage(language); + + //判断是否有数据 + if(baseDao.getLanguage(entity) == null){ + baseDao.insert(entity); + }else { + baseDao.updateLanguage(entity); + } + } + + @Override + public void deleteLanguage(String tableName, Long tableId) { + baseDao.deleteLanguage(tableName, tableId); + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysMenuServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysMenuServiceImpl.java new file mode 100644 index 0000000..47f8f08 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysMenuServiceImpl.java @@ -0,0 +1,122 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service.impl; + +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.exception.ErrorCode; +import com.dkha.server.system.common.exception.RenException; +import com.dkha.server.system.common.service.impl.BaseServiceImpl; +import com.dkha.server.system.common.utils.ConvertUtils; +import com.dkha.server.system.common.utils.HttpContextUtils; +import com.dkha.server.system.common.utils.TreeUtils; +import com.dkha.server.system.modules.security.user.UserDetail; +import com.dkha.server.system.modules.sys.dao.SysMenuDao; +import com.dkha.server.system.modules.sys.dto.SysMenuDTO; +import com.dkha.server.system.modules.sys.entity.SysMenuEntity; +import com.dkha.server.system.modules.sys.enums.SuperAdminEnum; +import com.dkha.server.system.modules.sys.service.SysLanguageService; +import com.dkha.server.system.modules.sys.service.SysMenuService; +import com.dkha.server.system.modules.sys.service.SysRoleMenuService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +public class SysMenuServiceImpl extends BaseServiceImpl implements SysMenuService { + @Autowired + private SysRoleMenuService sysRoleMenuService; + @Autowired + private SysLanguageService sysLanguageService; + + @Override + public SysMenuDTO get(Long id) { + SysMenuEntity entity = baseDao.getById(id, HttpContextUtils.getLanguage()); + + SysMenuDTO dto = ConvertUtils.sourceToTarget(entity, SysMenuDTO.class); + + return dto; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysMenuDTO dto) { + SysMenuEntity entity = ConvertUtils.sourceToTarget(dto, SysMenuEntity.class); + + //保存菜单 + insert(entity); + saveLanguage(entity.getId(), "name", entity.getName()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(SysMenuDTO dto) { + SysMenuEntity entity = ConvertUtils.sourceToTarget(dto, SysMenuEntity.class); + + //上级菜单不能为自身 + if(entity.getId().equals(entity.getPid())){ + throw new RenException(ErrorCode.SUPERIOR_MENU_ERROR); + } + + //更新菜单 + updateById(entity); + saveLanguage(entity.getId(), "name", entity.getName()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Long id) { + //删除菜单 + deleteById(id); + + //删除菜单国际化 + sysLanguageService.deleteLanguage("sys_menu", id); + + //删除角色菜单关系 + sysRoleMenuService.deleteByMenuId(id); + } + + @Override + public List getAllMenuList(Integer type) { + List menuList = baseDao.getMenuList(type, HttpContextUtils.getLanguage()); + + List dtoList = ConvertUtils.sourceToTarget(menuList, SysMenuDTO.class); + + return TreeUtils.build(dtoList, Constant.MENU_ROOT); + } + + @Override + public List getUserMenuList(UserDetail user, Integer type) { + List menuList; + + //系统管理员,拥有最高权限 + if(user.getSuperAdmin() == SuperAdminEnum.YES.value()){ + menuList = baseDao.getMenuList(type, HttpContextUtils.getLanguage()); + }else { + menuList = baseDao.getUserMenuList(user.getId(), type, HttpContextUtils.getLanguage()); + } + + List dtoList = ConvertUtils.sourceToTarget(menuList, SysMenuDTO.class); + + return TreeUtils.build(dtoList); + } + + @Override + public List getListPid(Long pid) { + List menuList = baseDao.getListPid(pid); + + return ConvertUtils.sourceToTarget(menuList, SysMenuDTO.class); + } + + private void saveLanguage(Long tableId, String fieldName, String fieldValue){ + sysLanguageService.saveOrUpdate("sys_menu", tableId, fieldName, fieldValue, HttpContextUtils.getLanguage()); + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysParamsServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysParamsServiceImpl.java new file mode 100644 index 0000000..9010c1f --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysParamsServiceImpl.java @@ -0,0 +1,142 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service.impl; + +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.exception.ErrorCode; +import com.dkha.server.system.common.exception.RenException; +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.service.impl.BaseServiceImpl; +import com.dkha.server.system.common.utils.ConvertUtils; +import com.dkha.server.system.modules.sys.dao.SysParamsDao; +import com.dkha.server.system.modules.sys.dto.SysParamsDTO; +import com.dkha.server.system.modules.sys.entity.SysParamsEntity; +import com.dkha.server.system.modules.sys.redis.SysParamsRedis; +import com.dkha.server.system.modules.sys.service.SysParamsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * 参数管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Service +public class SysParamsServiceImpl extends BaseServiceImpl implements SysParamsService { + @Autowired + private SysParamsRedis sysParamsRedis; + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, Constant.CREATE_DATE, false), + getWrapper(params) + ); + + return getPageData(page, SysParamsDTO.class); + } + + @Override + public List list(Map params) { + List entityList = baseDao.selectList(getWrapper(params)); + + return ConvertUtils.sourceToTarget(entityList, SysParamsDTO.class); + } + + private QueryWrapper getWrapper(Map params){ + String paramCode = (String) params.get("paramCode"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq("param_type", 1); + wrapper.like(UtilValidate.isNotEmpty(paramCode), "param_code", paramCode); + + return wrapper; + } + + @Override + public SysParamsDTO get(Long id) { + SysParamsEntity entity = baseDao.selectById(id); + + return ConvertUtils.sourceToTarget(entity, SysParamsDTO.class); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysParamsDTO dto) { + SysParamsEntity entity = ConvertUtils.sourceToTarget(dto, SysParamsEntity.class); + insert(entity); + + sysParamsRedis.set(entity.getParamCode(), entity.getParamValue()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(SysParamsDTO dto) { + SysParamsEntity entity = ConvertUtils.sourceToTarget(dto, SysParamsEntity.class); + updateById(entity); + + sysParamsRedis.set(entity.getParamCode(), entity.getParamValue()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Long[] ids) { + //删除Redis数据 + List paramCodeList = baseDao.getParamCodeList(ids); + String[] paramCodes = paramCodeList.toArray(new String[paramCodeList.size()]); + sysParamsRedis.delete(paramCodes); + + //删除 + deleteBatchIds(Arrays.asList(ids)); + } + + @Override + public String getValue(String paramCode) { + String paramValue = sysParamsRedis.get(paramCode); + if(paramValue == null){ + paramValue = baseDao.getValueByCode(paramCode); + + sysParamsRedis.set(paramCode, paramValue); + } + return paramValue; + } + + @Override + public T getValueObject(String paramCode, Class clazz) { + String paramValue = getValue(paramCode); + if(UtilValidate.isNotEmpty(paramValue)){ + return JSON.parseObject(paramValue, clazz); + } + + try { + return clazz.newInstance(); + } catch (Exception e) { + throw new RenException(ErrorCode.PARAMS_GET_ERROR); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public int updateValueByCode(String paramCode, String paramValue) { + int count = baseDao.updateValueByCode(paramCode, paramValue); + sysParamsRedis.set(paramCode, paramValue); + return count; + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRegionServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRegionServiceImpl.java new file mode 100644 index 0000000..6ad8c15 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRegionServiceImpl.java @@ -0,0 +1,237 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.dkha.common.enums.YNEnums; +import com.dkha.common.exception.DkException; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.modules.entities.FaceCameraEntity; +import com.dkha.server.services.FaceCameraService; +import com.dkha.server.services.IControlBayonetMidService; +import com.dkha.server.system.common.exception.ErrorCode; +import com.dkha.server.system.common.exception.RenException; +import com.dkha.server.system.common.service.impl.BaseServiceImpl; +import com.dkha.server.system.common.utils.ConvertUtils; +import com.dkha.server.system.common.utils.TreeUtils; +import com.dkha.server.system.modules.security.user.SecurityUser; +import com.dkha.server.system.modules.sys.dao.SysRegionDao; +import com.dkha.server.system.modules.sys.dto.SysDictDTO; +import com.dkha.server.system.modules.sys.dto.SysRegionDTO; +import com.dkha.server.system.modules.sys.dto.region.Region; +import com.dkha.server.system.modules.sys.dto.region.RegionCity; +import com.dkha.server.system.modules.sys.dto.region.RegionProvince; +import com.dkha.server.system.modules.sys.entity.SysRegionEntity; +import com.dkha.server.system.modules.sys.enums.RegionLeafEnum; +import com.dkha.server.system.modules.sys.enums.RegionLevelEnum; +import com.dkha.server.system.modules.sys.enums.RegionTopEnum; +import com.dkha.server.system.modules.sys.service.SysRegionService; +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.Date; +import java.util.List; +import java.util.Map; + + +@Service +public class SysRegionServiceImpl extends BaseServiceImpl implements SysRegionService { + + @Autowired + private IControlBayonetMidService controlBayonetMidServiceImpl; + + @Autowired + private FaceCameraService faceCameraServiceImpl; + + @Override + public List list(Map params) { + String pid = (String) params.get("pid"); + + if (UtilValidate.isEmpty(pid)) { + //查询一级 + params.put("treeLevel", RegionLevelEnum.ONE.value()); + } + //查询列表 + List entityList = baseDao.getList(params); + + List dtoList = new ArrayList<>(entityList.size()); + for (SysRegionEntity entity : entityList) { + SysRegionDTO dto = new SysRegionDTO(); + BeanUtils.copyProperties(entity, dto); + dto.setHasChildren(entity.getLeaf() != 1); + + dtoList.add(dto); + } + + return dtoList; + } + + @Override + public List allList() { + List list = baseDao.selectList(new QueryWrapper<>()); + List dtoList = ConvertUtils.sourceToTarget(list, SysRegionDTO.class); + return TreeUtils.build(dtoList); + } + + @Override + public List> getTreeList() { + return baseDao.getTreeList(); + } + + @Override + public SysRegionDTO get(Long id) { + SysRegionEntity entity = baseDao.getById(id); + + return ConvertUtils.sourceToTarget(entity, SysRegionDTO.class); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysRegionDTO dto) { + SysRegionEntity entity = ConvertUtils.sourceToTarget(dto, SysRegionEntity.class); + + //查询上级 + SysRegionEntity parentEntity = baseDao.getById(dto.getPid()); + if (parentEntity == null) { + entity.setTreeLevel(RegionLevelEnum.ONE.value()); + //查询当前有几个第一级区域 + List firstLevel = baseDao.selectList(new QueryWrapper().eq("tree_level", 1)); + //当前存在多个一级区域 + if (firstLevel != null && firstLevel.size() > 0) { + entity.setPid(Long.valueOf(firstLevel.size())); + } + } else { + + entity.setTreeLevel(parentEntity.getTreeLevel() + 1); + //上级存在,且为叶子节点,需要修改为非叶子节点 + if (parentEntity.getLeaf() == RegionLeafEnum.YES.value()) { + parentEntity.setLeaf(RegionLeafEnum.NO.value()); + baseDao.updateById(parentEntity); + } + } + entity.setCreator(SecurityUser.getUser() == null ? null : SecurityUser.getUser().getId()); + entity.setCreateDate(new Date()); + entity.setUpdater(SecurityUser.getUser() == null ? null : SecurityUser.getUser().getId()); + entity.setUpdateDate(new Date()); + //新增都是叶子节点 + entity.setLeaf(RegionLeafEnum.YES.value()); + insert(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(SysRegionDTO dto) { + SysRegionEntity entity = ConvertUtils.sourceToTarget(dto, SysRegionEntity.class); + + //上级不能为自身 + if (entity.getId().equals(entity.getPid())) { + throw new RenException(ErrorCode.SUPERIOR_REGION_ERROR); + } + + //查询上级 + SysRegionEntity parentEntity = baseDao.getById(dto.getPid()); + if (parentEntity == null) { + entity.setTreeLevel(RegionLevelEnum.ONE.value()); + } else { + entity.setTreeLevel(parentEntity.getTreeLevel() + 1); + //上级存在,且为叶子节点,需要修改为非叶子节点 + if (parentEntity.getLeaf() == RegionLeafEnum.YES.value()) { + parentEntity.setLeaf(RegionLeafEnum.NO.value()); + baseDao.updateById(parentEntity); + } + } + + //查询下级 + int subCount = baseDao.getCountByPid(dto.getId()); + if (subCount == 0) { + entity.setLeaf(RegionLeafEnum.YES.value()); + } else { + entity.setLeaf(RegionLeafEnum.NO.value()); + } + entity.setUpdater(SecurityUser.getUser() == null ? null : SecurityUser.getUser().getId()); + entity.setUpdateDate(new Date()); + updateById(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Long id) { + //判断是否为顶级区域 + SysRegionEntity dao = baseDao.getById(id); +// if (dao.getPid() == RegionTopEnum.FATHER.value()) { +// throw new DkException("该区域为顶级区域、不允许删除"); +// } + //判断区域下是否有摄像头 + List> list = faceCameraServiceImpl.listMaps(new QueryWrapper().eq("is_valid", YNEnums.YES.code).like("camera_region_firstlevel", "%" + id + "%")); + if (UtilValidate.isNotEmpty(list)) { + throw new DkException("该区域下存在布控任务或者摄像头,不允许删除"); + } + baseDao.deleteById(id); + //判断父级是否还有子级,若无修改上级为叶子节点 + if (baseDao.getCountByPid(dao.getPid()) == 0) { + SysRegionEntity fatherDao = baseDao.getById(dao.getPid()); + if (UtilValidate.isNotEmpty(fatherDao)) { + fatherDao.setLeaf(RegionLeafEnum.YES.value()); + baseDao.updateById(fatherDao); + } + + } + + } + + @Override + public int getCountByPid(Long pid) { + return baseDao.getCountByPid(pid); + } + + @Override + public List getRegionByLevel(Integer level) { + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("tree_level", level); + List list = baseDao.selectList(queryWrapper); + return list; + } + + @Override + public List getRegion(boolean threeLevel) { + List provinceList = baseDao.getListByLevel(RegionLevelEnum.ONE.value()); + List cityList = baseDao.getListByLevel(RegionLevelEnum.TWO.value()); + + List provinces = ConvertUtils.sourceToTarget(provinceList, RegionProvince.class); + List cities = ConvertUtils.sourceToTarget(cityList, RegionCity.class); + + for (RegionCity city : cities) { + for (RegionProvince province : provinces) { + if (city.getPid().equals(province.getId())) { + province.getCities().add(city); + } + } + } + + //无需显示3级区县 + if (!threeLevel) { + return provinces; + } + + List countyList = baseDao.getListByLevel(RegionLevelEnum.THREE.value()); + List counties = ConvertUtils.sourceToTarget(countyList, Region.class); + for (Region county : counties) { + for (RegionCity city : cities) { + if (county.getPid().equals(city.getId())) { + city.getCounties().add(county); + } + } + } + + return provinces; + } +} diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRoleDataScopeServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRoleDataScopeServiceImpl.java new file mode 100644 index 0000000..ce1a945 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRoleDataScopeServiceImpl.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service.impl; + +import com.dkha.common.util.UtilValidate; +import com.dkha.server.system.common.service.impl.BaseServiceImpl; +import com.dkha.server.system.modules.sys.dao.SysRoleDataScopeDao; +import com.dkha.server.system.modules.sys.entity.SysRoleDataScopeEntity; +import com.dkha.server.system.modules.sys.service.SysRoleDataScopeService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * 角色数据权限 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Service +public class SysRoleDataScopeServiceImpl extends BaseServiceImpl + implements SysRoleDataScopeService { + + @Override + public List getDeptIdList(Long roleId) { + return baseDao.getDeptIdList(roleId); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void saveOrUpdate(Long roleId, List deptIdList) { + //先删除角色数据权限关系 + deleteByRoleIds(new Long[]{roleId}); + + //角色没有一个数据权限的情况 + if(UtilValidate.isEmpty(deptIdList)){ + return ; + } + + //保存角色数据权限关系 + for(Long deptId : deptIdList){ + SysRoleDataScopeEntity sysRoleDataScopeEntity = new SysRoleDataScopeEntity(); + sysRoleDataScopeEntity.setDeptId(deptId); + sysRoleDataScopeEntity.setRoleId(roleId); + + //保存 + insert(sysRoleDataScopeEntity); + } + } + + @Override + public void deleteByRoleIds(Long[] roleIds) { + baseDao.deleteByRoleIds(roleIds); + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRoleMenuServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRoleMenuServiceImpl.java new file mode 100644 index 0000000..a75a1e5 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRoleMenuServiceImpl.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service.impl; + +import com.dkha.common.util.UtilValidate; +import com.dkha.server.system.common.service.impl.BaseServiceImpl; +import com.dkha.server.system.modules.sys.dao.SysRoleMenuDao; +import com.dkha.server.system.modules.sys.entity.SysRoleMenuEntity; +import com.dkha.server.system.modules.sys.service.SysRoleMenuService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + + +/** + * 角色与菜单对应关系 + * + * @author Mark sunlightcs@gmail.com + */ +@Service +public class SysRoleMenuServiceImpl extends BaseServiceImpl implements SysRoleMenuService { + + @Override + @Transactional(rollbackFor = Exception.class) + public void saveOrUpdate(Long roleId, List menuIdList) { + //先删除角色菜单关系 + deleteByRoleIds(new Long[]{roleId}); + + //角色没有一个菜单权限的情况 + if(UtilValidate.isEmpty(menuIdList)){ + return ; + } + + //保存角色菜单关系 + for(Long menuId : menuIdList){ + SysRoleMenuEntity sysRoleMenuEntity = new SysRoleMenuEntity(); + sysRoleMenuEntity.setMenuId(menuId); + sysRoleMenuEntity.setRoleId(roleId); + + //保存 + insert(sysRoleMenuEntity); + } + } + + @Override + public List getMenuIdList(Long roleId){ + return baseDao.getMenuIdList(roleId); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteByRoleIds(Long[] roleIds) { + baseDao.deleteByRoleIds(roleIds); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteByMenuId(Long menuId) { + baseDao.deleteByMenuId(menuId); + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRoleServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRoleServiceImpl.java new file mode 100644 index 0000000..498e84c --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRoleServiceImpl.java @@ -0,0 +1,135 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.service.impl.BaseServiceImpl; +import com.dkha.server.system.common.utils.ConvertUtils; +import com.dkha.server.system.modules.security.user.SecurityUser; +import com.dkha.server.system.modules.security.user.UserDetail; +import com.dkha.server.system.modules.sys.dao.SysRoleDao; +import com.dkha.server.system.modules.sys.dto.SysRoleDTO; +import com.dkha.server.system.modules.sys.entity.SysRoleEntity; +import com.dkha.server.system.modules.sys.enums.SuperAdminEnum; +import com.dkha.server.system.modules.sys.service.*; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * 角色 + * + * @author Mark sunlightcs@gmail.com + */ +@Service +public class SysRoleServiceImpl extends BaseServiceImpl implements SysRoleService { + @Autowired + private SysRoleMenuService sysRoleMenuService; + @Autowired + private SysRoleDataScopeService sysRoleDataScopeService; + @Autowired + private SysRoleUserService sysRoleUserService; + @Autowired + private SysDeptService sysDeptService; + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, Constant.CREATE_DATE, false), + getWrapper(params) + ); + + return getPageData(page, SysRoleDTO.class); + } + + @Override + public List list(Map params) { + List entityList = baseDao.selectList(getWrapper(params)); + + return ConvertUtils.sourceToTarget(entityList, SysRoleDTO.class); + } + + private QueryWrapper getWrapper(Map params){ + String name = (String)params.get("name"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.like(StringUtils.isNotBlank(name), "name", name); + + //普通管理员,只能查询所属部门及子部门的数据 + UserDetail user = SecurityUser.getUser(); + if(user.getSuperAdmin() == SuperAdminEnum.NO.value()) { + List deptIdList = sysDeptService.getSubDeptIdList(user.getDeptId()); + wrapper.in(deptIdList != null, "dept_id", deptIdList); + } + + return wrapper; + } + + @Override + public SysRoleDTO get(Long id) { + SysRoleEntity entity = baseDao.selectById(id); + + return ConvertUtils.sourceToTarget(entity, SysRoleDTO.class); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysRoleDTO dto) { + SysRoleEntity entity = ConvertUtils.sourceToTarget(dto, SysRoleEntity.class); + + //保存角色 + insert(entity); + + //保存角色菜单关系 + sysRoleMenuService.saveOrUpdate(entity.getId(), dto.getMenuIdList()); + + //保存角色数据权限关系 + sysRoleDataScopeService.saveOrUpdate(entity.getId(), dto.getDeptIdList()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(SysRoleDTO dto) { + SysRoleEntity entity = ConvertUtils.sourceToTarget(dto, SysRoleEntity.class); + + //更新角色 + updateById(entity); + + //更新角色菜单关系 + sysRoleMenuService.saveOrUpdate(entity.getId(), dto.getMenuIdList()); + + //更新角色数据权限关系 + sysRoleDataScopeService.saveOrUpdate(entity.getId(), dto.getDeptIdList()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Long[] ids) { + //删除角色 + baseDao.deleteBatchIds(Arrays.asList(ids)); + + //删除角色用户关系 + sysRoleUserService.deleteByRoleIds(ids); + + //删除角色菜单关系 + sysRoleMenuService.deleteByRoleIds(ids); + + //删除角色数据权限关系 + sysRoleDataScopeService.deleteByRoleIds(ids); + } + +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRoleUserServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRoleUserServiceImpl.java new file mode 100644 index 0000000..0cac819 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysRoleUserServiceImpl.java @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service.impl; + +import com.dkha.common.util.UtilValidate; +import com.dkha.server.system.common.service.impl.BaseServiceImpl; +import com.dkha.server.system.modules.sys.dao.SysRoleUserDao; +import com.dkha.server.system.modules.sys.entity.SysRoleUserEntity; +import com.dkha.server.system.modules.sys.service.SysRoleUserService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 角色用户关系 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Service +public class SysRoleUserServiceImpl extends BaseServiceImpl implements SysRoleUserService { + + @Override + public void saveOrUpdate(Long userId, List roleIdList) { + //先删除角色用户关系 + deleteByUserIds(new Long[]{userId}); + + //用户没有一个角色权限的情况 + if(UtilValidate.isEmpty(roleIdList)){ + return ; + } + + //保存角色用户关系 + for(Long roleId : roleIdList){ + SysRoleUserEntity sysRoleUserEntity = new SysRoleUserEntity(); + sysRoleUserEntity.setUserId(userId); + sysRoleUserEntity.setRoleId(roleId); + + //保存 + insert(sysRoleUserEntity); + } + } + + @Override + public void deleteByRoleIds(Long[] roleIds) { + baseDao.deleteByRoleIds(roleIds); + } + + @Override + public void deleteByUserIds(Long[] userIds) { + baseDao.deleteByUserIds(userIds); + } + + @Override + public List getRoleIdList(Long userId) { + + return baseDao.getRoleIdList(userId); + } +} \ No newline at end of file diff --git a/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysUserServiceImpl.java b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysUserServiceImpl.java new file mode 100644 index 0000000..1d9928e --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/system/modules/sys/service/impl/SysUserServiceImpl.java @@ -0,0 +1,152 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.server.system.modules.sys.service.impl; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.dkha.common.util.UtilValidate; +import com.dkha.server.system.common.constant.Constant; +import com.dkha.server.system.common.page.PageData; +import com.dkha.server.system.common.service.impl.BaseServiceImpl; +import com.dkha.server.system.common.utils.ConvertUtils; +import com.dkha.server.system.modules.security.password.PasswordUtils; +import com.dkha.server.system.modules.security.user.SecurityUser; +import com.dkha.server.system.modules.security.user.UserDetail; +import com.dkha.server.system.modules.sys.dao.SysUserDao; +import com.dkha.server.system.modules.sys.dto.SysUserDTO; +import com.dkha.server.system.modules.sys.entity.SysUserEntity; +import com.dkha.server.system.modules.sys.enums.SuperAdminEnum; +import com.dkha.server.system.modules.sys.service.SysDeptService; +import com.dkha.server.system.modules.sys.service.SysRoleUserService; +import com.dkha.server.system.modules.sys.service.SysUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + + +/** + * 系统用户 + * + * @author Mark sunlightcs@gmail.com + */ +@Service +public class SysUserServiceImpl extends BaseServiceImpl implements SysUserService { + @Autowired + private SysRoleUserService sysRoleUserService; + @Autowired + private SysDeptService sysDeptService; + + @Override + public PageData page(Map params) { + //转换成like + paramsToLike(params, "username"); + + //分页 + IPage page = getPage(params, Constant.CREATE_DATE, false); + + //普通管理员,只能查询所属部门及子部门的数据 + UserDetail user = SecurityUser.getUser(); + if(user.getSuperAdmin() == SuperAdminEnum.NO.value()) { + params.put("deptIdList", sysDeptService.getSubDeptIdList(user.getDeptId())); + } + + //查询 + List list = baseDao.getList(params); + + return getPageData(list, page.getTotal(), SysUserDTO.class); + } + + @Override + public List list(Map params) { + //普通管理员,只能查询所属部门及子部门的数据 + UserDetail user = SecurityUser.getUser(); + if(user.getSuperAdmin() == SuperAdminEnum.NO.value()) { + params.put("deptIdList", sysDeptService.getSubDeptIdList(user.getDeptId())); + } + + List entityList = baseDao.getList(params); + + return ConvertUtils.sourceToTarget(entityList, SysUserDTO.class); + } + + @Override + public SysUserDTO get(Long id) { + SysUserEntity entity = baseDao.getById(id); + + return ConvertUtils.sourceToTarget(entity, SysUserDTO.class); + } + + @Override + public SysUserDTO getByUsername(String username) { + SysUserEntity entity = baseDao.getByUsername(username); + return ConvertUtils.sourceToTarget(entity, SysUserDTO.class); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysUserDTO dto) { + SysUserEntity entity = ConvertUtils.sourceToTarget(dto, SysUserEntity.class); + + //密码加密 + String password = PasswordUtils.encode(entity.getPassword()); + entity.setPassword(password); + + //保存用户 + entity.setSuperAdmin(SuperAdminEnum.NO.value()); + insert(entity); + + //保存角色用户关系 + sysRoleUserService.saveOrUpdate(entity.getId(), dto.getRoleIdList()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(SysUserDTO dto) { + SysUserEntity entity = ConvertUtils.sourceToTarget(dto, SysUserEntity.class); + + //密码加密 + if(UtilValidate.isEmpty(dto.getPassword())){ + entity.setPassword(null); + }else{ + String password = PasswordUtils.encode(entity.getPassword()); + entity.setPassword(password); + } + + //更新用户 + updateById(entity); + + //更新角色用户关系 + sysRoleUserService.saveOrUpdate(entity.getId(), dto.getRoleIdList()); + } + + @Override + public void delete(Long[] ids) { + //删除用户 + baseDao.deleteBatchIds(Arrays.asList(ids)); + + //删除角色用户关系 + sysRoleUserService.deleteByUserIds(ids); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updatePassword(Long id, String newPassword) { + newPassword = PasswordUtils.encode(newPassword); + + baseDao.updatePassword(id, newPassword); + } + + @Override + public int getCountByDeptId(Long deptId) { + return baseDao.getCountByDeptId(deptId); + } +} diff --git a/face-server/src/main/java/com/dkha/server/util/FileToBase64.java b/face-server/src/main/java/com/dkha/server/util/FileToBase64.java new file mode 100644 index 0000000..d61a85e --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/util/FileToBase64.java @@ -0,0 +1,68 @@ +package com.dkha.server.util; + +import sun.misc.BASE64Decoder; +import sun.misc.BASE64Encoder; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; + +public class FileToBase64 { + /** + *

将文件转成base64 字符串

+ * @param path 文件路径 + * @return + * @throws Exception + */ + public static String encodeBase64File(String path) throws Exception { + File file = new File(path); + FileInputStream inputFile = new FileInputStream(file); + byte[] buffer = new byte[(int)file.length()]; + inputFile.read(buffer); + inputFile.close(); + return new BASE64Encoder().encode(buffer); + } + + public static String encodeBase64File( InputStream inputFile) throws Exception { + + byte[] buffer = new byte[(int)inputFile.available()]; + inputFile.read(buffer); + inputFile.close(); + return new BASE64Encoder().encode(buffer); + } + /** + *

将base64字符解码保存文件

+ * @param base64Code + * @param targetPath + * @throws Exception + */ + public static void decoderBase64File(String base64Code,String targetPath) throws Exception { + byte[] buffer = new BASE64Decoder().decodeBuffer(base64Code); + FileOutputStream out = new FileOutputStream(targetPath); + out.write(buffer); + out.close(); + } + /** + *

将base64字符保存文本文件

+ * @param base64Code + * @param targetPath + * @throws Exception + */ + public static void toFile(String base64Code,String targetPath) throws Exception { + byte[] buffer = base64Code.getBytes(); + FileOutputStream out = new FileOutputStream(targetPath); + out.write(buffer); + out.close(); + } + public static void main(String[] args) { + try { + String base64Code =encodeBase64File("/Users/Crazy/Pictures/zyb2.jpg"); + System.out.println(base64Code); + decoderBase64File(base64Code, "/Users/Crazy/Desktop/zyb.png"); + toFile(base64Code, "/Users/Crazy/Desktop/zyb.txt"); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/face-server/src/main/java/com/dkha/server/util/RequestUtil.java b/face-server/src/main/java/com/dkha/server/util/RequestUtil.java new file mode 100644 index 0000000..9e6b820 --- /dev/null +++ b/face-server/src/main/java/com/dkha/server/util/RequestUtil.java @@ -0,0 +1,29 @@ +package com.dkha.server.util; + +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +public class RequestUtil { + + public static String getStreamText(HttpServletRequest request) { + + try { + ServletInputStream inputStream = request.getInputStream(); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + + StringBuilder content = new StringBuilder(); + String line; + while ((line = bufferedReader.readLine()) != null) { + content.append(line); + } + return content.toString(); + } catch (IOException e) { + e.printStackTrace(); + } + + return null; + } +} diff --git a/face-server/src/main/resources/application-dev.yml b/face-server/src/main/resources/application-dev.yml new file mode 100644 index 0000000..fa1f4c3 --- /dev/null +++ b/face-server/src/main/resources/application-dev.yml @@ -0,0 +1,137 @@ +# Tomcat +server: + tomcat: + uri-encoding: UTF-8 + max-threads: 1000 + min-spare-threads: 30 + port: 8889 + connection-timeout: 5000ms + servlet: + context-path: /face + session: + cookie: + http-only: true + +spring: + messages: + encoding: UTF-8 + basename: i18n/messages + servlet: + multipart: + max-file-size: 500MB + max-request-size: 500MB + enabled: true + datasource: + druid: + #MySQL + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql://192.168.1.127:3306/face_application?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai + username: root + password: Dkha123 + initial-size: 10 + max-active: 100 + min-idle: 10 + max-wait: 6000 + pool-prepared-statements: true + max-pool-prepared-statement-per-connection-size: 20 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + #Oracle需要打开注释 + #validation-query: SELECT 1 FROM DUAL + test-while-idle: true + test-on-borrow: false + test-on-return: false + stat-view-servlet: + enabled: true + url-pattern: /druid/* + login-username: admin + login-password: admin + filter: + stat: + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: false + wall: + config: + multi-statement-allow: true + redis: + database: 0 + host: 192.168.1.127 + port: 6379 + password: Dkha123 # 密码(默认为空) + timeout: 6000ms # 连接超时时长(毫秒) + jedis: + pool: + max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) + max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-idle: 10 # 连接池中的最大空闲连接 + min-idle: 5 # 连接池中的最小空闲连接 + activiti: + check-process-definitions: false + +#mybatis +mybatis-plus: + mapper-locations: classpath:/mybatis/mapper/**/*.xml,classpath:/mappers/*.xml + #实体扫描,多个package用逗号或者分号分隔 + typeAliasesPackage: com.dkha.server.system.modules + global-config: + #数据库相关配置 + db-config: + #主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID"; + id-type: ID_WORKER + # 如果入库为空值,则忽略掉控空值 + insert-strategy: not_empty + update-strategy: not_empty + select-strategy: not_empty + banner: false + #原生配置 + configuration: + #是否开启自动驼峰命名规则(camel case)映射 + map-underscore-to-camel-case: true + #全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存,默认为 true + cache-enabled: false + call-setters-on-nulls: true + jdbc-type-for-null: 'null' + +# 用于控制swagger是否显示 +swagger: + show: true + +fdfs: + so-timeout: 600000 + connect-timeout: 6000 + tracker-list: #TrackerList参数,支持多个 + - 192.168.10.10:22122 + +# 是否开启redis缓存 true开启 false关闭 +renren.redis.open: false + + +#人脸API统一请求地址定义 +api: + server: + prefix: http://192.168.1.161:8013/dkha/ + #人脸检索最大返回值 + max: + result: 100 + #人脸分组最大支持图片数量 + group: + max: 30 + # 人脸分组最少图片数量 + min: 2 + # 图片支持格式 + picture: + type: (png|jpg|jpeg) + + +httpurlvideo: + url: http://127.0.0.1/ +# 视频上传支持的格式 +videotype: (mp4|flv|avi|rm|rmvb|wmv) + +#minio 配置 +minio: + url: http://192.168.1.161:9000 + accessKey: admin + secretKey: Dkha123. + bucketName: middleware diff --git a/face-server/src/main/resources/application-prod.yml b/face-server/src/main/resources/application-prod.yml new file mode 100644 index 0000000..b8a281b --- /dev/null +++ b/face-server/src/main/resources/application-prod.yml @@ -0,0 +1,137 @@ +# Tomcat +server: + tomcat: + uri-encoding: UTF-8 + max-threads: 1000 + min-spare-threads: 30 + port: 8889 + connection-timeout: 5000ms + servlet: + context-path: /face + session: + cookie: + http-only: true + +spring: + messages: + encoding: UTF-8 + basename: i18n/messages + servlet: + multipart: + max-file-size: 500MB + max-request-size: 500MB + enabled: true + datasource: + druid: + #MySQL + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql://127.0.0.1:3306/face_application?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai + username: root + password: Dkha123 + initial-size: 10 + max-active: 100 + min-idle: 10 + max-wait: 6000 + pool-prepared-statements: true + max-pool-prepared-statement-per-connection-size: 20 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + #Oracle需要打开注释 + #validation-query: SELECT 1 FROM DUAL + test-while-idle: true + test-on-borrow: false + test-on-return: false + stat-view-servlet: + enabled: true + url-pattern: /druid/* + login-username: admin + login-password: admin + filter: + stat: + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: false + wall: + config: + multi-statement-allow: true + redis: + database: 0 + host: 127.0.0.1 + port: 6379 + password: Dkha123 # 密码(默认为空) + timeout: 6000ms # 连接超时时长(毫秒) + jedis: + pool: + max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) + max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-idle: 10 # 连接池中的最大空闲连接 + min-idle: 5 # 连接池中的最小空闲连接 + activiti: + check-process-definitions: false + +#mybatis +mybatis-plus: + mapper-locations: classpath:/mybatis/mapper/**/*.xml,classpath:/mappers/*.xml + #实体扫描,多个package用逗号或者分号分隔 + typeAliasesPackage: com.dkha.server.system.modules + global-config: + #数据库相关配置 + db-config: + #主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID"; + id-type: ID_WORKER + # 如果入库为空值,则忽略掉控空值 + insert-strategy: not_empty + update-strategy: not_empty + select-strategy: not_empty + banner: false + #原生配置 + configuration: + #是否开启自动驼峰命名规则(camel case)映射 + map-underscore-to-camel-case: true + #全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存,默认为 true + cache-enabled: false + call-setters-on-nulls: true + jdbc-type-for-null: 'null' + +# 用于控制swagger是否显示 +swagger: + show: true + +fdfs: + so-timeout: 600000 + connect-timeout: 6000 + tracker-list: #TrackerList参数,支持多个 + - 192.168.10.10:22122 + +# 是否开启redis缓存 true开启 false关闭 +renren.redis.open: false + + +#人脸API统一请求地址定义 +api: + server: + prefix: http://127.0.0.1:8013/dkha/ + #人脸检索最大返回值 + max: + result: 100 + #人脸分组最大支持图片数量 + group: + max: 30 + # 人脸分组最少图片数量 + min: 2 + # 图片支持格式 + picture: + type: (png|jpg|jpeg) + + +httpurlvideo: + url: http://127.0.0.1/ +# 视频上传支持的格式 +videotype: (mp4|flv|avi|rm|rmvb|wmv) + +#minio 配置 +minio: + url: http://192.168.1.220:9000 + accessKey: admin + secretKey: Dkha123. + bucketName: middleware diff --git a/face-server/src/main/resources/application-test.yml b/face-server/src/main/resources/application-test.yml new file mode 100644 index 0000000..d9dff93 --- /dev/null +++ b/face-server/src/main/resources/application-test.yml @@ -0,0 +1,137 @@ +# Tomcat +server: + tomcat: + uri-encoding: UTF-8 + max-threads: 1000 + min-spare-threads: 30 + port: 8889 + connection-timeout: 5000ms + servlet: + context-path: /face + session: + cookie: + http-only: true + +spring: + messages: + encoding: UTF-8 + basename: i18n/messages + servlet: + multipart: + max-file-size: 500MB + max-request-size: 500MB + enabled: true + datasource: + druid: + #MySQL + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql://192.168.1.122:3306/face_application?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai + username: root + password: Dkha123 + initial-size: 10 + max-active: 100 + min-idle: 10 + max-wait: 6000 + pool-prepared-statements: true + max-pool-prepared-statement-per-connection-size: 20 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + #Oracle需要打开注释 + #validation-query: SELECT 1 FROM DUAL + test-while-idle: true + test-on-borrow: false + test-on-return: false + stat-view-servlet: + enabled: true + url-pattern: /druid/* + login-username: admin + login-password: admin + filter: + stat: + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: false + wall: + config: + multi-statement-allow: true + redis: + database: 0 + host: 192.168.1.122 + port: 6379 + password: Dkha123 # 密码(默认为空) + timeout: 6000ms # 连接超时时长(毫秒) + jedis: + pool: + max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) + max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-idle: 10 # 连接池中的最大空闲连接 + min-idle: 5 # 连接池中的最小空闲连接 + activiti: + check-process-definitions: false + +#mybatis +mybatis-plus: + mapper-locations: classpath:/mybatis/mapper/**/*.xml,classpath:/mappers/*.xml + #实体扫描,多个package用逗号或者分号分隔 + typeAliasesPackage: com.dkha.server.system.modules + global-config: + #数据库相关配置 + db-config: + #主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID"; + id-type: ID_WORKER + # 如果入库为空值,则忽略掉控空值 + insert-strategy: not_empty + update-strategy: not_empty + select-strategy: not_empty + banner: false + #原生配置 + configuration: + #是否开启自动驼峰命名规则(camel case)映射 + map-underscore-to-camel-case: true + #全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存,默认为 true + cache-enabled: false + call-setters-on-nulls: true + jdbc-type-for-null: 'null' + +# 用于控制swagger是否显示 +swagger: + show: true + +fdfs: + so-timeout: 600000 + connect-timeout: 6000 + tracker-list: #TrackerList参数,支持多个 + - 192.168.10.10:22122 + +# 是否开启redis缓存 true开启 false关闭 +renren.redis.open: false + + +#人脸API统一请求地址定义 +api: + server: + prefix: http://192.168.1.122:8013/dkha/ + #人脸检索最大返回值 + max: + result: 100 + #人脸分组最大支持图片数量 + group: + max: 30 + # 人脸分组最少图片数量 + min: 2 + # 图片支持格式 + picture: + type: (png|jpg|jpeg) + + +httpurlvideo: + url: http://127.0.0.1/ +# 视频上传支持的格式 +videotype: (mp4|flv|avi|rm|rmvb|wmv) + +#minio 配置 +minio: + url: http://192.168.1.122:9000 + accessKey: admin + secretKey: Dkha123. + bucketName: middleware diff --git a/face-server/src/main/resources/application.yml b/face-server/src/main/resources/application.yml new file mode 100644 index 0000000..c688559 --- /dev/null +++ b/face-server/src/main/resources/application.yml @@ -0,0 +1,4 @@ +spring: + # 环境 dev|test|prod + profiles: + active: dev diff --git a/face-server/src/main/resources/banner.txt b/face-server/src/main/resources/banner.txt new file mode 100644 index 0000000..46366f5 --- /dev/null +++ b/face-server/src/main/resources/banner.txt @@ -0,0 +1,23 @@ +${AnsiColor.BLACK} +//////////////////////////////////////////////////////////////////// +// _ooOoo_ // +// o8888888o // +// 88" . "88 // +// (| ^_^ |) // +// O\ = /O // +// ____/`---'\____ // +// .' \\| |// `. // +// / \\||| : |||// \ // +// / _||||| -:- |||||- \ // +// | | \\\ - /// | | // +// | \_| ''\---/'' | | // +// \ .-\__ `-` ___/-. / // +// ___`. .' /--.--\ `. . ___ // +// ."" '< `.___\_<|>_/___.' >'"". // +// | | : `- \`.;`\ _ /`;.`/ - ` : | | // +// \ \ `-. \_ __\ /__ _/ .-` / / // +// ========`-.____`-.___\_____/___.-`____.-'======== // +// `=---=' // +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // +// 佛祖保佑 永不宕机 永无BUG // +//////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/face-server/src/main/resources/i18n/messages.properties b/face-server/src/main/resources/i18n/messages.properties new file mode 100644 index 0000000..f696314 --- /dev/null +++ b/face-server/src/main/resources/i18n/messages.properties @@ -0,0 +1,35 @@ +#Default +500=\u670D\u52A1\u5668\u5185\u90E8\u5F02\u5E38 +401=\u672A\u6388\u6743 +403=\u62D2\u7EDD\u8BBF\u95EE\uFF0C\u6CA1\u6709\u6743\u9650 +10001={0}\u4E0D\u80FD\u4E3A\u7A7A +10002=\u6570\u636E\u5E93\u4E2D\u5DF2\u5B58\u5728\u8BE5\u8BB0\u5F55 +10003=\u83B7\u53D6\u53C2\u6570\u5931\u8D25 +10004=\u8D26\u53F7\u6216\u5BC6\u7801\u9519\u8BEF +10005=\u8D26\u53F7\u5DF2\u88AB\u505C\u7528 +10006=\u552F\u4E00\u6807\u8BC6\u4E0D\u80FD\u4E3A\u7A7A +10007=\u9A8C\u8BC1\u7801\u4E0D\u6B63\u786E +10008=\u5148\u5220\u9664\u5B50\u83DC\u5355\u6216\u6309\u94AE +10009=\u539F\u5BC6\u7801\u4E0D\u6B63\u786E +10010=\u8D26\u53F7\u4E0D\u5B58\u5728 +10011=\u4E0A\u7EA7\u90E8\u95E8\u9009\u62E9\u9519\u8BEF +10012=\u4E0A\u7EA7\u83DC\u5355\u4E0D\u80FD\u4E3A\u81EA\u8EAB +10013=\u6570\u636E\u6743\u9650\u63A5\u53E3\uFF0C\u53EA\u80FD\u662FMap\u7C7B\u578B\u53C2\u6570 +10014=\u8BF7\u5148\u5220\u9664\u4E0B\u7EA7\u90E8\u95E8 +10015=\u8BF7\u5148\u5220\u9664\u90E8\u95E8\u4E0B\u7684\u7528\u6237 +10016=\u90E8\u7F72\u5931\u8D25\uFF0C\u6CA1\u6709\u6D41\u7A0B +10017=\u6A21\u578B\u56FE\u4E0D\u6B63\u786E\uFF0C\u8BF7\u68C0\u67E5 +10018=\u5BFC\u51FA\u5931\u8D25\uFF0C\u6A21\u578BID\u4E3A{0} +10019=\u8BF7\u4E0A\u4F20\u6587\u4EF6 +10020=token\u4E0D\u80FD\u4E3A\u7A7A +10021=token\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55 +10022=\u8D26\u53F7\u5DF2\u88AB\u9501\u5B9A +10023=\u8BF7\u4E0A\u4F20zip\u3001bar\u3001bpmn\u3001bpmn20.xml\u683C\u5F0F\u6587\u4EF6 +10024=\u4E0A\u4F20\u6587\u4EF6\u5931\u8D25{0} +10025=\u53D1\u9001\u77ED\u4FE1\u5931\u8D25{0} +10026=\u90AE\u4EF6\u6A21\u677F\u4E0D\u5B58\u5728 +10027=Redis\u670D\u52A1\u5F02\u5E38 +10028=\u5B9A\u65F6\u4EFB\u52A1\u5931\u8D25 +10029=\u4E0D\u80FD\u5305\u542B\u975E\u6CD5\u5B57\u7B26 +10030=\u53C2\u6570\u683C\u5F0F\u4E0D\u6B63\u786E\uFF0C\u8BF7\u4F7F\u7528JSON\u683C\u5F0F +10031=\u8BF7\u5148\u5B8C\u6210\u77ED\u4FE1\u914D\u7F6E \ No newline at end of file diff --git a/face-server/src/main/resources/i18n/messages_en_US.properties b/face-server/src/main/resources/i18n/messages_en_US.properties new file mode 100644 index 0000000..d28e508 --- /dev/null +++ b/face-server/src/main/resources/i18n/messages_en_US.properties @@ -0,0 +1,35 @@ +#English +500=Server internal exception +401=Unauthorized +403=Access denied, no permissions +10001={0} cannot be empty +10002=The record already exists in the database +10003=Failed to get parameters +10004=The account number or password is incorrect. +10005=Account has been deactivated +10006=Unique ID cannot be empty +10007=The verification code is incorrect +10008=First delete submenu or button +10009=The original password is incorrect +10010=The account does not exist +10011=The superior department made a wrong choice +10012=Upper menu cannot be for itself +10013=Data permission interface, which can only be a Map type parameter. +10014=Please delete the subordinate department first +10015=Please delete the user under the department first +10016=Deployment failed, no process +10017=Model diagram is incorrect, please check +10018=The export failed with the model ID {0} +10019=Please upload a file +10020=token cannot be empty +10021=token is invalid, please log in again +10022=The account has been locked +10023=Please upload zip, bar, bpmn, bpmn20.xml format file +10024=Failed to upload file {0} +10025=Failed to send SMS {0} +10026=Mail template does not exist +10027=Redis service exception +10028=Timed task failed +10029=Cannot contain illegal characters +10030=The parameter format is incorrect. Please use JSON format. +10031=Please complete the SMS configuration first. \ No newline at end of file diff --git a/face-server/src/main/resources/i18n/messages_zh_CN.properties b/face-server/src/main/resources/i18n/messages_zh_CN.properties new file mode 100644 index 0000000..75029aa --- /dev/null +++ b/face-server/src/main/resources/i18n/messages_zh_CN.properties @@ -0,0 +1,38 @@ +#\u7B80\u4F53\u4E2D\u6587 +500=\u670D\u52A1\u5668\u5185\u90E8\u5F02\u5E38 +401=\u672A\u6388\u6743 +403=\u62D2\u7EDD\u8BBF\u95EE\uFF0C\u6CA1\u6709\u6743\u9650 +10001={0}\u4E0D\u80FD\u4E3A\u7A7A +10002=\u6570\u636E\u5E93\u4E2D\u5DF2\u5B58\u5728\u8BE5\u8BB0\u5F55 +10003=\u83B7\u53D6\u53C2\u6570\u5931\u8D25 +10004=\u8D26\u53F7\u6216\u5BC6\u7801\u9519\u8BEF +10005=\u8D26\u53F7\u5DF2\u88AB\u505C\u7528 +10006=\u552F\u4E00\u6807\u8BC6\u4E0D\u80FD\u4E3A\u7A7A +10007=\u9A8C\u8BC1\u7801\u4E0D\u6B63\u786E +10008=\u5148\u5220\u9664\u5B50\u83DC\u5355\u6216\u6309\u94AE +10009=\u539F\u5BC6\u7801\u4E0D\u6B63\u786E +10010=\u8D26\u53F7\u4E0D\u5B58\u5728 +10011=\u4E0A\u7EA7\u90E8\u95E8\u9009\u62E9\u9519\u8BEF +10012=\u4E0A\u7EA7\u83DC\u5355\u4E0D\u80FD\u4E3A\u81EA\u8EAB +10013=\u6570\u636E\u6743\u9650\u63A5\u53E3\uFF0C\u53EA\u80FD\u662FMap\u7C7B\u578B\u53C2\u6570 +10014=\u8BF7\u5148\u5220\u9664\u4E0B\u7EA7\u90E8\u95E8 +10015=\u8BF7\u5148\u5220\u9664\u90E8\u95E8\u4E0B\u7684\u7528\u6237 +10016=\u90E8\u7F72\u5931\u8D25\uFF0C\u6CA1\u6709\u6D41\u7A0B +10017=\u6A21\u578B\u56FE\u4E0D\u6B63\u786E\uFF0C\u8BF7\u68C0\u67E5 +10018=\u5BFC\u51FA\u5931\u8D25\uFF0C\u6A21\u578BID\u4E3A{0} +10019=\u8BF7\u4E0A\u4F20\u6587\u4EF6 +10020=token\u4E0D\u80FD\u4E3A\u7A7A +10021=token\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55 +10022=\u8D26\u53F7\u5DF2\u88AB\u9501\u5B9A +10023=\u8BF7\u4E0A\u4F20zip\u3001bar\u3001bpmn\u3001bpmn20.xml\u683C\u5F0F\u6587\u4EF6 +10024=\u4E0A\u4F20\u6587\u4EF6\u5931\u8D25{0} +10025=\u53D1\u9001\u77ED\u4FE1\u5931\u8D25{0} +10026=\u90AE\u4EF6\u6A21\u677F\u4E0D\u5B58\u5728 +10027=Redis\u670D\u52A1\u5F02\u5E38 +10028=\u5B9A\u65F6\u4EFB\u52A1\u5931\u8D25 +10029=\u4E0D\u80FD\u5305\u542B\u975E\u6CD5\u5B57\u7B26 +10030=\u53C2\u6570\u683C\u5F0F\u4E0D\u6B63\u786E\uFF0C\u8BF7\u4F7F\u7528JSON\u683C\u5F0F +10031=\u8BF7\u5148\u5B8C\u6210\u77ED\u4FE1\u914D\u7F6E + +71002=\u8d26\u53f7\u5df2\u8fc7\u671f\uff0c\u8bf7\u91cd\u65b0\u767b\u5f55\u0021 +71004=\u5f53\u524d\u8d26\u53f7\u5df2\u5728\u5176\u4ed6\u8bbe\u5907\u767b\u5f55\u0021 \ No newline at end of file diff --git a/face-server/src/main/resources/i18n/messages_zh_TW.properties b/face-server/src/main/resources/i18n/messages_zh_TW.properties new file mode 100644 index 0000000..e80ff94 --- /dev/null +++ b/face-server/src/main/resources/i18n/messages_zh_TW.properties @@ -0,0 +1,35 @@ +#\u7E41\u4F53\u4E2D\u6587 +500=\u670D\u52D9\u5668\u5167\u90E8\u7570\u5E38 +401=\u672A\u6388\u6B0A +403=\u62D2\u7D55\u8A2A\u554F\uFF0C\u6C92\u6709\u6B0A\u9650 +10001={0}\u4E0D\u80FD\u70BA\u7A7A +10002=\u6578\u64DA\u5EAB\u4E2D\u5DF2\u5B58\u5728\u8A72\u8A18\u9304 +10003=\u7372\u53D6\u53C3\u6578\u5931\u6557 +10004=\u8CEC\u865F\u6216\u5BC6\u78BC\u932F\u8AA4 +10005=\u8CEC\u865F\u5DF2\u88AB\u505C\u7528 +10006=\u552F\u4E00\u6A19\u8B58\u4E0D\u80FD\u70BA\u7A7A +10007=\u9A57\u8B49\u78BC\u4E0D\u6B63\u78BA +10008=\u5148\u522A\u9664\u5B50\u83DC\u55AE\u6216\u6309\u9215 +10009=\u539F\u5BC6\u78BC\u4E0D\u6B63\u78BA +10010=\u8CEC\u865F\u4E0D\u5B58\u5728 +10011=\u4E0A\u7D1A\u90E8\u9580\u9078\u64C7\u932F\u8AA4 +10012=\u4E0A\u7D1A\u83DC\u55AE\u4E0D\u80FD\u70BA\u81EA\u8EAB +10013=\u6578\u64DA\u6B0A\u9650\u63A5\u53E3\uFF0C\u53EA\u80FD\u662FMap\u985E\u578B\u53C3\u6578 +10014=\u8ACB\u5148\u522A\u9664\u4E0B\u7D1A\u90E8\u9580 +10015=\u8ACB\u5148\u522A\u9664\u90E8\u9580\u4E0B\u7684\u7528\u6236 +10016=\u90E8\u7F72\u5931\u6557\uFF0C\u6C92\u6709\u6D41\u7A0B +10017=\u6A21\u578B\u5716\u4E0D\u6B63\u78BA\uFF0C\u8ACB\u6AA2\u67E5 +10018=\u5C0E\u51FA\u5931\u6557\uFF0C\u6A21\u578BID\u70BA{0} +10019=\u8ACB\u4E0A\u50B3\u6587\u4EF6 +10020=token\u4E0D\u80FD\u70BA\u7A7A +10021=token\u5931\u6548\uFF0C\u8ACB\u91CD\u65B0\u767B\u9304 +10022=\u8CEC\u865F\u5DF2\u88AB\u9396\u5B9A +10023=\u8ACB\u4E0A\u50B3zip\u3001bar\u3001bpmn\u3001bpmn20.xml\u683C\u5F0F\u6587\u4EF6 +10024=\u4E0A\u50B3\u6587\u4EF6\u5931\u6557{0} +10025=\u767C\u9001\u77ED\u4FE1\u5931\u6557{0} +10026=\u90F5\u4EF6\u6A21\u677F\u4E0D\u5B58\u5728 +10027=Redis\u670D\u52D9\u7570\u5E38 +10028=\u5B9A\u6642\u4EFB\u52D9\u5931\u6557 +10029=\u4E0D\u80FD\u5305\u542B\u975E\u6CD5\u5B57\u7B26 +10030=\u53C3\u6578\u683C\u5F0F\u4E0D\u6B63\u78BA\uFF0C\u8ACB\u4F7F\u7528JSON\u683C\u5F0F +10031=\u8ACB\u5148\u5B8C\u6210\u77ED\u4FE1\u914D\u7F6E \ No newline at end of file diff --git a/face-server/src/main/resources/i18n/validation.properties b/face-server/src/main/resources/i18n/validation.properties new file mode 100644 index 0000000..0d08a87 --- /dev/null +++ b/face-server/src/main/resources/i18n/validation.properties @@ -0,0 +1,89 @@ +#Default +id.require=ID\u4E0D\u80FD\u4E3A\u7A7A +id.null=ID\u5FC5\u987B\u4E3A\u7A7A +pid.require=\u4E0A\u7EA7ID\uFF0C\u4E0D\u80FD\u4E3A\u7A7A +sort.number=\u6392\u5E8F\u503C\u4E0D\u80FD\u5C0F\u4E8E0 + +sysparams.paramcode.require=\u53C2\u6570\u7F16\u7801\u4E0D\u80FD\u4E3A\u7A7A +sysparams.paramvalue.require=\u53C2\u6570\u503C\u4E0D\u80FD\u4E3A\u7A7A + +sysuser.username.require=\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A +sysuser.password.require=\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A +sysuser.realname.require=\u59D3\u540D\u4E0D\u80FD\u4E3A\u7A7A +sysuser.gender.range=\u6027\u522B\u53D6\u503C\u8303\u56F40~2 +sysuser.email.require=\u90AE\u7BB1\u4E0D\u80FD\u4E3A\u7A7A +sysuser.email.error=\u90AE\u7BB1\u683C\u5F0F\u4E0D\u6B63\u786E +sysuser.mobile.require=\u624B\u673A\u53F7\u4E0D\u80FD\u4E3A\u7A7A +sysuser.deptId.require=\u90E8\u95E8\u4E0D\u80FD\u4E3A\u7A7A +sysuser.superadmin.range=\u8D85\u7EA7\u7BA1\u7406\u5458\u53D6\u503C\u8303\u56F40~1 +sysuser.status.range=\u72B6\u6001\u53D6\u503C\u8303\u56F40~1 +sysuser.captcha.require=\u9A8C\u8BC1\u7801\u4E0D\u80FD\u4E3A\u7A7A +sysuser.uuid.require=\u552F\u4E00\u6807\u8BC6\u4E0D\u80FD\u4E3A\u7A7A + +sysmenu.pid.require=\u8BF7\u9009\u62E9\u4E0A\u7EA7\u83DC\u5355 +sysmenu.name.require=\u83DC\u5355\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A +sysmenu.type.range=\u83DC\u5355\u7C7B\u578B\u53D6\u503C\u8303\u56F40~1 + +sysdept.pid.require=\u8BF7\u9009\u62E9\u4E0A\u7EA7\u90E8\u95E8 +sysdept.name.require=\u90E8\u95E8\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A + +sysrole.name.require=\u89D2\u8272\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A + +sysdict.type.require=\u5B57\u5178\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A +sysdict.name.require=\u5B57\u5178\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A + +schedule.status.range=\u72B6\u6001\u53D6\u503C\u8303\u56F40~1 +schedule.cron.require=cron\u8868\u8FBE\u5F0F\u4E0D\u80FD\u4E3A\u7A7A +schedule.bean.require=bean\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A + +oss.type.range=\u7C7B\u578B\u53D6\u503C\u8303\u56F41~5 + +sms.platform.range=\u5E73\u53F0\u7C7B\u578B\u53D6\u503C\u8303\u56F41~2 +aliyun.accesskeyid.require=\u963F\u91CC\u4E91AccessKeyId\u4E0D\u80FD\u4E3A\u7A7A +aliyun.accesskeysecret.require=\u963F\u91CC\u4E91AccessKeySecret\u4E0D\u80FD\u4E3A\u7A7A +aliyun.signname.require=\u963F\u91CC\u4E91\u77ED\u4FE1\u7B7E\u540D\u4E0D\u80FD\u4E3A\u7A7A +aliyun.templatecode.require=\u963F\u91CC\u4E91\u77ED\u4FE1\u6A21\u677F\u4E0D\u80FD\u4E3A\u7A7A +aliyun.domain.require=\u963F\u91CC\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A +aliyun.domain.url=\u963F\u91CC\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E +aliyun.endPoint.require=\u963F\u91CC\u4E91EndPoint\u4E0D\u80FD\u4E3A\u7A7A +aliyun.bucketname.require=\u963F\u91CC\u4E91BucketName\u4E0D\u80FD\u4E3A\u7A7A + +qcloud.appid.require=\u817E\u8BAF\u4E91AppId\u4E0D\u80FD\u4E3A\u7A7A +qcloud.appkey.require=\u817E\u8BAF\u4E91AppKey\u4E0D\u80FD\u4E3A\u7A7A +qcloud.secretId.require=\u817E\u8BAF\u4E91SecretId\u4E0D\u80FD\u4E3A\u7A7A +qcloud.secretkey.require=\u817E\u8BAF\u4E91SecretKey\u4E0D\u80FD\u4E3A\u7A7A +qcloud.signname.require=\u817E\u8BAF\u4E91\u77ED\u4FE1\u7B7E\u540D\u4E0D\u80FD\u4E3A\u7A7A +qcloud.templateid.require=\u817E\u8BAF\u4E91\u77ED\u4FE1\u6A21\u677FID\u4E0D\u80FD\u4E3A\u7A7A +qcloud.domain.require=\u817E\u8BAF\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A +qcloud.domain.url=\u817E\u8BAF\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E +qcloud.bucketname.require=\u817E\u8BAF\u4E91BucketName\u4E0D\u80FD\u4E3A\u7A7A +qcloud.region.require=\u6240\u5C5E\u5730\u533A\u4E0D\u80FD\u4E3A\u7A7A + +qiniu.domain.require=\u4E03\u725B\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A +qiniu.domain.url=\u4E03\u725B\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E +qiniu.accesskey.require=\u4E03\u725BAccessKey\u4E0D\u80FD\u4E3A\u7A7A +qiniu.secretkey.require=\u4E03\u725BSecretKey\u4E0D\u80FD\u4E3A\u7A7A +qiniu.bucketname.require=\u4E03\u725B\u7A7A\u95F4\u540D\u4E0D\u80FD\u4E3A\u7A7A + +fastdfs.domain.require=FastDFS\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A +fastdfs.domain.url=FastDFS\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E + +local.domain.require=\u672C\u5730\u4E0A\u4F20\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A +local.domain.url=\u672C\u5730\u4E0A\u4F20\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E +local.path.url=\u5B58\u50A8\u76EE\u5F55\u4E0D\u80FD\u4E3A\u7A7A + +email.smtp.require=SMTP\u4E0D\u80FD\u4E3A\u7A7A +email.port.require=\u7AEF\u53E3\u53F7\u4E0D\u80FD\u4E3A\u7A7A +email.username.require=\u90AE\u7BB1\u8D26\u53F7\u4E0D\u80FD\u4E3A\u7A7A +email.password.require=\u90AE\u7BB1\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A + +mail.name.require=\u6A21\u677F\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A +mail.subject.require=\u90AE\u4EF6\u4E3B\u9898\u4E0D\u80FD\u4E3A\u7A7A +mail.content.require=\u90AE\u4EF6\u6B63\u6587\u4E0D\u80FD\u4E3A\u7A7A + +model.name.require=\u6A21\u578B\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A +model.key.require=\u6A21\u578B\u6807\u8BC6\u4E0D\u80FD\u4E3A\u7A7A + +news.title.require=\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A +news.content.require=\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A +news.pubdate.require=\u53D1\u5E03\u65F6\u95F4\u4E0D\u80FD\u4E3A\u7A7A \ No newline at end of file diff --git a/face-server/src/main/resources/i18n/validation_en_US.properties b/face-server/src/main/resources/i18n/validation_en_US.properties new file mode 100644 index 0000000..d971977 --- /dev/null +++ b/face-server/src/main/resources/i18n/validation_en_US.properties @@ -0,0 +1,90 @@ +#English +id.require=ID can not be empty +id.null=ID has to be empty +pid.require=Parent ID, cannot be empty +sort.number=The sort value cannot be less than 0 + +sysparams.paramcode.require=Parameter encoding cannot be empty +sysparams.paramvalue.require=Parameter values cannot be empty + +sysuser.username.require=The username cannot be empty +sysuser.password.require=The password cannot be empty +sysuser.realname.require=The realname cannot be empty +sysuser.gender.range=Gender ranges from 0 to 2 +sysuser.email.require=Mailbox cannot be empty +sysuser.email.error=Incorrect email format +sysuser.mobile.require=The phone number cannot be empty +sysuser.deptId.require=Departments cannot be empty +sysuser.superadmin.range=Super administrator values range from 0 to 1 +sysuser.status.range=State ranges from 0 to 1 +sysuser.captcha.require=The captcha cannot be empty +sysuser.uuid.require=The unique identifier cannot be empty + +sysmenu.pid.require=Please select superior menu +sysmenu.name.require=Menu name cannot be empty +sysmenu.type.range=Menu type ranges from 0 to 1 + +sysdept.pid.require=Please select superior department +sysdept.name.require=The department name cannot be empty + +sysrole.name.require=The role name cannot be empty + +sysdict.type.require=The dictionary type cannot be empty +sysdict.name.require=The dictionary name cannot be empty + +schedule.status.range=Status ranges from 0 to 1 +schedule.cron.require=Cron expression cannot be empty +schedule.bean.require=Bean name cannot be empty + +oss.type.range=Type ranges from 1 to 5 + +aliyun.accesskeyid.require=Aliyun AccessKeyId cannot be empty +aliyun.accesskeysecret.require=Aliyun AccessKeySecret cannot be empty +aliyun.signname.require=Aliyun message signature cannot be empty +aliyun.templatecode.require=Aliyun message template cannot be empty +aliyun.domain.require=Aliyun bound domain name cannot be empty +aliyun.domain.url=Aliyun binding domain name format is incorrect +aliyun.endPoint.require=The aliyun EndPoint cannot be empty +aliyun.bucketname.require=Aliyun BucketName cannot be empty + +qcloud.appid.require=Tencent cloud AppId cannot be empty +qcloud.appkey.require=Tencent cloud AppKey cannot be empty +qcloud.secretId.require=Tencent cloud SecretId cannot be empty +qcloud.secretkey.require=Tencent cloud SecretKey cannot be empty +qcloud.signname.require=Tencent cloud SMS signature cannot be empty +qcloud.templateid.require=Tencent cloud SMS template ID cannot be empty +qcloud.domain.require=Tencent cloud bound domain name cannot be empty +qcloud.domain.url=Tencent cloud binding domain name format is incorrect +qcloud.bucketname.require=Tencent cloud BucketName cannot be empty +qcloud.region.require=The region cannot be empty + +qiniu.domain.require=Bound domain name cannot be empty +qiniu.domain.url=Binding domain name format is incorrect +qiniu.accesskey.require=The AccessKey cannot be empty +qiniu.secretkey.require=The SecretKey of seven cows cannot be empty +qiniu.bucketname.require=Space names cannot be empty + +fastdfs.domain.require=FastDFS bound domain name cannot be empty +fastdfs.domain.url=FastDFS bound domain name format is incorrect + +local.domain.require=Local upload bound domain name cannot be empty +local.domain.url=The domain name bound for local upload is not formatted correctly +local.path.url=The storage directory cannot be empty + +sms.platform.range=Platform type ranges from 1 to 2 + +email.smtp.require=SMTP cannot be empty +email.port.require=Port number cannot be empty +email.username.require=The email account cannot be empty +email.password.require=The password cannot be empty + +mail.name.require=The template name cannot be empty +mail.subject.require=Mail subject cannot be empty +mail.content.require=Message text cannot be empty + +model.name.require=The model name cannot be empty +model.key.require=The model key cannot be empty + +news.title.require=The title cannot be empty +news.content.require=Content cannot be empty +news.pubdate.require=The release time cannot be empty diff --git a/face-server/src/main/resources/i18n/validation_zh_CN.properties b/face-server/src/main/resources/i18n/validation_zh_CN.properties new file mode 100644 index 0000000..336a80d --- /dev/null +++ b/face-server/src/main/resources/i18n/validation_zh_CN.properties @@ -0,0 +1,89 @@ +#\u7B80\u4F53\u4E2D\u6587 +id.require=ID\u4E0D\u80FD\u4E3A\u7A7A +id.null=ID\u5FC5\u987B\u4E3A\u7A7A +pid.require=\u4E0A\u7EA7ID\uFF0C\u4E0D\u80FD\u4E3A\u7A7A +sort.number=\u6392\u5E8F\u503C\u4E0D\u80FD\u5C0F\u4E8E0 + +sysparams.paramcode.require=\u53C2\u6570\u7F16\u7801\u4E0D\u80FD\u4E3A\u7A7A +sysparams.paramvalue.require=\u53C2\u6570\u503C\u4E0D\u80FD\u4E3A\u7A7A + +sysuser.username.require=\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A +sysuser.password.require=\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A +sysuser.realname.require=\u59D3\u540D\u4E0D\u80FD\u4E3A\u7A7A +sysuser.gender.range=\u6027\u522B\u53D6\u503C\u8303\u56F40~2 +sysuser.email.require=\u90AE\u7BB1\u4E0D\u80FD\u4E3A\u7A7A +sysuser.email.error=\u90AE\u7BB1\u683C\u5F0F\u4E0D\u6B63\u786E +sysuser.mobile.require=\u624B\u673A\u53F7\u4E0D\u80FD\u4E3A\u7A7A +sysuser.deptId.require=\u90E8\u95E8\u4E0D\u80FD\u4E3A\u7A7A +sysuser.superadmin.range=\u8D85\u7EA7\u7BA1\u7406\u5458\u53D6\u503C\u8303\u56F40~1 +sysuser.status.range=\u72B6\u6001\u53D6\u503C\u8303\u56F40~1 +sysuser.captcha.require=\u9A8C\u8BC1\u7801\u4E0D\u80FD\u4E3A\u7A7A +sysuser.uuid.require=\u552F\u4E00\u6807\u8BC6\u4E0D\u80FD\u4E3A\u7A7A + +sysmenu.pid.require=\u8BF7\u9009\u62E9\u4E0A\u7EA7\u83DC\u5355 +sysmenu.name.require=\u83DC\u5355\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A +sysmenu.type.range=\u83DC\u5355\u7C7B\u578B\u53D6\u503C\u8303\u56F40~1 + +sysdept.pid.require=\u8BF7\u9009\u62E9\u4E0A\u7EA7\u90E8\u95E8 +sysdept.name.require=\u90E8\u95E8\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A + +sysrole.name.require=\u89D2\u8272\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A + +sysdict.type.require=\u5B57\u5178\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A +sysdict.name.require=\u5B57\u5178\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A + +schedule.status.range=\u72B6\u6001\u53D6\u503C\u8303\u56F40~1 +schedule.cron.require=cron\u8868\u8FBE\u5F0F\u4E0D\u80FD\u4E3A\u7A7A +schedule.bean.require=bean\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A + +oss.type.range=\u7C7B\u578B\u53D6\u503C\u8303\u56F41~5 + +aliyun.accesskeyid.require=\u963F\u91CC\u4E91AccessKeyId\u4E0D\u80FD\u4E3A\u7A7A +aliyun.accesskeysecret.require=\u963F\u91CC\u4E91AccessKeySecret\u4E0D\u80FD\u4E3A\u7A7A +aliyun.signname.require=\u963F\u91CC\u4E91\u77ED\u4FE1\u7B7E\u540D\u4E0D\u80FD\u4E3A\u7A7A +aliyun.templatecode.require=\u963F\u91CC\u4E91\u77ED\u4FE1\u6A21\u677F\u4E0D\u80FD\u4E3A\u7A7A +aliyun.domain.require=\u963F\u91CC\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A +aliyun.domain.url=\u963F\u91CC\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E +aliyun.endPoint.require=\u963F\u91CC\u4E91EndPoint\u4E0D\u80FD\u4E3A\u7A7A +aliyun.bucketname.require=\u963F\u91CC\u4E91BucketName\u4E0D\u80FD\u4E3A\u7A7A + +qcloud.appid.require=\u817E\u8BAF\u4E91AppId\u4E0D\u80FD\u4E3A\u7A7A +qcloud.appkey.require=\u817E\u8BAF\u4E91AppKey\u4E0D\u80FD\u4E3A\u7A7A +qcloud.secretId.require=\u817E\u8BAF\u4E91SecretId\u4E0D\u80FD\u4E3A\u7A7A +qcloud.secretkey.require=\u817E\u8BAF\u4E91SecretKey\u4E0D\u80FD\u4E3A\u7A7A +qcloud.signname.require=\u817E\u8BAF\u4E91\u77ED\u4FE1\u7B7E\u540D\u4E0D\u80FD\u4E3A\u7A7A +qcloud.templateid.require=\u817E\u8BAF\u4E91\u77ED\u4FE1\u6A21\u677FID\u4E0D\u80FD\u4E3A\u7A7A +qcloud.domain.require=\u817E\u8BAF\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A +qcloud.domain.url=\u817E\u8BAF\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E +qcloud.bucketname.require=\u817E\u8BAF\u4E91BucketName\u4E0D\u80FD\u4E3A\u7A7A +qcloud.region.require=\u6240\u5C5E\u5730\u533A\u4E0D\u80FD\u4E3A\u7A7A + +qiniu.domain.require=\u4E03\u725B\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A +qiniu.domain.url=\u4E03\u725B\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E +qiniu.accesskey.require=\u4E03\u725BAccessKey\u4E0D\u80FD\u4E3A\u7A7A +qiniu.secretkey.require=\u4E03\u725BSecretKey\u4E0D\u80FD\u4E3A\u7A7A +qiniu.bucketname.require=\u4E03\u725B\u7A7A\u95F4\u540D\u4E0D\u80FD\u4E3A\u7A7A + +fastdfs.domain.require=FastDFS\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A +fastdfs.domain.url=FastDFS\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E + +local.domain.require=\u672C\u5730\u4E0A\u4F20\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A +local.domain.url=\u672C\u5730\u4E0A\u4F20\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E +local.path.url=\u5B58\u50A8\u76EE\u5F55\u4E0D\u80FD\u4E3A\u7A7A + +sms.platform.range=\u5E73\u53F0\u7C7B\u578B\u53D6\u503C\u8303\u56F41~2 +email.smtp.require=SMTP\u4E0D\u80FD\u4E3A\u7A7A +email.port.require=\u7AEF\u53E3\u53F7\u4E0D\u80FD\u4E3A\u7A7A +email.username.require=\u90AE\u7BB1\u8D26\u53F7\u4E0D\u80FD\u4E3A\u7A7A +email.password.require=\u90AE\u7BB1\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A + +mail.name.require=\u6A21\u677F\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A +mail.subject.require=\u90AE\u4EF6\u4E3B\u9898\u4E0D\u80FD\u4E3A\u7A7A +mail.content.require=\u90AE\u4EF6\u6B63\u6587\u4E0D\u80FD\u4E3A\u7A7A + +model.name.require=\u6A21\u578B\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A +model.key.require=\u6A21\u578B\u6807\u8BC6\u4E0D\u80FD\u4E3A\u7A7A + +news.title.require=\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A +news.content.require=\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A +news.pubdate.require=\u53D1\u5E03\u65F6\u95F4\u4E0D\u80FD\u4E3A\u7A7A \ No newline at end of file diff --git a/face-server/src/main/resources/i18n/validation_zh_TW.properties b/face-server/src/main/resources/i18n/validation_zh_TW.properties new file mode 100644 index 0000000..b01b6b9 --- /dev/null +++ b/face-server/src/main/resources/i18n/validation_zh_TW.properties @@ -0,0 +1,90 @@ +#\u7E41\u4F53\u4E2D\u6587 +id.require=ID\u4E0D\u80FD\u70BA\u7A7A +id.null=ID\u5FC5\u9808\u70BA\u7A7A +pid.require=\u4E0A\u7D1AID\uFF0C\u4E0D\u80FD\u70BA\u7A7A +sort.number=\u6392\u5E8F\u503C\u4E0D\u80FD\u5C0F\u65BC0 + +sysparams.paramcode.require=\u53C3\u6578\u7DE8\u78BC\u4E0D\u80FD\u70BA\u7A7A +sysparams.paramvalue.require=\u53C3\u6578\u503C\u4E0D\u80FD\u70BA\u7A7A + +sysuser.username.require=\u7528\u6236\u540D\u4E0D\u80FD\u70BA\u7A7A +sysuser.password.require=\u5BC6\u78BC\u4E0D\u80FD\u70BA\u7A7A +sysuser.realname.require=\u59D3\u540D\u4E0D\u80FD\u70BA\u7A7A +sysuser.gender.range=\u6027\u5225\u53D6\u503C\u7BC4\u570D0~2 +sysuser.email.require=\u90F5\u7BB1\u4E0D\u80FD\u70BA\u7A7A +sysuser.email.error=\u90F5\u7BB1\u683C\u5F0F\u4E0D\u6B63\u78BA +sysuser.mobile.require=\u624B\u6A5F\u865F\u4E0D\u80FD\u70BA\u7A7A +sysuser.deptId.require=\u90E8\u9580\u4E0D\u80FD\u70BA\u7A7A +sysuser.superadmin.range=\u8D85\u7D1A\u7BA1\u7406\u54E1\u53D6\u503C\u7BC4\u570D0~1 +sysuser.status.range=\u72C0\u614B\u53D6\u503C\u7BC4\u570D0~1 +sysuser.captcha.require=\u9A57\u8B49\u78BC\u4E0D\u80FD\u70BA\u7A7A +sysuser.uuid.require=\u552F\u4E00\u6A19\u8B58\u4E0D\u80FD\u70BA\u7A7A + +sysmenu.pid.require=\u8ACB\u9078\u64C7\u4E0A\u7D1A\u83DC\u55AE +sysmenu.name.require=\u83DC\u55AE\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A +sysmenu.type.range=\u83DC\u55AE\u985E\u578B\u53D6\u503C\u7BC4\u570D0~1 + +sysdept.pid.require=\u8ACB\u9078\u64C7\u4E0A\u7D1A\u90E8\u9580 +sysdept.name.require=\u90E8\u9580\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A + +sysrole.name.require=\u89D2\u8272\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A + +sysdict.type.require=\u5B57\u5178\u985E\u578B\u4E0D\u80FD\u70BA\u7A7A +sysdict.name.require=\u5B57\u5178\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A + +schedule.status.range=\u72C0\u614B\u53D6\u503C\u7BC4\u570D0~1 +schedule.cron.require=cron\u8868\u9054\u5F0F\u4E0D\u80FD\u70BA\u7A7A +schedule.bean.require=bean\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A + +oss.type.range=\u985E\u578B\u53D6\u503C\u7BC4\u570D1~5 + +aliyun.accesskeyid.require=\u963F\u91CC\u96F2AccessKeyId\u4E0D\u80FD\u70BA\u7A7A +aliyun.accesskeysecret.require=\u963F\u91CC\u96F2AccessKeySecret\u4E0D\u80FD\u70BA\u7A7A +aliyun.signname.require=\u963F\u91CC\u96F2\u77ED\u4FE1\u7C3D\u540D\u4E0D\u80FD\u70BA\u7A7A +aliyun.templatecode.require=\u963F\u91CC\u96F2\u77ED\u4FE1\u6A21\u677F\u4E0D\u80FD\u70BA\u7A7A +aliyun.domain.require=\u963F\u91CC\u96F2\u7D81\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u70BA\u7A7A +aliyun.domain.url=\u963F\u91CC\u96F2\u7D81\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u78BA +aliyun.endPoint.require=\u963F\u91CC\u96F2EndPoint\u4E0D\u80FD\u70BA\u7A7A +aliyun.bucketname.require=\u963F\u91CC\u96F2BucketName\u4E0D\u80FD\u70BA\u7A7A + +qcloud.appid.require=\u9A30\u8A0A\u96F2AppId\u4E0D\u80FD\u70BA\u7A7A +qcloud.appkey.require=\u9A30\u8A0A\u96F2AppKey\u4E0D\u80FD\u70BA\u7A7A +qcloud.secretId.require=\u9A30\u8A0A\u96F2SecretId\u4E0D\u80FD\u70BA\u7A7A +qcloud.secretkey.require=\u9A30\u8A0A\u96F2SecretKey\u4E0D\u80FD\u70BA\u7A7A +qcloud.signname.require=\u9A30\u8A0A\u96F2\u77ED\u4FE1\u7C3D\u540D\u4E0D\u80FD\u70BA\u7A7A +qcloud.templateid.require=\u9A30\u8A0A\u96F2\u77ED\u4FE1\u6A21\u677FID\u4E0D\u80FD\u70BA\u7A7A +qcloud.domain.require=\u9A30\u8A0A\u96F2\u7D81\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u70BA\u7A7A +qcloud.domain.url=\u9A30\u8A0A\u96F2\u7D81\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u78BA +qcloud.bucketname.require=\u9A30\u8A0A\u96F2BucketName\u4E0D\u80FD\u70BA\u7A7A +qcloud.region.require=\u6240\u5C6C\u5730\u5340\u4E0D\u80FD\u70BA\u7A7A + +qiniu.domain.require=\u4E03\u725B\u7D81\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u70BA\u7A7A +qiniu.domain.url=\u4E03\u725B\u7D81\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u78BA +qiniu.accesskey.require=\u4E03\u725BAccessKey\u4E0D\u80FD\u70BA\u7A7A +qiniu.secretkey.require=\u4E03\u725BSecretKey\u4E0D\u80FD\u70BA\u7A7A +qiniu.bucketname.require=\u4E03\u725B\u7A7A\u9593\u540D\u4E0D\u80FD\u70BA\u7A7A + +fastdfs.domain.require=FastDFS\u7D81\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u70BA\u7A7A +fastdfs.domain.url=FastDFS\u7D81\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u78BA + +local.domain.require=\u672C\u5730\u4E0A\u50B3\u7D81\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u70BA\u7A7A +local.domain.url=\u672C\u5730\u4E0A\u50B3\u7D81\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u78BA +local.path.url=\u5B58\u5132\u76EE\u9304\u4E0D\u80FD\u70BA\u7A7A + +sms.platform.range=\u5E73\u53F0\u985E\u578B\u53D6\u503C\u7BC4\u570D1~2 + +email.smtp.require=SMTP\u4E0D\u80FD\u70BA\u7A7A +email.port.require=\u7AEF\u53E3\u865F\u4E0D\u80FD\u70BA\u7A7A +email.username.require=\u90F5\u7BB1\u8CEC\u865F\u4E0D\u80FD\u70BA\u7A7A +email.password.require=\u90F5\u7BB1\u5BC6\u78BC\u4E0D\u80FD\u70BA\u7A7A + +mail.name.require=\u6A21\u677F\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A +mail.subject.require=\u90F5\u4EF6\u4E3B\u984C\u4E0D\u80FD\u70BA\u7A7A +mail.content.require=\u90F5\u4EF6\u6B63\u6587\u4E0D\u80FD\u70BA\u7A7A + +model.name.require=\u6A21\u578B\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A +model.key.require=\u6A21\u578B\u6A19\u8B58\u4E0D\u80FD\u70BA\u7A7A + +news.title.require=\u6A19\u984C\u4E0D\u80FD\u70BA\u7A7A +news.content.require=\u5167\u5BB9\u4E0D\u80FD\u70BA\u7A7A +news.pubdate.require=\u767C\u4F48\u6642\u9593\u4E0D\u80FD\u70BA\u7A7A \ No newline at end of file diff --git a/face-server/src/main/resources/logback-spring.xml b/face-server/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..7239257 --- /dev/null +++ b/face-server/src/main/resources/logback-spring.xml @@ -0,0 +1,60 @@ + + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + /mnt/appSystems/logs/${app_name}/%d{yyyy-MM, aux}/trace.%d{yyyy-MM-dd}.%i.log + + 500MB + + 10 + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + + + + + + /appSystems/logs/error.%d{yyyy-MM-dd}.%i.log + + /mnt/appSystems/logs/${app_name}/%d{yyyy-MM, aux}/error.%d{yyyy-MM-dd}.%i.log + + 500MB + + 10 + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + + + ERROR + ACCEPT + DENY + + + + + + + + + + + \ No newline at end of file diff --git a/face-server/src/main/resources/mybatis/mapper/ControlBayonetMidMapper.xml b/face-server/src/main/resources/mybatis/mapper/ControlBayonetMidMapper.xml new file mode 100644 index 0000000..176bfce --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/ControlBayonetMidMapper.xml @@ -0,0 +1,35 @@ + + + + + + update control_bayonet_mid set is_valid=#{State},update_time=now(),update_by=#{UpdateBy} where id_control_task=#{taskID} + + + + DELETE FROM control_bayonet_mid WHERE id_control_task =#{taskID} + + + + + + + + + + + diff --git a/face-server/src/main/resources/mybatis/mapper/ControlLibraryMidMapper.xml b/face-server/src/main/resources/mybatis/mapper/ControlLibraryMidMapper.xml new file mode 100644 index 0000000..e11fb57 --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/ControlLibraryMidMapper.xml @@ -0,0 +1,16 @@ + + + + + delete from control_library_mid where id_control_task=#{taskID} + + + + + + + diff --git a/face-server/src/main/resources/mybatis/mapper/ControlTaskMapper.xml b/face-server/src/main/resources/mybatis/mapper/ControlTaskMapper.xml new file mode 100644 index 0000000..3cba040 --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/ControlTaskMapper.xml @@ -0,0 +1,114 @@ + + + + + + `id_control_task`, + `task_name`, + `control_object`, + `disposal_type`, + `control_type`, + `control_start_time`, + `control_end_time`, + `control_region`, + `control_threshold`, + `control_status`, + `receive`, + `remarks`, + `is_valid`, + `create_time`, + `update_time`, + `create_by`, + `update_by`, + task_no, + viedourl, + imgurl + + + + + + + + + + + + + + + diff --git a/face-server/src/main/resources/mybatis/mapper/FaceCameraDao.xml b/face-server/src/main/resources/mybatis/mapper/FaceCameraDao.xml new file mode 100644 index 0000000..172435b --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/FaceCameraDao.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/face-server/src/main/resources/mybatis/mapper/FaceCameraMapper.xml b/face-server/src/main/resources/mybatis/mapper/FaceCameraMapper.xml new file mode 100644 index 0000000..95d51ab --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/FaceCameraMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/face-server/src/main/resources/mybatis/mapper/FaceLibraryMapper.xml b/face-server/src/main/resources/mybatis/mapper/FaceLibraryMapper.xml new file mode 100644 index 0000000..121f854 --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/FaceLibraryMapper.xml @@ -0,0 +1,26 @@ + + + + + + diff --git a/face-server/src/main/resources/mybatis/mapper/FaceTrackMapper.xml b/face-server/src/main/resources/mybatis/mapper/FaceTrackMapper.xml new file mode 100644 index 0000000..2d7abe9 --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/FaceTrackMapper.xml @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/face-server/src/main/resources/mybatis/mapper/PortraitMapper.xml b/face-server/src/main/resources/mybatis/mapper/PortraitMapper.xml new file mode 100644 index 0000000..3dd4017 --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/PortraitMapper.xml @@ -0,0 +1,156 @@ + + + + + + + + DELETE FROM portrait WHERE id_factory =#{taskID} + + + + + diff --git a/face-server/src/main/resources/mybatis/mapper/WarningInformationMapper.xml b/face-server/src/main/resources/mybatis/mapper/WarningInformationMapper.xml new file mode 100644 index 0000000..34b7197 --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/WarningInformationMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/face-server/src/main/resources/mybatis/mapper/log/SysLogErrorDao.xml b/face-server/src/main/resources/mybatis/mapper/log/SysLogErrorDao.xml new file mode 100644 index 0000000..26dabce --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/log/SysLogErrorDao.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/face-server/src/main/resources/mybatis/mapper/log/SysLogLoginDao.xml b/face-server/src/main/resources/mybatis/mapper/log/SysLogLoginDao.xml new file mode 100644 index 0000000..4b27814 --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/log/SysLogLoginDao.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/face-server/src/main/resources/mybatis/mapper/log/SysLogOperationDao.xml b/face-server/src/main/resources/mybatis/mapper/log/SysLogOperationDao.xml new file mode 100644 index 0000000..b295356 --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/log/SysLogOperationDao.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/face-server/src/main/resources/mybatis/mapper/sys/SysDeptDao.xml b/face-server/src/main/resources/mybatis/mapper/sys/SysDeptDao.xml new file mode 100644 index 0000000..b7e4680 --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/sys/SysDeptDao.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/face-server/src/main/resources/mybatis/mapper/sys/SysDictDataDao.xml b/face-server/src/main/resources/mybatis/mapper/sys/SysDictDataDao.xml new file mode 100644 index 0000000..f9af478 --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/sys/SysDictDataDao.xml @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/face-server/src/main/resources/mybatis/mapper/sys/SysDictTypeDao.xml b/face-server/src/main/resources/mybatis/mapper/sys/SysDictTypeDao.xml new file mode 100644 index 0000000..e1a23be --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/sys/SysDictTypeDao.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/face-server/src/main/resources/mybatis/mapper/sys/SysLanguageDao.xml b/face-server/src/main/resources/mybatis/mapper/sys/SysLanguageDao.xml new file mode 100644 index 0000000..88e6482 --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/sys/SysLanguageDao.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + delete from sys_language where table_name=#{tableName} and table_id=#{tableId} + + \ No newline at end of file diff --git a/face-server/src/main/resources/mybatis/mapper/sys/SysMenuDao.xml b/face-server/src/main/resources/mybatis/mapper/sys/SysMenuDao.xml new file mode 100644 index 0000000..d845bd2 --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/sys/SysMenuDao.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/face-server/src/main/resources/mybatis/mapper/sys/SysParamsDao.xml b/face-server/src/main/resources/mybatis/mapper/sys/SysParamsDao.xml new file mode 100644 index 0000000..482815f --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/sys/SysParamsDao.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + update sys_params set param_value = #{paramValue} where param_code = #{paramCode} + + \ No newline at end of file diff --git a/face-server/src/main/resources/mybatis/mapper/sys/SysRegionDao.xml b/face-server/src/main/resources/mybatis/mapper/sys/SysRegionDao.xml new file mode 100644 index 0000000..ca91ddb --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/sys/SysRegionDao.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/face-server/src/main/resources/mybatis/mapper/sys/SysRoleDao.xml b/face-server/src/main/resources/mybatis/mapper/sys/SysRoleDao.xml new file mode 100644 index 0000000..9229109 --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/sys/SysRoleDao.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/face-server/src/main/resources/mybatis/mapper/sys/SysRoleDataScopeDao.xml b/face-server/src/main/resources/mybatis/mapper/sys/SysRoleDataScopeDao.xml new file mode 100644 index 0000000..710682a --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/sys/SysRoleDataScopeDao.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + delete from sys_role_data_scope where role_id in + + #{roleId} + + + + \ No newline at end of file diff --git a/face-server/src/main/resources/mybatis/mapper/sys/SysRoleMenuDao.xml b/face-server/src/main/resources/mybatis/mapper/sys/SysRoleMenuDao.xml new file mode 100644 index 0000000..487efec --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/sys/SysRoleMenuDao.xml @@ -0,0 +1,20 @@ + + + + + + + + + delete from sys_role_menu where role_id in + + #{roleId} + + + + + delete from sys_role_menu where menu_id = #{value} + + \ No newline at end of file diff --git a/face-server/src/main/resources/mybatis/mapper/sys/SysRoleUserDao.xml b/face-server/src/main/resources/mybatis/mapper/sys/SysRoleUserDao.xml new file mode 100644 index 0000000..938a00f --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/sys/SysRoleUserDao.xml @@ -0,0 +1,24 @@ + + + + + + + delete from sys_role_user where role_id in + + #{roleId} + + + + + delete from sys_role_user where user_id in + + #{userId} + + + + + + \ No newline at end of file diff --git a/face-server/src/main/resources/mybatis/mapper/sys/SysUserDao.xml b/face-server/src/main/resources/mybatis/mapper/sys/SysUserDao.xml new file mode 100644 index 0000000..3497975 --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/sys/SysUserDao.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + update sys_user set password = #{newPassword} where id = #{id} + + + + + \ No newline at end of file diff --git a/face-server/src/main/resources/mybatis/mapper/sys/SysUserTokenDao.xml b/face-server/src/main/resources/mybatis/mapper/sys/SysUserTokenDao.xml new file mode 100644 index 0000000..c6c3348 --- /dev/null +++ b/face-server/src/main/resources/mybatis/mapper/sys/SysUserTokenDao.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + update sys_user_token set token = #{token} where user_id = #{userId} + + \ No newline at end of file diff --git a/face-server/src/main/resources/mybatis/mybatis.cfg.xml b/face-server/src/main/resources/mybatis/mybatis.cfg.xml new file mode 100644 index 0000000..bcdf41a --- /dev/null +++ b/face-server/src/main/resources/mybatis/mybatis.cfg.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/face-server/src/main/resources/摄像头导入模板.xls b/face-server/src/main/resources/摄像头导入模板.xls new file mode 100644 index 0000000000000000000000000000000000000000..dff70ddf6d88a17557b9d587b1ec6ca88612e50f GIT binary patch literal 39936 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 WM@Z;%KU4#MPanVkLivM5^8X*W!2#I- literal 0 HcmV?d00001 diff --git a/face-snapShot/pom.xml b/face-snapShot/pom.xml new file mode 100644 index 0000000..b06f916 --- /dev/null +++ b/face-snapShot/pom.xml @@ -0,0 +1,69 @@ + + + + face-application + com.dkha + 1.0-SNAPSHOT + + 4.0.0 + + face-snapShot + + + + + com.dkha + face-common + ${project.version} + + + + org.springframework + springloaded + + + org.springframework.boot + spring-boot-devtools + true + true + + + + + + + + + + io.springfox + springfox-swagger2 + + + io.springfox + springfox-swagger-ui + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework.boot + spring-boot-starter-web + + + + + + org.springframework.boot + spring-boot-maven-plugin + + com.dkha.face.FaceSnapShotMain + + + + + \ No newline at end of file diff --git a/face-snapShot/src/main/java/com/dkha/face/FaceSnapShotMain.java b/face-snapShot/src/main/java/com/dkha/face/FaceSnapShotMain.java new file mode 100644 index 0000000..1ab8e2e --- /dev/null +++ b/face-snapShot/src/main/java/com/dkha/face/FaceSnapShotMain.java @@ -0,0 +1,25 @@ +package com.dkha.face; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: FaceSnapShotMain + * @Package com.dkha.face.contral + * @author: panhui + * @date: 2019/12/25 10:09 + * @Copyright: 成都电科慧安 + */ +@SpringBootApplication +@EnableSwagger2 +public class FaceSnapShotMain { + + public static void main(String[]args) + { + SpringApplication.run(FaceSnapShotMain.class,args); + } +} diff --git a/face-snapShot/src/main/java/com/dkha/face/contral/FaceSnapContal.java b/face-snapShot/src/main/java/com/dkha/face/contral/FaceSnapContal.java new file mode 100644 index 0000000..26f9c25 --- /dev/null +++ b/face-snapShot/src/main/java/com/dkha/face/contral/FaceSnapContal.java @@ -0,0 +1,60 @@ +package com.dkha.face.contral; + +import com.dkha.face.modules.ReceiveSnapVO; +import com.dkha.face.modules.RecevieVO; +import com.google.gson.Gson; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: FaceSnapContal + * @Package com.dkha.face.contral + * @author: panhui + * @date: 2019/12/25 10:59 + * @Copyright: 成都电科慧安 + */ +@RestController +@RequestMapping("/face") +@Api(tags = "抓拍机管理") +@Slf4j +public class FaceSnapContal { + + + @Autowired + private Gson gson; + + @PostMapping("/snapshot") + @ApiOperation(value = "接收抓拍信息") + public String snapshot(@RequestBody RecevieVO recevieVO) + { + String json=gson.toJson(recevieVO); + log.error("接收卡口数据:"+json); + return json; + } + + @PostMapping("/test1") + @ApiOperation(value = "测试抓拍信息") + public String snapshot(@RequestBody ReceiveSnapVO receiveSnapVO) + { + String json=gson.toJson(receiveSnapVO); + log.error("接收卡口数据:"+json); + + System.out.println(receiveSnapVO.getBody().getPicture().size()); + return json; + } + + @PostMapping("/tripWire") + @ApiOperation(value = "人员绊线统计") + public String tripWire(@RequestBody RecevieVO recevieVO) + { + String json=gson.toJson(recevieVO); + log.error("接收绊线数据:"+json); + return json; + } +} diff --git a/face-snapShot/src/main/java/com/dkha/face/modules/ReceiveSnapVO.java b/face-snapShot/src/main/java/com/dkha/face/modules/ReceiveSnapVO.java new file mode 100644 index 0000000..b21788f --- /dev/null +++ b/face-snapShot/src/main/java/com/dkha/face/modules/ReceiveSnapVO.java @@ -0,0 +1,482 @@ +package com.dkha.face.modules; + +import java.util.List; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ReceiveSnapVO + * @Package com.dkha.face.modules + * @author: panhui + * @date: 2019/12/25 16:31 + * @Copyright: 成都电科慧安 + */ +public class ReceiveSnapVO { + + /** + * cmd : face_snapshot + * id : 0 + * body : {"age":2,"event_type":1,"face":[{"confidence":72,"data_type":1,"eye_dist":142,"face_id":1285,"pitch":0,"rect":{"bottom":733,"left":926,"right":1068,"top":584},"rel_rect":{"bottom":239,"left":94,"right":236,"top":90},"roll":0,"yaw":0}],"have_glasses":1,"have_hat":0,"have_mask":0,"num":1,"picture":[{"data":"","length":10015,"type":2}],"serialno":"6e25d4fe-b6abfa6d","sex":0,"snapshot":{"data":"","length":156397,"type":2},"time_str":"2019-12-25 12:56:04","timestamp":{"msec":351,"sec":1577249764},"trigger":1} + */ + + private String cmd; + private int id; + private BodyBean body; + + public String getCmd() { + return cmd; + } + + public void setCmd(String cmd) { + this.cmd = cmd; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public BodyBean getBody() { + return body; + } + + public void setBody(BodyBean body) { + this.body = body; + } + + public static class BodyBean { + /** + * age : 2 + * event_type : 1 + * face : [{"confidence":72,"data_type":1,"eye_dist":142,"face_id":1285,"pitch":0,"rect":{"bottom":733,"left":926,"right":1068,"top":584},"rel_rect":{"bottom":239,"left":94,"right":236,"top":90},"roll":0,"yaw":0}] + * have_glasses : 1 + * have_hat : 0 + * have_mask : 0 + * num : 1 + * picture : [{"data":"","length":10015,"type":2}] + * serialno : 6e25d4fe-b6abfa6d + * sex : 0 + * snapshot : {"data":"","length":156397,"type":2} + * time_str : 2019-12-25 12:56:04 + * timestamp : {"msec":351,"sec":1577249764} + * trigger : 1 + */ + + private int age; + private int event_type; + private int have_glasses; + private int have_hat; + private int have_mask; + private int num; + private String serialno; + private int sex; + private SnapshotBean snapshot; + private String time_str; + private TimestampBean timestamp; + private int trigger; + private List face; + private List picture; + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public int getEvent_type() { + return event_type; + } + + public void setEvent_type(int event_type) { + this.event_type = event_type; + } + + public int getHave_glasses() { + return have_glasses; + } + + public void setHave_glasses(int have_glasses) { + this.have_glasses = have_glasses; + } + + public int getHave_hat() { + return have_hat; + } + + public void setHave_hat(int have_hat) { + this.have_hat = have_hat; + } + + public int getHave_mask() { + return have_mask; + } + + public void setHave_mask(int have_mask) { + this.have_mask = have_mask; + } + + public int getNum() { + return num; + } + + public void setNum(int num) { + this.num = num; + } + + public String getSerialno() { + return serialno; + } + + public void setSerialno(String serialno) { + this.serialno = serialno; + } + + public int getSex() { + return sex; + } + + public void setSex(int sex) { + this.sex = sex; + } + + public SnapshotBean getSnapshot() { + return snapshot; + } + + public void setSnapshot(SnapshotBean snapshot) { + this.snapshot = snapshot; + } + + public String getTime_str() { + return time_str; + } + + public void setTime_str(String time_str) { + this.time_str = time_str; + } + + public TimestampBean getTimestamp() { + return timestamp; + } + + public void setTimestamp(TimestampBean timestamp) { + this.timestamp = timestamp; + } + + public int getTrigger() { + return trigger; + } + + public void setTrigger(int trigger) { + this.trigger = trigger; + } + + public List getFace() { + return face; + } + + public void setFace(List face) { + this.face = face; + } + + public List getPicture() { + return picture; + } + + public void setPicture(List picture) { + this.picture = picture; + } + + public static class SnapshotBean { + /** + * data : + * length : 156397 + * type : 2 + */ + + private String data; + private int length; + private int type; + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + } + + public static class TimestampBean { + /** + * msec : 351 + * sec : 1577249764 + */ + + private int msec; + private int sec; + + public int getMsec() { + return msec; + } + + public void setMsec(int msec) { + this.msec = msec; + } + + public int getSec() { + return sec; + } + + public void setSec(int sec) { + this.sec = sec; + } + } + + public static class FaceBean { + /** + * confidence : 72 + * data_type : 1 + * eye_dist : 142 + * face_id : 1285 + * pitch : 0 + * rect : {"bottom":733,"left":926,"right":1068,"top":584} + * rel_rect : {"bottom":239,"left":94,"right":236,"top":90} + * roll : 0 + * yaw : 0 + */ + + private int confidence; + private int data_type; + private int eye_dist; + private int face_id; + private int pitch; + private RectBean rect; + private RelRectBean rel_rect; + private int roll; + private int yaw; + + public int getConfidence() { + return confidence; + } + + public void setConfidence(int confidence) { + this.confidence = confidence; + } + + public int getData_type() { + return data_type; + } + + public void setData_type(int data_type) { + this.data_type = data_type; + } + + public int getEye_dist() { + return eye_dist; + } + + public void setEye_dist(int eye_dist) { + this.eye_dist = eye_dist; + } + + public int getFace_id() { + return face_id; + } + + public void setFace_id(int face_id) { + this.face_id = face_id; + } + + public int getPitch() { + return pitch; + } + + public void setPitch(int pitch) { + this.pitch = pitch; + } + + public RectBean getRect() { + return rect; + } + + public void setRect(RectBean rect) { + this.rect = rect; + } + + public RelRectBean getRel_rect() { + return rel_rect; + } + + public void setRel_rect(RelRectBean rel_rect) { + this.rel_rect = rel_rect; + } + + public int getRoll() { + return roll; + } + + public void setRoll(int roll) { + this.roll = roll; + } + + public int getYaw() { + return yaw; + } + + public void setYaw(int yaw) { + this.yaw = yaw; + } + + public static class RectBean { + /** + * bottom : 733 + * left : 926 + * right : 1068 + * top : 584 + */ + + private int bottom; + private int left; + private int right; + private int top; + + public int getBottom() { + return bottom; + } + + public void setBottom(int bottom) { + this.bottom = bottom; + } + + public int getLeft() { + return left; + } + + public void setLeft(int left) { + this.left = left; + } + + public int getRight() { + return right; + } + + public void setRight(int right) { + this.right = right; + } + + public int getTop() { + return top; + } + + public void setTop(int top) { + this.top = top; + } + } + + public static class RelRectBean { + /** + * bottom : 239 + * left : 94 + * right : 236 + * top : 90 + */ + + private int bottom; + private int left; + private int right; + private int top; + + public int getBottom() { + return bottom; + } + + public void setBottom(int bottom) { + this.bottom = bottom; + } + + public int getLeft() { + return left; + } + + public void setLeft(int left) { + this.left = left; + } + + public int getRight() { + return right; + } + + public void setRight(int right) { + this.right = right; + } + + public int getTop() { + return top; + } + + public void setTop(int top) { + this.top = top; + } + } + } + + public static class PictureBean { + /** + * data : + * length : 10015 + * type : 2 + */ + + private String data; + private int length; + private int type; + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + } + } +} diff --git a/face-snapShot/src/main/java/com/dkha/face/modules/RecevieVO.java b/face-snapShot/src/main/java/com/dkha/face/modules/RecevieVO.java new file mode 100644 index 0000000..8d37043 --- /dev/null +++ b/face-snapShot/src/main/java/com/dkha/face/modules/RecevieVO.java @@ -0,0 +1,28 @@ +package com.dkha.face.modules; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @version V1.0 + * @Description: TODO(用于接收抓拍机返回的数据) + * All rights 成都电科慧安 + * @Title: RecevieVO + * @Package com.dkha.face.modules + * @author: panhui + * @date: 2019/12/25 11:30 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NotNull +@JsonInclude(JsonInclude.Include.NON_NULL) +public class RecevieVO { + + private String cmd; + private Integer id; + private Object body; +} diff --git a/face-snapShot/src/main/resources/application.yml b/face-snapShot/src/main/resources/application.yml new file mode 100644 index 0000000..174babe --- /dev/null +++ b/face-snapShot/src/main/resources/application.yml @@ -0,0 +1,2 @@ +server: + port: 1990 diff --git a/face-task/pom.xml b/face-task/pom.xml new file mode 100644 index 0000000..3be788c --- /dev/null +++ b/face-task/pom.xml @@ -0,0 +1,109 @@ + + + + face-application + com.dkha + 1.0-SNAPSHOT + + 4.0.0 + + face-task + + + + com.dkha + face-common + ${project.version} + + + + org.springframework + springloaded + + + org.springframework.boot + spring-boot-devtools + true + true + + + + org.springframework.boot + spring-boot-starter-websocket + + + org.springframework.boot + spring-boot-starter-data-redis + + + redis.clients + jedis + + + + + + + + + + io.springfox + springfox-swagger2 + + + io.springfox + springfox-swagger-ui + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework.boot + spring-boot-starter-web + + + + com.baomidou + mybatis-plus-boot-starter + + + com.baomidou + mybatis-plus-generator + + + + + org.freemarker + freemarker + + + mysql + mysql-connector-java + + + org.projectlombok + lombok + + + com.alibaba + druid-spring-boot-starter + + + + + + org.springframework.boot + spring-boot-maven-plugin + + com.dkha.task.FaceTaskMain + + + + + + \ No newline at end of file diff --git a/face-task/src/main/java/com/dkha/task/FaceTaskMain.java b/face-task/src/main/java/com/dkha/task/FaceTaskMain.java new file mode 100644 index 0000000..6ec30d7 --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/FaceTaskMain.java @@ -0,0 +1,62 @@ +package com.dkha.task; + +import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor; +import com.dkha.task.config.MyMetaObjectHandler; +import com.dkha.task.service.WebSocketContral; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.PropertySource; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; +import springfox.documentation.swagger2.annotations.EnableSwagger2; +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: FaceSnapShotMain + * @Package com.dkha.face.contral + * @author: panhui + * @date: 2019/12/25 10:09 + * @Copyright: 成都电科慧安 + */ +@EnableSwagger2 +@SpringBootApplication(scanBasePackages = {"com.dkha.common","com.dkha.task"}) +@MapperScan("com.dkha.task.modual.mapper") +@EnableScheduling +@EnableAsync +public class FaceTaskMain { + + public static void main(String[]args) + { + SpringApplication springApplication = new SpringApplication(FaceTaskMain.class); + ConfigurableApplicationContext configurableApplicationContext = springApplication.run(args); + //解决WebSocket不能注入的问题 + WebSocketContral.setApplicationContext(configurableApplicationContext); + } + + /** + * mybatis-plus自动注入插件 + * + * @return + */ + @Bean + public MyMetaObjectHandler createMyMetaObjectHandler() { + return new MyMetaObjectHandler(); + } + + /** + * mybatis-plus执行效率插件 + * @return + */ + //@Bean + // 设置 dev test 环境开启 + //@Profile({"dev"}) + public PerformanceInterceptor performanceInterceptor() { + return new PerformanceInterceptor(); + } + + +} diff --git a/face-task/src/main/java/com/dkha/task/comm/TimerData.java b/face-task/src/main/java/com/dkha/task/comm/TimerData.java new file mode 100644 index 0000000..36a96cb --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/comm/TimerData.java @@ -0,0 +1,38 @@ +package com.dkha.task.comm; + +import com.dkha.task.modual.vo.BayonetVO; + +import java.text.SimpleDateFormat; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @version V1.0 + * @Description: TODO(定时任务里面的统计) + * All rights 成都电科慧安 + * @Title: TimerData + * @Package com.dkha.server.common + * @author: panhui + * @date: 2020/1/3 14:26 + * @Copyright: 成都电科慧安 + */ +public class TimerData { + //预警总数统计 + public static Long WARNING_NUM = -1L; + + //存储卡口不同的数据 + public static ConcurrentHashMap bayonetMap=new ConcurrentHashMap<>(); + + /** + * 不同的session保存不同的token + */ + public static ConcurrentHashMap tokens=new ConcurrentHashMap<>(); + + //获取当前时间 + public static String TIME_MARK=new SimpleDateFormat("yyyyMMdd").format(System.currentTimeMillis()); + + //系统处理的数量 50 + public static final Integer SYSTEM_DEEL_NUM=100; + //每次处理数据中 redis过期时间 + public static final Long expireTime=3000L; +} + diff --git a/face-task/src/main/java/com/dkha/task/config/MyMetaObjectHandler.java b/face-task/src/main/java/com/dkha/task/config/MyMetaObjectHandler.java new file mode 100644 index 0000000..bf861ba --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/config/MyMetaObjectHandler.java @@ -0,0 +1,42 @@ +package com.dkha.task.config; + +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import com.dkha.common.enums.YNEnums; +import org.apache.ibatis.reflection.MetaObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Date; + +/** + * 公共字段自动填充处理类 + */ +public class MyMetaObjectHandler implements MetaObjectHandler { + private static final Logger LOGGER = LoggerFactory.getLogger(MyMetaObjectHandler.class); + + + @Override + public void insertFill(MetaObject metaObject) { + + /** + * Ps:此处不能用下划线表示数据库字段,要使用驼峰命名 + */ + + Object isValidData = this.getFieldValByName( + "isValid", metaObject); + if (isValidData == null) { + this.setFieldValByName("isValid", YNEnums.YES.code, metaObject); + } + this.setFieldValByName("createTime", new Date(), metaObject); + this.setFieldValByName("createBy", String.valueOf(0L), metaObject); + this.setFieldValByName("updateTime", new Date(), metaObject); + this.setFieldValByName("updateBy", String.valueOf(0L), metaObject); + } + + @Override + public void updateFill(MetaObject metaObject) { + this.setUpdateFieldValByName("updateTime", new Date(), metaObject); + this.setUpdateFieldValByName("updateBy", String.valueOf(0L), metaObject); + } +} + diff --git a/face-task/src/main/java/com/dkha/task/config/WebSocketConfig.java b/face-task/src/main/java/com/dkha/task/config/WebSocketConfig.java new file mode 100644 index 0000000..07a6786 --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/config/WebSocketConfig.java @@ -0,0 +1,19 @@ +package com.dkha.task.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/** + * @Author Spring + * @Since 2019/9/12 20:10 + * @Description + */ +@Configuration +public class WebSocketConfig { + + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/face-task/src/main/java/com/dkha/task/contral/TestContral.java b/face-task/src/main/java/com/dkha/task/contral/TestContral.java new file mode 100644 index 0000000..8cca7e3 --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/contral/TestContral.java @@ -0,0 +1,61 @@ +package com.dkha.task.contral; + +import com.dkha.task.modual.entity.FaceTrackEntity; +import com.dkha.task.modual.mapper.SysUserTokenDao; +import com.dkha.task.service.FaceTrackService; +import com.dkha.task.service.WebSocketContral; +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.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: TestContral + * @Package com.dkha.task.contral + * @author: panhui + * @date: 2019/12/31 18:24 + * @Copyright: 成都电科慧安 + */ +@RestController +@RequestMapping("/socket") +public class TestContral { + + @Autowired + private WebSocketContral webSocketContral; + + @Autowired + private SysUserTokenDao sysUserTokenDao; + + + @Autowired + private FaceTrackService faceTrackService; + + @GetMapping("/test1") + public String test1(String token) + { + System.out.println("sysUserTokenDao="+sysUserTokenDao.getByToken(token,new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()))); + webSocketContral.sendMessage("xxxxxxxxxxx"); + return "xxx"; + } + + + @GetMapping("/test2") + public String test2() + { + List faceTrackEntities=new ArrayList<>(); + FaceTrackEntity faceTrackEntity=new FaceTrackEntity(); + faceTrackEntity.setTrajectoryThreshold(0.8); + faceTrackEntity.setIdPortrait(111L); + faceTrackEntities.add(faceTrackEntity); + faceTrackService.saveBatch(faceTrackEntities); + return "xxx"; + } +} diff --git a/face-task/src/main/java/com/dkha/task/contral/TimerContral.java b/face-task/src/main/java/com/dkha/task/contral/TimerContral.java new file mode 100644 index 0000000..ac1d486 --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/contral/TimerContral.java @@ -0,0 +1,273 @@ +package com.dkha.task.contral; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dkha.common.enums.ErrEnum; +import com.dkha.common.enums.SocketEnum; +import com.dkha.common.http.HttpUtil; +import com.dkha.common.modules.vo.camera.BayOnetCameraVO; +import com.dkha.common.modules.vo.camera.CameraInfoVO; +import com.dkha.common.modules.vo.dto.FaceLibraryVO; +import com.dkha.common.modules.vo.face.AlarmReturnVO; +import com.dkha.common.modules.vo.face.ApiAlarmVO; +import com.dkha.common.modules.vo.face.PageVO; +import com.dkha.common.modules.vo.warning.BayoneReturnListVO; +import com.dkha.common.modules.vo.warning.WarningPageVO; +import com.dkha.common.redis.RedisKeys; +import com.dkha.common.redis.RedisUtils; +import com.dkha.common.util.UrlUtil; +import com.dkha.common.util.UtilValidate; +import com.dkha.task.comm.TimerData; +import com.dkha.task.modual.vo.ReturnVO; +import com.dkha.task.service.ApiDeelService; +import com.dkha.task.service.IControlBayonetMidService; +import com.dkha.task.service.WebSocketContral; +import com.dkha.task.service.impl.AsyncServiceImpl; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: TimerContral + * @Package com.dkha.task.contral + * @author: panhui + * @date: 2020/1/2 16:31 + * @Copyright: 成都电科慧安 + */ +@Slf4j +@Component +public class TimerContral { + + @Value("${face.warning-url}") + private String warningUrl; + + @Value("${face.bayonet-url}") + private String bayonetUrl; + + @Autowired + private HttpUtil httpUtil; + + @Autowired + private WebSocketContral webSocketContral; + + @Autowired + private Gson gson; + + @Autowired + private RedisUtils redisUtils; + + /** + * 预警内容的定时数据 10秒后啓動每次10毫秒運行 TODO 後續記得加上token + */ + @Scheduled(fixedDelay = 50, initialDelay = 1000 * 10) + public void warning() { + try { +// String userToken = ""; +// if (UtilValidate.isNotEmpty(redisUtils.get("token"))) { +// userToken = (String) redisUtils.get("token"); +// } else { +// return; +// } + //更改ddd + ApiAlarmVO apiAlarmVO = new ApiAlarmVO(); +// apiAlarmVO.setToken(userToken); + String json = UrlUtil.postData(warningUrl, apiAlarmVO, httpUtil, gson); + if (UtilValidate.isEmpty(json)) { + return; + } + Page pages = gson.fromJson(json, Page.class); + if (TimerData.WARNING_NUM.intValue() == -1 || pages.getTotal() == 0L || TimerData.WARNING_NUM.intValue() == pages.getTotal()) { + if (TimerData.WARNING_NUM.intValue() == -1 && pages.getTotal() != 0L) { + //刚启动的时候 + TimerData.WARNING_NUM = pages.getTotal(); + } + } else { + Long count = pages.getTotal() - TimerData.WARNING_NUM; + if(count<0){ + count = 1L; + } + ApiAlarmVO apiVO = new ApiAlarmVO(); +// apiVO.setToken(userToken); + PageVO pageVo = new PageVO(); + pageVo.setPageSize(count.intValue()); + apiVO.setPage(pageVo); + String jsonData = UrlUtil.postData(warningUrl, apiVO, httpUtil, gson); + if (UtilValidate.isNotEmpty(jsonData)) { + Page page = gson.fromJson(jsonData, Page.class); + try { + List myRecords = gson.fromJson(gson.toJson(page.getRecords()), new TypeToken>() { + }.getType()); + myRecords.forEach(e -> + { + ReturnVO returnVO = new ReturnVO(ErrEnum.OK, e); + returnVO.setCmd(SocketEnum.WARNING.getCode()); + webSocketContral.sendMessage(gson.toJson(returnVO)); + try { + if (myRecords.size() > 1) { + Thread.sleep(50); + } + } catch (Exception ex) { + } + }); + } catch (Exception ex) { + } finally { + TimerData.WARNING_NUM = pages.getTotal(); + } + } + } + } catch (Exception e) { + log.error("预警系统异常,休眠10秒再试{}", e.getMessage()); + try { + Thread.sleep(10000); + } catch (InterruptedException e1) { + + } + } + } + + + @Autowired + private AsyncServiceImpl asyncContral; + + /** + * 卡口数据获取 TODO 後續記得加上token + */ + @Scheduled(fixedDelay = 40, initialDelay = 20000) + public void bayonet() { + try { + TimerData.bayonetMap.forEach((a, b) -> + { +// String sessionId = a; +// String userToken = ""; +// if (UtilValidate.isNotEmpty(redisUtils.get(RedisKeys.getSessionIdKey(sessionId)))) { +// userToken = (String) redisUtils.get(RedisKeys.getSessionIdKey(sessionId)); +// } else { +// return; +// } + ApiAlarmVO apiAlarmVO = new ApiAlarmVO(); +// apiAlarmVO.setToken(userToken); + String json = UrlUtil.getData(bayonetUrl + "/" + b.getCarmeraId() + "/" + 1, httpUtil, gson); + + if (UtilValidate.isEmpty(json)) { + return; + } +// if (json.length() < 4) { +// if (ErrEnum.UNAUTHORIZED.getCode().intValue() == Integer.valueOf(json)) { +// webSocketContral.sendMessage(gson.toJson(new ReturnVO(ErrEnum.UNAUTHORIZED))); +// TimerData.bayonetMap.remove(a); +// return; +// } +// } + + BayoneReturnListVO bayoneReturnListVO = gson.fromJson(json, BayoneReturnListVO.class); + if (b.getBayonetNum().intValue() == -1 || bayoneReturnListVO.getToDaySnapShot() == 0L || b.getBayonetNum() == bayoneReturnListVO.getToDaySnapShot()) { + if (b.getBayonetNum().intValue() == -1 && bayoneReturnListVO.getToDaySnapShot() != 0L) { + //刚启动的时候 + b.setBayonetNum(bayoneReturnListVO.getToDaySnapShot()); + } + } else { + Long count = bayoneReturnListVO.getToDaySnapShot() - b.getBayonetNum(); + String jsonData = UrlUtil.getData(bayonetUrl + "/" + b.getCarmeraId() + "/" + count, httpUtil, gson); + if (UtilValidate.isNotEmpty(jsonData)) { +// System.out.println(bayoneReturnListVO.getToDaySnapShot() + "bayonet发现预警!" + count + "==" + b.getBayonetNum()); + BayoneReturnListVO bayoneVO = gson.fromJson(jsonData, BayoneReturnListVO.class); + try { + List myRecords = gson.fromJson(gson.toJson(bayoneVO.getResult()), new TypeToken>() { + }.getType()); + myRecords.forEach(e -> + { + e.setToDaySnapShot(bayoneVO.getToDaySnapShot()); + e.setTotalSnapShot(bayoneVO.getTotalSnapShot()); + ReturnVO returnVO = new ReturnVO(ErrEnum.OK, e); + returnVO.setCmd(SocketEnum.BAYONET.getCode()); + asyncContral.bayonetInfo(a, gson.toJson(returnVO)); + }); + } catch (Exception ex) { + } finally { + b.setBayonetNum(bayoneReturnListVO.getToDaySnapShot()); + } + } + } + }); + } catch (Exception e) { + log.error("卡口系统异常,休眠10秒再试{}", e.getMessage()); + try { + Thread.sleep(10000); + } catch (InterruptedException e1) { + + } + } + } + + + @Autowired + private IControlBayonetMidService iControlBayonetMidService; + + + @Autowired + private ApiDeelService apiDeelService; + + /** + * 人物轨迹信息 TODO 後續記得加上token + */ + @Scheduled(fixedDelay = 1000 * 60, initialDelay = 10000) + public void bayonetTrack() { + log.error("轨迹检测开始"); + //获取布控摄像头的列表 + List cameraList = iControlBayonetMidService.selectCameraByTask(); + if (UtilValidate.isEmpty(cameraList)) { + return; + } + String nowTime = new SimpleDateFormat("yyyy-MM-dd").format(System.currentTimeMillis()); +// CameraInfoVO cameraInfoVO = cameraList.get(0); +// System.out.println(cameraInfoVO); +// cameraList.clear(); +// cameraInfoVO.setIdFaceCamera("1210110089958686721"); +// cameraList.add(cameraInfoVO); +// log.error("摄像头类别"+gson.toJson(cameraList)); + cameraList.forEach(a -> + { + //不存在摄像头数据了 + if (!redisUtils.exists(RedisKeys.getCameraByTrack(nowTime, a.getIdFaceCamera()))) { + FaceLibraryVO faceLibraryVO = new FaceLibraryVO(); + faceLibraryVO.setName("摄像头库" + nowTime + ":" + a.getIdFaceCamera()); + faceLibraryVO = apiDeelService.addLib(faceLibraryVO); //暂时去掉 +// faceLibraryVO=new FaceLibraryVO(); +// faceLibraryVO.setLibraryId(a.getIdFaceCamera()); + if (UtilValidate.isNotEmpty(faceLibraryVO)) { + //创建人脸库 使用时间+摄像头id + //给redis赋值 + //每个摄像头创建一个线程一直运行程序检测时间如果不是当天则自动关闭 + //关联新建的库id和一些基本信息 + BayOnetCameraVO bayOnetCameraVO = new BayOnetCameraVO(a.getIdFaceCamera(), faceLibraryVO.getLibraryId().toString(), 0L, new ArrayList<>()); + redisUtils.set(RedisKeys.getCameraByTrack(nowTime, a.getIdFaceCamera()), gson.toJson(bayOnetCameraVO)); + //运行一个线程检索的方法 + asyncContral.trackByCamera(nowTime, a.getIdFaceCamera()); + log.error("运行检测的方法:{},{}", nowTime, a.getIdFaceCamera()); + return; + } + } else { + //利用redis的过期来判定任务是否异常退出 + //30秒过期 + if (!redisUtils.exists(RedisKeys.getCameraByExpired(nowTime, a.getIdFaceCamera()))) { + //运行一个线程检索的方法 + log.error("过期时候运行检测的方法:{},{}", nowTime, a.getIdFaceCamera()); + asyncContral.trackByCamera(nowTime, a.getIdFaceCamera()); + } + } + }); + } + + +} diff --git a/face-task/src/main/java/com/dkha/task/modual/BaseDao.java b/face-task/src/main/java/com/dkha/task/modual/BaseDao.java new file mode 100644 index 0000000..d5caaf5 --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/modual/BaseDao.java @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.task.modual; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 基础Dao + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface BaseDao extends BaseMapper { + +} diff --git a/face-task/src/main/java/com/dkha/task/modual/SysUserTokenEntity.java b/face-task/src/main/java/com/dkha/task/modual/SysUserTokenEntity.java new file mode 100644 index 0000000..2b52d61 --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/modual/SysUserTokenEntity.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.task.modual; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 系统用户Token + */ +@Data +@TableName("sys_user_token") +public class SysUserTokenEntity implements Serializable { + private static final long serialVersionUID = 1L; + /** + * id + */ + @TableId + private Long id; + /** + * 用户ID + */ + private Long userId; + /** + * 用户token + */ + private String token; + /** + * 过期时间 + */ + private Date expireDate; + /** + * 更新时间 + */ + private Date updateDate; + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + private Date createDate; + +} \ No newline at end of file diff --git a/face-task/src/main/java/com/dkha/task/modual/entity/ControlBayonetMid.java b/face-task/src/main/java/com/dkha/task/modual/entity/ControlBayonetMid.java new file mode 100644 index 0000000..ae3546a --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/modual/entity/ControlBayonetMid.java @@ -0,0 +1,62 @@ +package com.dkha.task.modual.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 布控和摄像头中间表 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value="ControlBayonetMid对象", description="布控和摄像头中间表") +public class ControlBayonetMid implements Serializable { + + private static final long serialVersionUID = 1L; + @ApiModelProperty(value = "id") + @TableId(value = "id", type = IdType.ID_WORKER) + private Long id; + + @ApiModelProperty(value = "id布控id") + private Long idControlTask; + + @ApiModelProperty(value = "摄像头id") + private Long idFaceCamera; + + @ApiModelProperty(value = "是否有效 Y有效 N无效") + @TableField(fill = FieldFill.INSERT) + private String isValid; + + @ApiModelProperty(value = "创建时间") + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date createTime; + + @ApiModelProperty(value = "更新时间") + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateTime; + + @ApiModelProperty(value = "创建人") + @TableField(fill = FieldFill.INSERT) + private String createBy; + + @ApiModelProperty(value = "更新人") + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updateBy; + + +} diff --git a/face-task/src/main/java/com/dkha/task/modual/entity/FaceCamera.java b/face-task/src/main/java/com/dkha/task/modual/entity/FaceCamera.java new file mode 100644 index 0000000..77d319f --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/modual/entity/FaceCamera.java @@ -0,0 +1,107 @@ +package com.dkha.task.modual.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 摄像头表 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value="FaceCamera对象", description="摄像头表") +public class FaceCamera implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @TableId(value = "id_face_camera", type = IdType.ID_WORKER) + private Long idFaceCamera; + + @ApiModelProperty(value = "摄像头名称") + private String cameraName; + + @ApiModelProperty(value = "摄像头区域-码值") + private String cameraRegionFirstlevel; + + @ApiModelProperty(value = "摄像头详细地址") + private String cameraAddress; + + @ApiModelProperty(value = "摄像头经度") + private String cameratLongitude; + + @ApiModelProperty(value = "摄像头纬度") + private String cameraLatitude; + + @ApiModelProperty(value = "位置类型-码值") + private String cameratLocationtypeId; + + @ApiModelProperty(value = "公安机关代码") + private String publicSecurityCode; + + @ApiModelProperty(value = "公安机关名称") + private String publicSecurityName; + + @ApiModelProperty(value = "建设单位") + private String constructionUnit; + + @ApiModelProperty(value = "管理单位") + private String managementUnit; + + @ApiModelProperty(value = "管理人员") + private String managementPersonnel; + + @ApiModelProperty(value = "联系电话") + private String contactNumber; + + @ApiModelProperty(value = "IP") + private String ip; + + @ApiModelProperty(value = "用户名") + private String userName; + + @ApiModelProperty(value = "密码") + private String passwd; + + @ApiModelProperty(value = "品牌") + private String brand; + + @ApiModelProperty(value = "rtsp地址") + private String rtspUrl; + + @ApiModelProperty(value = "备注信息") + private String remarks; + + @ApiModelProperty(value = "是否运行 Y启动 N未启动") + private String status; + + @ApiModelProperty(value = "是否有效 Y有效 N无效") + private String isValid; + + @ApiModelProperty(value = "创建时间") + private Date createTime; + + @ApiModelProperty(value = "更新时间") + private Date updateTime; + + @ApiModelProperty(value = "创建人") + private String createBy; + + @ApiModelProperty(value = "更新人") + private String updateBy; + + +} diff --git a/face-task/src/main/java/com/dkha/task/modual/entity/FaceTrackEntity.java b/face-task/src/main/java/com/dkha/task/modual/entity/FaceTrackEntity.java new file mode 100644 index 0000000..96b3719 --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/modual/entity/FaceTrackEntity.java @@ -0,0 +1,84 @@ +package com.dkha.task.modual.entity; + + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Value; +import lombok.experimental.Accessors; +import java.io.Serializable; +import java.util.Date; + +/** + * + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 2020-01-10 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value="FaceTrackEntity对象", description="轨迹对象") +@TableName(value = "face_track") +public class FaceTrackEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 轨迹id + */ + @ApiModelProperty(value = "id_face_track") + @TableId(value = "id_face_track", type = IdType.ID_WORKER) + private Long idFaceTrack; + /** + * 人像id + */ + private Long idPortrait; + /** + * 摄像头id + */ + private Long idFaceCamera; + /** + * 库id + */ + private Long idFactory; + /** + * 人物数据 + */ + private String characterData; + /** + * 关联数据 + */ + private String linkedData; + /** + * 分组时间 + */ + private String packetTime; + /** + * 当月数据关联 + */ + private String monthData; + /** + * 轨迹判定阈值 + */ + private Double trajectoryThreshold; + /** + * 创建人 + */ + private String createBy; + /** + * 创建时间 + */ + private Date createTime; + /** + * 更新人 + */ + private String updateBy; + /** + * 更新时间 + */ + private Date updateTime; +} \ No newline at end of file diff --git a/face-task/src/main/java/com/dkha/task/modual/mapper/ControlBayonetMidMapper.java b/face-task/src/main/java/com/dkha/task/modual/mapper/ControlBayonetMidMapper.java new file mode 100644 index 0000000..7697a42 --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/modual/mapper/ControlBayonetMidMapper.java @@ -0,0 +1,36 @@ +package com.dkha.task.modual.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dkha.common.modules.vo.camera.CameraInfoVO; +import com.dkha.task.modual.entity.ControlBayonetMid; +import com.dkha.task.modual.entity.FaceCamera; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 布控和摄像头中间表 Mapper 接口 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Mapper +public interface ControlBayonetMidMapper extends BaseMapper { + /** + * 根据任务ID删除任务和摄像头的中间表 + * + * @Return Integer >0成功 + */ + Integer deletetaskandcarmerbytaskid(@Param("taskID") String taskID); + + Integer selectexistByCarmeID(@Param("idcamera") String idcamera); + + Integer updateCarmerValidaStateByTaskID(@Param("taskID") String taskID, @Param("State") String State, @Param("UpdateBy") String UpdateBy); + + List selectFaceCameraBytaskID(@Param("taskID") String taskID); + List selectFaceCameraBytask(); + int getControlByRegion(@Param("regionId") long regionId); +} diff --git a/face-task/src/main/java/com/dkha/task/modual/mapper/FaceTrackMapper.java b/face-task/src/main/java/com/dkha/task/modual/mapper/FaceTrackMapper.java new file mode 100644 index 0000000..7d5c04a --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/modual/mapper/FaceTrackMapper.java @@ -0,0 +1,41 @@ +package com.dkha.task.modual.mapper; + + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dkha.task.modual.entity.FaceTrackEntity; +import com.dkha.task.modual.vo.FaceTrackVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 2020-01-10 + */ +@Mapper +public interface FaceTrackMapper extends BaseMapper { + /** + * 根据摄像头和分组时间查询 + * @param idFaceCamera + * @param packetTime + * @return + */ + List querByidCameraAndTime(@Param("idFaceCamera")Long idFaceCamera, @Param("packetTime")String packetTime); + /** + * 根据摄像头Id和开始,结束时间,人脸ID + * @param faceTrackVO + * @return + */ + List queryByidCamerAndFaceId(@Param("faceTrackVO")FaceTrackVO faceTrackVO); + + /** + * 根据图片路径和开始,结束时间 + * @param faceTrackVO + * @return + */ + List queryByurlAndTime(@Param("faceTrackVO")FaceTrackVO faceTrackVO); +} \ No newline at end of file diff --git a/face-task/src/main/java/com/dkha/task/modual/mapper/SysUserTokenDao.java b/face-task/src/main/java/com/dkha/task/modual/mapper/SysUserTokenDao.java new file mode 100644 index 0000000..c9f2765 --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/modual/mapper/SysUserTokenDao.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dkha.task.modual.mapper; + +import com.dkha.task.modual.BaseDao; +import com.dkha.task.modual.SysUserTokenEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Service; + +import java.util.Date; + +/** + * 系统用户Token + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysUserTokenDao extends BaseDao { + + SysUserTokenEntity getByToken(@Param("value") String value, @Param("time") String time); + + void updateToken(@Param("userId") Long userId, @Param("token") String token); +} diff --git a/face-task/src/main/java/com/dkha/task/modual/vo/BayonetVO.java b/face-task/src/main/java/com/dkha/task/modual/vo/BayonetVO.java new file mode 100644 index 0000000..36b1ce2 --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/modual/vo/BayonetVO.java @@ -0,0 +1,30 @@ +package com.dkha.task.modual.vo; + +import com.dkha.common.modules.vo.warning.WarningPageVO; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: PageMsgVO + * @Package com.dkha.task.modual.vo + * @author: panhui + * @date: 2020/1/3 15:14 + * @Copyright: 成都电科慧安 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +public class BayonetVO{ + //当前查询的数量 + private Long bayonetNum=-1L; + //摄像头id + private String carmeraId; + + +} diff --git a/face-task/src/main/java/com/dkha/task/modual/vo/FaceTrackVO.java b/face-task/src/main/java/com/dkha/task/modual/vo/FaceTrackVO.java new file mode 100644 index 0000000..ef0edb2 --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/modual/vo/FaceTrackVO.java @@ -0,0 +1,46 @@ +package com.dkha.task.modual.vo; + + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +/** + * + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 2020-01-10 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class FaceTrackVO implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 图片url + */ + private String url; + /** + * 人像id + */ + private String faceId; + /** + * 摄像头id + */ + private Long idFaceCamera; + /** + * 库id + */ + private String startTime; + /** + * 人物数据 + */ + private String endTime; +} \ No newline at end of file diff --git a/face-task/src/main/java/com/dkha/task/modual/vo/ReturnVO.java b/face-task/src/main/java/com/dkha/task/modual/vo/ReturnVO.java new file mode 100644 index 0000000..d42c06f --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/modual/vo/ReturnVO.java @@ -0,0 +1,162 @@ +package com.dkha.task.modual.vo; + + +import com.dkha.common.enums.ErrEnum; +import com.dkha.common.exception.DkException; +import com.dkha.common.util.UtilValidate; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.BindingResult; + +import java.io.Serializable; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ReturnVO + * @Package com.dkha.api.modules + * @author: panhui + * @date: 2019/12/2 13:34 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel(value="API通用返回", description="Api通用返回結構類") +public class ReturnVO implements Serializable { + + private Integer code; + private String message; + private String cmd; + private Object data; + private static final long serialVersionUID = 1L; + + + public ReturnVO(Object data, Integer code, String message) { + this.code = code; + this.data = data; + this.message = message; + } + + public ReturnVO(ErrEnum errEnum) { + this.code = errEnum.getCode(); + this.data = null; + this.message = errEnum.getMsg(); + } + public ReturnVO(ErrEnum errEnum,Object data) { + this.code = errEnum.getCode(); + this.data = data; + this.message = errEnum.getMsg(); + } + + public ReturnVO(Integer code, String message) { + this.code = code; + this.data = null; + this.message = message; + } + + /** + * 操作成功返回集 code为200 + */ + public ReturnVO successResult(Object data) { + ReturnVO ReturnVO = new ReturnVO(); + ReturnVO.code = ErrEnum.OK.getCode(); + ReturnVO.data = data; + ReturnVO.message = ErrEnum.OK.getMsg(); + return ReturnVO; + } + + /** + * 操作成功返回集 code为200 + * @param message + * @param data + */ + public ReturnVO successResult(String message, Object data) { + ReturnVO ReturnVO = new ReturnVO(); + ReturnVO.code = ErrEnum.OK.getCode(); + ReturnVO.data = data; + ReturnVO.message = UtilValidate.isEmpty(message) ? ErrEnum.OK.getMsg() : message; + return ReturnVO; + } + + /** + * 操作失败返回集 默认code 500 + * @param message + * @return + */ + public ReturnVO failResult(String message) { + ReturnVO ReturnVO = new ReturnVO(); + ReturnVO.code = ErrEnum.ERROR.getCode(); + ReturnVO.data = null; + ReturnVO.message = message; + return ReturnVO; + } + + /** + * 参数不正确 默认code + * @param message + * @return + */ + public ReturnVO paramErrorResult(String message) { + ReturnVO ReturnVO = new ReturnVO(); + ReturnVO.code = ErrEnum.BAD_REQUEST.getCode(); + ReturnVO.data = null; + ReturnVO.message = (UtilValidate.isEmpty(message)?ErrEnum.BAD_REQUEST.getMsg():message); + return ReturnVO; + } + + /** + * 没有查询到数据 默认code + * @param message + * @return + */ + public ReturnVO notInfoResult(String message) { + ReturnVO ReturnVO = new ReturnVO(); + ReturnVO.code = ErrEnum.NOT_FOUND.getCode(); + ReturnVO.data = null; + ReturnVO.message = (UtilValidate.isEmpty(message)?ErrEnum.NOT_FOUND.getMsg():message); + return ReturnVO; + } + + /** + * 操作失败返回集 + * @param + * @return + */ + public ReturnVO fail() { + ReturnVO ReturnVO = new ReturnVO(); + ReturnVO.code = ErrEnum.ERROR.getCode(); + ReturnVO.data = null; + ReturnVO.message = ErrEnum.ERROR.getMsg(); + return ReturnVO; + } + + /** + * 操作失败返回集 + * @param data + * @param message + * @param code + */ + public ReturnVO failResult(Integer code, String message, Object data) { + ReturnVO ReturnVO = new ReturnVO(); + ReturnVO.code = UtilValidate.isEmpty(code) ? ErrEnum.ERROR.getCode() : code; + ReturnVO.data = data; + ReturnVO.message = UtilValidate.isEmpty(message) ? ErrEnum.ERROR.getMsg() : message; + return ReturnVO; + } + + /** + * 用于Hibernate-validate vo校验 + * @param bindingResult + */ + public void validate(BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new DkException(bindingResult.getFieldError().getDefaultMessage()); + } + } +} diff --git a/face-task/src/main/java/com/dkha/task/service/ApiDeelService.java b/face-task/src/main/java/com/dkha/task/service/ApiDeelService.java new file mode 100644 index 0000000..4a1b1e6 --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/service/ApiDeelService.java @@ -0,0 +1,34 @@ +package com.dkha.task.service; + +import com.dkha.common.modules.vo.ApiVO; +import com.dkha.common.modules.vo.dto.FaceLibraryVO; +import org.springframework.stereotype.Service; + +/** + * @version V1.0 + * @Description: TODO(操作api的service层) + * All rights 成都电科慧安 + * @Title: ApiDeelService + * @Package com.dkha.task.service + * @author: panhui + * @date: 2020/1/9 17:00 + * @Copyright: 成都电科慧安 + */ +@Service +public interface ApiDeelService { + + + /** + * 创建一个人脸库 + * @return + */ + FaceLibraryVO addLib(FaceLibraryVO faceLibraryVO); + + /** + * 根据时间获取当天数据摄像头的es抓拍数据 + * @param cameraId + * @return + */ + void getApi(String cameraId,String time,Long bayonetNum,String libId); + +} diff --git a/face-task/src/main/java/com/dkha/task/service/FaceTrackService.java b/face-task/src/main/java/com/dkha/task/service/FaceTrackService.java new file mode 100644 index 0000000..32a26f9 --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/service/FaceTrackService.java @@ -0,0 +1,44 @@ +package com.dkha.task.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.dkha.task.modual.entity.FaceTrackEntity; +import com.dkha.task.modual.vo.FaceTrackVO; + +import java.util.List; + +/** + * + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 2020-01-10 + */ +public interface FaceTrackService extends IService { + /** + * 新增 + * @param faceTrackEntity + * @return + */ + int addFaceTrackEntity(FaceTrackEntity faceTrackEntity); + /** + * 根据摄像头和分组时间查询 + * @param idFaceCamera + * @param packetTime + * @return + */ + List querByidCameraAndTime(Long idFaceCamera, String packetTime); + + /** + * 根据摄像头Id和开始,结束时间,人脸ID + * @param faceTrackVO + * @return + */ + List queryByidCamerAndFaceId(FaceTrackVO faceTrackVO); + + /** + * 根据图片路径和开始,结束时间 + * @param faceTrackVO + * @return + */ + List queryByurlAndTime(FaceTrackVO faceTrackVO); +} \ No newline at end of file diff --git a/face-task/src/main/java/com/dkha/task/service/IControlBayonetMidService.java b/face-task/src/main/java/com/dkha/task/service/IControlBayonetMidService.java new file mode 100644 index 0000000..92549e0 --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/service/IControlBayonetMidService.java @@ -0,0 +1,57 @@ +package com.dkha.task.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.dkha.common.modules.vo.camera.CameraInfoVO; +import com.dkha.task.modual.entity.ControlBayonetMid; +import com.dkha.task.modual.entity.FaceCamera; + +import java.util.List; + +/** + *

+ * 布控和摄像头中间表 服务类 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +public interface IControlBayonetMidService extends IService { + /** + * 根据任务ID删除任务和摄像头的中间表 + */ + Integer deletetaskandcarmerbytaskid(String taskID); + + /** + * 根据摄像头ID判断是否存在任务 + */ + long selectexistByCarmeID(String idcamera); + + /** + * 更新中间库摄像头状态 + */ + Integer updateCarmerValidaStateByTaskID(String taskID, String State, String UpdateBy); + + /** + * 根据任务ID获取摄像头列表 + */ + List selectFaceCameraBytaskID(String taskid); + + /** + * 查询所有有布控任务的摄像头 + */ + List selectCameraByTask(); + + /** + * 获取最新布控的一个摄像头 + */ + ControlBayonetMid selectFaceCameraByTime(); + + /** + * 根据区域获取布控任务 + * + * @param regionId + * @return + */ + int getControlByRegion(long regionId); + +} diff --git a/face-task/src/main/java/com/dkha/task/service/WebSocketContral.java b/face-task/src/main/java/com/dkha/task/service/WebSocketContral.java new file mode 100644 index 0000000..509aca4 --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/service/WebSocketContral.java @@ -0,0 +1,174 @@ +package com.dkha.task.service; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; + +import com.dkha.common.enums.ErrEnum; +import com.dkha.common.enums.SocketEnum; +import com.dkha.common.redis.RedisKeys; +import com.dkha.common.redis.RedisUtils; +import com.dkha.common.util.UtilValidate; +import com.dkha.task.comm.TimerData; +import com.dkha.task.modual.SysUserTokenEntity; +import com.dkha.task.modual.mapper.SysUserTokenDao; +import com.dkha.task.modual.vo.BayonetVO; +import com.dkha.task.modual.vo.ReturnVO; +import com.google.gson.Gson; +import lombok.Data; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Component; + +import lombok.extern.slf4j.Slf4j; + +@Component +@ServerEndpoint("/webSocket") +@Slf4j +public class WebSocketContral { + + + private Session session; + private Gson gson=new Gson(); + + private static CopyOnWriteArraySet webSocketSet=new CopyOnWriteArraySet(); + public static Map myMap=new ConcurrentHashMap(); + + private RedisUtils redisUtils; + //此处是解决无法注入的关键 + private static ApplicationContext applicationContext; + //要注入的service或者dao + private SysUserTokenDao sysUserTokenDao; + + public static void setApplicationContext(ApplicationContext applicationContext) { + WebSocketContral.applicationContext = applicationContext; + } + + @OnOpen + public void opOpen(Session session) + { + redisUtils =applicationContext.getBean(RedisUtils.class); + this.session=session; + if(myMap.containsKey(session.getId())) + { + try { + this.session.close(); + } catch (IOException e) { + } +// log.error("已经存在"); + return; + } + sysUserTokenDao=applicationContext.getBean(SysUserTokenDao.class); + String time=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()); + SysUserTokenEntity sysUserTokenEntity= null;//sysUserTokenDao.getByToken(token,time); + if(UtilValidate.isEmpty(sysUserTokenEntity)) + { + log.error("token过期"); + sessionSendMsg(session,gson.toJson(new ReturnVO(ErrEnum.UNAUTHORIZED))); + try { + this.session.close(); + } catch (Exception e) { + } + return; + } +// //广播使用 +// redisUtils.set("token",token); +// //对应使用 +// redisUtils.set(RedisKeys.getSessionIdKey(session.getId()),token); +// TimerData.tokens.put(session.getId(),token); + webSocketSet.add(this); + myMap.put(session.getId(), this); +// log.info(session.getId()+"【websocket消息】有新的连接,总数:{},{},{}",webSocketSet.size(),myMap.size(),token); + + } + @OnClose + public void onClose() + { +// log.info(this.session.getId()+"【websocket消息】连接断开,总数:{},{}",webSocketSet.size(),myMap.size()); + if(TimerData.bayonetMap.containsKey(this.session.getId())) { + TimerData.bayonetMap.remove(this.session.getId()); + } + myMap.remove(this.session.getId()); + webSocketSet.remove(this); +// log.info("关闭成功{},{},{}",webSocketSet.size(),myMap.size(),TimerData.bayonetMap.size()); + } + @OnMessage + public void onMessage(String message) + { +// log.error("接收数据:{}",message); + if(UtilValidate.isEmpty(this.session) || this.session.isOpen()==false){return;} + if(UtilValidate.isNotEmpty(message)) + { + ReturnVO returnVO=gson.fromJson(message,ReturnVO.class); + if(UtilValidate.isNotEmpty(returnVO) && returnVO.getCode().intValue()==ErrEnum.OK.getCode() && returnVO.getCmd().equals(SocketEnum.BAYONET.getCode())) + { + if(UtilValidate.isNotEmpty(returnVO.getData())) + { + Map myMap=gson.fromJson(gson.toJson(returnVO.getData()),Map.class); + if(UtilValidate.isNotEmpty(myMap) && myMap.containsKey("carmeraId")) + { + TimerData.bayonetMap.put(this.session.getId(), new BayonetVO(-1L,myMap.get("carmeraId"))); +// log.error("更换摄像头:{}",TimerData.bayonetMap.get(this.session.getId())); + } + } + } + } +// log.info("【websocket消息】收到客户端消息:{}",message); + } + + + /** + * 给指定id用户推送信息 + * @param message + */ + public void sendMessage(String id,String message) + { + for(WebSocketContral websocket:webSocketSet) + { + if(websocket.session.getId().equals(id)) + { +// log.info("【websocket消息】给ID={}发送消息,message={}",id,message); + sessionSendMsg(websocket.session,message); + break; + } + + } + } + /** + * 群发消息调用 + * @param message + */ + public void sendMessage(String message) + { + for(WebSocketContral websocket:webSocketSet) + { +// log.info("【websocket消息】广播消息,message={}",message); + sessionSendMsg(websocket.session,message); + } + } + + /** + * 发送消息 + * @param session + * @param message + */ + private void sessionSendMsg(Session session,String message) + { + try { + session.getBasicRemote().sendText(message); + } catch (Exception e) { + log.error("socket发送消息错误:"+e.getMessage()); + } + } + + +} diff --git a/face-task/src/main/java/com/dkha/task/service/impl/ApiDeelServiceImpl.java b/face-task/src/main/java/com/dkha/task/service/impl/ApiDeelServiceImpl.java new file mode 100644 index 0000000..a42932e --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/service/impl/ApiDeelServiceImpl.java @@ -0,0 +1,302 @@ +package com.dkha.task.service.impl; + +import com.alibaba.fastjson.JSONObject; +import com.dkha.common.enums.ApiUrlEnum; +import com.dkha.common.fileupload.MinioUtil; +import com.dkha.common.http.HttpUtil; +import com.dkha.common.modules.vo.ReturnVO; +import com.dkha.common.modules.vo.camera.BayOnetCameraVO; +import com.dkha.common.modules.vo.camera.PeopleVO; +import com.dkha.common.modules.vo.dto.FaceLibraryVO; +import com.dkha.common.modules.vo.face.*; +import com.dkha.common.modules.vo.warning.BayoneReturnListVO; +import com.dkha.common.redis.RedisKeys; +import com.dkha.common.redis.RedisUtils; +import com.dkha.common.util.*; +import com.dkha.task.comm.TimerData; +import com.dkha.task.service.ApiDeelService; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.awt.image.BufferedImage; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: ApiDeelServiceImpl + * @Package com.dkha.task.service.impl + * @author: panhui + * @date: 2020/1/9 17:02 + * @Copyright: 成都电科慧安 + */ +@Component +@Slf4j +public class ApiDeelServiceImpl implements ApiDeelService { + + @Value("${api.server.prefix}") + private String link; + + @Autowired + private HttpUtil httpUtil; + + @Autowired + private Gson gson; + + @Override + public FaceLibraryVO addLib(FaceLibraryVO faceLibraryVO) { + try { + log.info("参数:==============================: " + faceLibraryVO.toString() +" json " + JSONObject.toJSONString(faceLibraryVO)); + ReturnVO faceLibrary1 = (ReturnVO) httpUtil.post(link + ApiUrlEnum.FACELIB_POSTURL.getUrl(), faceLibraryVO, ReturnVO.class); + /**调用API*/ + String json = gson.toJson(faceLibrary1.getData()); + return gson.fromJson(json, FaceLibraryVO.class); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + @Value("${face.bayonet-url}") + private String bayonetUrl; + + + @Autowired + private RedisUtils redisUtils; + + + @Autowired + private MinioUtil minioUtil; + + @Value("${face.minScore}") + private Double minScore; + + @Value("${face.maxRetNb}") + private Integer maxRetNb; + + /** + * 轨迹中人脸比对和数据存储 + * + * @param cameraId 摄像头id + * @param time 时间 + * @param bayonetNum 检索的数据 + * @param libId 关联人脸库的id + * @return + */ + @Override + public void getApi(String cameraId, String time, Long bayonetNum, String libId) { + +// bayonetNum +// log.error("bayonetNum:{}=={}",bayonetNum,libId); + AtomicReference nowNum = new AtomicReference<>(bayonetNum.longValue()); + //先求总数,判断总数 + String apiUrl = bayonetUrl + "/" + cameraId + "/" + 1; + BayoneReturnListVO bayoneReturnListVO = getRecord(apiUrl); + if (UtilValidate.isEmpty(bayoneReturnListVO)) { + return; + } + //判断数据是否系统能处理的数量 + Long resNum = bayoneReturnListVO.getToDaySnapShot() - bayonetNum; + if (resNum.intValue() == 0) { + return; + } + //如果条数大于50 就分批次处理。每次最大处理50/100根据系统情况来定 + if (resNum.intValue() <= TimerData.SYSTEM_DEEL_NUM.intValue()) { + //进行数据处理然后设置redis中的数量为今日数量 + String apiIfUrl = bayonetUrl + "/" + cameraId + "/" + resNum; + BayoneReturnListVO newBayone = getRecord(apiIfUrl); + if (UtilValidate.isEmpty(newBayone)) { + //如果异常可能会一直操作这几个数据,正常情况不会发生 下面如果异常就会自动跳过当前数据 +// setNum(time,cameraId,bayoneReturnListVO.getToDaySnapShot()); 暂时不需要 + return; + } + List myRecords = gson.fromJson(gson.toJson(newBayone.getResult()), new TypeToken>() { + }.getType()); + if (UtilValidate.isEmpty(myRecords)) { + return; + } + myRecords.forEach(e -> + { + nowNum.set(nowNum.get() + 1); + //当前人脸的数据 + if (e.getFaces().size() > 0) { + //需要绑定的人物基本信息 + PeopleVO peopleVO = new PeopleVO(); + peopleVO.setBgUrl(e.getFaceBgUrl()); + peopleVO.setEsId(e.getAlarmId()); + peopleVO.setTimestamp(TimeUtil.exchangeTime(e.getDate())); + peopleVO.setCameraId(cameraId); + ApiFaceVO apiFaceVO = e.getFaces().get(0); + peopleVO.setPosition(apiFaceVO.getFaceRect()); + peopleVO.setFeatureVO(apiFaceVO.getFeature()); + peopleVO.setTime(e.getDate()); + try { + try { + BufferedImage bufferedImage = Base64ImageUtils.urlToBufferImage(new URL(e.getFaceBgUrl())); + InputStream inputStream = Base64ImageUtils.encodeHeadImage(bufferedImage, apiFaceVO.getFaceRect()); + String fileName = "camera/" + this.generateFileName(e.getFaceBgUrl()); + JSONObject map = minioUtil.uploadFile(inputStream, fileName, null); + if (!map.getString("flag").equals("0")) { + return; + } + peopleVO.setFaceUrl(map.get("url").toString()); + }catch (Exception ex){ + return; + } + //将人脸的数据进行入库比对和数据redis绑定 +// { "url":"http://10.51.10.201:88/mytest/1.jpg", "libraryIds": [ "1210094601505505282" ], "minScore": 0.9 , "page": {"pageSize":1} } + //获取所有摄像头库的列表 + ApiFaceSearchVO apiFaceSearchVO = new ApiFaceSearchVO(); + apiFaceSearchVO.setUrl(peopleVO.getFaceUrl()); + apiFaceSearchVO.setLibraryIds(Arrays.asList(libId)); + apiFaceSearchVO.setMinScore(minScore); + PageVO pageVO = new PageVO(); + pageVO.setPageSize(1); + apiFaceSearchVO.setPageVO(pageVO); +// log.error("检索参数:{}",gson.toJson(apiFaceSearchVO)); + String json = UrlUtil.postApiData(link + ApiUrlEnum.FACE_SEARCH_LIB.getUrl(), apiFaceSearchVO, httpUtil, gson); + if (UtilValidate.isEmpty(json)) { + return; + } +// log.error("检索结果:{}",json); + ApiFaceSearchReturnVO apiFaceSearchReturnVO = gson.fromJson(json, ApiFaceSearchReturnVO.class); + if (UtilValidate.isEmpty(apiFaceSearchReturnVO) || UtilValidate.isEmpty(apiFaceSearchReturnVO.getFaces())) { + return; + } + //表示没有比分需要将人脸数据进行入库 + if (UtilValidate.isEmpty(apiFaceSearchReturnVO.getFaces().get(0).getFaceList())) { + //创建人脸到当前库中,同时绑定数据 + ImagesVO imageVO = new ImagesVO(); + imageVO.setUrl(peopleVO.getFaceUrl()); + imageVO.setLibraryId(libId); +// log.error("入库参数{}",gson.toJson(imageVO)); + String addJson = UrlUtil.postApiData(link + ApiUrlEnum.FACE_POSTURL.getUrl(), imageVO, httpUtil, gson); + if (UtilValidate.isEmpty(addJson)) { + return; + } + ImageReturnVO imageReturnVO = gson.fromJson(addJson, ImageReturnVO.class); +// log.error("添加库返回的数据"+addJson); + peopleVO.setFaceId(imageReturnVO.getFaceId()); //入库成功后设置faceid +// {"faceId":"1216603167224016897","libraryId":"1216584625997000705","faceRect":{"x":0,"y":0,"w":76,"h":100},"face":{"url":"http://10.51.10.201:9001/middleware/20200113/camera/1578895730480-2.jpg","faceUrl":"http://10.51.10.201:9001/middleware/173/ef7ec4b8b0214a7b9fe3648d3808982e.jpg"}} + } else { + //比中返回数据的id + peopleVO.setFaceId(apiFaceSearchReturnVO.getFaces().get(0).getFaceList().get(0).getFaceId()); + peopleVO.setScore(apiFaceSearchReturnVO.getFaces().get(0).getFaceList().get(0).getHitSimilarity()); + //将库中的id和数据进行绑定 +// log.error("已经在库里面{}",apiFaceSearchReturnVO.getFaces().get(0).getFaceList().get(0).getFaceId()); + } + dataBing(time, cameraId, peopleVO); + //如果在库中则绑定到redis中 + //不在库里面则新创建一个绑定的人物信息 + //检索库然后分组库 + } catch (Exception e1) { + e1.printStackTrace(); + return; + } + try { + Thread.sleep(50); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + } + setNum(time, cameraId, nowNum.get()); + }); + //对数据条数进行赋值 +// bayoneReturnListVO.getToDaySnapShot() + } + setNum(time, cameraId, bayoneReturnListVO.getToDaySnapShot()); + } + + + /** + * 对数据进行绑定 + * + * @param time + * @param cameraId + * @param peopleVO + */ + private void dataBing(String time, String cameraId, PeopleVO peopleVO) { +// log.error("绑定数据的时候{}",gson.toJson(peopleVO)); + if (redisUtils.exists(RedisKeys.getCameraByTrack(time, cameraId))) { + BayOnetCameraVO bayOnetCameraVO = gson.fromJson(redisUtils.get(RedisKeys.getCameraByTrack(time, cameraId)).toString(), BayOnetCameraVO.class); + List myList = new ArrayList<>(); + if (redisUtils.exists(RedisKeys.getCameraByFaceId(time, cameraId, peopleVO.getFaceId()))) { + List peopleVOList = gson.fromJson(redisUtils.get(RedisKeys.getCameraByFaceId(time, cameraId, peopleVO.getFaceId())).toString(), new TypeToken>() { + }.getType()); + myList.addAll(peopleVOList); + } + else + { +//// 将数据绑定在里面 + +// if(UtilValidate.isEmpty(bayOnetCameraVO.getPeopleVO())) +// { +// bayOnetCameraVO.setPeopleVO(peopleVO); +// } + bayOnetCameraVO.getFeatIds().add(peopleVO.getFaceId()); + redisUtils.set(RedisKeys.getCameraByTrack(time, cameraId),gson.toJson(bayOnetCameraVO)); + } + myList.add(peopleVO); + redisUtils.set(RedisKeys.getCameraByFaceId(time, cameraId, peopleVO.getFaceId()), myList); + } + } + + /** + * 生成唯一文件名 + * + * @param originFileName + * @return + */ + private String generateFileName(String originFileName) { + // todo 迁移到资源文件中 + //当前时间 + long timeMillis = System.currentTimeMillis(); + int shortUUID = IntUUID.getShortUUID(); + String[] originalFileNameCompose = originFileName.split("\\."); + //获取原文件后缀 + String originalFileNameSuffix = originalFileNameCompose[originalFileNameCompose.length - 1]; + return timeMillis + "-" + shortUUID + "." + originalFileNameSuffix; + } + + /** + * 设置redis的num + * + * @param time + * @param cameraId + * @param deelNum + */ + private void setNum(String time, String cameraId, Long deelNum) { + if (redisUtils.exists(RedisKeys.getCameraByTrack(time, cameraId))) { + BayOnetCameraVO bayOnetCameraVO = gson.fromJson(redisUtils.get(RedisKeys.getCameraByTrack(time, cameraId)).toString(), BayOnetCameraVO.class); + bayOnetCameraVO.setWarningNum(deelNum); + redisUtils.set(RedisKeys.getCameraByTrack(time, cameraId), gson.toJson(bayOnetCameraVO)); + } + } + + + private BayoneReturnListVO getRecord(String url) { + String jsonData = UrlUtil.getData(url, httpUtil, gson); + if (UtilValidate.isEmpty(jsonData)) { + return null; + } + if (UtilValidate.isNotEmpty(jsonData)) { +// //如果本次数据异常就暂时不继续处理了 + try { + return gson.fromJson(jsonData, BayoneReturnListVO.class); + } catch (Exception ex) { + return null; + } + } + return null; + } +} diff --git a/face-task/src/main/java/com/dkha/task/service/impl/AsyncServiceImpl.java b/face-task/src/main/java/com/dkha/task/service/impl/AsyncServiceImpl.java new file mode 100644 index 0000000..37f3079 --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/service/impl/AsyncServiceImpl.java @@ -0,0 +1,190 @@ +package com.dkha.task.service.impl; + +import com.dkha.common.modules.vo.camera.BayOnetCameraVO; +import com.dkha.common.modules.vo.camera.PeopleVO; +import com.dkha.common.modules.vo.face.ApiAlarmVO; +import com.dkha.common.redis.RedisKeys; +import com.dkha.common.redis.RedisUtils; +import com.dkha.common.util.TimeUtil; +import com.dkha.common.util.UtilValidate; +import com.dkha.task.comm.TimerData; +import com.dkha.task.modual.entity.FaceTrackEntity; +import com.dkha.task.service.ApiDeelService; +import com.dkha.task.service.FaceTrackService; +import com.dkha.task.service.WebSocketContral; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.TimeoutUtils; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: AsyncContral + * @Package com.dkha.task.contral + * @author: panhui + * @date: 2020/1/3 17:34 + * @Copyright: 成都电科慧安 + */ +@Component +@Slf4j +public class AsyncServiceImpl { + + + @Autowired + private WebSocketContral webSocketContral; + + /** + * 卡口信息 + * + * @return + */ +// @Async 多綫程抛出異常 + public void bayonetInfo(String a, String b) { + webSocketContral.sendMessage(a, b); +// System.out.println(a+"-----"+b); +// try { +// Thread.sleep(10000); +// }catch (Exception e){} +// return null; + } + + @Autowired + private Gson gson; + + @Autowired + private RedisUtils redisUtils; + + @Autowired + private ApiDeelService apiDeelService; + + @Autowired + private FaceTrackService faceTrackService; + @Value("${face.minScore}") + private Double minScore; + + /** + * 轨迹分析统计每个摄像头的分组信息 + */ + @Async + public void trackByCamera(String time, String cameraId) { + Long deelNum = 0L; + try { + while (true) { + String nowTime = new SimpleDateFormat("yyyy-MM-dd").format(System.currentTimeMillis()); +// log.error("綫程任務{},{},{}",nowTime,time,cameraId); + if (!nowTime.equals(time)) { + //后续将redis里面的数据存到数据库做多时间的轨迹分析 + if (redisUtils.exists(RedisKeys.getCameraByTrack(time, cameraId))) { + BayOnetCameraVO bayOnetCameraVO = gson.fromJson(redisUtils.get(RedisKeys.getCameraByTrack(time, cameraId)).toString(), BayOnetCameraVO.class); + try { + List myList = new ArrayList<>(); + for (String faceId : bayOnetCameraVO.getFeatIds()) { + if (redisUtils.exists(RedisKeys.getCameraByFaceId(time, cameraId, faceId))) { + List peopleVOList = gson.fromJson(redisUtils.get(RedisKeys.getCameraByFaceId(time, cameraId, faceId)).toString(), new TypeToken>() { + }.getType()); + if (UtilValidate.isNotEmpty(peopleVOList)) { + FaceTrackEntity faceTrackEntity = new FaceTrackEntity(); + faceTrackEntity.setIdPortrait(new Long(faceId)); + faceTrackEntity.setIdFaceCamera(new Long(bayOnetCameraVO.getCameraId())); + faceTrackEntity.setIdFactory(new Long(bayOnetCameraVO.getAssociationLibraryId())); + faceTrackEntity.setCharacterData(gson.toJson(peopleVOList.get(0))); + faceTrackEntity.setLinkedData(gson.toJson(peopleVOList)); + faceTrackEntity.setPacketTime(time); + faceTrackEntity.setTrajectoryThreshold(minScore); + myList.add(faceTrackEntity); + } + } + } + if (UtilValidate.isNotEmpty(myList)) { + faceTrackService.saveBatch(myList); + } + }catch (Exception e){} + deelLastDayTask(time, cameraId, bayOnetCameraVO); + } else { + deelTaskState(time, cameraId, deelNum); + } + //后续可以增加一个任务根据将数据库中本月的人物的数据进行人物关联 + //清理掉没用的记录 + break; + } + //使用过期时间来做是否异常检验,因为可能会遇到这边还没处理结束,定时器那边认为当前方法结束的情况 + //30秒过期 + if (!redisUtils.exists(RedisKeys.getCameraByExpired(time, cameraId))) { + redisUtils.set(RedisKeys.getCameraByExpired(time, cameraId), "运行", TimerData.expireTime); + } else { + redisUtils.expire(RedisKeys.getCameraByExpired(time, cameraId), TimerData.expireTime); + } + //检索当前摄像头下所有预警的信息,处理的数据数量存入redis中防止程序重启后又要重新操作了 +// System.out.println("xxxxxxxxxxxx::"+redisUtils.get(RedisKeys.getCameraByTrack(time, cameraId)).toString()); + if(redisUtils.exists(RedisKeys.getCameraByTrack(time, cameraId))) + { + BayOnetCameraVO bayOnetCameraVO = gson.fromJson(redisUtils.get(RedisKeys.getCameraByTrack(time, cameraId)).toString(), BayOnetCameraVO.class); + deelNum = bayOnetCameraVO.getWarningNum(); + apiDeelService.getApi(cameraId, time, deelNum, bayOnetCameraVO.getAssociationLibraryId()); + } + try { + Thread.sleep(4000); + } catch (InterruptedException e) { + } + } + } catch (Exception e) { + deelTaskState(time, cameraId, deelNum); + } + } + + /** + * 时间过期清理多余的redis数据 + * + * @param time + * @param cameraId + * @param bayOnetCameraVO + */ + private void deelLastDayTask(String time, String cameraId, BayOnetCameraVO bayOnetCameraVO) { + try { + log.error("清理数据{},{}",time,cameraId); + if(UtilValidate.isNotEmpty(bayOnetCameraVO.getFeatIds())) + { + bayOnetCameraVO.getFeatIds().forEach(e -> + { + if (redisUtils.exists(RedisKeys.getCameraByFaceId(time, cameraId, e))) { + redisUtils.delete(RedisKeys.getCameraByFaceId(time, cameraId, e)); + } + }); + } + if (redisUtils.exists(RedisKeys.getCameraByTrack(time, cameraId))) { + redisUtils.delete(RedisKeys.getCameraByTrack(time, cameraId)); + } + } catch (Exception e) { + log.error("删除redis中过期数据异常{}", e.getMessage()); + } + } + + /** + * 处理任务状态和当前检测数量 + * + * @param time + * @param cameraId + * @param deelNum + */ + private void deelTaskState(String time, String cameraId, Long deelNum) { + if (redisUtils.exists(RedisKeys.getCameraByTrack(time, cameraId))) { + BayOnetCameraVO bayOnetCameraVO = gson.fromJson(redisUtils.get(RedisKeys.getCameraByTrack(time, cameraId)).toString(), BayOnetCameraVO.class); + bayOnetCameraVO.setWarningNum(deelNum); + redisUtils.set(RedisKeys.getCameraByTrack(time, cameraId), gson.toJson(bayOnetCameraVO)); + } + if (redisUtils.exists(RedisKeys.getCameraByExpired(time, cameraId))) { + redisUtils.delete(RedisKeys.getCameraByExpired(time, cameraId)); + } + } +} diff --git a/face-task/src/main/java/com/dkha/task/service/impl/ControlBayonetMidServiceImpl.java b/face-task/src/main/java/com/dkha/task/service/impl/ControlBayonetMidServiceImpl.java new file mode 100644 index 0000000..2dd2b19 --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/service/impl/ControlBayonetMidServiceImpl.java @@ -0,0 +1,67 @@ +package com.dkha.task.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.dkha.common.modules.vo.camera.CameraInfoVO; +import com.dkha.task.modual.entity.ControlBayonetMid; +import com.dkha.task.modual.entity.FaceCamera; +import com.dkha.task.modual.mapper.ControlBayonetMidMapper; +import com.dkha.task.service.IControlBayonetMidService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + *

+ * 布控和摄像头中间表 服务实现类 + *

+ * + * @author Spring + * @since 2019-12-09 + */ +@Service +public class ControlBayonetMidServiceImpl extends ServiceImpl implements IControlBayonetMidService { + + @Autowired + ControlBayonetMidMapper controlBayonetMidMapper; + + @Override + public Integer deletetaskandcarmerbytaskid(String taskID) { + return controlBayonetMidMapper.deletetaskandcarmerbytaskid(taskID); + } + + @Override + public long selectexistByCarmeID(String idcamera) { + long rs = controlBayonetMidMapper.selectexistByCarmeID(idcamera); + return rs; + } + + @Override + public Integer updateCarmerValidaStateByTaskID(String taskID, String State, String UpdateBy) { + return controlBayonetMidMapper.updateCarmerValidaStateByTaskID(taskID, State, UpdateBy); + } + + @Override + public List selectFaceCameraBytaskID(String taskid) { + return controlBayonetMidMapper.selectFaceCameraBytaskID(taskid); + } + + @Override + public List selectCameraByTask() { + return controlBayonetMidMapper.selectFaceCameraBytask(); + } + + @Override + public ControlBayonetMid selectFaceCameraByTime() { + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("is_valid", "Y").orderByDesc("create_time").last("limit 1"); + return controlBayonetMidMapper.selectOne(queryWrapper); + } + + @Override + public int getControlByRegion(long regionId) { + return controlBayonetMidMapper.getControlByRegion(regionId); + } +} diff --git a/face-task/src/main/java/com/dkha/task/service/impl/FaceTrackServiceImpl.java b/face-task/src/main/java/com/dkha/task/service/impl/FaceTrackServiceImpl.java new file mode 100644 index 0000000..3733575 --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/service/impl/FaceTrackServiceImpl.java @@ -0,0 +1,71 @@ +package com.dkha.task.service.impl; + + + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.dkha.common.exception.DkException; +import com.dkha.task.modual.entity.FaceTrackEntity; +import com.dkha.task.modual.mapper.FaceTrackMapper; +import com.dkha.task.modual.vo.FaceTrackVO; +import com.dkha.task.service.FaceTrackService; + + +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + + +/** + * + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 2020-01-10 + */ +@Service +public class FaceTrackServiceImpl extends ServiceImpl implements FaceTrackService { + + @Resource + private FaceTrackMapper faceTrackMapper; + @Override + public int addFaceTrackEntity(FaceTrackEntity faceTrackEntity) { + int count; + try{ + count = faceTrackMapper.insert(faceTrackEntity); + }catch (Exception e){ + throw new DkException("新增失败"); + } + return count; + } + + /** + *根据摄像头和分组时间查询 + * @param idFaceCamera + * @param packetTime + * @return + */ + @Override + public List querByidCameraAndTime(Long idFaceCamera, String packetTime) { + return faceTrackMapper.querByidCameraAndTime(idFaceCamera,packetTime); + } + + /** + *根据摄像头Id和开始,结束时间,人脸ID + * @param faceTrackVO + * @return + */ + @Override + public List queryByidCamerAndFaceId(FaceTrackVO faceTrackVO) { + return faceTrackMapper.queryByidCamerAndFaceId(faceTrackVO); + } + + /** + *根据图片路径和开始,结束时间 + * @param faceTrackVO + * @return + */ + @Override + public List queryByurlAndTime(FaceTrackVO faceTrackVO) { + return faceTrackMapper.queryByurlAndTime(faceTrackVO); + } +} \ No newline at end of file diff --git a/face-task/src/main/java/com/dkha/task/util/PeopleComparableUitl.java b/face-task/src/main/java/com/dkha/task/util/PeopleComparableUitl.java new file mode 100644 index 0000000..448e4f4 --- /dev/null +++ b/face-task/src/main/java/com/dkha/task/util/PeopleComparableUitl.java @@ -0,0 +1,43 @@ +package com.dkha.task.util; + +import com.dkha.common.modules.vo.camera.PeopleVO; +import com.dkha.common.modules.vo.face.FeatureVO; +import com.dkha.common.modules.vo.position.PositionVO; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @version V1.0 + * @Description: TODO(please write your description) + * All rights 成都电科慧安 + * @Title: PeopleComparableUitl + * @Package com.dkha.task.util + * @author: panhui + * @date: 2020/1/14 16:09 + * @Copyright: 成都电科慧安 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PeopleComparableUitl implements Comparable{ + private String esId; + private String faceUrl; + private String bgUrl; + private PositionVO position; + private Long timestamp; + private String time; + private Double score; + private FeatureVO featureVO; + private String faceId; + + @Override + public int compareTo(PeopleComparableUitl peopleVO) { + + if(this.timestamp.intValue()!=peopleVO.getTimestamp().intValue()) + { + return (this.timestamp.intValue()-peopleVO.getTimestamp().intValue()); + } + return 0; + } +} diff --git a/face-task/src/main/resources/application-dev.yml b/face-task/src/main/resources/application-dev.yml new file mode 100644 index 0000000..37b665e --- /dev/null +++ b/face-task/src/main/resources/application-dev.yml @@ -0,0 +1,108 @@ +server: + port: 1993 + servlet: + context-path: /task +spring: + datasource: + druid: + #MySQL + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql://192.168.1.127:3306/face_application?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai + username: root + password: Dkha123 + initial-size: 10 + max-active: 100 + min-idle: 10 + max-wait: 6000 + pool-prepared-statements: true + max-pool-prepared-statement-per-connection-size: 20 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + #Oracle需要打开注释 + #validation-query: SELECT 1 FROM DUAL + test-while-idle: true + test-on-borrow: false + test-on-return: false + stat-view-servlet: + enabled: true + url-pattern: /druid/* + login-username: admin + login-password: admin + filter: + stat: + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: false + wall: + config: + multi-statement-allow: true + redis: + database: 0 + host: 192.168.1.127 + port: 6379 + password: Dkha123 # 密码(默认为空) + timeout: 6000ms # 连接超时时长(毫秒) + jedis: + pool: + max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) + max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-idle: 10 # 连接池中的最大空闲连接 + min-idle: 5 # 连接池中的最小空闲连接 + +#mybatis +mybatis-plus: + mapper-locations: classpath:/mybatis/mapper/**/*.xml,classpath:/mappers/*.xml + #实体扫描,多个package用逗号或者分号分隔 + typeAliasesPackage: com.dkha.server.system.modules + global-config: + #数据库相关配置 + db-config: + #主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID"; + id-type: ID_WORKER + # 如果入库为空值,则忽略掉控空值 + insert-strategy: not_empty + update-strategy: not_empty + select-strategy: not_empty + banner: false + #原生配置 + configuration: + #是否开启自动驼峰命名规则(camel case)映射 + map-underscore-to-camel-case: true + #全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存,默认为 true + cache-enabled: false + call-setters-on-nulls: true + jdbc-type-for-null: 'null' + +# 用于控制swagger是否显示 +swagger: + show: true +face: + warning-url: http://192.168.1.127:8889/face/warning/alarm + bayonet-url: http://192.168.1.127:8889/face/warning/todayBayonetBySize + #用于轨迹中比对最小比中分值 + minScore: 0.8 + #返回一条比中数据即可 + maxRetNb: 1 + +#人脸API统一请求地址定义 +api: + server: + prefix: http://192.168.1.127:8013/dkha/ + #人脸检索最大返回值 + max: + result: 100 + #人脸分组最大支持图片数量 + group: + max: 30 + # 人脸分组最少图片数量 + min: 2 + # 图片支持格式 + picture: + type: (png|jpg|jpeg) + +#minio 配置 +minio: + url: http://192.168.1.127:9000 + accessKey: admin + secretKey: Dkha123. + bucketName: middleware diff --git a/face-task/src/main/resources/application-prod.yml b/face-task/src/main/resources/application-prod.yml new file mode 100644 index 0000000..b8fc51a --- /dev/null +++ b/face-task/src/main/resources/application-prod.yml @@ -0,0 +1,108 @@ +server: + port: 1993 + servlet: + context-path: /task +spring: + datasource: + druid: + #MySQL + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql://192.168.1.127:3306/face_application?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai + username: root + password: Dkha123 + initial-size: 10 + max-active: 100 + min-idle: 10 + max-wait: 6000 + pool-prepared-statements: true + max-pool-prepared-statement-per-connection-size: 20 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + #Oracle需要打开注释 + #validation-query: SELECT 1 FROM DUAL + test-while-idle: true + test-on-borrow: false + test-on-return: false + stat-view-servlet: + enabled: true + url-pattern: /druid/* + login-username: admin + login-password: admin + filter: + stat: + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: false + wall: + config: + multi-statement-allow: true + redis: + database: 0 + host: 192.168.1.127 + port: 6379 + password: Dkha123 # 密码(默认为空) + timeout: 6000ms # 连接超时时长(毫秒) + jedis: + pool: + max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) + max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-idle: 10 # 连接池中的最大空闲连接 + min-idle: 5 # 连接池中的最小空闲连接 + +#mybatis +mybatis-plus: + mapper-locations: classpath:/mybatis/mapper/**/*.xml,classpath:/mappers/*.xml + #实体扫描,多个package用逗号或者分号分隔 + typeAliasesPackage: com.dkha.server.system.modules + global-config: + #数据库相关配置 + db-config: + #主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID"; + id-type: ID_WORKER + # 如果入库为空值,则忽略掉控空值 + insert-strategy: not_empty + update-strategy: not_empty + select-strategy: not_empty + banner: false + #原生配置 + configuration: + #是否开启自动驼峰命名规则(camel case)映射 + map-underscore-to-camel-case: true + #全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存,默认为 true + cache-enabled: false + call-setters-on-nulls: true + jdbc-type-for-null: 'null' + +# 用于控制swagger是否显示 +swagger: + show: true +face: + warning-url: http://127.0.0.1:8889/face/warning/alarm + bayonet-url: http://127.0.0.1:8889/face/warning/todayBayonetBySize + #用于轨迹中比对最小比中分值 + minScore: 0.8 + #返回一条比中数据即可 + maxRetNb: 1 + +#人脸API统一请求地址定义 +api: + server: + prefix: http://127.0.0.1:8013/dkha/ + #人脸检索最大返回值 + max: + result: 100 + #人脸分组最大支持图片数量 + group: + max: 30 + # 人脸分组最少图片数量 + min: 2 + # 图片支持格式 + picture: + type: (png|jpg|jpeg) + +#minio 配置 +minio: + url: http://192.168.1.127:9000 + accessKey: admin + secretKey: Dkha123. + bucketName: middleware diff --git a/face-task/src/main/resources/application-test.yml b/face-task/src/main/resources/application-test.yml new file mode 100644 index 0000000..5c2c3e1 --- /dev/null +++ b/face-task/src/main/resources/application-test.yml @@ -0,0 +1,108 @@ +server: + port: 1993 + servlet: + context-path: /task +spring: + datasource: + druid: + #MySQL + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql://192.168.1.122:3306/face_application?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai + username: root + password: Dkha123 + initial-size: 10 + max-active: 100 + min-idle: 10 + max-wait: 6000 + pool-prepared-statements: true + max-pool-prepared-statement-per-connection-size: 20 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + #Oracle需要打开注释 + #validation-query: SELECT 1 FROM DUAL + test-while-idle: true + test-on-borrow: false + test-on-return: false + stat-view-servlet: + enabled: true + url-pattern: /druid/* + login-username: admin + login-password: admin + filter: + stat: + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: false + wall: + config: + multi-statement-allow: true + redis: + database: 0 + host: 192.168.1.122 + port: 6379 + password: Dkha123 # 密码(默认为空) + timeout: 6000ms # 连接超时时长(毫秒) + jedis: + pool: + max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) + max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-idle: 10 # 连接池中的最大空闲连接 + min-idle: 5 # 连接池中的最小空闲连接 + +#mybatis +mybatis-plus: + mapper-locations: classpath:/mybatis/mapper/**/*.xml,classpath:/mappers/*.xml + #实体扫描,多个package用逗号或者分号分隔 + typeAliasesPackage: com.dkha.server.system.modules + global-config: + #数据库相关配置 + db-config: + #主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID"; + id-type: ID_WORKER + # 如果入库为空值,则忽略掉控空值 + insert-strategy: not_empty + update-strategy: not_empty + select-strategy: not_empty + banner: false + #原生配置 + configuration: + #是否开启自动驼峰命名规则(camel case)映射 + map-underscore-to-camel-case: true + #全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存,默认为 true + cache-enabled: false + call-setters-on-nulls: true + jdbc-type-for-null: 'null' + +# 用于控制swagger是否显示 +swagger: + show: true +face: + warning-url: http://192.168.1.122:8889/face/warning/alarm + bayonet-url: http://192.168.1.122:8889/face/warning/todayBayonetBySize + #用于轨迹中比对最小比中分值 + minScore: 0.8 + #返回一条比中数据即可 + maxRetNb: 1 + +#人脸API统一请求地址定义 +api: + server: + prefix: http://192.168.1.122:8013/dkha/ + #人脸检索最大返回值 + max: + result: 100 + #人脸分组最大支持图片数量 + group: + max: 30 + # 人脸分组最少图片数量 + min: 2 + # 图片支持格式 + picture: + type: (png|jpg|jpeg) + +#minio 配置 +minio: + url: http://192.168.1.122:9000 + accessKey: admin + secretKey: Dkha123. + bucketName: middleware diff --git a/face-task/src/main/resources/application.yml b/face-task/src/main/resources/application.yml new file mode 100644 index 0000000..c688559 --- /dev/null +++ b/face-task/src/main/resources/application.yml @@ -0,0 +1,4 @@ +spring: + # 环境 dev|test|prod + profiles: + active: dev diff --git a/face-task/src/main/resources/logback-spring.xml b/face-task/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..5277d76 --- /dev/null +++ b/face-task/src/main/resources/logback-spring.xml @@ -0,0 +1,59 @@ + + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + /mnt/appSystems/logs/${app_name}/%d{yyyy-MM, aux}/trace.%d{yyyy-MM-dd}.%i.log + + 500MB + + 10 + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + + + + + + /appSystems/logs/error.%d{yyyy-MM-dd}.%i.log + + /mnt/appSystems/logs/${app_name}/%d{yyyy-MM, aux}/error.%d{yyyy-MM-dd}.%i.log + + 500MB + + 10 + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + + + ERROR + ACCEPT + DENY + + + + + + + + + + + \ No newline at end of file diff --git a/face-task/src/main/resources/mybatis/mapper/ControlBayonetMidMapper.xml b/face-task/src/main/resources/mybatis/mapper/ControlBayonetMidMapper.xml new file mode 100644 index 0000000..1b45829 --- /dev/null +++ b/face-task/src/main/resources/mybatis/mapper/ControlBayonetMidMapper.xml @@ -0,0 +1,33 @@ + + + + + + update control_bayonet_mid set is_valid=#{State},update_time=now(),update_by=#{UpdateBy} where id_control_task=#{taskID} + + + + DELETE FROM control_bayonet_mid WHERE id_control_task =#{taskID} + + + + + + + + diff --git a/face-task/src/main/resources/mybatis/mapper/FaceTrackMapper.xml b/face-task/src/main/resources/mybatis/mapper/FaceTrackMapper.xml new file mode 100644 index 0000000..b87da89 --- /dev/null +++ b/face-task/src/main/resources/mybatis/mapper/FaceTrackMapper.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/face-task/src/main/resources/mybatis/mapper/sys/SysUserTokenDao.xml b/face-task/src/main/resources/mybatis/mapper/sys/SysUserTokenDao.xml new file mode 100644 index 0000000..331f6ab --- /dev/null +++ b/face-task/src/main/resources/mybatis/mapper/sys/SysUserTokenDao.xml @@ -0,0 +1,15 @@ + + + + + + id,user_id,token,expire_date,update_date,create_date + + + + + update sys_user_token set token = #{token} where user_id = #{userId} + + \ No newline at end of file diff --git a/face-task/src/main/resources/mybatis/mybatis.cfg.xml b/face-task/src/main/resources/mybatis/mybatis.cfg.xml new file mode 100644 index 0000000..bcdf41a --- /dev/null +++ b/face-task/src/main/resources/mybatis/mybatis.cfg.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/face-task/src/main/resources/static/images/Ink_Note.ico b/face-task/src/main/resources/static/images/Ink_Note.ico new file mode 100644 index 0000000000000000000000000000000000000000..c6824f867d955937c7600a2093af65be956181fe GIT binary patch literal 30139 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¬$W7%@#tJzre?KXpmFRhh)Zjfq&NLg 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 literal 0 HcmV?d00001 diff --git a/face-task/src/main/resources/static/images/bg_blue.png b/face-task/src/main/resources/static/images/bg_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..d9ae250bb91d8fd304dee5d0de6c3b6b73dad937 GIT binary patch literal 1587 zcmeAS@N?(olHy`uVBq!ia0vp^cY(N&gAGUqN-gULQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS=07?{;ELn2Bde0{8v^K*7iAWdWaj57fJ{tG z$}cUkRRX#c;)UD-xUqS~&|m@vn0`fKfxe-h0mw@*g}%P{mFDKcRTq~8r6Sym)!^cg z%7Rq=pw#00(xPNw#HA^NtSYc_E=o--$uA1Y&(DE{Vn9ZINq%ugeu09sGbq$76*R&# z^HTE5i#5S|e0{Av^NLFn^O93NU2K(rrs!p6rdU~6I2yWGIGYIiTm>a|Ny5uL9=BDPA!1Sgd^jhH53rY^T1wfl!Qj0RnQd8WD@^cly-nPob z?G{s<=0WwQ;C71{PQCg-$LND17b&t~LckORV#1RykONQrsd>N@Uj$6rNp6P(7#Nrq zd%8G=RNQ)VbAPsQqRfGZyN_h_CUr}FWDoJ0_~?PkitgDK9DM(n|8d8%3Ni%=#=Lo? zq4Z8xXYMY}pbMTNJwYtqf@|!ZG8SK2_SM!??4?5HyP}ED8}%*MmHd>G|D@Kr`f8R* z_^wi|u0^{O^;#_j824V{FqVIIZ0gtB?ciDUl^o;KM!EIa1Pe$z_B>O@#z$ppiTjV~NZ8j!Gp zl|u;v3&<*1A#ewufGh&Luy^nw@FHdxb_Bl2xQH2!8(%O0t$|^3trL*_qPVNg)PZeV zl)cr(v$xrnw`zZsEDg97 z-TBDrWY>ap_fyY~-Fn`dfBwC%X`F2&S9#ROh02Rh&Og_(@QNpWfy_@4jP2)9H)H zcNyecU0kcq+ICYo&7OY{q)eg2Y*KAE$;NQ@4*uKP9&OxL?ckPQAWaw^_rv z&*$6>tNxa=>zDoe49n|%OT->k&T^S@L}kZ8wOt3f^1sO+5}xzogn`Y$&OV;QP$ut$ z*f4_`4^{8aX+1GX{=($wjStw4_thCKc>nLuoDbLcMoApBjGHv+X<15B@g9}OAGYmQ dTVBU)z`$_yz0!5|6c$i1?&<31vd$@?2>`R-N_+qS literal 0 HcmV?d00001 diff --git a/face-task/src/main/resources/static/images/bg_green.png b/face-task/src/main/resources/static/images/bg_green.png new file mode 100644 index 0000000000000000000000000000000000000000..4acb45d23ed98e3fa6ab214e8f717fc6d19845d9 GIT binary patch literal 1584 zcmeAS@N?(olHy`uVBq!ia0vp^cY(N&gAGUqN-gULQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS=07?{;ELn2Bde0{8v^K*7iAWdWaj57fJ{tG z$}cUkRRX#c;)UD-xUqS~&|m@vn0`fKfxe-h0mw@*g}%P{mFDKcRTq~8r6Sym)!^cg z%7Rq=pw#00(xPNw#HA^NtSYc_E=o--$uA1Y&(DE{Vn9ZINq%ugeu09sGbq$76*R&# z^HTE5i#5S|e0{Av^NLFn^O93NU2K(rrs!p6rdXMp8#ucfIGGw7f`F@|rJ;$rqlJl! znX{{jp{uC{Os`9Ra%paAUI|QZ3PP_LPQ9SykXrz>*(J3ovn(~mttdZN0qkw7Ox$iU z#%Uf@ZwhX=nBdf_4|I$^C~}b^8zuxyK_DhP=>j?M#Gjf6Oz}m)q%Ee+dXa&FX@RGU zV@SoVH#awC3nxk(c)0sWQ1ogM#h?{>Suc|cHy?{E`4sZ*mqFuC)o*ZR!5q)O@9P zdsH{qT4mJ<`?TM_sA+4?>1mbJy}_LFs^^75^l?}An_69bMru|9vK@TL*oD1=4}ljk zyRakhMaD(UaNPKU;UWS%lr+3RU{=xTx9AC44)Z$Nhiz?wv0y z(Z0s`^7h?ZmDl^;eXHC2^RSn~(ej-aZd`9Ydi-SR$J?K}*QV{=Xjk+tWTk;oOxNRz z6I~0^-A^5RmzMkW^kVhz+ve|!;om;%!SGA*OckQ?P z_xH{JU-S6kq_yAfrWIxs>Fo6An=U*t-?(_`wm+{PPn@~()`yeAn`2wlcgWPP;r_f( z_U`&62Mi7;@^!!8&*@+A^8(N2xh&$#F51PFJ^3@6^|jBe;EOz% z&^EoMSWL;g&cQ$LXp^)|?B5iJ`+t90K3rdY)u5?(kBX}F+7m3#D?E=qlr8b~`zw~f Y@L&7GEB*%uI6!5%r>mdKI;Vst0R1>e8U}fi7AzZCsS=07?{;ELn2Bde0{8v^K*7iAWdWaj57fJ{tG z$}cUkRRX#c;)UD-xUqS~&|m@vn0`fKfxe-h0mw@*g}%P{mFDKcRTq~8r6Sym)!^cg z%7Rq=pw#00(xPNw#HA^NtSYc_E=o--$uA1Y&(DE{Vn9ZINq%ugeu09sGbq$76*R&# z^HTE5i#5S|e0{Av^NLFn^O93NU2K(rrs!p6rdS!98#}ogx)~T7f`F@|lO<5Afs2!y zql>eFxq%x@uSMv>2~2MaLa!lCy`bcfTL84#CABECEH%ZgC_h&L>}{(|oNjS- z#c3W?ZwgMgxVqugs}FRHJ}7dLA{!l9&h={zLVq{jso^v>znzn|wBVyl!Gzse z`?oH+VjslxbGL2BxpWJSV<|I=RjV7EVnt;|UN^m15RrP(@t_O)BIb*XNVxF@!$kyk zC~0_szzS9lB?v4at6+t|9ee_^2<*b%!H2+$m_gRSFqzglloT*sEM3F+>HF&Izs)-G zZdxhSSKoct?pVTK_pK^^Ez2ii>FTZf{u#whzn^w9?)ig+)p2XDoeR_2YU1l3DJXM$ zVp09}+qruqVr&0YB`0ftn|^P`j1K$VV$0H87eD>^=g-`oFJD$aG?M+~|24|m`uw|f zYjkeD>b$KRuQmO#t4&;-Pt9!0pnJJ_b$jegzy3V+_%{elBhH+0zeGpK-XKJ=}EqQ1!Ol)yKcx zlX?05kGpi?Uyn@!=Vwa<_IMUN_APlVdhe2bi@L?dz=Vn>VOiETC{tQlR9oWwhezh= zikp5g*xvJEHMeW4N;%N^`?JNv_0^FQ2QA|!O@3RK(p0=>$%7AkyVG3$iX|}24*BqQ T8c+Q@Q1R{Q>gTe~DWM4ff!kEe literal 0 HcmV?d00001 diff --git a/face-task/src/main/resources/static/images/deskicon.ico b/face-task/src/main/resources/static/images/deskicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..2ccf37cfd1a625533f6b906952f09ca407799d42 GIT binary patch literal 16958 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 fP00(-nXJS2x$wPh@?B0D*C`Ud^G&+mM;yTk;U literal 0 HcmV?d00001 diff --git a/face-task/src/main/resources/static/images/jt.png b/face-task/src/main/resources/static/images/jt.png new file mode 100644 index 0000000000000000000000000000000000000000..32576164cf65c7a505dba13f0921d2063c67041c GIT binary patch literal 441 zcmV;q0Y?6bP)-i^ku_j{r6F zgEfM{uQkgUejnP8H5yrP#qaL}d%&^5$j#00Ys-3^>3{`aBKfsp6}XW#nwdro7&Tzj jfKdZR4H!BG00bBSEHGeSK~gRv00000NkvXXu0mjfhfTiT literal 0 HcmV?d00001 diff --git a/face-task/src/main/resources/static/images/pulse.ico b/face-task/src/main/resources/static/images/pulse.ico new file mode 100644 index 0000000000000000000000000000000000000000..20f0ea3e30526862d411e364488c35634290c012 GIT binary patch literal 353118 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%0DW1Ha_Z0e;JrTm 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 literal 0 HcmV?d00001 diff --git a/face-task/src/main/resources/static/images/ringtones.ico b/face-task/src/main/resources/static/images/ringtones.ico new file mode 100644 index 0000000000000000000000000000000000000000..dfc5da31a37a0efff72f6d191c6ef9f716b97a2f GIT binary patch literal 51881 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�E4tU@wh>|$bbM} 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 F{{VRCS9|~f literal 0 HcmV?d00001 diff --git a/face-task/src/main/resources/static/index.html b/face-task/src/main/resources/static/index.html new file mode 100644 index 0000000..4a2e3d0 --- /dev/null +++ b/face-task/src/main/resources/static/index.html @@ -0,0 +1,76 @@ + + + + + + + + + + + + + +测试websocket!! + +
V
+ + \ No newline at end of file diff --git a/face-task/src/main/resources/static/index1.html b/face-task/src/main/resources/static/index1.html new file mode 100644 index 0000000..667baf6 --- /dev/null +++ b/face-task/src/main/resources/static/index1.html @@ -0,0 +1,57 @@ + + + + + + + + + + +
+ ~ +
+ + \ No newline at end of file diff --git a/face-task/src/main/resources/static/index2.html b/face-task/src/main/resources/static/index2.html new file mode 100644 index 0000000..a262d5b --- /dev/null +++ b/face-task/src/main/resources/static/index2.html @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + +测试websocket!! +
+
+
+
+
+
+ + +
+ + \ No newline at end of file diff --git a/face-task/src/main/resources/static/index4.html b/face-task/src/main/resources/static/index4.html new file mode 100644 index 0000000..92254b2 --- /dev/null +++ b/face-task/src/main/resources/static/index4.html @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + +测试websocket!! + + + + + + + + + + + +
+
+
+
+
+
+ + +
+ + \ No newline at end of file diff --git a/face-task/src/main/resources/static/indexline.html b/face-task/src/main/resources/static/indexline.html new file mode 100644 index 0000000..0f8a2e6 --- /dev/null +++ b/face-task/src/main/resources/static/indexline.html @@ -0,0 +1,44 @@ + + + + + + + + +ٶȵͼ·; + + +
+ + + + \ No newline at end of file diff --git a/face-task/src/main/resources/static/indexmove.html b/face-task/src/main/resources/static/indexmove.html new file mode 100644 index 0000000..e7f2ce6 --- /dev/null +++ b/face-task/src/main/resources/static/indexmove.html @@ -0,0 +1,66 @@ + + + + + + + +ٶȵͼ·; + + +
+ + + \ No newline at end of file diff --git a/face-task/src/main/resources/static/js/baidu.js b/face-task/src/main/resources/static/js/baidu.js new file mode 100644 index 0000000..ec31bc8 --- /dev/null +++ b/face-task/src/main/resources/static/js/baidu.js @@ -0,0 +1 @@ +var getRandomColor=function(){return(function(a,b,c){return(c?arguments.callee(a,b,c-1):'#')+b[a.floor(a.random()*16)]})(Math,'0123456789abcdef',5)};function showPoly(a){var b=new BMap.Map("allmap");b.centerAndZoom(new BMap.Point(114.253477,30.606323),13);b.enableScrollWheelZoom(true);a=JSON.parse(a);var d=a[0].split(',');for(c=0;cxxxxxxxxx"); +//var str="
"; +var str="
"+$("#msgContent").html()+"
"; +k.setContent(str); +//k. setStyle({ color : "red", fontSize : "12px" }) ; + k.setStyle({ + color: "#000", + border: "0px", + backgroundColor: "0.000000000001", //通过这个方法,去掉背景色 + fontSize: "12px", + height: "20px", + lineHeight: "20px" + }); +k.setTitle("标题"); +k.addEventListener("click", function(){alert(this.getPosition().lng+","+this.getPosition().lat)}); +i.setLabel(k) +}; +var e = Math.floor(a.length / 11); +var f = a.length % 11; +var g = new BMap.DrivingRoute(b, { +onSearchComplete: function(i) { +if (g.getStatus() == BMAP_STATUS_SUCCESS) { +var j = g.getResults().getPlan(0); +var k = j.getNumRoutes(); +for (var l = 0; l < k; l++) { +var m = j.getRoute(l).getPath(); +var n = new BMap.Polyline(m); +var o = getColor(); +n.setStrokeColor(o); +//线的粗细 +n.setStrokeWeight(4); +b.addOverlay(n) +} +} +} +}); +for (var h = 0; h < e; h++) { +var i = a.slice(h * 11 + 1, (h + 1) * 11); +g.search(a[h * 11], a[(h + 1) * 11 - 1], { +waypoints: i +}) +}; +if (f != 0) { +var i = a.slice(e * 11, a.length - 1); +g.search(a[e * 11], a[a.length - 1], { +waypoints: i +}) +} +} \ No newline at end of file diff --git a/face-task/src/main/resources/static/js/jiemi2.js b/face-task/src/main/resources/static/js/jiemi2.js new file mode 100644 index 0000000..b4bce0d --- /dev/null +++ b/face-task/src/main/resources/static/js/jiemi2.js @@ -0,0 +1,90 @@ +var getColor=function(a) +{ + if(a==0) + { + return "red"; + }else + { + return "green"; + } +} +function showPoly(a,b) { + //去掉点击某个点弹出东西 +for (var c = 0; c < a.data.length; c++) { + var adlength=a.data[c].length; + var posistionarr=[]; + for(var c1=0;c1"+task.taskName+"-"+task.cmName+"
"); + k.setStyle({ + color: "red", + border: "0px", + backgroundColor: "0.000000000001", //通过这个方法,去掉背景色 + fontSize: "16px", + height: "20px", + lineHeight: "20px" + }); + k.setTitle("标题"); + k.addEventListener("click", function(){alert(this.getPosition().lng+","+this.getPosition().lat)}); + i.setLabel(k) +} + +//划线 +function lines(posistionarr,b,type) +{ + // var driving2 = new BMap.DrivingRoute(b, {renderOptions:{map: b, autoViewport: true}}); //驾车实例 + // driving2.search(posistionarr[0], posistionarr[1]); //显示一条公交线路 + + if(1==1){ + var e = Math.floor(posistionarr.length / 11); + var f = posistionarr.length % 11; + var g = new BMap.DrivingRoute(b, { + onSearchComplete: function(i) { + if (g.getStatus() == BMAP_STATUS_SUCCESS) { + var j = g.getResults().getPlan(0); + var k = j.getNumRoutes(); + for (var l = 0; l < k; l++) { + var m = j.getRoute(l).getPath(); + var n = new BMap.Polyline(m); + var o = getColor(type); + n.setStrokeColor(o); + //线的粗细 + n.setStrokeWeight(4); + b.addOverlay(n) + } + } + } + }); + for (var h = 0; h < e; h++) { + var i = posistionarr.slice(h * 11 + 1, (h + 1) * 11); + g.search(posistionarr[h * 11], posistionarr[(h + 1) * 11 - 1], { + waypoints: i + }) + }; + if (f != 0) { + var i = posistionarr.slice(e * 11, posistionarr.length - 1); + g.search(posistionarr[e * 11], posistionarr[posistionarr.length - 1], { + waypoints: i + }) + } + } +} \ No newline at end of file diff --git a/face-task/src/main/resources/static/js/jquery-1.6.2.min.js b/face-task/src/main/resources/static/js/jquery-1.6.2.min.js new file mode 100644 index 0000000..ca044d4 --- /dev/null +++ b/face-task/src/main/resources/static/js/jquery-1.6.2.min.js @@ -0,0 +1,18 @@ +/*! + * jQuery JavaScript Library v1.6.2 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Thu Jun 30 14:16:56 2011 -0400 + */ +(function(a,b){function cv(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cs(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"":"")+""),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cr(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cq(){cn=b}function cp(){setTimeout(cq,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){try{return new a.XMLHttpRequest}catch(b){}}function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bx(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bm(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(be,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bl(a){f.nodeName(a,"input")?bk(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bk)}function bk(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bj(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bi(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bh(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i=0===c})}function V(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function N(a,b){return(a&&a!=="*"?a+".":"")+b.replace(z,"`").replace(A,"&")}function M(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;ic)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function K(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function E(){return!0}function D(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"$1-$2").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z])/ig,x=function(a,b){return b.toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!A){A=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a);return c===b||D.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(b,c,d){a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),d=c.documentElement,(!d||!d.nodeName||d.nodeName==="parsererror")&&e.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c
a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0},m&&f.extend(p,{position:"absolute",left:-1e3,top:-1e3});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
t
",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0),o.innerHTML="",n.removeChild(o);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([a-z])([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g=f.expando,h=typeof c=="string",i,j=a.nodeType,k=j?f.cache:a,l=j?a[f.expando]:a[f.expando]&&f.expando;if((!l||e&&l&&!k[l][g])&&h&&d===b)return;l||(j?a[f.expando]=l=++f.uuid:l=f.expando),k[l]||(k[l]={},j||(k[l].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?k[l][g]=f.extend(k[l][g],c):k[l]=f.extend(k[l],c);i=k[l],e&&(i[g]||(i[g]={}),i=i[g]),d!==b&&(i[f.camelCase(c)]=d);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[f.camelCase(c)]||i[c]:i}},removeData:function(b,c,d){if(!!f.acceptData(b)){var e=f.expando,g=b.nodeType,h=g?f.cache:b,i=g?b[f.expando]:f.expando;if(!h[i])return;if(c){var j=d?h[i][e]:h[i];if(j){delete j[c];if(!l(j))return}}if(d){delete h[i][e];if(!l(h[i]))return}var k=h[i][e];f.support.deleteExpando||h!=a?delete h[i]:h[i]=null,k?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=k):g&&(f.support.deleteExpando?delete b[f.expando]:b.removeAttribute?b.removeAttribute(f.expando):b[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;d=e.value;return typeof d=="string"?d.replace(p,""):d==null?"":d}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);j&&(c=f.attrFix[c]||c,i=f.attrHooks[c],i||(t.test(c)?i=w:v&&c!=="className"&&(f.nodeName(a,"form")||u.test(c))&&(i=v)));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j&&(h=i.get(a,c))!==null)return h;h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.support.getSetAttribute?a.removeAttribute(b):(f.attr(a,b,""),a.removeAttributeNode(a.getAttributeNode(b))),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},tabIndex:{get:function(a){var c=a.getAttributeNode("tabIndex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}},value:{get:function(a,b){if(v&&f.nodeName(a,"button"))return v.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(v&&f.nodeName(a,"button"))return v.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);i&&(c=f.propFix[c]||c,h=f.propHooks[c]);return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==b?g:a[c]},propHooks:{}}),w={get:function(a,c){return f.prop(a,c)?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},f.support.getSetAttribute||(f.attrFix=f.propFix,v=f.attrHooks.name=f.attrHooks.title=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,c){var d=a.getAttributeNode(c);if(d){d.nodeValue=b;return b}}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var x=/\.(.*)$/,y=/^(?:textarea|input|select)$/i,z=/\./g,A=/ /g,B=/[^\w\s.|`]/g,C=function(a){return a.replace(B,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=D;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=D);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),C).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i. +shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d!=null?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},J=function(c){var d=c.target,e,g;if(!!y.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=I(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:J,beforedeactivate:J,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&J.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&J.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",I(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in H)f.event.add(this,c+".specialChange",H[c]);return y.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return y.test(this.nodeName)}},H=f.event.special.change.filters,H.focus=H.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g0)for(h=g;h0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=T.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a=="string")return f.inArray(this[0],a?f(a):this.parent().children());return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(V(c[0])||V(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=S.call(arguments);O.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!U[a]?f.unique(e):e,(this.length>1||Q.test(d))&&P.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var X=/ jQuery\d+="(?:\d+|null)"/g,Y=/^\s+/,Z=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,$=/<([\w:]+)/,_=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};bf.optgroup=bf.option,bf.tbody=bf.tfoot=bf.colgroup=bf.caption=bf.thead,bf.th=bf.td,f.support.htmlSerialize||(bf._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(X,""):null;if(typeof a=="string"&&!bb.test(a)&&(f.support.leadingWhitespace||!Y.test(a))&&!bf[($.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Z,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j +)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bi(a,d),e=bj(a),g=bj(d);for(h=0;e[h];++h)bi(e[h],g[h])}if(b){bh(a,d);if(c){e=bj(a),g=bj(d);for(h=0;e[h];++h)bh(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!ba.test(k))k=b.createTextNode(k);else{k=k.replace(Z,"<$1>");var l=($.exec(k)||["",""])[1].toLowerCase(),m=bf[l]||bf._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=_.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&Y.test(k)&&o.insertBefore(b.createTextNode(Y.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bo.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle;c.zoom=1;var e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.filter=bn.test(g)?g.replace(bn,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bx(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(by=function(a,c){var d,e,g;c=c.replace(bp,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bz=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bq.test(d)&&br.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bx=by||bz,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bB=/%20/g,bC=/\[\]$/,bD=/\r?\n/g,bE=/#.*$/,bF=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bG=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bH=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,bI=/^(?:GET|HEAD)$/,bJ=/^\/\//,bK=/\?/,bL=/)<[^<]*)*<\/script>/gi,bM=/^(?:select|textarea)/i,bN=/\s+/,bO=/([?&])_=[^&]*/,bP=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bQ=f.fn.load,bR={},bS={},bT,bU;try{bT=e.href}catch(bV){bT=c.createElement("a"),bT.href="",bT=bT.href}bU=bP.exec(bT.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bQ)return bQ.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bL,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bM.test(this.nodeName)||bG.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bD,"\r\n")}}):{name:b.name,value:c.replace(bD,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?f.extend(!0,a,f.ajaxSettings,b):(b=a,a=f.extend(!0,f.ajaxSettings,b));for(var c in{context:1,url:1})c in b?a[c]=b[c]:c in f.ajaxSettings&&(a[c]=f.ajaxSettings[c]);return a},ajaxSettings:{url:bT,isLocal:bH.test(bU[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":"*/*"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML}},ajaxPrefilter:bW(bR),ajaxTransport:bW(bS),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a?4:0;var o,r,u,w=l?bZ(d,v,l):b,x,y;if(a>=200&&a<300||a===304){if(d.ifModified){if(x=v.getResponseHeader("Last-Modified"))f.lastModified[k]=x;if(y=v.getResponseHeader("Etag"))f.etag[k]=y}if(a===304)c="notmodified",o=!0;else try{r=b$(d,w),c="success",o=!0}catch(z){c="parsererror",u=z}}else{u=c;if(!c||a)c="error",a<0&&(a=0)}v.status=a,v.statusText=c,o?h.resolveWith(e,[r,c,v]):h.rejectWith(e,[v,c,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,c]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bF.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bE,"").replace(bJ,bU[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bN),d.crossDomain==null&&(r=bP.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bU[1]&&r[2]==bU[2]&&(r[3]||(r[1]==="http:"?80:443))==(bU[3]||(bU[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bX(bR,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bI.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bK.test(d.url)?"&":"?")+d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bO,"$1_="+x);d.url=y+(y===d.url?(bK.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", */*; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bX(bS,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){status<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)bY(g,a[g],c,e);return d.join("&").replace(bB,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var b_=f.now(),ca=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+b_++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ca.test(b.url)||e&&ca.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ca,l),b.url===j&&(e&&(k=k.replace(ca,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cb=a.ActiveXObject?function(){for(var a in cd)cd[a](0,1)}:!1,cc=0,cd;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ce()||cf()}:ce,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cb&&delete cd[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cc,cb&&(cd||(cd={},f(a).unload(cb)),cd[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cg={},ch,ci,cj=/^(?:toggle|show|hide)$/,ck=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cl,cm=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cn,co=a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cr("show",3),a,b,c);for(var g=0,h=this.length;g=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){for(var a=f.timers,b=0;b
";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cu.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cu.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cv(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cv(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a&&a.style?parseFloat(f.css(a,d,"padding")):null},f.fn["outer"+c]=function(a){var b=this[0];return b&&b.style?parseFloat(f.css(b,d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c];return e.document.compatMode==="CSS1Compat"&&g||e.document.body["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var h=f.css(e,d),i=parseFloat(h);return f.isNaN(i)?h:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); \ No newline at end of file diff --git a/face-task/src/main/resources/static/js/jquery-3.2.1.slim.min.js b/face-task/src/main/resources/static/js/jquery-3.2.1.slim.min.js new file mode 100644 index 0000000..105d00e --- /dev/null +++ b/face-task/src/main/resources/static/js/jquery-3.2.1.slim.min.js @@ -0,0 +1,4 @@ +/*! jQuery v3.2.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/parseXML,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-event/ajax,-effects,-effects/Tween,-effects/animatedSelector | (c) JS Foundation and other contributors | jquery.org/license */ +!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/parseXML,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-event/ajax,-effects,-effects/Tween,-effects/animatedSelector",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a); +}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S),a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c1)}}),r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var _a,ab=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return T(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?_a:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),_a={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=ab[b]||r.find.attr;ab[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=ab[g],ab[g]=e,e=null!=c(a,b,d)?g:null,ab[g]=f),e}});var bb=/^(?:input|select|textarea|button)$/i,cb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function db(a){var b=a.match(L)||[];return b.join(" ")}function eb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,eb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=eb(c),d=1===c.nodeType&&" "+db(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=db(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,eb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=eb(c),d=1===c.nodeType&&" "+db(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=db(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,eb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=eb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+db(eb(c))+" ").indexOf(b)>-1)return!0;return!1}});var fb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(fb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:db(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var gb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!gb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,gb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var hb=/\[\]$/,ib=/\r?\n/g,jb=/^(?:submit|button|image|reset|file)$/i,kb=/^(?:input|select|textarea|keygen)/i;function lb(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||hb.test(a)?d(a,e):lb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d); +});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)lb(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)lb(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&kb.test(this.nodeName)&&!jb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ib,"\r\n")}}):{name:b.name,value:c.replace(ib,"\r\n")}}).get()}}),r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="
",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=C.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=qa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),b=f.ownerDocument,c=b.documentElement,e=b.defaultView,{top:d.top+e.pageYOffset-c.clientTop,left:d.left+e.pageXOffset-c.clientLeft}):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),B(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||ra})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return T(this,function(a,d,e){var f;return r.isWindow(a)?f=a:9===a.nodeType&&(f=a.defaultView),void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Pa(o.pixelPosition,function(a,c){if(c)return c=Oa(a,b),Ma.test(c)?r(a).position()[b]+"px":c})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return T(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.holdReady=function(a){a?r.readyWait++:r.ready(!0)},r.isArray=Array.isArray,r.parseJSON=JSON.parse,r.nodeName=B,"function"==typeof define&&define.amd&&define("jquery",[],function(){return r});var mb=a.jQuery,nb=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=nb),b&&a.jQuery===r&&(a.jQuery=mb),r},b||(a.jQuery=a.$=r),r}); diff --git a/face-task/src/main/resources/static/js/yj.js b/face-task/src/main/resources/static/js/yj.js new file mode 100644 index 0000000..e473ce5 --- /dev/null +++ b/face-task/src/main/resources/static/js/yj.js @@ -0,0 +1,136 @@ +var getColor = function () { + return "green"; +} +var b; +var marker = new Map(); +var lable = new Map(); + +function showPoly(a1, b1) { + //去掉点击某个点弹出东西 + b = new BMap.Map("allmap", {enableMapClick: false}); + // {"cameraID":"1211828133370216450","cameraName":"创新中心北","lng":"103.907065","lat":"30.701563"} + b.centerAndZoom(new BMap.Point(a1[0].lng, a1[0].lat), b1); + b.enableScrollWheelZoom(true); + for (var c = 0; c < a1.length; c++) { + var i = new BMap.Marker(new BMap.Point(a1[c].lng, a1[c].lat)); + //i.setTitle(a1[c].cameraName); + var k = new BMap.Label("arms", { + //距离点的左右位置和上下位置 + offset: new BMap.Size(0, 28) + }); + k.setStyle({ + color: "white", + border: "0px", + // backgroundColor: "0.000000000001", //通过这个方法,去掉背景色 + backgroundColor: "#9DB7F2", //通过这个方法,去掉背景色 + fontSize: "12px", + height: "20px", + // border:"1px solid black", + lineHeight: "20px" + }); + k.setContent("  "+a1[c].cameraName+"  "); + b.addOverlay(i); + i.setLabel(k); + // i.addEventListener("mouseover", function () { + // this.setLabel(k); + // }); + // i.addEventListener("mouseout",function () { + // if(k!=undefined) + // { + // this.getMap().removeOverlay(k); + // } + // }); + marker.set(a1[c].cameraID, i); + } +} + +function showArm(jsonval) { + marker.get(jsonval.data.cameraId).getMap().removeOverlay(lable.get(jsonval.data.cameraId)); + // var randomWidthNum=Math.floor(Math.random()*50+1); + // var randomHeightNum=Math.floor(Math.random()*50+1); + var randomWidthNum=0; + var randomHeightNum=0; + var k = new BMap.Label("arms" + jsonval.data.cameraId, { + //距离点的左右位置和上下位置 + offset: new BMap.Size(-105-randomWidthNum, -115+randomHeightNum) + }); + var str = "
\n" + + "
\n" + + // "
" + + "
" + + // ""+ + " " + + "
\n" + + "
\n" + + "
\n" + + " 姓   名:" + jsonval.data.name + "\n" + + "
\n" + + "
\n" + + " 性   别:" + jsonval.data.sex + "\n" + + "
\n" + + "
\n" + + " 人像库:" + jsonval.data.libName + "\n" + + "
\n" + + "
\n" + + " 比   分:" + jsonval.data.score + "\n" + + "
\n" + + "
\n" + + " 时  间:" + jsonval.data.time + "\n" + + "
" + + "
\n" + + "
"; + k.setContent(str); + k.setStyle({ + color: "#000", + border: "0px", + backgroundColor: "0.000000000001", //通过这个方法,去掉背景色 + fontSize: "12px", + height: "20px", + lineHeight: "20px" + }); + k.addEventListener("click", function () { + alert("详细数据展示一个窗体:" + this.getPosition().lng + "," + this.getPosition().lat) + }); + marker.get(jsonval.data.cameraId).setLabel(k); + lable.set(jsonval.data.cameraId, k); + var i = 0; + var canvas= document.getElementById("imgicon"+jsonval.data.cameraId); + var cxt = canvas.getContext("2d"); + cxt.clearRect(0,0,120,120); + // //绘制图片 + var img = new Image(); + img.src = jsonval.data.bgImg; + img.onload = function() { + cxt.drawImage(img,jsonval.data.positionVO.x,jsonval.data.positionVO.y,jsonval.data.positionVO.w,jsonval.data.positionVO.h,0,0,120,120); + } + var timer = setInterval(function () { + document.getElementById("notice").play(); + if (i % 2 == 0) { + $("#msgContent" + jsonval.data.cameraId).removeClass("msg_bg_blue"); + $("#msgContent" + jsonval.data.cameraId).addClass("msg_bg_red"); + } else { + $("#msgContent" + jsonval.data.cameraId).removeClass("msg_bg_red"); + $("#msgContent" + jsonval.data.cameraId).addClass("msg_bg_blue"); + } + if (i > 10) { + $("#msgContent" + jsonval.data.cameraId).removeClass("msg_bg_red", "msg_bg_blue"); + clearInterval(timer); + } + i++; + }, 500) + + // alert("#msgContent"+jsonval.data.cameraId); + // $("#msgContent"+jsonval.data.cameraId).show() + // // var json={"code":200,"message":"成功","cmd":"WARNING","data":{"bgImg":"http://10.51.10.203:32080/g10203/M00/40/C1/CjMKy14ULjyADahlAAEjVYElPnw887.jpg","positionVO":{"x":199,"y":209,"w":25,"h":34},"score":0.81317765,"time":"2020-01-07 15:07:48","faceUrl":"http://10.51.10.201:9001/middleware/20191227/787a39d0ee114a68b627812153222bcd.jpg","name":"7","sex":"男","idCard":"150981198409254695","age":35,"taskId":"1211831416948211713","taskName":"小会议室走廊","taskType":"3","libName":"10000人像库","libId":"1210121197004161026"}}; + // if(jsonval.code==200) + // { + // $("#msgContent"+jsonval.data.cameraId).show(); + // $("#msgContent_img1"+jsonval.data.cameraId).attr("src",jsonval.data.bgImg); + // $("#msgContent_img2"+jsonval.data.cameraId).attr("src",jsonval.data.faceUrl); + // $("#msgContent_name"+jsonval.data.cameraId).html(jsonval.data.name); + // $("#msgContent_sex"+jsonval.data.cameraId).html(jsonval.data.sex); + // $("#msgContent_lib"+jsonval.data.cameraId).html(jsonval.data.libName); + // $("#msgContent_time"+jsonval.data.cameraId).html(jsonval.data.time); + // + // } +} \ No newline at end of file diff --git a/face-task/src/main/resources/static/map.html b/face-task/src/main/resources/static/map.html new file mode 100644 index 0000000..9c84444 --- /dev/null +++ b/face-task/src/main/resources/static/map.html @@ -0,0 +1,222 @@ + + + + + + + + + + 百度地图路线途经点 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/face-task/src/main/resources/static/mp3/song.mp3 b/face-task/src/main/resources/static/mp3/song.mp3 new file mode 100644 index 0000000..e69de29 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..2127140 --- /dev/null +++ b/pom.xml @@ -0,0 +1,245 @@ + + + 4.0.0 + + com.dkha + face-application + pom + 1.0-SNAPSHOT + + face-common + face-server + face-snapShot + face-task + + + + org.springframework.boot + spring-boot-starter-parent + 2.1.4.RELEASE + + + + + 2.7.0 + 3.1.2 + 3.1.2 + 5.1.38 + 1.18.4 + 1.1.10 + 2.9.0 + 1.2.45 + 3.5 + 6.0.8 + 1.3.5 + 4.1.34.Final + Greenwich.SR1 + 3.2.0 + 2.6 + 3.1.0 + 0.0.9 + 1.2.1 + 2.2.2 + 3.2.0 + 1.2.8.RELEASE + 1.4.0 + 1.11.3 + 2.6 + 1.9.1 + 20.0 + 1.9.1 + 2.0.1.Final + 6.1.0.Final + 2.6 + 3.9 + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${cloud-version} + pom + import + + + + commons-lang + commons-lang + ${commons-lang.version} + + + + + io.springfox + springfox-swagger2 + ${swagger.version} + + + io.springfox + springfox-swagger-ui + ${swagger.version} + + + + javax.validation + validation-api + ${javax-validation.version} + + + + org.hibernate + hibernate-validator + + + + org.projectlombok + lombok + ${lombok.version} + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + redis.clients + jedis + ${jedis.version} + + + com.alibaba + fastjson + ${fastjson.version} + + + org.apache.commons + commons-lang3 + ${commons.lang.version} + + + io.minio + minio + ${minio.version} + + + com.auth0 + java-jwt + ${jwt-version} + + + cn.afterturn + easypoi-base + ${easypoi.version} + + + cn.afterturn + easypoi-web + ${easypoi.version} + + + cn.afterturn + easypoi-annotation + ${easypoi.version} + + + + com.github.axet + kaptcha + ${kaptcha.version} + + + com.baomidou + mybatis-plus-generator + ${mybatisplusgenerator.version} + + + com.baomidou + mybatis-plus-boot-starter + ${mybatisplus.version} + + + com.ecwid.consul + consul-api + ${version.consul-api} + + + + net.sf.json-lib + json-lib + ${net.sf.json-lib.version} + jdk15 + + + com.auth0 + java-jwt + ${jwt-version} + + + org.springframework + springloaded + ${springloaded.version} + + + org.apache.shiro + shiro-core + ${shiro.version} + + + org.apache.shiro + shiro-spring + ${shiro.version} + + + org.jsoup + jsoup + ${jsoup.version} + + + commons-io + commons-io + ${commons-io-version} + + + org.aspectj + aspectjrt + ${aspectjrt.version} + + + io.netty + netty-all + ${netty.version} + + + com.google.guava + guava + ${guava.version} + + + org.aspectj + aspectjrt + ${aspectj.version} + + + + org.apache.poi + poi + ${poi.version} + + + org.apache.poi + poi-ooxml + ${poi.version} + + + org.apache.poi + poi-ooxml-schemas + ${poi.version} + + + + \ No newline at end of file