From 12981b9dbd0a97f4d75a7a1c56bf2233d394ac8c Mon Sep 17 00:00:00 2001 From: shi Date: Tue, 11 Feb 2025 15:27:15 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ff-admin/pom.xml | 128 + .../src/main/java/com/ff/FFApplication.java | 44 + .../java/com/ff/FFServletInitializer.java | 18 + .../java/com/ff/annotation/CheckHeader.java | 20 + .../com/ff/annotation/HeaderCheckAspect.java | 69 + .../ff/api/controller/ApiGameController.java | 119 + .../api/controller/ApiMemberController.java | 125 + .../com/ff/api/request/GameLoginRequest.java | 58 + .../api/request/MemberCreateApiRequest.java | 32 + .../ff/api/request/MemberInfoApiRequest.java | 32 + .../common/controller/CaptchaController.java | 95 + .../common/controller/CurrencyController.java | 104 + .../ff/common/controller/LangController.java | 104 + .../controller/TenantSecretKeyController.java | 104 + .../java/com/ff/common/domain/Currency.java | 54 + .../main/java/com/ff/common/domain/Lang.java | 37 + .../com/ff/common/domain/TenantSecretKey.java | 37 + .../com/ff/common/mapper/CurrencyMapper.java | 61 + .../java/com/ff/common/mapper/LangMapper.java | 61 + .../common/mapper/TenantSecretKeyMapper.java | 69 + .../ff/common/service/ICurrencyService.java | 61 + .../com/ff/common/service/ILangService.java | 61 + .../service/ITenantSecretKeyService.java | 69 + .../service/impl/CurrencyServiceImpl.java | 96 + .../common/service/impl/LangServiceImpl.java | 96 + .../impl/TenantSecretKeyServiceImpl.java | 107 + .../config/ContentRefreshedEventListener.java | 54 + .../main/java/com/ff/config/KeyConfig.java | 44 + .../java/com/ff/config/SwaggerConfig.java | 121 + .../ff/file/controller/FileController.java | 45 + .../com/ff/file/service/ISysFileService.java | 21 + .../service/impl/LocalSysFileServiceImpl.java | 48 + .../java/com/ff/game/api/IGamesService.java | 139 ++ .../api/jili/address/MyJILIAddressSource.java | 33 + .../ff/game/api/jili/client/JILIClient.java | 56 + .../dto/JILIBetRecordDataResponseDTO.java | 89 + .../jili/dto/JILIBetRecordResponseDTO.java | 62 + .../dto/JILICancelFreeSpinResponseDTO.java | 23 + .../dto/JILICreateFreeSpinResponseDTO.java | 31 + .../jili/dto/JILICreateMemberResponseDTO.java | 28 + .../dto/JILIExchangeMoneyResponseDTO.java | 72 + .../ff/game/api/jili/dto/JILIGamesDTO.java | 38 + .../game/api/jili/dto/JILIGamesDataDTO.java | 66 + .../JILIGetFreeSpinDashflowResponseDTO.java | 74 + .../dto/JILIGetGameDetailResponseDTO.java | 31 + .../api/jili/dto/JILIKickMemberAllDTO.java | 21 + .../game/api/jili/dto/JILIKickMemberDTO.java | 15 + .../JILILoginWithoutRedirectResponseDTO.java | 23 + .../game/api/jili/dto/JILIMemberInfoDTO.java | 62 + .../service/impl/GamesJILIServiceImpl.java | 763 ++++++ .../game/api/request/BetRecordByTimeDTO.java | 40 + .../api/request/CancelFreeSpinRequestDTO.java | 17 + .../api/request/CreateFreeSpinRequestDTO.java | 62 + .../api/request/CreateMemberRequestDTO.java | 26 + .../ExchangeTransferMoneyRequestDTO.java | 52 + .../ff/game/api/request/GameUniqueDTO.java | 19 + .../game/api/request/GamesBaseRequestDTO.java | 37 + .../game/api/request/GamesDataBuildDTO.java | 31 + .../com/ff/game/api/request/GamesLogin.java | 44 + .../GetFreeSpinDashflowRequestDTO.java | 19 + .../api/request/GetGameDetailRequestDTO.java | 22 + .../api/request/GetGameDetailResponseDTO.java | 21 + .../ff/game/api/request/KickMemberAllDTO.java | 15 + .../api/request/KickMemberRequestDTO.java | 18 + .../api/request/MemberInfoRequestDTO.java | 25 + .../api/request/MemberInfoResponseDTO.java | 39 + .../api/xk/dto/XKBetRecordResponseDTO.java | 54 + .../api/xk/dto/XKCreateMemberResponseDTO.java | 32 + .../xk/dto/XKExchangeMoneyResponseDTO.java | 46 + .../com/ff/game/api/xk/dto/XKGamesDTO.java | 56 + .../game/api/xk/dto/XKKickMemberAllDTO.java | 27 + .../ff/game/api/xk/dto/XKKickMemberDTO.java | 13 + .../XKLoginWithoutRedirectResponseDTO.java | 29 + .../ff/game/api/xk/dto/XKMemberInfoDTO.java | 49 + .../xk/service/impl/GamesXKServiceImpl.java | 618 +++++ .../GameBettingDetailsController.java | 104 + .../ff/game/controller/GameController.java | 104 + .../GameExchangeMoneyController.java | 104 + .../controller/GameFreeRecordController.java | 104 + .../controller/GamePlatformController.java | 104 + .../controller/GameSecretKeyController.java | 104 + .../main/java/com/ff/game/domain/Game.java | 64 + .../ff/game/domain/GameBettingDetails.java | 109 + .../com/ff/game/domain/GameExchangeMoney.java | 81 + .../com/ff/game/domain/GameFreeRecord.java | 83 + .../java/com/ff/game/domain/GamePlatform.java | 54 + .../com/ff/game/domain/GameSecretKey.java | 49 + .../game/mapper/GameBettingDetailsMapper.java | 61 + .../game/mapper/GameExchangeMoneyMapper.java | 61 + .../ff/game/mapper/GameFreeRecordMapper.java | 61 + .../java/com/ff/game/mapper/GameMapper.java | 82 + .../ff/game/mapper/GamePlatformMapper.java | 70 + .../ff/game/mapper/GameSecretKeyMapper.java | 90 + .../service/IGameBettingDetailsService.java | 61 + .../service/IGameExchangeMoneyService.java | 61 + .../game/service/IGameFreeRecordService.java | 61 + .../ff/game/service/IGamePlatformService.java | 71 + .../game/service/IGameSecretKeyService.java | 94 + .../com/ff/game/service/IGameService.java | 81 + .../impl/GameBettingDetailsServiceImpl.java | 96 + .../impl/GameExchangeMoneyServiceImpl.java | 96 + .../impl/GameFreeRecordServiceImpl.java | 96 + .../service/impl/GamePlatformServiceImpl.java | 108 + .../impl/GameSecretKeyServiceImpl.java | 134 + .../ff/game/service/impl/GameServiceImpl.java | 132 + .../member/controller/MemberController.java | 104 + .../java/com/ff/member/domain/Member.java | 48 + .../com/ff/member/mapper/MemberMapper.java | 79 + .../com/ff/member/service/IMemberService.java | 77 + .../service/impl/MemberServiceImpl.java | 119 + .../ff/monitor/SysLogininforController.java | 78 + .../com/ff/monitor/SysOperlogController.java | 65 + .../com/ff/quartz/config/ScheduleConfig.java | 57 + .../quartz/controller/SysJobController.java | 179 ++ .../controller/SysJobLogController.java | 88 + .../java/com/ff/quartz/domain/SysJob.java | 172 ++ .../java/com/ff/quartz/domain/SysJobLog.java | 156 ++ .../com/ff/quartz/mapper/SysJobLogMapper.java | 65 + .../com/ff/quartz/mapper/SysJobMapper.java | 68 + .../ff/quartz/service/ISysJobLogService.java | 57 + .../com/ff/quartz/service/ISysJobService.java | 103 + .../service/impl/SysJobLogServiceImpl.java | 88 + .../service/impl/SysJobServiceImpl.java | 262 ++ .../main/java/com/ff/quartz/task/RyTask.java | 34 + .../com/ff/quartz/util/AbstractQuartzJob.java | 100 + .../java/com/ff/quartz/util/CronUtils.java | 64 + .../com/ff/quartz/util/JobInvokeUtil.java | 183 ++ .../QuartzDisallowConcurrentExecution.java | 23 + .../ff/quartz/util/QuartzJobExecution.java | 21 + .../com/ff/quartz/util/ScheduleUtils.java | 132 + .../com/ff/system/SysConfigController.java | 129 + .../ff/system/SysDatasourceController.java | 105 + .../java/com/ff/system/SysDeptController.java | 126 + .../com/ff/system/SysDictDataController.java | 126 + .../com/ff/system/SysDictTypeController.java | 125 + .../com/ff/system/SysIndexController.java | 29 + .../com/ff/system/SysLoginController.java | 99 + .../java/com/ff/system/SysMenuController.java | 136 + .../java/com/ff/system/SysPostController.java | 123 + .../com/ff/system/SysProfileController.java | 131 + .../com/ff/system/SysRegisterController.java | 38 + .../java/com/ff/system/SysRoleController.java | 256 ++ .../java/com/ff/system/SysUserController.java | 250 ++ .../META-INF/spring-devtools.properties | 1 + .../src/main/resources/application-druid.yml | 95 + .../src/main/resources/application-prod.yml | 97 + ff-admin/src/main/resources/application.yml | 138 ++ .../main/resources/i18n/messages.properties | 44 + ff-admin/src/main/resources/logback.xml | 93 + .../mapper/common/CurrencyMapper.xml | 111 + .../resources/mapper/common/LangMapper.xml | 87 + .../mapper/common/TenantSecretKeyMapper.xml | 92 + .../mapper/game/GameBettingDetailsMapper.xml | 167 ++ .../mapper/game/GameExchangeMoneyMapper.xml | 132 + .../mapper/game/GameFreeRecordMapper.xml | 132 + .../main/resources/mapper/game/GameMapper.xml | 142 ++ .../mapper/game/GamePlatformMapper.xml | 104 + .../mapper/game/GameSecretKeyMapper.xml | 118 + .../resources/mapper/member/MemberMapper.xml | 102 + .../mapper/quartz/SysJobLogMapper.xml | 96 + .../resources/mapper/quartz/SysJobMapper.xml | 111 + .../main/resources/mybatis/mybatis-config.xml | 20 + .../META-INF/spring-devtools.properties | 1 + ff-admin/target/classes/application-druid.yml | 95 + ff-admin/target/classes/application-prod.yml | 97 + ff-admin/target/classes/application.yml | 138 ++ .../target/classes/com/ff/FFApplication.class | Bin 0 -> 2280 bytes .../classes/com/ff/FFServletInitializer.class | Bin 0 -> 859 bytes .../ContentRefreshedEventListener.class | Bin 0 -> 2628 bytes .../classes/com/ff/config/SwaggerConfig.class | Bin 0 -> 6485 bytes .../ff/file/controller/FileController.class | Bin 0 -> 2065 bytes .../com/ff/file/service/ISysFileService.class | Bin 0 -> 242 bytes .../impl/LocalSysFileServiceImpl.class | Bin 0 -> 2299 bytes .../member/controller/MemberController.class | Bin 0 -> 3950 bytes .../classes/com/ff/member/domain/Member.class | Bin 0 -> 4564 bytes .../com/ff/member/mapper/MemberMapper.class | Bin 0 -> 688 bytes .../ff/member/service/IMemberService.class | Bin 0 -> 693 bytes .../service/impl/MemberServiceImpl.class | Bin 0 -> 2180 bytes .../ff/monitor/SysLogininforController.class | Bin 0 -> 3807 bytes .../com/ff/monitor/SysOperlogController.class | Bin 0 -> 3209 bytes .../quartz/controller/SysJobController.class | Bin 0 -> 6794 bytes .../controller/SysJobLogController.class | Bin 0 -> 3630 bytes .../classes/com/ff/quartz/domain/SysJob.class | Bin 0 -> 4835 bytes .../com/ff/quartz/domain/SysJobLog.class | Bin 0 -> 3372 bytes .../ff/quartz/mapper/SysJobLogMapper.class | Bin 0 -> 698 bytes .../com/ff/quartz/mapper/SysJobMapper.class | Bin 0 -> 648 bytes .../ff/quartz/service/ISysJobLogService.class | Bin 0 -> 590 bytes .../ff/quartz/service/ISysJobService.class | Bin 0 -> 872 bytes .../service/impl/SysJobLogServiceImpl.class | Bin 0 -> 1739 bytes .../service/impl/SysJobServiceImpl.class | Bin 0 -> 5723 bytes .../classes/com/ff/quartz/task/RyTask.class | Bin 0 -> 2381 bytes .../ff/quartz/util/AbstractQuartzJob.class | Bin 0 -> 3818 bytes .../com/ff/quartz/util/CronUtils.class | Bin 0 -> 1278 bytes .../com/ff/quartz/util/JobInvokeUtil.class | Bin 0 -> 5641 bytes .../QuartzDisallowConcurrentExecution.class | Bin 0 -> 861 bytes .../ff/quartz/util/QuartzJobExecution.class | Bin 0 -> 733 bytes .../com/ff/quartz/util/ScheduleUtils.class | Bin 0 -> 6291 bytes .../com/ff/system/SysConfigController.class | Bin 0 -> 5332 bytes .../ff/system/SysDatasourceController.class | Bin 0 -> 4188 bytes .../com/ff/system/SysDeptController.class | Bin 0 -> 5991 bytes .../com/ff/system/SysDictDataController.class | Bin 0 -> 5512 bytes .../com/ff/system/SysDictTypeController.class | Bin 0 -> 5257 bytes .../com/ff/system/SysIndexController.class | Bin 0 -> 1028 bytes .../com/ff/system/SysLoginController.class | Bin 0 -> 3882 bytes .../com/ff/system/SysMenuController.class | Bin 0 -> 5438 bytes .../com/ff/system/SysPostController.class | Bin 0 -> 5138 bytes .../com/ff/system/SysProfileController.class | Bin 0 -> 5589 bytes .../com/ff/system/SysRegisterController.class | Bin 0 -> 1903 bytes .../com/ff/system/SysRoleController.class | Bin 0 -> 9606 bytes .../com/ff/system/SysUserController.class | Bin 0 -> 11764 bytes .../target/classes/i18n/messages.properties | 44 + ff-admin/target/classes/logback.xml | 93 + .../mapper/game/GameBettingDetailsMapper.xml | 167 ++ .../mapper/game/GameExchangeMoneyMapper.xml | 132 + .../mapper/game/GameFreeRecordMapper.xml | 132 + .../target/classes/mapper/game/GameMapper.xml | 142 ++ .../mapper/game/GamePlatformMapper.xml | 104 + .../mapper/game/GameSecretKeyMapper.xml | 118 + .../classes/mapper/member/MemberMapper.xml | 102 + .../classes/mapper/quartz/SysJobLogMapper.xml | 96 + .../classes/mapper/quartz/SysJobMapper.xml | 111 + .../target/classes/mybatis/mybatis-config.xml | 20 + ff-base/pom.xml | 198 ++ .../com/ff/base/annotation/Anonymous.java | 15 + .../com/ff/base/annotation/DataScope.java | 29 + .../com/ff/base/annotation/DataSource.java | 24 + .../java/com/ff/base/annotation/Excel.java | 193 ++ .../java/com/ff/base/annotation/Excels.java | 20 + .../main/java/com/ff/base/annotation/Log.java | 48 + .../com/ff/base/annotation/RateLimiter.java | 37 + .../com/ff/base/annotation/RepeatSubmit.java | 26 + .../com/ff/base/annotation/Sensitive.java | 25 + .../com/ff/base/aspectj/DataScopeAspect.java | 185 ++ .../com/ff/base/aspectj/DataSourceAspect.java | 73 + .../java/com/ff/base/aspectj/LogAspect.java | 256 ++ .../ff/base/aspectj/RateLimiterAspect.java | 91 + .../com/ff/base/config/ApplicationConfig.java | 31 + .../java/com/ff/base/config/AsyncConfig.java | 17 + .../com/ff/base/config/CaptchaConfig.java | 85 + .../java/com/ff/base/config/DruidConfig.java | 112 + .../java/com/ff/base/config/FFConfig.java | 122 + .../config/FastJson2JsonRedisSerializer.java | 53 + .../java/com/ff/base/config/FilterConfig.java | 59 + .../java/com/ff/base/config/I18nConfig.java | 60 + .../com/ff/base/config/IdGeneratorUtil.java | 34 + .../com/ff/base/config/JacksonConfig.java | 24 + .../ff/base/config/KaptchaTextCreator.java | 69 + .../com/ff/base/config/MyBatisConfig.java | 133 + .../java/com/ff/base/config/RedisConfig.java | 69 + .../com/ff/base/config/ResourcesConfig.java | 84 + .../com/ff/base/config/SecurityConfig.java | 165 ++ .../java/com/ff/base/config/ServerConfig.java | 33 + .../com/ff/base/config/ThreadPoolConfig.java | 64 + .../config/properties/DruidProperties.java | 89 + .../properties/PermitAllUrlProperties.java | 70 + .../serializer/SensitiveJsonSerializer.java | 68 + .../ff/base/constant/BusinessConstants.java | 70 + .../com/ff/base/constant/CacheConstants.java | 71 + .../com/ff/base/constant/ConfigConstants.java | 94 + .../java/com/ff/base/constant/Constants.java | 238 ++ .../com/ff/base/constant/GenConstants.java | 120 + .../java/com/ff/base/constant/HttpStatus.java | 99 + .../ff/base/constant/ScheduleConstants.java | 50 + .../com/ff/base/constant/UserConstants.java | 78 + .../base/core/controller/BaseController.java | 203 ++ .../com/ff/base/core/domain/AjaxResult.java | 218 ++ .../com/ff/base/core/domain/BaseEntity.java | 63 + .../com/ff/base/core/domain/TreeEntity.java | 32 + .../com/ff/base/core/domain/TreeSelect.java | 52 + .../ff/base/core/domain/model/LoginBody.java | 33 + .../ff/base/core/domain/model/LoginForm.java | 48 + .../ff/base/core/domain/model/LoginUser.java | 281 +++ .../base/core/domain/model/RegisterBody.java | 11 + .../com/ff/base/core/page/PageDomain.java | 103 + .../com/ff/base/core/page/TableDataInfo.java | 85 + .../com/ff/base/core/page/TableSupport.java | 56 + .../com/ff/base/core/redis/RedisCache.java | 244 ++ .../com/ff/base/core/text/CharsetKit.java | 87 + .../java/com/ff/base/core/text/Convert.java | 1011 ++++++++ .../com/ff/base/core/text/StrFormatter.java | 92 + .../ff/base/datasource/DynamicDataSource.java | 83 + .../DynamicDataSourceContextHolder.java | 60 + .../decorator/ContextCopyingDecorator.java | 47 + .../com/ff/base/enums/AccountAuditStatus.java | 33 + .../com/ff/base/enums/AccountChangeType.java | 40 + .../java/com/ff/base/enums/AccountType.java | 22 + .../base/enums/ActivityBetPlatformType.java | 26 + .../ff/base/enums/ActivityBetSendStatus.java | 26 + .../com/ff/base/enums/ActivityBetSendWay.java | 29 + .../enums/ActivityChargeReceiveLimitType.java | 36 + .../enums/ActivityChargeRepeatReceive.java | 29 + .../base/enums/ActivityChargeRewardType.java | 27 + .../ff/base/enums/ActivityChargeRuleType.java | 27 + .../base/enums/ActivityChargeSendStatus.java | 26 + .../ff/base/enums/ActivityChargeSendWay.java | 28 + .../ActivityExtensionAccordCondition.java | 23 + .../enums/ActivityExtensionChargeStatus.java | 23 + .../enums/ActivityExtensionChargeType.java | 27 + .../base/enums/ActivityExtensionLoginApp.java | 23 + .../enums/ActivityExtensionRewardType.java | 27 + .../enums/ActivityExtensionSendStatus.java | 27 + .../base/enums/ActivityExtensionSendWay.java | 29 + .../ff/base/enums/ActivityLimitedTimeDay.java | 26 + .../com/ff/base/enums/ActivityLoopType.java | 27 + .../ff/base/enums/ActivityMainEntrance.java | 26 + .../ff/base/enums/ActivityReceiveCount.java | 26 + .../base/enums/ActivityReceiveLimitType.java | 35 + .../base/enums/ActivityRewardAuditStatus.java | 25 + .../com/ff/base/enums/ActivityShowStatus.java | 27 + .../com/ff/base/enums/ActivityStatus.java | 27 + .../ff/base/enums/ActivityTemplateType.java | 50 + .../com/ff/base/enums/AgentModelType.java | 36 + .../ff/base/enums/AndroidForceDownload.java | 24 + .../com/ff/base/enums/AnnouncementStatus.java | 25 + .../java/com/ff/base/enums/AppLocation.java | 23 + .../java/com/ff/base/enums/AwardType.java | 24 + .../java/com/ff/base/enums/BannerStatus.java | 25 + .../java/com/ff/base/enums/BetTaskSource.java | 39 + .../java/com/ff/base/enums/BetTaskStatus.java | 38 + .../java/com/ff/base/enums/BoxStatusType.java | 25 + .../com/ff/base/enums/BusinessStatus.java | 20 + .../java/com/ff/base/enums/BusinessType.java | 59 + .../java/com/ff/base/enums/CalcModeType.java | 25 + .../ff/base/enums/CalcPerformanceType.java | 26 + .../java/com/ff/base/enums/CalcRangeType.java | 24 + .../java/com/ff/base/enums/CalculateType.java | 28 + .../java/com/ff/base/enums/ChangeStatus.java | 28 + .../java/com/ff/base/enums/ChannelType.java | 27 + .../com/ff/base/enums/ChargeOrderFlag.java | 23 + .../ff/base/enums/ChargeOrderPayStatus.java | 43 + .../main/java/com/ff/base/enums/CostType.java | 24 + .../com/ff/base/enums/DataSourceType.java | 19 + .../com/ff/base/enums/DesensitizedType.java | 60 + .../java/com/ff/base/enums/DeviceType.java | 27 + .../com/ff/base/enums/DirectFlagType.java | 26 + .../base/enums/DiscountReceiveSmallType.java | 63 + .../ff/base/enums/DiscountReceiveSource.java | 28 + .../ff/base/enums/DiscountReceiveStatus.java | 30 + .../java/com/ff/base/enums/DnsRecordType.java | 38 + .../ff/base/enums/DomainCloudfareStatus.java | 25 + .../java/com/ff/base/enums/DomainSonType.java | 27 + .../ff/base/enums/DomainSonUsageStatus.java | 26 + .../java/com/ff/base/enums/DomainStatus.java | 27 + .../java/com/ff/base/enums/DomainType.java | 24 + .../java/com/ff/base/enums/DownloadType.java | 23 + .../main/java/com/ff/base/enums/DrawType.java | 22 + .../java/com/ff/base/enums/EnableStatus.java | 24 + .../java/com/ff/base/enums/EventType.java | 22 + .../com/ff/base/enums/FeedbackStatus.java | 24 + .../java/com/ff/base/enums/FrameStatus.java | 26 + .../java/com/ff/base/enums/FreeStatus.java | 31 + .../java/com/ff/base/enums/FyPayStatus.java | 44 + .../ff/base/enums/GameCollectionStatus.java | 30 + .../java/com/ff/base/enums/GameEventEnum.java | 22 + .../java/com/ff/base/enums/GameHotStatus.java | 29 + .../com/ff/base/enums/GameOpenStatus.java | 29 + .../java/com/ff/base/enums/GamePlatforms.java | 28 + .../com/ff/base/enums/GamePlayStatus.java | 30 + .../ff/base/enums/GamePopularCategory.java | 29 + .../com/ff/base/enums/GamePopularStatus.java | 29 + .../com/ff/base/enums/GamePopularType.java | 29 + .../java/com/ff/base/enums/GameStatus.java | 30 + .../java/com/ff/base/enums/HttpMethod.java | 37 + .../com/ff/base/enums/InitiatingType.java | 22 + .../java/com/ff/base/enums/JILIGameType.java | 73 + .../main/java/com/ff/base/enums/LangType.java | 23 + .../com/ff/base/enums/LayoutLoginType.java | 23 + .../java/com/ff/base/enums/LimitType.java | 20 + .../java/com/ff/base/enums/LinkPosition.java | 27 + .../java/com/ff/base/enums/LoadStatus.java | 26 + .../main/java/com/ff/base/enums/LoopType.java | 23 + .../java/com/ff/base/enums/MarqueeStatus.java | 25 + .../ff/base/enums/MemberLogOperProject.java | 47 + .../com/ff/base/enums/MemberLogOperType.java | 29 + .../java/com/ff/base/enums/MemberStatus.java | 53 + .../java/com/ff/base/enums/NoticeStatus.java | 25 + .../java/com/ff/base/enums/NoticeType.java | 28 + .../java/com/ff/base/enums/OperationType.java | 23 + .../java/com/ff/base/enums/OperatorType.java | 24 + .../main/java/com/ff/base/enums/PageType.java | 37 + .../com/ff/base/enums/PatternSourceType.java | 25 + .../main/java/com/ff/base/enums/PlayType.java | 23 + .../java/com/ff/base/enums/ReadStatus.java | 23 + .../base/enums/RealtimeRebateReceiveType.java | 21 + .../base/enums/RealtimeRebateSettleType.java | 24 + .../ff/base/enums/RebateSettlePeriodType.java | 26 + .../java/com/ff/base/enums/ReceiptType.java | 26 + .../com/ff/base/enums/ReceiveLimitType.java | 36 + .../com/ff/base/enums/ReceiveTimeType.java | 27 + .../java/com/ff/base/enums/RegisteWay.java | 25 + .../java/com/ff/base/enums/RepairStatus.java | 33 + .../main/java/com/ff/base/enums/SetType.java | 26 + .../com/ff/base/enums/SettleDurationType.java | 36 + .../java/com/ff/base/enums/SettleStatus.java | 24 + .../main/java/com/ff/base/enums/SonType.java | 23 + .../java/com/ff/base/enums/StopStatus.java | 25 + .../java/com/ff/base/enums/SupplierCode.java | 36 + .../java/com/ff/base/enums/SysUseType.java | 21 + .../java/com/ff/base/enums/TaskBindType.java | 49 + .../java/com/ff/base/enums/TaskGiveType.java | 21 + .../main/java/com/ff/base/enums/TaskType.java | 27 + .../com/ff/base/enums/TimePeriodType.java | 42 + .../main/java/com/ff/base/enums/TimeType.java | 26 + .../main/java/com/ff/base/enums/Tourist.java | 23 + .../com/ff/base/enums/TrackEventType.java | 41 + .../java/com/ff/base/enums/TransferType.java | 30 + .../java/com/ff/base/enums/UsageStatus.java | 23 + .../java/com/ff/base/enums/UserStatus.java | 30 + .../java/com/ff/base/enums/WindowStatus.java | 23 + .../java/com/ff/base/enums/WindowType.java | 25 + .../ff/base/enums/WithdrawAccountStatus.java | 25 + .../ff/base/enums/WithdrawBehalfStatus.java | 27 + .../com/ff/base/enums/WithdrawStatus.java | 49 + .../com/ff/base/enums/WithdrawTipStatus.java | 24 + .../java/com/ff/base/enums/XKGameType.java | 74 + .../java/com/ff/base/enums/XjPayStatus.java | 41 + .../ff/base/exception/DemoModeException.java | 15 + .../ff/base/exception/GlobalException.java | 58 + .../ff/base/exception/ServiceException.java | 74 + .../com/ff/base/exception/UtilException.java | 26 + .../ff/base/exception/base/BaseException.java | 97 + .../ff/base/exception/file/FileException.java | 19 + .../FileNameLengthLimitExceededException.java | 16 + .../file/FileSizeLimitExceededException.java | 16 + .../exception/file/FileUploadException.java | 61 + .../file/InvalidExtensionException.java | 80 + .../ff/base/exception/job/TaskException.java | 34 + .../exception/user/BlackListException.java | 16 + .../base/exception/user/CaptchaException.java | 16 + .../user/CaptchaExpireException.java | 18 + .../ff/base/exception/user/UserException.java | 18 + .../user/UserNotExistsException.java | 16 + .../user/UserPasswordNotMatchException.java | 18 + ...UserPasswordRetryLimitExceedException.java | 18 + .../base/filter/PropertyPreExcludeFilter.java | 24 + .../com/ff/base/filter/RepeatableFilter.java | 48 + .../base/filter/RepeatedlyRequestWrapper.java | 77 + .../java/com/ff/base/filter/XssFilter.java | 72 + .../filter/XssHttpServletRequestWrapper.java | 112 + .../DataSourceSwitchInterceptor.java | 52 + .../interceptor/RepeatSubmitInterceptor.java | 57 + .../impl/SameUrlDataInterceptor.java | 111 + .../com/ff/base/manager/AsyncManager.java | 75 + .../com/ff/base/manager/ShutdownManager.java | 40 + .../ff/base/manager/factory/AsyncFactory.java | 103 + .../context/AuthenticationContextHolder.java | 28 + .../context/PermissionContextHolder.java | 27 + .../encode/CustomMd5PasswordEncoder.java | 38 + .../filter/JwtAuthenticationTokenFilter.java | 90 + .../handle/AuthenticationEntryPointImpl.java | 35 + .../handle/LogoutSuccessHandlerImpl.java | 54 + .../provider/MyDaoAuthenticationProvider.java | 141 ++ .../com/ff/base/system/domain/SysConfig.java | 112 + .../ff/base/system/domain/SysDatasource.java | 52 + .../com/ff/base/system/domain/SysDept.java | 204 ++ .../ff/base/system/domain/SysDictData.java | 199 ++ .../ff/base/system/domain/SysDictType.java | 97 + .../ff/base/system/domain/SysLogininfor.java | 144 ++ .../com/ff/base/system/domain/SysMenu.java | 275 +++ .../com/ff/base/system/domain/SysOperLog.java | 269 ++ .../com/ff/base/system/domain/SysPost.java | 125 + .../com/ff/base/system/domain/SysRole.java | 242 ++ .../ff/base/system/domain/SysRoleDept.java | 46 + .../ff/base/system/domain/SysRoleMenu.java | 46 + .../com/ff/base/system/domain/SysUser.java | 352 +++ .../ff/base/system/domain/SysUserOnline.java | 113 + .../ff/base/system/domain/SysUserPost.java | 46 + .../ff/base/system/domain/SysUserRole.java | 46 + .../com/ff/base/system/domain/vo/MetaVo.java | 106 + .../ff/base/system/domain/vo/RouterVo.java | 149 ++ .../base/system/mapper/SysConfigMapper.java | 85 + .../system/mapper/SysDatasourceMapper.java | 70 + .../ff/base/system/mapper/SysDeptMapper.java | 119 + .../base/system/mapper/SysDictDataMapper.java | 96 + .../base/system/mapper/SysDictTypeMapper.java | 84 + .../system/mapper/SysLogininforMapper.java | 43 + .../ff/base/system/mapper/SysMenuMapper.java | 126 + .../base/system/mapper/SysOperLogMapper.java | 49 + .../ff/base/system/mapper/SysPostMapper.java | 100 + .../base/system/mapper/SysRoleDeptMapper.java | 45 + .../ff/base/system/mapper/SysRoleMapper.java | 108 + .../base/system/mapper/SysRoleMenuMapper.java | 45 + .../ff/base/system/mapper/SysUserMapper.java | 135 + .../base/system/mapper/SysUserPostMapper.java | 45 + .../base/system/mapper/SysUserRoleMapper.java | 63 + .../system/service/ISysConfigService.java | 98 + .../system/service/ISysDatasourceService.java | 78 + .../base/system/service/ISysDeptService.java | 125 + .../system/service/ISysDictDataService.java | 61 + .../system/service/ISysDictTypeService.java | 99 + .../system/service/ISysLogininforService.java | 41 + .../base/system/service/ISysMenuService.java | 145 ++ .../system/service/ISysOperLogService.java | 49 + .../base/system/service/ISysPostService.java | 100 + .../base/system/service/ISysRoleService.java | 174 ++ .../system/service/ISysUserOnlineService.java | 48 + .../base/system/service/ISysUserService.java | 214 ++ .../service/impl/SysConfigServiceImpl.java | 227 ++ .../impl/SysDatasourceServiceImpl.java | 129 + .../service/impl/SysDeptServiceImpl.java | 339 +++ .../service/impl/SysDictDataServiceImpl.java | 112 + .../service/impl/SysDictTypeServiceImpl.java | 204 ++ .../impl/SysLogininforServiceImpl.java | 66 + .../service/impl/SysMenuServiceImpl.java | 538 ++++ .../service/impl/SysOperLogServiceImpl.java | 77 + .../service/impl/SysPostServiceImpl.java | 179 ++ .../service/impl/SysRoleServiceImpl.java | 424 ++++ .../impl/SysUserOnlineServiceImpl.java | 96 + .../service/impl/SysUserServiceImpl.java | 557 +++++ .../main/java/com/ff/base/utils/Arith.java | 114 + .../java/com/ff/base/utils/DateUtils.java | 896 +++++++ .../com/ff/base/utils/DesensitizedUtil.java | 51 + .../java/com/ff/base/utils/DictUtils.java | 240 ++ .../java/com/ff/base/utils/ExceptionUtil.java | 40 + .../main/java/com/ff/base/utils/JsonUtil.java | 118 + .../main/java/com/ff/base/utils/LogUtils.java | 18 + .../java/com/ff/base/utils/MessageUtils.java | 26 + .../java/com/ff/base/utils/NumberUtils.java | 60 + .../java/com/ff/base/utils/PageUtils.java | 35 + .../java/com/ff/base/utils/SecurityUtils.java | 243 ++ .../java/com/ff/base/utils/ServletUtils.java | 220 ++ .../ff/base/utils/SnowflakeIdGenerator.java | 73 + .../java/com/ff/base/utils/StringUtils.java | 610 +++++ .../java/com/ff/base/utils/TenantUtils.java | 53 + .../main/java/com/ff/base/utils/Threads.java | 96 + .../com/ff/base/utils/bean/BeanUtils.java | 143 ++ .../ff/base/utils/bean/BeanValidators.java | 24 + .../com/ff/base/utils/domain/DomainInfo.java | 142 ++ .../com/ff/base/utils/domain/DomainUtils.java | 178 ++ .../com/ff/base/utils/file/FileTypeUtils.java | 77 + .../ff/base/utils/file/FileUploadUtils.java | 234 ++ .../com/ff/base/utils/file/FileUtils.java | 384 +++ .../com/ff/base/utils/file/ImageUtils.java | 99 + .../com/ff/base/utils/file/MimeTypeUtils.java | 59 + .../com/ff/base/utils/html/EscapeUtil.java | 168 ++ .../com/ff/base/utils/html/HTMLFilter.java | 566 +++++ .../base/utils/http/HttpClientSslUtils.java | 451 ++++ .../com/ff/base/utils/http/HttpHelper.java | 56 + .../com/ff/base/utils/http/HttpUtils.java | 326 +++ .../com/ff/base/utils/ip/AddressUtils.java | 56 + .../java/com/ff/base/utils/ip/IpUtils.java | 383 +++ .../com/ff/base/utils/nginx/NginxUtils.java | 94 + .../base/utils/poi/ExcelHandlerAdapter.java | 24 + .../java/com/ff/base/utils/poi/ExcelUtil.java | 1768 +++++++++++++ .../ff/base/utils/qrcode/QRCodeGenerator.java | 28 + .../ff/base/utils/reflect/ReflectUtils.java | 406 +++ .../java/com/ff/base/utils/sign/Base64.java | 291 +++ .../java/com/ff/base/utils/sign/Md5Utils.java | 109 + .../com/ff/base/utils/spring/SpringUtils.java | 158 ++ .../java/com/ff/base/utils/sql/SqlUtil.java | 70 + .../java/com/ff/base/utils/uuid/IdUtils.java | 51 + .../main/java/com/ff/base/utils/uuid/Seq.java | 87 + .../java/com/ff/base/utils/uuid/UUID.java | 485 ++++ .../com/ff/base/web/domain/server/Cpu.java | 101 + .../com/ff/base/web/domain/server/Jvm.java | 131 + .../com/ff/base/web/domain/server/Mem.java | 61 + .../com/ff/base/web/domain/server/Sys.java | 84 + .../ff/base/web/domain/server/SysFile.java | 114 + .../web/exception/GlobalExceptionHandler.java | 146 ++ .../web/service/MemberDetailsServiceImpl.java | 59 + .../base/web/service/PermissionService.java | 160 ++ .../ff/base/web/service/SysLoginService.java | 183 ++ .../base/web/service/SysPasswordService.java | 89 + .../web/service/SysPermissionService.java | 84 + .../base/web/service/SysRegisterService.java | 115 + .../com/ff/base/web/service/TokenService.java | 232 ++ .../web/service/UserDetailsServiceImpl.java | 66 + .../src/main/java/com/ff/base/xss/Xss.java | 29 + .../java/com/ff/base/xss/XssValidator.java | 40 + .../mapper/system/SysConfigMapper.xml | 132 + .../mapper/system/SysDatasourceMapper.xml | 115 + .../resources/mapper/system/SysDeptMapper.xml | 159 ++ .../mapper/system/SysDictDataMapper.xml | 125 + .../mapper/system/SysDictTypeMapper.xml | 107 + .../mapper/system/SysLogininforMapper.xml | 57 + .../resources/mapper/system/SysMenuMapper.xml | 206 ++ .../mapper/system/SysOperLogMapper.xml | 87 + .../resources/mapper/system/SysPostMapper.xml | 122 + .../mapper/system/SysRoleDeptMapper.xml | 34 + .../resources/mapper/system/SysRoleMapper.xml | 154 ++ .../mapper/system/SysRoleMenuMapper.xml | 34 + .../resources/mapper/system/SysUserMapper.xml | 246 ++ .../mapper/system/SysUserPostMapper.xml | 34 + .../mapper/system/SysUserRoleMapper.xml | 44 + .../com/ff/base/annotation/Anonymous.class | Bin 0 -> 446 bytes .../com/ff/base/annotation/DataScope.class | Bin 0 -> 568 bytes .../com/ff/base/annotation/DataSource.class | Bin 0 -> 611 bytes .../ff/base/annotation/Excel$ColumnType.class | Bin 0 -> 1381 bytes .../com/ff/base/annotation/Excel$Type.class | Bin 0 -> 1288 bytes .../com/ff/base/annotation/Excel.class | Bin 0 -> 2016 bytes .../com/ff/base/annotation/Excels.class | Bin 0 -> 431 bytes .../classes/com/ff/base/annotation/Log.class | Bin 0 -> 886 bytes .../com/ff/base/annotation/RateLimiter.class | Bin 0 -> 690 bytes .../com/ff/base/annotation/RepeatSubmit.class | Bin 0 -> 630 bytes .../com/ff/base/annotation/Sensitive.class | Bin 0 -> 662 bytes .../com/ff/base/aspectj/DataScopeAspect.class | Bin 0 -> 6521 bytes .../ff/base/aspectj/DataSourceAspect.class | Bin 0 -> 2707 bytes .../com/ff/base/aspectj/LogAspect.class | Bin 0 -> 9647 bytes .../ff/base/aspectj/RateLimiterAspect.class | Bin 0 -> 4975 bytes .../ff/base/config/ApplicationConfig.class | Bin 0 -> 1852 bytes .../com/ff/base/config/AsyncConfig.class | Bin 0 -> 455 bytes .../com/ff/base/config/CaptchaConfig.class | Bin 0 -> 2411 bytes .../com/ff/base/config/DruidConfig$1.class | Bin 0 -> 2067 bytes .../com/ff/base/config/DruidConfig.class | Bin 0 -> 4119 bytes .../classes/com/ff/base/config/FFConfig.class | Bin 0 -> 2172 bytes .../config/FastJson2JsonRedisSerializer.class | Bin 0 -> 2730 bytes .../com/ff/base/config/FilterConfig.class | Bin 0 -> 2355 bytes .../com/ff/base/config/I18nConfig.class | Bin 0 -> 3047 bytes .../com/ff/base/config/IdGeneratorUtil.class | Bin 0 -> 1102 bytes .../com/ff/base/config/JacksonConfig.class | Bin 0 -> 1878 bytes .../ff/base/config/KaptchaTextCreator.class | Bin 0 -> 1695 bytes .../com/ff/base/config/MyBatisConfig.class | Bin 0 -> 6361 bytes .../com/ff/base/config/RedisConfig.class | Bin 0 -> 3068 bytes .../com/ff/base/config/ResourcesConfig.class | Bin 0 -> 4169 bytes .../com/ff/base/config/SecurityConfig.class | Bin 0 -> 11516 bytes .../com/ff/base/config/ServerConfig.class | Bin 0 -> 1402 bytes .../ff/base/config/ThreadPoolConfig$1.class | Bin 0 -> 1247 bytes .../com/ff/base/config/ThreadPoolConfig.class | Bin 0 -> 2282 bytes .../config/properties/DruidProperties.class | Bin 0 -> 2664 bytes .../properties/PermitAllUrlProperties.class | Bin 0 -> 5794 bytes .../serializer/SensitiveJsonSerializer.class | Bin 0 -> 3657 bytes .../ff/base/constant/BusinessConstants.class | Bin 0 -> 1070 bytes .../com/ff/base/constant/CacheConstants.class | Bin 0 -> 959 bytes .../ff/base/constant/ConfigConstants.class | Bin 0 -> 1328 bytes .../com/ff/base/constant/Constants.class | Bin 0 -> 2677 bytes .../com/ff/base/constant/GenConstants.class | Bin 0 -> 2779 bytes .../com/ff/base/constant/HttpStatus.class | Bin 0 -> 949 bytes .../constant/ScheduleConstants$Status.class | Bin 0 -> 1414 bytes .../ff/base/constant/ScheduleConstants.class | Bin 0 -> 704 bytes .../com/ff/base/constant/UserConstants.class | Bin 0 -> 1149 bytes .../core/controller/BaseController$1.class | Bin 0 -> 939 bytes .../base/core/controller/BaseController.class | Bin 0 -> 4563 bytes .../com/ff/base/core/domain/AjaxResult.class | Bin 0 -> 3070 bytes .../com/ff/base/core/domain/BaseEntity.class | Bin 0 -> 5616 bytes .../com/ff/base/core/domain/TreeEntity.class | Bin 0 -> 3722 bytes .../com/ff/base/core/domain/TreeSelect.class | Bin 0 -> 4735 bytes .../ff/base/core/domain/model/LoginBody.class | Bin 0 -> 2665 bytes .../ff/base/core/domain/model/LoginForm.class | Bin 0 -> 4344 bytes .../ff/base/core/domain/model/LoginUser.class | Bin 0 -> 8754 bytes .../base/core/domain/model/RegisterBody.class | Bin 0 -> 344 bytes .../com/ff/base/core/page/PageDomain.class | Bin 0 -> 4002 bytes .../com/ff/base/core/page/TableDataInfo.class | Bin 0 -> 1614 bytes .../com/ff/base/core/page/TableSupport.class | Bin 0 -> 1481 bytes .../com/ff/base/core/redis/RedisCache.class | Bin 0 -> 8497 bytes .../com/ff/base/core/text/CharsetKit.class | Bin 0 -> 1808 bytes .../com/ff/base/core/text/Convert.class | Bin 0 -> 14124 bytes .../com/ff/base/core/text/StrFormatter.class | Bin 0 -> 1836 bytes .../base/datasource/DynamicDataSource.class | Bin 0 -> 3544 bytes .../DynamicDataSourceContextHolder.class | Bin 0 -> 1891 bytes .../decorator/ContextCopyingDecorator.class | Bin 0 -> 2851 bytes .../ff/base/enums/AccountAuditStatus.class | Bin 0 -> 1589 bytes .../com/ff/base/enums/AccountChangeType.class | Bin 0 -> 2613 bytes .../com/ff/base/enums/AccountType.class | Bin 0 -> 1502 bytes .../base/enums/ActivityBetPlatformType.class | Bin 0 -> 1519 bytes .../ff/base/enums/ActivityBetSendStatus.class | Bin 0 -> 1786 bytes .../ff/base/enums/ActivityBetSendWay.class | Bin 0 -> 1682 bytes .../ActivityChargeReceiveLimitType.class | Bin 0 -> 2867 bytes .../enums/ActivityChargeRepeatReceive.class | Bin 0 -> 1537 bytes .../base/enums/ActivityChargeRewardType.class | Bin 0 -> 1604 bytes .../base/enums/ActivityChargeRuleType.class | Bin 0 -> 1590 bytes .../base/enums/ActivityChargeSendStatus.class | Bin 0 -> 1516 bytes .../ff/base/enums/ActivityChargeSendWay.class | Bin 0 -> 1612 bytes .../ActivityExtensionAccordCondition.class | Bin 0 -> 1579 bytes .../enums/ActivityExtensionChargeStatus.class | Bin 0 -> 1561 bytes .../enums/ActivityExtensionChargeType.class | Bin 0 -> 1643 bytes .../enums/ActivityExtensionLoginApp.class | Bin 0 -> 1513 bytes .../enums/ActivityExtensionRewardType.class | Bin 0 -> 1631 bytes .../enums/ActivityExtensionSendStatus.class | Bin 0 -> 1920 bytes .../base/enums/ActivityExtensionSendWay.class | Bin 0 -> 1724 bytes .../base/enums/ActivityLimitedTimeDay.class | Bin 0 -> 1498 bytes .../com/ff/base/enums/ActivityLoopType.class | Bin 0 -> 1603 bytes .../ff/base/enums/ActivityMainEntrance.class | Bin 0 -> 1486 bytes .../ff/base/enums/ActivityReceiveCount.class | Bin 0 -> 1524 bytes .../base/enums/ActivityReceiveLimitType.class | Bin 0 -> 2706 bytes .../enums/ActivityRewardAuditStatus.class | Bin 0 -> 1605 bytes .../ff/base/enums/ActivityShowStatus.class | Bin 0 -> 1452 bytes .../com/ff/base/enums/ActivityStatus.class | Bin 0 -> 1857 bytes .../ff/base/enums/ActivityTemplateType.class | Bin 0 -> 3307 bytes .../com/ff/base/enums/AgentModelType.class | Bin 0 -> 2385 bytes .../ff/base/enums/AndroidForceDownload.class | Bin 0 -> 1501 bytes .../ff/base/enums/AnnouncementStatus.class | Bin 0 -> 1814 bytes .../com/ff/base/enums/AppLocation.class | Bin 0 -> 1529 bytes .../classes/com/ff/base/enums/AwardType.class | Bin 0 -> 1499 bytes .../com/ff/base/enums/BannerStatus.class | Bin 0 -> 1772 bytes .../com/ff/base/enums/BetTaskSource.class | Bin 0 -> 2074 bytes .../com/ff/base/enums/BetTaskStatus.class | Bin 0 -> 1811 bytes .../com/ff/base/enums/BoxStatusType.class | Bin 0 -> 1539 bytes .../com/ff/base/enums/BusinessStatus.class | Bin 0 -> 1015 bytes .../com/ff/base/enums/BusinessType.class | Bin 0 -> 1432 bytes .../com/ff/base/enums/CalcModeType.class | Bin 0 -> 1471 bytes .../ff/base/enums/CalcPerformanceType.class | Bin 0 -> 1599 bytes .../com/ff/base/enums/CalcRangeType.class | Bin 0 -> 1477 bytes .../com/ff/base/enums/CalculateType.class | Bin 0 -> 2083 bytes .../com/ff/base/enums/ChangeStatus.class | Bin 0 -> 1509 bytes .../com/ff/base/enums/ChannelType.class | Bin 0 -> 1935 bytes .../com/ff/base/enums/ChargeOrderFlag.class | Bin 0 -> 1558 bytes .../ff/base/enums/ChargeOrderPayStatus.class | Bin 0 -> 3623 bytes .../classes/com/ff/base/enums/CostType.class | Bin 0 -> 1561 bytes .../com/ff/base/enums/DataSourceType.class | Bin 0 -> 1015 bytes .../com/ff/base/enums/DesensitizedType.class | Bin 0 -> 3355 bytes .../com/ff/base/enums/DeviceType.class | Bin 0 -> 1713 bytes .../com/ff/base/enums/DirectFlagType.class | Bin 0 -> 1544 bytes .../base/enums/DiscountReceiveSmallType.class | Bin 0 -> 4664 bytes .../ff/base/enums/DiscountReceiveSource.class | Bin 0 -> 1644 bytes .../ff/base/enums/DiscountReceiveStatus.class | Bin 0 -> 2079 bytes .../com/ff/base/enums/DnsRecordType.class | Bin 0 -> 2068 bytes .../ff/base/enums/DomainCloudfareStatus.class | Bin 0 -> 1613 bytes .../com/ff/base/enums/DomainSonType.class | Bin 0 -> 1892 bytes .../ff/base/enums/DomainSonUsageStatus.class | Bin 0 -> 1852 bytes .../com/ff/base/enums/DomainStatus.class | Bin 0 -> 1560 bytes .../com/ff/base/enums/DomainType.class | Bin 0 -> 1477 bytes .../com/ff/base/enums/DownloadType.class | Bin 0 -> 1541 bytes .../classes/com/ff/base/enums/DrawType.class | Bin 0 -> 1406 bytes .../com/ff/base/enums/EnableStatus.class | Bin 0 -> 1503 bytes .../classes/com/ff/base/enums/EventType.class | Bin 0 -> 1499 bytes .../com/ff/base/enums/FeedbackStatus.class | Bin 0 -> 1622 bytes .../com/ff/base/enums/FrameStatus.class | Bin 0 -> 1765 bytes .../com/ff/base/enums/FreeStatus.class | Bin 0 -> 1496 bytes .../com/ff/base/enums/FyPayStatus.class | Bin 0 -> 3619 bytes .../ff/base/enums/GameCollectionStatus.class | Bin 0 -> 1572 bytes .../com/ff/base/enums/GameEventEnum.class | Bin 0 -> 1486 bytes .../com/ff/base/enums/GameHotStatus.class | Bin 0 -> 1419 bytes .../com/ff/base/enums/GameOpenStatus.class | Bin 0 -> 1522 bytes .../com/ff/base/enums/GamePlatforms.class | Bin 0 -> 1377 bytes .../com/ff/base/enums/GamePlayStatus.class | Bin 0 -> 1604 bytes .../ff/base/enums/GamePopularCategory.class | Bin 0 -> 1562 bytes .../com/ff/base/enums/GamePopularStatus.class | Bin 0 -> 1554 bytes .../com/ff/base/enums/GamePopularType.class | Bin 0 -> 1547 bytes .../com/ff/base/enums/GameStatus.class | Bin 0 -> 1551 bytes .../com/ff/base/enums/HttpMethod.class | Bin 0 -> 2140 bytes .../com/ff/base/enums/InitiatingType.class | Bin 0 -> 1556 bytes .../com/ff/base/enums/JILIGameType.class | Bin 0 -> 4112 bytes .../classes/com/ff/base/enums/LangType.class | Bin 0 -> 1376 bytes .../com/ff/base/enums/LayoutLoginType.class | Bin 0 -> 1540 bytes .../classes/com/ff/base/enums/LimitType.class | Bin 0 -> 978 bytes .../com/ff/base/enums/LinkPosition.class | Bin 0 -> 1782 bytes .../com/ff/base/enums/LoadStatus.class | Bin 0 -> 1758 bytes .../classes/com/ff/base/enums/LoopType.class | Bin 0 -> 1545 bytes .../com/ff/base/enums/MarqueeStatus.class | Bin 0 -> 1780 bytes .../ff/base/enums/MemberLogOperProject.class | Bin 0 -> 3188 bytes .../com/ff/base/enums/MemberLogOperType.class | Bin 0 -> 1537 bytes .../com/ff/base/enums/MemberStatus.class | Bin 0 -> 2587 bytes .../com/ff/base/enums/NoticeStatus.class | Bin 0 -> 1688 bytes .../com/ff/base/enums/NoticeType.class | Bin 0 -> 1828 bytes .../com/ff/base/enums/OperationType.class | Bin 0 -> 1492 bytes .../com/ff/base/enums/OperatorType.class | Bin 0 -> 1054 bytes .../classes/com/ff/base/enums/PageType.class | Bin 0 -> 2023 bytes .../com/ff/base/enums/PatternSourceType.class | Bin 0 -> 1484 bytes .../classes/com/ff/base/enums/PlayType.class | Bin 0 -> 1524 bytes .../com/ff/base/enums/ReadStatus.class | Bin 0 -> 1512 bytes .../enums/RealtimeRebateReceiveType.class | Bin 0 -> 1567 bytes .../base/enums/RealtimeRebateSettleType.class | Bin 0 -> 1684 bytes .../base/enums/RebateSettlePeriodType.class | Bin 0 -> 1821 bytes .../com/ff/base/enums/ReceiptType.class | Bin 0 -> 1706 bytes .../com/ff/base/enums/ReceiveLimitType.class | Bin 0 -> 2786 bytes .../com/ff/base/enums/ReceiveTimeType.class | Bin 0 -> 1902 bytes .../com/ff/base/enums/RegisteWay.class | Bin 0 -> 1655 bytes .../com/ff/base/enums/RepairStatus.class | Bin 0 -> 1529 bytes .../classes/com/ff/base/enums/SetType.class | Bin 0 -> 1496 bytes .../ff/base/enums/SettleDurationType.class | Bin 0 -> 2131 bytes .../com/ff/base/enums/SettleStatus.class | Bin 0 -> 1532 bytes .../classes/com/ff/base/enums/SonType.class | Bin 0 -> 1529 bytes .../com/ff/base/enums/StopStatus.class | Bin 0 -> 1508 bytes .../com/ff/base/enums/SupplierCode.class | Bin 0 -> 2564 bytes .../com/ff/base/enums/SysUseType.class | Bin 0 -> 1532 bytes .../com/ff/base/enums/TaskBindType.class | Bin 0 -> 3251 bytes .../com/ff/base/enums/TaskGiveType.class | Bin 0 -> 1538 bytes .../classes/com/ff/base/enums/TaskType.class | Bin 0 -> 1748 bytes .../com/ff/base/enums/TimePeriodType.class | Bin 0 -> 2630 bytes .../classes/com/ff/base/enums/TimeType.class | Bin 0 -> 1751 bytes .../classes/com/ff/base/enums/Tourist.class | Bin 0 -> 1506 bytes .../com/ff/base/enums/TrackEventType.class | Bin 0 -> 3398 bytes .../com/ff/base/enums/TransferType.class | Bin 0 -> 1705 bytes .../com/ff/base/enums/UsageStatus.class | Bin 0 -> 1536 bytes .../com/ff/base/enums/UserStatus.class | Bin 0 -> 1466 bytes .../com/ff/base/enums/WindowStatus.class | Bin 0 -> 1538 bytes .../com/ff/base/enums/WindowType.class | Bin 0 -> 1728 bytes .../ff/base/enums/WithdrawAccountStatus.class | Bin 0 -> 1557 bytes .../ff/base/enums/WithdrawBehalfStatus.class | Bin 0 -> 1675 bytes .../com/ff/base/enums/WithdrawStatus.class | Bin 0 -> 3836 bytes .../com/ff/base/enums/WithdrawTipStatus.class | Bin 0 -> 1571 bytes .../com/ff/base/enums/XKGameType.class | Bin 0 -> 4090 bytes .../com/ff/base/enums/XjPayStatus.class | Bin 0 -> 3361 bytes .../ff/base/exception/DemoModeException.class | Bin 0 -> 398 bytes .../ff/base/exception/GlobalException.class | Bin 0 -> 1008 bytes .../ff/base/exception/ServiceException.class | Bin 0 -> 1300 bytes .../com/ff/base/exception/UtilException.class | Bin 0 -> 806 bytes .../base/exception/base/BaseException.class | Bin 0 -> 1968 bytes .../base/exception/file/FileException.class | Bin 0 -> 618 bytes ...FileNameLengthLimitExceededException.class | Bin 0 -> 699 bytes .../file/FileSizeLimitExceededException.class | Bin 0 -> 656 bytes .../exception/file/FileUploadException.class | Bin 0 -> 1371 bytes ...ption$InvalidFlashExtensionException.class | Bin 0 -> 757 bytes ...ption$InvalidImageExtensionException.class | Bin 0 -> 757 bytes ...ption$InvalidMediaExtensionException.class | Bin 0 -> 757 bytes ...ption$InvalidVideoExtensionException.class | Bin 0 -> 757 bytes .../file/InvalidExtensionException.class | Bin 0 -> 1870 bytes .../exception/job/TaskException$Code.class | Bin 0 -> 1407 bytes .../ff/base/exception/job/TaskException.class | Bin 0 -> 1065 bytes .../exception/user/BlackListException.class | Bin 0 -> 490 bytes .../exception/user/CaptchaException.class | Bin 0 -> 490 bytes .../user/CaptchaExpireException.class | Bin 0 -> 509 bytes .../base/exception/user/UserException.class | Bin 0 -> 618 bytes .../user/UserNotExistsException.class | Bin 0 -> 504 bytes .../user/UserPasswordNotMatchException.class | Bin 0 -> 533 bytes ...serPasswordRetryLimitExceedException.class | Bin 0 -> 728 bytes .../filter/PropertyPreExcludeFilter.class | Bin 0 -> 800 bytes .../com/ff/base/filter/RepeatableFilter.class | Bin 0 -> 1682 bytes .../filter/RepeatedlyRequestWrapper$1.class | Bin 0 -> 1403 bytes .../filter/RepeatedlyRequestWrapper.class | Bin 0 -> 1910 bytes .../com/ff/base/filter/XssFilter.class | Bin 0 -> 2859 bytes .../XssHttpServletRequestWrapper$1.class | Bin 0 -> 1394 bytes .../filter/XssHttpServletRequestWrapper.class | Bin 0 -> 2286 bytes .../DataSourceSwitchInterceptor.class | Bin 0 -> 1576 bytes .../interceptor/RepeatSubmitInterceptor.class | Bin 0 -> 2036 bytes .../impl/SameUrlDataInterceptor.class | Bin 0 -> 4489 bytes .../com/ff/base/manager/AsyncManager.class | Bin 0 -> 1948 bytes .../com/ff/base/manager/ShutdownManager.class | Bin 0 -> 1304 bytes .../base/manager/factory/AsyncFactory$1.class | Bin 0 -> 3156 bytes .../base/manager/factory/AsyncFactory$2.class | Bin 0 -> 1167 bytes .../base/manager/factory/AsyncFactory.class | Bin 0 -> 1993 bytes .../context/AuthenticationContextHolder.class | Bin 0 -> 1146 bytes .../context/PermissionContextHolder.class | Bin 0 -> 1132 bytes .../encode/CustomMd5PasswordEncoder.class | Bin 0 -> 1141 bytes .../filter/JwtAuthenticationTokenFilter.class | Bin 0 -> 4979 bytes .../handle/AuthenticationEntryPointImpl.class | Bin 0 -> 1827 bytes .../handle/LogoutSuccessHandlerImpl.class | Bin 0 -> 2666 bytes .../MyDaoAuthenticationProvider.class | Bin 0 -> 7677 bytes .../com/ff/base/system/domain/SysConfig.class | Bin 0 -> 3431 bytes .../ff/base/system/domain/SysDatasource.class | Bin 0 -> 5497 bytes .../com/ff/base/system/domain/SysDept.class | Bin 0 -> 4898 bytes .../SysDictData$DictDataSimpleView.class | Bin 0 -> 243 bytes .../ff/base/system/domain/SysDictData.class | Bin 0 -> 5192 bytes .../ff/base/system/domain/SysDictType.class | Bin 0 -> 3198 bytes .../ff/base/system/domain/SysLogininfor.class | Bin 0 -> 3025 bytes .../com/ff/base/system/domain/SysMenu.class | Bin 0 -> 6121 bytes .../ff/base/system/domain/SysOperLog.class | Bin 0 -> 5422 bytes .../com/ff/base/system/domain/SysPost.class | Bin 0 -> 3621 bytes .../com/ff/base/system/domain/SysRole.class | Bin 0 -> 6066 bytes .../ff/base/system/domain/SysRoleDept.class | Bin 0 -> 1301 bytes .../ff/base/system/domain/SysRoleMenu.class | Bin 0 -> 1301 bytes .../com/ff/base/system/domain/SysUser.class | Bin 0 -> 8218 bytes .../ff/base/system/domain/SysUserOnline.class | Bin 0 -> 1986 bytes .../ff/base/system/domain/SysUserPost.class | Bin 0 -> 1301 bytes .../ff/base/system/domain/SysUserRole.class | Bin 0 -> 1301 bytes .../com/ff/base/system/domain/vo/MetaVo.class | Bin 0 -> 1983 bytes .../ff/base/system/domain/vo/RouterVo.class | Bin 0 -> 2940 bytes .../base/system/mapper/SysConfigMapper.class | Bin 0 -> 834 bytes .../system/mapper/SysDatasourceMapper.class | Bin 0 -> 787 bytes .../ff/base/system/mapper/SysDeptMapper.class | Bin 0 -> 1418 bytes .../system/mapper/SysDictDataMapper.class | Bin 0 -> 1201 bytes .../system/mapper/SysDictTypeMapper.class | Bin 0 -> 881 bytes .../system/mapper/SysLogininforMapper.class | Bin 0 -> 524 bytes .../ff/base/system/mapper/SysMenuMapper.class | Bin 0 -> 1522 bytes .../base/system/mapper/SysOperLogMapper.class | Bin 0 -> 581 bytes .../ff/base/system/mapper/SysPostMapper.class | Bin 0 -> 1104 bytes .../system/mapper/SysRoleDeptMapper.class | Bin 0 -> 411 bytes .../ff/base/system/mapper/SysRoleMapper.class | Bin 0 -> 1224 bytes .../system/mapper/SysRoleMenuMapper.class | Bin 0 -> 402 bytes .../ff/base/system/mapper/SysUserMapper.class | Bin 0 -> 1141 bytes .../system/mapper/SysUserPostMapper.class | Bin 0 -> 401 bytes .../system/mapper/SysUserRoleMapper.class | Bin 0 -> 681 bytes .../system/service/ISysConfigService.class | Bin 0 -> 866 bytes .../service/ISysDatasourceService.class | Bin 0 -> 808 bytes .../base/system/service/ISysDeptService.class | Bin 0 -> 1376 bytes .../system/service/ISysDictDataService.class | Bin 0 -> 678 bytes .../system/service/ISysDictTypeService.class | Bin 0 -> 1121 bytes .../service/ISysLogininforService.class | Bin 0 -> 529 bytes .../base/system/service/ISysMenuService.class | Bin 0 -> 1638 bytes .../system/service/ISysOperLogService.class | Bin 0 -> 586 bytes .../base/system/service/ISysPostService.class | Bin 0 -> 965 bytes .../base/system/service/ISysRoleService.class | Bin 0 -> 1551 bytes .../service/ISysUserOnlineService.class | Bin 0 -> 590 bytes .../base/system/service/ISysUserService.class | Bin 0 -> 1654 bytes .../service/impl/SysConfigServiceImpl.class | Bin 0 -> 6633 bytes .../impl/SysDatasourceServiceImpl.class | Bin 0 -> 2717 bytes .../service/impl/SysDeptServiceImpl.class | Bin 0 -> 9794 bytes .../service/impl/SysDictDataServiceImpl.class | Bin 0 -> 2672 bytes .../service/impl/SysDictTypeServiceImpl.class | Bin 0 -> 7434 bytes .../impl/SysLogininforServiceImpl.class | Bin 0 -> 1489 bytes .../service/impl/SysMenuServiceImpl.class | Bin 0 -> 13946 bytes .../service/impl/SysOperLogServiceImpl.class | Bin 0 -> 1625 bytes .../service/impl/SysPostServiceImpl.class | Bin 0 -> 3663 bytes .../service/impl/SysRoleServiceImpl.class | Bin 0 -> 9134 bytes .../impl/SysUserOnlineServiceImpl.class | Bin 0 -> 2628 bytes .../service/impl/SysUserServiceImpl.class | Bin 0 -> 12946 bytes .../classes/com/ff/base/utils/Arith.class | Bin 0 -> 1934 bytes .../classes/com/ff/base/utils/DateUtils.class | Bin 0 -> 17951 bytes .../com/ff/base/utils/DesensitizedUtil.class | Bin 0 -> 892 bytes .../classes/com/ff/base/utils/DictUtils.class | Bin 0 -> 5111 bytes .../com/ff/base/utils/ExceptionUtil.class | Bin 0 -> 1338 bytes .../classes/com/ff/base/utils/JsonUtil.class | Bin 0 -> 5147 bytes .../classes/com/ff/base/utils/LogUtils.class | Bin 0 -> 658 bytes .../com/ff/base/utils/MessageUtils.class | Bin 0 -> 940 bytes .../com/ff/base/utils/NumberUtils.class | Bin 0 -> 2877 bytes .../classes/com/ff/base/utils/PageUtils.class | Bin 0 -> 1351 bytes .../com/ff/base/utils/SecurityUtils.class | Bin 0 -> 6633 bytes .../com/ff/base/utils/ServletUtils.class | Bin 0 -> 5961 bytes .../ff/base/utils/SnowflakeIdGenerator.class | Bin 0 -> 2072 bytes .../com/ff/base/utils/StringUtils.class | Bin 0 -> 10030 bytes .../com/ff/base/utils/TenantUtils.class | Bin 0 -> 1688 bytes .../classes/com/ff/base/utils/Threads.class | Bin 0 -> 2555 bytes .../com/ff/base/utils/bean/BeanUtils.class | Bin 0 -> 4275 bytes .../ff/base/utils/bean/BeanValidators.class | Bin 0 -> 1217 bytes .../utils/domain/DomainInfo$WhoisInfo.class | Bin 0 -> 8529 bytes .../com/ff/base/utils/domain/DomainInfo.class | Bin 0 -> 5362 bytes .../ff/base/utils/domain/DomainUtils.class | Bin 0 -> 5722 bytes .../ff/base/utils/file/FileTypeUtils.class | Bin 0 -> 1364 bytes .../ff/base/utils/file/FileUploadUtils.class | Bin 0 -> 5914 bytes .../com/ff/base/utils/file/FileUtils.class | Bin 0 -> 10396 bytes .../com/ff/base/utils/file/ImageUtils.class | Bin 0 -> 2862 bytes .../ff/base/utils/file/MimeTypeUtils.class | Bin 0 -> 1883 bytes .../com/ff/base/utils/html/EscapeUtil.class | Bin 0 -> 2961 bytes .../com/ff/base/utils/html/HTMLFilter.class | Bin 0 -> 13385 bytes .../utils/http/HttpClientSslUtils$1.class | Bin 0 -> 248 bytes .../HttpClientSslUtils$TrustAllCerts.class | Bin 0 -> 1301 bytes ...entSslUtils$TrustAllHostnameVerifier.class | Bin 0 -> 726 bytes ...entSslUtils$TrustAllX509TrustManager.class | Bin 0 -> 1256 bytes .../base/utils/http/HttpClientSslUtils.class | Bin 0 -> 17790 bytes .../com/ff/base/utils/http/HttpHelper.class | Bin 0 -> 2482 bytes .../com/ff/base/utils/http/HttpUtils$1.class | Bin 0 -> 221 bytes .../HttpUtils$TrustAnyHostnameVerifier.class | Bin 0 -> 900 bytes .../http/HttpUtils$TrustAnyTrustManager.class | Bin 0 -> 1181 bytes .../com/ff/base/utils/http/HttpUtils.class | Bin 0 -> 10958 bytes .../com/ff/base/utils/ip/AddressUtils.class | Bin 0 -> 2157 bytes .../com/ff/base/utils/ip/IpUtils.class | Bin 0 -> 6691 bytes .../com/ff/base/utils/nginx/NginxUtils.class | Bin 0 -> 4608 bytes .../base/utils/poi/ExcelHandlerAdapter.class | Bin 0 -> 290 bytes .../com/ff/base/utils/poi/ExcelUtil.class | Bin 0 -> 48209 bytes .../base/utils/qrcode/QRCodeGenerator.class | Bin 0 -> 1876 bytes .../ff/base/utils/reflect/ReflectUtils.class | Bin 0 -> 10852 bytes .../com/ff/base/utils/sign/Base64.class | Bin 0 -> 4493 bytes .../com/ff/base/utils/sign/Md5Utils.class | Bin 0 -> 3555 bytes .../ff/base/utils/spring/SpringUtils.class | Bin 0 -> 3418 bytes .../com/ff/base/utils/sql/SqlUtil.class | Bin 0 -> 1814 bytes .../com/ff/base/utils/uuid/IdUtils.class | Bin 0 -> 693 bytes .../classes/com/ff/base/utils/uuid/Seq.class | Bin 0 -> 1912 bytes .../com/ff/base/utils/uuid/UUID$Holder.class | Bin 0 -> 554 bytes .../classes/com/ff/base/utils/uuid/UUID.class | Bin 0 -> 6373 bytes .../com/ff/base/web/domain/server/Cpu.class | Bin 0 -> 1584 bytes .../com/ff/base/web/domain/server/Jvm.class | Bin 0 -> 2463 bytes .../com/ff/base/web/domain/server/Mem.class | Bin 0 -> 1070 bytes .../com/ff/base/web/domain/server/Sys.class | Bin 0 -> 1335 bytes .../ff/base/web/domain/server/SysFile.class | Bin 0 -> 1713 bytes .../exception/GlobalExceptionHandler.class | Bin 0 -> 7044 bytes .../service/MemberDetailsServiceImpl.class | Bin 0 -> 3123 bytes .../base/web/service/PermissionService.class | Bin 0 -> 3440 bytes .../ff/base/web/service/SysLoginService.class | Bin 0 -> 6603 bytes .../base/web/service/SysPasswordService.class | Bin 0 -> 3446 bytes .../web/service/SysPermissionService.class | Bin 0 -> 2553 bytes .../base/web/service/SysRegisterService.class | Bin 0 -> 4012 bytes .../ff/base/web/service/TokenService.class | Bin 0 -> 7282 bytes .../web/service/UserDetailsServiceImpl.class | Bin 0 -> 3226 bytes .../target/classes/com/ff/base/xss/Xss.class | Bin 0 -> 797 bytes .../com/ff/base/xss/XssValidator.class | Bin 0 -> 1825 bytes .../classes/mapper/system/SysConfigMapper.xml | 132 + .../mapper/system/SysDatasourceMapper.xml | 115 + .../classes/mapper/system/SysDeptMapper.xml | 159 ++ .../mapper/system/SysDictDataMapper.xml | 125 + .../mapper/system/SysDictTypeMapper.xml | 107 + .../mapper/system/SysLogininforMapper.xml | 57 + .../classes/mapper/system/SysMenuMapper.xml | 206 ++ .../mapper/system/SysOperLogMapper.xml | 87 + .../classes/mapper/system/SysPostMapper.xml | 122 + .../mapper/system/SysRoleDeptMapper.xml | 34 + .../classes/mapper/system/SysRoleMapper.xml | 154 ++ .../mapper/system/SysRoleMenuMapper.xml | 34 + .../classes/mapper/system/SysUserMapper.xml | 246 ++ .../mapper/system/SysUserPostMapper.xml | 34 + .../mapper/system/SysUserRoleMapper.xml | 44 + ff-gen/pom.xml | 49 + .../java/com/ff/gen/config/GenConfig.java | 73 + .../com/ff/gen/controller/GenController.java | 252 ++ .../main/java/com/ff/gen/domain/GenTable.java | 386 +++ .../com/ff/gen/domain/GenTableColumn.java | 374 +++ .../ff/gen/mapper/GenTableColumnMapper.java | 61 + .../com/ff/gen/mapper/GenTableMapper.java | 92 + .../service/GenTableColumnServiceImpl.java | 69 + .../ff/gen/service/GenTableServiceImpl.java | 532 ++++ .../gen/service/IGenTableColumnService.java | 45 + .../com/ff/gen/service/IGenTableService.java | 131 + .../main/java/com/ff/gen/util/GenUtils.java | 262 ++ .../com/ff/gen/util/VelocityInitializer.java | 35 + .../java/com/ff/gen/util/VelocityUtils.java | 409 +++ ff-gen/src/main/resources/generator.yml | 10 + .../mapper/gen/GenTableColumnMapper.xml | 127 + .../resources/mapper/gen/GenTableMapper.xml | 214 ++ .../main/resources/vm/java/controller.java.vm | 115 + .../src/main/resources/vm/java/domain.java.vm | 58 + .../src/main/resources/vm/java/mapper.java.vm | 91 + .../main/resources/vm/java/service.java.vm | 61 + .../resources/vm/java/serviceImpl.java.vm | 169 ++ .../main/resources/vm/java/sub-domain.java.vm | 76 + ff-gen/src/main/resources/vm/js/api.js.vm | 44 + ff-gen/src/main/resources/vm/sql/sql.vm | 22 + .../main/resources/vm/vue/index-tree.vue.vm | 505 ++++ ff-gen/src/main/resources/vm/vue/index.vue.vm | 602 +++++ .../resources/vm/vue/v3/index-tree.vue.vm | 474 ++++ .../src/main/resources/vm/vue/v3/index.vue.vm | 590 +++++ .../src/main/resources/vm/xml/mapper.xml.vm | 140 ++ .../classes/com/ff/gen/config/GenConfig.class | Bin 0 -> 1569 bytes .../com/ff/gen/controller/GenController.class | Bin 0 -> 9807 bytes .../classes/com/ff/gen/domain/GenTable.class | Bin 0 -> 7788 bytes .../com/ff/gen/domain/GenTableColumn.class | Bin 0 -> 7443 bytes .../ff/gen/mapper/GenTableColumnMapper.class | Bin 0 -> 753 bytes .../com/ff/gen/mapper/GenTableMapper.class | Bin 0 -> 944 bytes .../service/GenTableColumnServiceImpl.class | Bin 0 -> 1556 bytes .../ff/gen/service/GenTableServiceImpl.class | Bin 0 -> 15635 bytes .../gen/service/IGenTableColumnService.class | Bin 0 -> 480 bytes .../com/ff/gen/service/IGenTableService.class | Bin 0 -> 1296 bytes .../classes/com/ff/gen/util/GenUtils.class | Bin 0 -> 5795 bytes .../com/ff/gen/util/VelocityInitializer.class | Bin 0 -> 1050 bytes .../com/ff/gen/util/VelocityUtils.class | Bin 0 -> 10796 bytes ff-gen/target/classes/generator.yml | 10 + .../mapper/gen/GenTableColumnMapper.xml | 127 + .../classes/mapper/gen/GenTableMapper.xml | 214 ++ .../target/classes/vm/java/controller.java.vm | 115 + ff-gen/target/classes/vm/java/domain.java.vm | 58 + ff-gen/target/classes/vm/java/mapper.java.vm | 91 + ff-gen/target/classes/vm/java/service.java.vm | 61 + .../classes/vm/java/serviceImpl.java.vm | 169 ++ .../target/classes/vm/java/sub-domain.java.vm | 76 + ff-gen/target/classes/vm/js/api.js.vm | 44 + ff-gen/target/classes/vm/sql/sql.vm | 22 + .../target/classes/vm/vue/index-tree.vue.vm | 505 ++++ ff-gen/target/classes/vm/vue/index.vue.vm | 602 +++++ .../classes/vm/vue/v3/index-tree.vue.vm | 474 ++++ ff-gen/target/classes/vm/vue/v3/index.vue.vm | 590 +++++ ff-gen/target/classes/vm/xml/mapper.xml.vm | 140 ++ pom.xml | 254 ++ sh/linux/create.sh | 6 + sh/linux/nginx.sh | 41 + sh/linux/publish.sh | 15 + sh/linux/start-manager-api.sh | 20 + sh/win/create.bat | 6 + sh/win/publish.bat | 23 + sh/win/start.bat | 23 + sql/ff-admin.sql | 2186 +++++++++++++++++ sql/update_liukang.sql | 903 +++++++ sql/update_shi.sql | 422 ++++ sql/update_xiongshang.sql | 359 +++ 1041 files changed, 63875 insertions(+) create mode 100644 ff-admin/pom.xml create mode 100644 ff-admin/src/main/java/com/ff/FFApplication.java create mode 100644 ff-admin/src/main/java/com/ff/FFServletInitializer.java create mode 100644 ff-admin/src/main/java/com/ff/annotation/CheckHeader.java create mode 100644 ff-admin/src/main/java/com/ff/annotation/HeaderCheckAspect.java create mode 100644 ff-admin/src/main/java/com/ff/api/controller/ApiGameController.java create mode 100644 ff-admin/src/main/java/com/ff/api/controller/ApiMemberController.java create mode 100644 ff-admin/src/main/java/com/ff/api/request/GameLoginRequest.java create mode 100644 ff-admin/src/main/java/com/ff/api/request/MemberCreateApiRequest.java create mode 100644 ff-admin/src/main/java/com/ff/api/request/MemberInfoApiRequest.java create mode 100644 ff-admin/src/main/java/com/ff/common/controller/CaptchaController.java create mode 100644 ff-admin/src/main/java/com/ff/common/controller/CurrencyController.java create mode 100644 ff-admin/src/main/java/com/ff/common/controller/LangController.java create mode 100644 ff-admin/src/main/java/com/ff/common/controller/TenantSecretKeyController.java create mode 100644 ff-admin/src/main/java/com/ff/common/domain/Currency.java create mode 100644 ff-admin/src/main/java/com/ff/common/domain/Lang.java create mode 100644 ff-admin/src/main/java/com/ff/common/domain/TenantSecretKey.java create mode 100644 ff-admin/src/main/java/com/ff/common/mapper/CurrencyMapper.java create mode 100644 ff-admin/src/main/java/com/ff/common/mapper/LangMapper.java create mode 100644 ff-admin/src/main/java/com/ff/common/mapper/TenantSecretKeyMapper.java create mode 100644 ff-admin/src/main/java/com/ff/common/service/ICurrencyService.java create mode 100644 ff-admin/src/main/java/com/ff/common/service/ILangService.java create mode 100644 ff-admin/src/main/java/com/ff/common/service/ITenantSecretKeyService.java create mode 100644 ff-admin/src/main/java/com/ff/common/service/impl/CurrencyServiceImpl.java create mode 100644 ff-admin/src/main/java/com/ff/common/service/impl/LangServiceImpl.java create mode 100644 ff-admin/src/main/java/com/ff/common/service/impl/TenantSecretKeyServiceImpl.java create mode 100644 ff-admin/src/main/java/com/ff/config/ContentRefreshedEventListener.java create mode 100644 ff-admin/src/main/java/com/ff/config/KeyConfig.java create mode 100644 ff-admin/src/main/java/com/ff/config/SwaggerConfig.java create mode 100644 ff-admin/src/main/java/com/ff/file/controller/FileController.java create mode 100644 ff-admin/src/main/java/com/ff/file/service/ISysFileService.java create mode 100644 ff-admin/src/main/java/com/ff/file/service/impl/LocalSysFileServiceImpl.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/IGamesService.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/jili/address/MyJILIAddressSource.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/jili/client/JILIClient.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIBetRecordDataResponseDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIBetRecordResponseDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICancelFreeSpinResponseDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICreateFreeSpinResponseDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICreateMemberResponseDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIExchangeMoneyResponseDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGamesDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGamesDataDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGetFreeSpinDashflowResponseDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGetGameDetailResponseDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIKickMemberAllDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIKickMemberDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/jili/dto/JILILoginWithoutRedirectResponseDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIMemberInfoDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/jili/service/impl/GamesJILIServiceImpl.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/request/BetRecordByTimeDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/request/CancelFreeSpinRequestDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/request/CreateFreeSpinRequestDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/request/CreateMemberRequestDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/request/ExchangeTransferMoneyRequestDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/request/GameUniqueDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/request/GamesBaseRequestDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/request/GamesDataBuildDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/request/GamesLogin.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/request/GetFreeSpinDashflowRequestDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/request/GetGameDetailRequestDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/request/GetGameDetailResponseDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/request/KickMemberAllDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/request/KickMemberRequestDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/request/MemberInfoRequestDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/request/MemberInfoResponseDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/xk/dto/XKBetRecordResponseDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/xk/dto/XKCreateMemberResponseDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/xk/dto/XKExchangeMoneyResponseDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/xk/dto/XKGamesDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/xk/dto/XKKickMemberAllDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/xk/dto/XKKickMemberDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/xk/dto/XKLoginWithoutRedirectResponseDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/xk/dto/XKMemberInfoDTO.java create mode 100644 ff-admin/src/main/java/com/ff/game/api/xk/service/impl/GamesXKServiceImpl.java create mode 100644 ff-admin/src/main/java/com/ff/game/controller/GameBettingDetailsController.java create mode 100644 ff-admin/src/main/java/com/ff/game/controller/GameController.java create mode 100644 ff-admin/src/main/java/com/ff/game/controller/GameExchangeMoneyController.java create mode 100644 ff-admin/src/main/java/com/ff/game/controller/GameFreeRecordController.java create mode 100644 ff-admin/src/main/java/com/ff/game/controller/GamePlatformController.java create mode 100644 ff-admin/src/main/java/com/ff/game/controller/GameSecretKeyController.java create mode 100644 ff-admin/src/main/java/com/ff/game/domain/Game.java create mode 100644 ff-admin/src/main/java/com/ff/game/domain/GameBettingDetails.java create mode 100644 ff-admin/src/main/java/com/ff/game/domain/GameExchangeMoney.java create mode 100644 ff-admin/src/main/java/com/ff/game/domain/GameFreeRecord.java create mode 100644 ff-admin/src/main/java/com/ff/game/domain/GamePlatform.java create mode 100644 ff-admin/src/main/java/com/ff/game/domain/GameSecretKey.java create mode 100644 ff-admin/src/main/java/com/ff/game/mapper/GameBettingDetailsMapper.java create mode 100644 ff-admin/src/main/java/com/ff/game/mapper/GameExchangeMoneyMapper.java create mode 100644 ff-admin/src/main/java/com/ff/game/mapper/GameFreeRecordMapper.java create mode 100644 ff-admin/src/main/java/com/ff/game/mapper/GameMapper.java create mode 100644 ff-admin/src/main/java/com/ff/game/mapper/GamePlatformMapper.java create mode 100644 ff-admin/src/main/java/com/ff/game/mapper/GameSecretKeyMapper.java create mode 100644 ff-admin/src/main/java/com/ff/game/service/IGameBettingDetailsService.java create mode 100644 ff-admin/src/main/java/com/ff/game/service/IGameExchangeMoneyService.java create mode 100644 ff-admin/src/main/java/com/ff/game/service/IGameFreeRecordService.java create mode 100644 ff-admin/src/main/java/com/ff/game/service/IGamePlatformService.java create mode 100644 ff-admin/src/main/java/com/ff/game/service/IGameSecretKeyService.java create mode 100644 ff-admin/src/main/java/com/ff/game/service/IGameService.java create mode 100644 ff-admin/src/main/java/com/ff/game/service/impl/GameBettingDetailsServiceImpl.java create mode 100644 ff-admin/src/main/java/com/ff/game/service/impl/GameExchangeMoneyServiceImpl.java create mode 100644 ff-admin/src/main/java/com/ff/game/service/impl/GameFreeRecordServiceImpl.java create mode 100644 ff-admin/src/main/java/com/ff/game/service/impl/GamePlatformServiceImpl.java create mode 100644 ff-admin/src/main/java/com/ff/game/service/impl/GameSecretKeyServiceImpl.java create mode 100644 ff-admin/src/main/java/com/ff/game/service/impl/GameServiceImpl.java create mode 100644 ff-admin/src/main/java/com/ff/member/controller/MemberController.java create mode 100644 ff-admin/src/main/java/com/ff/member/domain/Member.java create mode 100644 ff-admin/src/main/java/com/ff/member/mapper/MemberMapper.java create mode 100644 ff-admin/src/main/java/com/ff/member/service/IMemberService.java create mode 100644 ff-admin/src/main/java/com/ff/member/service/impl/MemberServiceImpl.java create mode 100644 ff-admin/src/main/java/com/ff/monitor/SysLogininforController.java create mode 100644 ff-admin/src/main/java/com/ff/monitor/SysOperlogController.java create mode 100644 ff-admin/src/main/java/com/ff/quartz/config/ScheduleConfig.java create mode 100644 ff-admin/src/main/java/com/ff/quartz/controller/SysJobController.java create mode 100644 ff-admin/src/main/java/com/ff/quartz/controller/SysJobLogController.java create mode 100644 ff-admin/src/main/java/com/ff/quartz/domain/SysJob.java create mode 100644 ff-admin/src/main/java/com/ff/quartz/domain/SysJobLog.java create mode 100644 ff-admin/src/main/java/com/ff/quartz/mapper/SysJobLogMapper.java create mode 100644 ff-admin/src/main/java/com/ff/quartz/mapper/SysJobMapper.java create mode 100644 ff-admin/src/main/java/com/ff/quartz/service/ISysJobLogService.java create mode 100644 ff-admin/src/main/java/com/ff/quartz/service/ISysJobService.java create mode 100644 ff-admin/src/main/java/com/ff/quartz/service/impl/SysJobLogServiceImpl.java create mode 100644 ff-admin/src/main/java/com/ff/quartz/service/impl/SysJobServiceImpl.java create mode 100644 ff-admin/src/main/java/com/ff/quartz/task/RyTask.java create mode 100644 ff-admin/src/main/java/com/ff/quartz/util/AbstractQuartzJob.java create mode 100644 ff-admin/src/main/java/com/ff/quartz/util/CronUtils.java create mode 100644 ff-admin/src/main/java/com/ff/quartz/util/JobInvokeUtil.java create mode 100644 ff-admin/src/main/java/com/ff/quartz/util/QuartzDisallowConcurrentExecution.java create mode 100644 ff-admin/src/main/java/com/ff/quartz/util/QuartzJobExecution.java create mode 100644 ff-admin/src/main/java/com/ff/quartz/util/ScheduleUtils.java create mode 100644 ff-admin/src/main/java/com/ff/system/SysConfigController.java create mode 100644 ff-admin/src/main/java/com/ff/system/SysDatasourceController.java create mode 100644 ff-admin/src/main/java/com/ff/system/SysDeptController.java create mode 100644 ff-admin/src/main/java/com/ff/system/SysDictDataController.java create mode 100644 ff-admin/src/main/java/com/ff/system/SysDictTypeController.java create mode 100644 ff-admin/src/main/java/com/ff/system/SysIndexController.java create mode 100644 ff-admin/src/main/java/com/ff/system/SysLoginController.java create mode 100644 ff-admin/src/main/java/com/ff/system/SysMenuController.java create mode 100644 ff-admin/src/main/java/com/ff/system/SysPostController.java create mode 100644 ff-admin/src/main/java/com/ff/system/SysProfileController.java create mode 100644 ff-admin/src/main/java/com/ff/system/SysRegisterController.java create mode 100644 ff-admin/src/main/java/com/ff/system/SysRoleController.java create mode 100644 ff-admin/src/main/java/com/ff/system/SysUserController.java create mode 100644 ff-admin/src/main/resources/META-INF/spring-devtools.properties create mode 100644 ff-admin/src/main/resources/application-druid.yml create mode 100644 ff-admin/src/main/resources/application-prod.yml create mode 100644 ff-admin/src/main/resources/application.yml create mode 100644 ff-admin/src/main/resources/i18n/messages.properties create mode 100644 ff-admin/src/main/resources/logback.xml create mode 100644 ff-admin/src/main/resources/mapper/common/CurrencyMapper.xml create mode 100644 ff-admin/src/main/resources/mapper/common/LangMapper.xml create mode 100644 ff-admin/src/main/resources/mapper/common/TenantSecretKeyMapper.xml create mode 100644 ff-admin/src/main/resources/mapper/game/GameBettingDetailsMapper.xml create mode 100644 ff-admin/src/main/resources/mapper/game/GameExchangeMoneyMapper.xml create mode 100644 ff-admin/src/main/resources/mapper/game/GameFreeRecordMapper.xml create mode 100644 ff-admin/src/main/resources/mapper/game/GameMapper.xml create mode 100644 ff-admin/src/main/resources/mapper/game/GamePlatformMapper.xml create mode 100644 ff-admin/src/main/resources/mapper/game/GameSecretKeyMapper.xml create mode 100644 ff-admin/src/main/resources/mapper/member/MemberMapper.xml create mode 100644 ff-admin/src/main/resources/mapper/quartz/SysJobLogMapper.xml create mode 100644 ff-admin/src/main/resources/mapper/quartz/SysJobMapper.xml create mode 100644 ff-admin/src/main/resources/mybatis/mybatis-config.xml create mode 100644 ff-admin/target/classes/META-INF/spring-devtools.properties create mode 100644 ff-admin/target/classes/application-druid.yml create mode 100644 ff-admin/target/classes/application-prod.yml create mode 100644 ff-admin/target/classes/application.yml create mode 100644 ff-admin/target/classes/com/ff/FFApplication.class create mode 100644 ff-admin/target/classes/com/ff/FFServletInitializer.class create mode 100644 ff-admin/target/classes/com/ff/config/ContentRefreshedEventListener.class create mode 100644 ff-admin/target/classes/com/ff/config/SwaggerConfig.class create mode 100644 ff-admin/target/classes/com/ff/file/controller/FileController.class create mode 100644 ff-admin/target/classes/com/ff/file/service/ISysFileService.class create mode 100644 ff-admin/target/classes/com/ff/file/service/impl/LocalSysFileServiceImpl.class create mode 100644 ff-admin/target/classes/com/ff/member/controller/MemberController.class create mode 100644 ff-admin/target/classes/com/ff/member/domain/Member.class create mode 100644 ff-admin/target/classes/com/ff/member/mapper/MemberMapper.class create mode 100644 ff-admin/target/classes/com/ff/member/service/IMemberService.class create mode 100644 ff-admin/target/classes/com/ff/member/service/impl/MemberServiceImpl.class create mode 100644 ff-admin/target/classes/com/ff/monitor/SysLogininforController.class create mode 100644 ff-admin/target/classes/com/ff/monitor/SysOperlogController.class create mode 100644 ff-admin/target/classes/com/ff/quartz/controller/SysJobController.class create mode 100644 ff-admin/target/classes/com/ff/quartz/controller/SysJobLogController.class create mode 100644 ff-admin/target/classes/com/ff/quartz/domain/SysJob.class create mode 100644 ff-admin/target/classes/com/ff/quartz/domain/SysJobLog.class create mode 100644 ff-admin/target/classes/com/ff/quartz/mapper/SysJobLogMapper.class create mode 100644 ff-admin/target/classes/com/ff/quartz/mapper/SysJobMapper.class create mode 100644 ff-admin/target/classes/com/ff/quartz/service/ISysJobLogService.class create mode 100644 ff-admin/target/classes/com/ff/quartz/service/ISysJobService.class create mode 100644 ff-admin/target/classes/com/ff/quartz/service/impl/SysJobLogServiceImpl.class create mode 100644 ff-admin/target/classes/com/ff/quartz/service/impl/SysJobServiceImpl.class create mode 100644 ff-admin/target/classes/com/ff/quartz/task/RyTask.class create mode 100644 ff-admin/target/classes/com/ff/quartz/util/AbstractQuartzJob.class create mode 100644 ff-admin/target/classes/com/ff/quartz/util/CronUtils.class create mode 100644 ff-admin/target/classes/com/ff/quartz/util/JobInvokeUtil.class create mode 100644 ff-admin/target/classes/com/ff/quartz/util/QuartzDisallowConcurrentExecution.class create mode 100644 ff-admin/target/classes/com/ff/quartz/util/QuartzJobExecution.class create mode 100644 ff-admin/target/classes/com/ff/quartz/util/ScheduleUtils.class create mode 100644 ff-admin/target/classes/com/ff/system/SysConfigController.class create mode 100644 ff-admin/target/classes/com/ff/system/SysDatasourceController.class create mode 100644 ff-admin/target/classes/com/ff/system/SysDeptController.class create mode 100644 ff-admin/target/classes/com/ff/system/SysDictDataController.class create mode 100644 ff-admin/target/classes/com/ff/system/SysDictTypeController.class create mode 100644 ff-admin/target/classes/com/ff/system/SysIndexController.class create mode 100644 ff-admin/target/classes/com/ff/system/SysLoginController.class create mode 100644 ff-admin/target/classes/com/ff/system/SysMenuController.class create mode 100644 ff-admin/target/classes/com/ff/system/SysPostController.class create mode 100644 ff-admin/target/classes/com/ff/system/SysProfileController.class create mode 100644 ff-admin/target/classes/com/ff/system/SysRegisterController.class create mode 100644 ff-admin/target/classes/com/ff/system/SysRoleController.class create mode 100644 ff-admin/target/classes/com/ff/system/SysUserController.class create mode 100644 ff-admin/target/classes/i18n/messages.properties create mode 100644 ff-admin/target/classes/logback.xml create mode 100644 ff-admin/target/classes/mapper/game/GameBettingDetailsMapper.xml create mode 100644 ff-admin/target/classes/mapper/game/GameExchangeMoneyMapper.xml create mode 100644 ff-admin/target/classes/mapper/game/GameFreeRecordMapper.xml create mode 100644 ff-admin/target/classes/mapper/game/GameMapper.xml create mode 100644 ff-admin/target/classes/mapper/game/GamePlatformMapper.xml create mode 100644 ff-admin/target/classes/mapper/game/GameSecretKeyMapper.xml create mode 100644 ff-admin/target/classes/mapper/member/MemberMapper.xml create mode 100644 ff-admin/target/classes/mapper/quartz/SysJobLogMapper.xml create mode 100644 ff-admin/target/classes/mapper/quartz/SysJobMapper.xml create mode 100644 ff-admin/target/classes/mybatis/mybatis-config.xml create mode 100644 ff-base/pom.xml create mode 100644 ff-base/src/main/java/com/ff/base/annotation/Anonymous.java create mode 100644 ff-base/src/main/java/com/ff/base/annotation/DataScope.java create mode 100644 ff-base/src/main/java/com/ff/base/annotation/DataSource.java create mode 100644 ff-base/src/main/java/com/ff/base/annotation/Excel.java create mode 100644 ff-base/src/main/java/com/ff/base/annotation/Excels.java create mode 100644 ff-base/src/main/java/com/ff/base/annotation/Log.java create mode 100644 ff-base/src/main/java/com/ff/base/annotation/RateLimiter.java create mode 100644 ff-base/src/main/java/com/ff/base/annotation/RepeatSubmit.java create mode 100644 ff-base/src/main/java/com/ff/base/annotation/Sensitive.java create mode 100644 ff-base/src/main/java/com/ff/base/aspectj/DataScopeAspect.java create mode 100644 ff-base/src/main/java/com/ff/base/aspectj/DataSourceAspect.java create mode 100644 ff-base/src/main/java/com/ff/base/aspectj/LogAspect.java create mode 100644 ff-base/src/main/java/com/ff/base/aspectj/RateLimiterAspect.java create mode 100644 ff-base/src/main/java/com/ff/base/config/ApplicationConfig.java create mode 100644 ff-base/src/main/java/com/ff/base/config/AsyncConfig.java create mode 100644 ff-base/src/main/java/com/ff/base/config/CaptchaConfig.java create mode 100644 ff-base/src/main/java/com/ff/base/config/DruidConfig.java create mode 100644 ff-base/src/main/java/com/ff/base/config/FFConfig.java create mode 100644 ff-base/src/main/java/com/ff/base/config/FastJson2JsonRedisSerializer.java create mode 100644 ff-base/src/main/java/com/ff/base/config/FilterConfig.java create mode 100644 ff-base/src/main/java/com/ff/base/config/I18nConfig.java create mode 100644 ff-base/src/main/java/com/ff/base/config/IdGeneratorUtil.java create mode 100644 ff-base/src/main/java/com/ff/base/config/JacksonConfig.java create mode 100644 ff-base/src/main/java/com/ff/base/config/KaptchaTextCreator.java create mode 100644 ff-base/src/main/java/com/ff/base/config/MyBatisConfig.java create mode 100644 ff-base/src/main/java/com/ff/base/config/RedisConfig.java create mode 100644 ff-base/src/main/java/com/ff/base/config/ResourcesConfig.java create mode 100644 ff-base/src/main/java/com/ff/base/config/SecurityConfig.java create mode 100644 ff-base/src/main/java/com/ff/base/config/ServerConfig.java create mode 100644 ff-base/src/main/java/com/ff/base/config/ThreadPoolConfig.java create mode 100644 ff-base/src/main/java/com/ff/base/config/properties/DruidProperties.java create mode 100644 ff-base/src/main/java/com/ff/base/config/properties/PermitAllUrlProperties.java create mode 100644 ff-base/src/main/java/com/ff/base/config/serializer/SensitiveJsonSerializer.java create mode 100644 ff-base/src/main/java/com/ff/base/constant/BusinessConstants.java create mode 100644 ff-base/src/main/java/com/ff/base/constant/CacheConstants.java create mode 100644 ff-base/src/main/java/com/ff/base/constant/ConfigConstants.java create mode 100644 ff-base/src/main/java/com/ff/base/constant/Constants.java create mode 100644 ff-base/src/main/java/com/ff/base/constant/GenConstants.java create mode 100644 ff-base/src/main/java/com/ff/base/constant/HttpStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/constant/ScheduleConstants.java create mode 100644 ff-base/src/main/java/com/ff/base/constant/UserConstants.java create mode 100644 ff-base/src/main/java/com/ff/base/core/controller/BaseController.java create mode 100644 ff-base/src/main/java/com/ff/base/core/domain/AjaxResult.java create mode 100644 ff-base/src/main/java/com/ff/base/core/domain/BaseEntity.java create mode 100644 ff-base/src/main/java/com/ff/base/core/domain/TreeEntity.java create mode 100644 ff-base/src/main/java/com/ff/base/core/domain/TreeSelect.java create mode 100644 ff-base/src/main/java/com/ff/base/core/domain/model/LoginBody.java create mode 100644 ff-base/src/main/java/com/ff/base/core/domain/model/LoginForm.java create mode 100644 ff-base/src/main/java/com/ff/base/core/domain/model/LoginUser.java create mode 100644 ff-base/src/main/java/com/ff/base/core/domain/model/RegisterBody.java create mode 100644 ff-base/src/main/java/com/ff/base/core/page/PageDomain.java create mode 100644 ff-base/src/main/java/com/ff/base/core/page/TableDataInfo.java create mode 100644 ff-base/src/main/java/com/ff/base/core/page/TableSupport.java create mode 100644 ff-base/src/main/java/com/ff/base/core/redis/RedisCache.java create mode 100644 ff-base/src/main/java/com/ff/base/core/text/CharsetKit.java create mode 100644 ff-base/src/main/java/com/ff/base/core/text/Convert.java create mode 100644 ff-base/src/main/java/com/ff/base/core/text/StrFormatter.java create mode 100644 ff-base/src/main/java/com/ff/base/datasource/DynamicDataSource.java create mode 100644 ff-base/src/main/java/com/ff/base/datasource/DynamicDataSourceContextHolder.java create mode 100644 ff-base/src/main/java/com/ff/base/decorator/ContextCopyingDecorator.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/AccountAuditStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/AccountChangeType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/AccountType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityBetPlatformType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityBetSendStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityBetSendWay.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityChargeReceiveLimitType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityChargeRepeatReceive.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityChargeRewardType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityChargeRuleType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityChargeSendStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityChargeSendWay.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityExtensionAccordCondition.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityExtensionChargeStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityExtensionChargeType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityExtensionLoginApp.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityExtensionRewardType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityExtensionSendStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityExtensionSendWay.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityLimitedTimeDay.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityLoopType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityMainEntrance.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityReceiveCount.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityReceiveLimitType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityRewardAuditStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityShowStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ActivityTemplateType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/AgentModelType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/AndroidForceDownload.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/AnnouncementStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/AppLocation.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/AwardType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/BannerStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/BetTaskSource.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/BetTaskStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/BoxStatusType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/BusinessStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/BusinessType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/CalcModeType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/CalcPerformanceType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/CalcRangeType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/CalculateType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ChangeStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ChannelType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ChargeOrderFlag.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ChargeOrderPayStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/CostType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/DataSourceType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/DesensitizedType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/DeviceType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/DirectFlagType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/DiscountReceiveSmallType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/DiscountReceiveSource.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/DiscountReceiveStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/DnsRecordType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/DomainCloudfareStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/DomainSonType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/DomainSonUsageStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/DomainStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/DomainType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/DownloadType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/DrawType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/EnableStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/EventType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/FeedbackStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/FrameStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/FreeStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/FyPayStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/GameCollectionStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/GameEventEnum.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/GameHotStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/GameOpenStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/GamePlatforms.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/GamePlayStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/GamePopularCategory.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/GamePopularStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/GamePopularType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/GameStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/HttpMethod.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/InitiatingType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/JILIGameType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/LangType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/LayoutLoginType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/LimitType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/LinkPosition.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/LoadStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/LoopType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/MarqueeStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/MemberLogOperProject.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/MemberLogOperType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/MemberStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/NoticeStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/NoticeType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/OperationType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/OperatorType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/PageType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/PatternSourceType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/PlayType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ReadStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/RealtimeRebateReceiveType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/RealtimeRebateSettleType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/RebateSettlePeriodType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ReceiptType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ReceiveLimitType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/ReceiveTimeType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/RegisteWay.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/RepairStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/SetType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/SettleDurationType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/SettleStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/SonType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/StopStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/SupplierCode.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/SysUseType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/TaskBindType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/TaskGiveType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/TaskType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/TimePeriodType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/TimeType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/Tourist.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/TrackEventType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/TransferType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/UsageStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/UserStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/WindowStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/WindowType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/WithdrawAccountStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/WithdrawBehalfStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/WithdrawStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/WithdrawTipStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/XKGameType.java create mode 100644 ff-base/src/main/java/com/ff/base/enums/XjPayStatus.java create mode 100644 ff-base/src/main/java/com/ff/base/exception/DemoModeException.java create mode 100644 ff-base/src/main/java/com/ff/base/exception/GlobalException.java create mode 100644 ff-base/src/main/java/com/ff/base/exception/ServiceException.java create mode 100644 ff-base/src/main/java/com/ff/base/exception/UtilException.java create mode 100644 ff-base/src/main/java/com/ff/base/exception/base/BaseException.java create mode 100644 ff-base/src/main/java/com/ff/base/exception/file/FileException.java create mode 100644 ff-base/src/main/java/com/ff/base/exception/file/FileNameLengthLimitExceededException.java create mode 100644 ff-base/src/main/java/com/ff/base/exception/file/FileSizeLimitExceededException.java create mode 100644 ff-base/src/main/java/com/ff/base/exception/file/FileUploadException.java create mode 100644 ff-base/src/main/java/com/ff/base/exception/file/InvalidExtensionException.java create mode 100644 ff-base/src/main/java/com/ff/base/exception/job/TaskException.java create mode 100644 ff-base/src/main/java/com/ff/base/exception/user/BlackListException.java create mode 100644 ff-base/src/main/java/com/ff/base/exception/user/CaptchaException.java create mode 100644 ff-base/src/main/java/com/ff/base/exception/user/CaptchaExpireException.java create mode 100644 ff-base/src/main/java/com/ff/base/exception/user/UserException.java create mode 100644 ff-base/src/main/java/com/ff/base/exception/user/UserNotExistsException.java create mode 100644 ff-base/src/main/java/com/ff/base/exception/user/UserPasswordNotMatchException.java create mode 100644 ff-base/src/main/java/com/ff/base/exception/user/UserPasswordRetryLimitExceedException.java create mode 100644 ff-base/src/main/java/com/ff/base/filter/PropertyPreExcludeFilter.java create mode 100644 ff-base/src/main/java/com/ff/base/filter/RepeatableFilter.java create mode 100644 ff-base/src/main/java/com/ff/base/filter/RepeatedlyRequestWrapper.java create mode 100644 ff-base/src/main/java/com/ff/base/filter/XssFilter.java create mode 100644 ff-base/src/main/java/com/ff/base/filter/XssHttpServletRequestWrapper.java create mode 100644 ff-base/src/main/java/com/ff/base/interceptor/DataSourceSwitchInterceptor.java create mode 100644 ff-base/src/main/java/com/ff/base/interceptor/RepeatSubmitInterceptor.java create mode 100644 ff-base/src/main/java/com/ff/base/interceptor/impl/SameUrlDataInterceptor.java create mode 100644 ff-base/src/main/java/com/ff/base/manager/AsyncManager.java create mode 100644 ff-base/src/main/java/com/ff/base/manager/ShutdownManager.java create mode 100644 ff-base/src/main/java/com/ff/base/manager/factory/AsyncFactory.java create mode 100644 ff-base/src/main/java/com/ff/base/security/context/AuthenticationContextHolder.java create mode 100644 ff-base/src/main/java/com/ff/base/security/context/PermissionContextHolder.java create mode 100644 ff-base/src/main/java/com/ff/base/security/encode/CustomMd5PasswordEncoder.java create mode 100644 ff-base/src/main/java/com/ff/base/security/filter/JwtAuthenticationTokenFilter.java create mode 100644 ff-base/src/main/java/com/ff/base/security/handle/AuthenticationEntryPointImpl.java create mode 100644 ff-base/src/main/java/com/ff/base/security/handle/LogoutSuccessHandlerImpl.java create mode 100644 ff-base/src/main/java/com/ff/base/security/provider/MyDaoAuthenticationProvider.java create mode 100644 ff-base/src/main/java/com/ff/base/system/domain/SysConfig.java create mode 100644 ff-base/src/main/java/com/ff/base/system/domain/SysDatasource.java create mode 100644 ff-base/src/main/java/com/ff/base/system/domain/SysDept.java create mode 100644 ff-base/src/main/java/com/ff/base/system/domain/SysDictData.java create mode 100644 ff-base/src/main/java/com/ff/base/system/domain/SysDictType.java create mode 100644 ff-base/src/main/java/com/ff/base/system/domain/SysLogininfor.java create mode 100644 ff-base/src/main/java/com/ff/base/system/domain/SysMenu.java create mode 100644 ff-base/src/main/java/com/ff/base/system/domain/SysOperLog.java create mode 100644 ff-base/src/main/java/com/ff/base/system/domain/SysPost.java create mode 100644 ff-base/src/main/java/com/ff/base/system/domain/SysRole.java create mode 100644 ff-base/src/main/java/com/ff/base/system/domain/SysRoleDept.java create mode 100644 ff-base/src/main/java/com/ff/base/system/domain/SysRoleMenu.java create mode 100644 ff-base/src/main/java/com/ff/base/system/domain/SysUser.java create mode 100644 ff-base/src/main/java/com/ff/base/system/domain/SysUserOnline.java create mode 100644 ff-base/src/main/java/com/ff/base/system/domain/SysUserPost.java create mode 100644 ff-base/src/main/java/com/ff/base/system/domain/SysUserRole.java create mode 100644 ff-base/src/main/java/com/ff/base/system/domain/vo/MetaVo.java create mode 100644 ff-base/src/main/java/com/ff/base/system/domain/vo/RouterVo.java create mode 100644 ff-base/src/main/java/com/ff/base/system/mapper/SysConfigMapper.java create mode 100644 ff-base/src/main/java/com/ff/base/system/mapper/SysDatasourceMapper.java create mode 100644 ff-base/src/main/java/com/ff/base/system/mapper/SysDeptMapper.java create mode 100644 ff-base/src/main/java/com/ff/base/system/mapper/SysDictDataMapper.java create mode 100644 ff-base/src/main/java/com/ff/base/system/mapper/SysDictTypeMapper.java create mode 100644 ff-base/src/main/java/com/ff/base/system/mapper/SysLogininforMapper.java create mode 100644 ff-base/src/main/java/com/ff/base/system/mapper/SysMenuMapper.java create mode 100644 ff-base/src/main/java/com/ff/base/system/mapper/SysOperLogMapper.java create mode 100644 ff-base/src/main/java/com/ff/base/system/mapper/SysPostMapper.java create mode 100644 ff-base/src/main/java/com/ff/base/system/mapper/SysRoleDeptMapper.java create mode 100644 ff-base/src/main/java/com/ff/base/system/mapper/SysRoleMapper.java create mode 100644 ff-base/src/main/java/com/ff/base/system/mapper/SysRoleMenuMapper.java create mode 100644 ff-base/src/main/java/com/ff/base/system/mapper/SysUserMapper.java create mode 100644 ff-base/src/main/java/com/ff/base/system/mapper/SysUserPostMapper.java create mode 100644 ff-base/src/main/java/com/ff/base/system/mapper/SysUserRoleMapper.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/ISysConfigService.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/ISysDatasourceService.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/ISysDeptService.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/ISysDictDataService.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/ISysDictTypeService.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/ISysLogininforService.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/ISysMenuService.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/ISysOperLogService.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/ISysPostService.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/ISysRoleService.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/ISysUserOnlineService.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/ISysUserService.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/impl/SysConfigServiceImpl.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/impl/SysDatasourceServiceImpl.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/impl/SysDeptServiceImpl.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/impl/SysDictDataServiceImpl.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/impl/SysDictTypeServiceImpl.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/impl/SysLogininforServiceImpl.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/impl/SysMenuServiceImpl.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/impl/SysOperLogServiceImpl.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/impl/SysPostServiceImpl.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/impl/SysRoleServiceImpl.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/impl/SysUserOnlineServiceImpl.java create mode 100644 ff-base/src/main/java/com/ff/base/system/service/impl/SysUserServiceImpl.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/Arith.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/DateUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/DesensitizedUtil.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/DictUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/ExceptionUtil.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/JsonUtil.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/LogUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/MessageUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/NumberUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/PageUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/SecurityUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/ServletUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/SnowflakeIdGenerator.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/StringUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/TenantUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/Threads.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/bean/BeanUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/bean/BeanValidators.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/domain/DomainInfo.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/domain/DomainUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/file/FileTypeUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/file/FileUploadUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/file/FileUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/file/ImageUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/file/MimeTypeUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/html/EscapeUtil.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/html/HTMLFilter.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/http/HttpClientSslUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/http/HttpHelper.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/http/HttpUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/ip/AddressUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/ip/IpUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/nginx/NginxUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/poi/ExcelHandlerAdapter.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/poi/ExcelUtil.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/qrcode/QRCodeGenerator.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/reflect/ReflectUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/sign/Base64.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/sign/Md5Utils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/spring/SpringUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/sql/SqlUtil.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/uuid/IdUtils.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/uuid/Seq.java create mode 100644 ff-base/src/main/java/com/ff/base/utils/uuid/UUID.java create mode 100644 ff-base/src/main/java/com/ff/base/web/domain/server/Cpu.java create mode 100644 ff-base/src/main/java/com/ff/base/web/domain/server/Jvm.java create mode 100644 ff-base/src/main/java/com/ff/base/web/domain/server/Mem.java create mode 100644 ff-base/src/main/java/com/ff/base/web/domain/server/Sys.java create mode 100644 ff-base/src/main/java/com/ff/base/web/domain/server/SysFile.java create mode 100644 ff-base/src/main/java/com/ff/base/web/exception/GlobalExceptionHandler.java create mode 100644 ff-base/src/main/java/com/ff/base/web/service/MemberDetailsServiceImpl.java create mode 100644 ff-base/src/main/java/com/ff/base/web/service/PermissionService.java create mode 100644 ff-base/src/main/java/com/ff/base/web/service/SysLoginService.java create mode 100644 ff-base/src/main/java/com/ff/base/web/service/SysPasswordService.java create mode 100644 ff-base/src/main/java/com/ff/base/web/service/SysPermissionService.java create mode 100644 ff-base/src/main/java/com/ff/base/web/service/SysRegisterService.java create mode 100644 ff-base/src/main/java/com/ff/base/web/service/TokenService.java create mode 100644 ff-base/src/main/java/com/ff/base/web/service/UserDetailsServiceImpl.java create mode 100644 ff-base/src/main/java/com/ff/base/xss/Xss.java create mode 100644 ff-base/src/main/java/com/ff/base/xss/XssValidator.java create mode 100644 ff-base/src/main/resources/mapper/system/SysConfigMapper.xml create mode 100644 ff-base/src/main/resources/mapper/system/SysDatasourceMapper.xml create mode 100644 ff-base/src/main/resources/mapper/system/SysDeptMapper.xml create mode 100644 ff-base/src/main/resources/mapper/system/SysDictDataMapper.xml create mode 100644 ff-base/src/main/resources/mapper/system/SysDictTypeMapper.xml create mode 100644 ff-base/src/main/resources/mapper/system/SysLogininforMapper.xml create mode 100644 ff-base/src/main/resources/mapper/system/SysMenuMapper.xml create mode 100644 ff-base/src/main/resources/mapper/system/SysOperLogMapper.xml create mode 100644 ff-base/src/main/resources/mapper/system/SysPostMapper.xml create mode 100644 ff-base/src/main/resources/mapper/system/SysRoleDeptMapper.xml create mode 100644 ff-base/src/main/resources/mapper/system/SysRoleMapper.xml create mode 100644 ff-base/src/main/resources/mapper/system/SysRoleMenuMapper.xml create mode 100644 ff-base/src/main/resources/mapper/system/SysUserMapper.xml create mode 100644 ff-base/src/main/resources/mapper/system/SysUserPostMapper.xml create mode 100644 ff-base/src/main/resources/mapper/system/SysUserRoleMapper.xml create mode 100644 ff-base/target/classes/com/ff/base/annotation/Anonymous.class create mode 100644 ff-base/target/classes/com/ff/base/annotation/DataScope.class create mode 100644 ff-base/target/classes/com/ff/base/annotation/DataSource.class create mode 100644 ff-base/target/classes/com/ff/base/annotation/Excel$ColumnType.class create mode 100644 ff-base/target/classes/com/ff/base/annotation/Excel$Type.class create mode 100644 ff-base/target/classes/com/ff/base/annotation/Excel.class create mode 100644 ff-base/target/classes/com/ff/base/annotation/Excels.class create mode 100644 ff-base/target/classes/com/ff/base/annotation/Log.class create mode 100644 ff-base/target/classes/com/ff/base/annotation/RateLimiter.class create mode 100644 ff-base/target/classes/com/ff/base/annotation/RepeatSubmit.class create mode 100644 ff-base/target/classes/com/ff/base/annotation/Sensitive.class create mode 100644 ff-base/target/classes/com/ff/base/aspectj/DataScopeAspect.class create mode 100644 ff-base/target/classes/com/ff/base/aspectj/DataSourceAspect.class create mode 100644 ff-base/target/classes/com/ff/base/aspectj/LogAspect.class create mode 100644 ff-base/target/classes/com/ff/base/aspectj/RateLimiterAspect.class create mode 100644 ff-base/target/classes/com/ff/base/config/ApplicationConfig.class create mode 100644 ff-base/target/classes/com/ff/base/config/AsyncConfig.class create mode 100644 ff-base/target/classes/com/ff/base/config/CaptchaConfig.class create mode 100644 ff-base/target/classes/com/ff/base/config/DruidConfig$1.class create mode 100644 ff-base/target/classes/com/ff/base/config/DruidConfig.class create mode 100644 ff-base/target/classes/com/ff/base/config/FFConfig.class create mode 100644 ff-base/target/classes/com/ff/base/config/FastJson2JsonRedisSerializer.class create mode 100644 ff-base/target/classes/com/ff/base/config/FilterConfig.class create mode 100644 ff-base/target/classes/com/ff/base/config/I18nConfig.class create mode 100644 ff-base/target/classes/com/ff/base/config/IdGeneratorUtil.class create mode 100644 ff-base/target/classes/com/ff/base/config/JacksonConfig.class create mode 100644 ff-base/target/classes/com/ff/base/config/KaptchaTextCreator.class create mode 100644 ff-base/target/classes/com/ff/base/config/MyBatisConfig.class create mode 100644 ff-base/target/classes/com/ff/base/config/RedisConfig.class create mode 100644 ff-base/target/classes/com/ff/base/config/ResourcesConfig.class create mode 100644 ff-base/target/classes/com/ff/base/config/SecurityConfig.class create mode 100644 ff-base/target/classes/com/ff/base/config/ServerConfig.class create mode 100644 ff-base/target/classes/com/ff/base/config/ThreadPoolConfig$1.class create mode 100644 ff-base/target/classes/com/ff/base/config/ThreadPoolConfig.class create mode 100644 ff-base/target/classes/com/ff/base/config/properties/DruidProperties.class create mode 100644 ff-base/target/classes/com/ff/base/config/properties/PermitAllUrlProperties.class create mode 100644 ff-base/target/classes/com/ff/base/config/serializer/SensitiveJsonSerializer.class create mode 100644 ff-base/target/classes/com/ff/base/constant/BusinessConstants.class create mode 100644 ff-base/target/classes/com/ff/base/constant/CacheConstants.class create mode 100644 ff-base/target/classes/com/ff/base/constant/ConfigConstants.class create mode 100644 ff-base/target/classes/com/ff/base/constant/Constants.class create mode 100644 ff-base/target/classes/com/ff/base/constant/GenConstants.class create mode 100644 ff-base/target/classes/com/ff/base/constant/HttpStatus.class create mode 100644 ff-base/target/classes/com/ff/base/constant/ScheduleConstants$Status.class create mode 100644 ff-base/target/classes/com/ff/base/constant/ScheduleConstants.class create mode 100644 ff-base/target/classes/com/ff/base/constant/UserConstants.class create mode 100644 ff-base/target/classes/com/ff/base/core/controller/BaseController$1.class create mode 100644 ff-base/target/classes/com/ff/base/core/controller/BaseController.class create mode 100644 ff-base/target/classes/com/ff/base/core/domain/AjaxResult.class create mode 100644 ff-base/target/classes/com/ff/base/core/domain/BaseEntity.class create mode 100644 ff-base/target/classes/com/ff/base/core/domain/TreeEntity.class create mode 100644 ff-base/target/classes/com/ff/base/core/domain/TreeSelect.class create mode 100644 ff-base/target/classes/com/ff/base/core/domain/model/LoginBody.class create mode 100644 ff-base/target/classes/com/ff/base/core/domain/model/LoginForm.class create mode 100644 ff-base/target/classes/com/ff/base/core/domain/model/LoginUser.class create mode 100644 ff-base/target/classes/com/ff/base/core/domain/model/RegisterBody.class create mode 100644 ff-base/target/classes/com/ff/base/core/page/PageDomain.class create mode 100644 ff-base/target/classes/com/ff/base/core/page/TableDataInfo.class create mode 100644 ff-base/target/classes/com/ff/base/core/page/TableSupport.class create mode 100644 ff-base/target/classes/com/ff/base/core/redis/RedisCache.class create mode 100644 ff-base/target/classes/com/ff/base/core/text/CharsetKit.class create mode 100644 ff-base/target/classes/com/ff/base/core/text/Convert.class create mode 100644 ff-base/target/classes/com/ff/base/core/text/StrFormatter.class create mode 100644 ff-base/target/classes/com/ff/base/datasource/DynamicDataSource.class create mode 100644 ff-base/target/classes/com/ff/base/datasource/DynamicDataSourceContextHolder.class create mode 100644 ff-base/target/classes/com/ff/base/decorator/ContextCopyingDecorator.class create mode 100644 ff-base/target/classes/com/ff/base/enums/AccountAuditStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/AccountChangeType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/AccountType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityBetPlatformType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityBetSendStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityBetSendWay.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityChargeReceiveLimitType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityChargeRepeatReceive.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityChargeRewardType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityChargeRuleType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityChargeSendStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityChargeSendWay.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityExtensionAccordCondition.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityExtensionChargeStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityExtensionChargeType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityExtensionLoginApp.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityExtensionRewardType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityExtensionSendStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityExtensionSendWay.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityLimitedTimeDay.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityLoopType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityMainEntrance.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityReceiveCount.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityReceiveLimitType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityRewardAuditStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityShowStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ActivityTemplateType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/AgentModelType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/AndroidForceDownload.class create mode 100644 ff-base/target/classes/com/ff/base/enums/AnnouncementStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/AppLocation.class create mode 100644 ff-base/target/classes/com/ff/base/enums/AwardType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/BannerStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/BetTaskSource.class create mode 100644 ff-base/target/classes/com/ff/base/enums/BetTaskStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/BoxStatusType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/BusinessStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/BusinessType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/CalcModeType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/CalcPerformanceType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/CalcRangeType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/CalculateType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ChangeStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ChannelType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ChargeOrderFlag.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ChargeOrderPayStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/CostType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/DataSourceType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/DesensitizedType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/DeviceType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/DirectFlagType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/DiscountReceiveSmallType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/DiscountReceiveSource.class create mode 100644 ff-base/target/classes/com/ff/base/enums/DiscountReceiveStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/DnsRecordType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/DomainCloudfareStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/DomainSonType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/DomainSonUsageStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/DomainStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/DomainType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/DownloadType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/DrawType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/EnableStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/EventType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/FeedbackStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/FrameStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/FreeStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/FyPayStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/GameCollectionStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/GameEventEnum.class create mode 100644 ff-base/target/classes/com/ff/base/enums/GameHotStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/GameOpenStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/GamePlatforms.class create mode 100644 ff-base/target/classes/com/ff/base/enums/GamePlayStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/GamePopularCategory.class create mode 100644 ff-base/target/classes/com/ff/base/enums/GamePopularStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/GamePopularType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/GameStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/HttpMethod.class create mode 100644 ff-base/target/classes/com/ff/base/enums/InitiatingType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/JILIGameType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/LangType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/LayoutLoginType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/LimitType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/LinkPosition.class create mode 100644 ff-base/target/classes/com/ff/base/enums/LoadStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/LoopType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/MarqueeStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/MemberLogOperProject.class create mode 100644 ff-base/target/classes/com/ff/base/enums/MemberLogOperType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/MemberStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/NoticeStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/NoticeType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/OperationType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/OperatorType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/PageType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/PatternSourceType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/PlayType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ReadStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/RealtimeRebateReceiveType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/RealtimeRebateSettleType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/RebateSettlePeriodType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ReceiptType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ReceiveLimitType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/ReceiveTimeType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/RegisteWay.class create mode 100644 ff-base/target/classes/com/ff/base/enums/RepairStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/SetType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/SettleDurationType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/SettleStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/SonType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/StopStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/SupplierCode.class create mode 100644 ff-base/target/classes/com/ff/base/enums/SysUseType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/TaskBindType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/TaskGiveType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/TaskType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/TimePeriodType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/TimeType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/Tourist.class create mode 100644 ff-base/target/classes/com/ff/base/enums/TrackEventType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/TransferType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/UsageStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/UserStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/WindowStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/WindowType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/WithdrawAccountStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/WithdrawBehalfStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/WithdrawStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/WithdrawTipStatus.class create mode 100644 ff-base/target/classes/com/ff/base/enums/XKGameType.class create mode 100644 ff-base/target/classes/com/ff/base/enums/XjPayStatus.class create mode 100644 ff-base/target/classes/com/ff/base/exception/DemoModeException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/GlobalException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/ServiceException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/UtilException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/base/BaseException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/file/FileException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/file/FileNameLengthLimitExceededException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/file/FileSizeLimitExceededException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/file/FileUploadException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException$InvalidFlashExtensionException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException$InvalidImageExtensionException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException$InvalidMediaExtensionException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException$InvalidVideoExtensionException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/job/TaskException$Code.class create mode 100644 ff-base/target/classes/com/ff/base/exception/job/TaskException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/user/BlackListException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/user/CaptchaException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/user/CaptchaExpireException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/user/UserException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/user/UserNotExistsException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/user/UserPasswordNotMatchException.class create mode 100644 ff-base/target/classes/com/ff/base/exception/user/UserPasswordRetryLimitExceedException.class create mode 100644 ff-base/target/classes/com/ff/base/filter/PropertyPreExcludeFilter.class create mode 100644 ff-base/target/classes/com/ff/base/filter/RepeatableFilter.class create mode 100644 ff-base/target/classes/com/ff/base/filter/RepeatedlyRequestWrapper$1.class create mode 100644 ff-base/target/classes/com/ff/base/filter/RepeatedlyRequestWrapper.class create mode 100644 ff-base/target/classes/com/ff/base/filter/XssFilter.class create mode 100644 ff-base/target/classes/com/ff/base/filter/XssHttpServletRequestWrapper$1.class create mode 100644 ff-base/target/classes/com/ff/base/filter/XssHttpServletRequestWrapper.class create mode 100644 ff-base/target/classes/com/ff/base/interceptor/DataSourceSwitchInterceptor.class create mode 100644 ff-base/target/classes/com/ff/base/interceptor/RepeatSubmitInterceptor.class create mode 100644 ff-base/target/classes/com/ff/base/interceptor/impl/SameUrlDataInterceptor.class create mode 100644 ff-base/target/classes/com/ff/base/manager/AsyncManager.class create mode 100644 ff-base/target/classes/com/ff/base/manager/ShutdownManager.class create mode 100644 ff-base/target/classes/com/ff/base/manager/factory/AsyncFactory$1.class create mode 100644 ff-base/target/classes/com/ff/base/manager/factory/AsyncFactory$2.class create mode 100644 ff-base/target/classes/com/ff/base/manager/factory/AsyncFactory.class create mode 100644 ff-base/target/classes/com/ff/base/security/context/AuthenticationContextHolder.class create mode 100644 ff-base/target/classes/com/ff/base/security/context/PermissionContextHolder.class create mode 100644 ff-base/target/classes/com/ff/base/security/encode/CustomMd5PasswordEncoder.class create mode 100644 ff-base/target/classes/com/ff/base/security/filter/JwtAuthenticationTokenFilter.class create mode 100644 ff-base/target/classes/com/ff/base/security/handle/AuthenticationEntryPointImpl.class create mode 100644 ff-base/target/classes/com/ff/base/security/handle/LogoutSuccessHandlerImpl.class create mode 100644 ff-base/target/classes/com/ff/base/security/provider/MyDaoAuthenticationProvider.class create mode 100644 ff-base/target/classes/com/ff/base/system/domain/SysConfig.class create mode 100644 ff-base/target/classes/com/ff/base/system/domain/SysDatasource.class create mode 100644 ff-base/target/classes/com/ff/base/system/domain/SysDept.class create mode 100644 ff-base/target/classes/com/ff/base/system/domain/SysDictData$DictDataSimpleView.class create mode 100644 ff-base/target/classes/com/ff/base/system/domain/SysDictData.class create mode 100644 ff-base/target/classes/com/ff/base/system/domain/SysDictType.class create mode 100644 ff-base/target/classes/com/ff/base/system/domain/SysLogininfor.class create mode 100644 ff-base/target/classes/com/ff/base/system/domain/SysMenu.class create mode 100644 ff-base/target/classes/com/ff/base/system/domain/SysOperLog.class create mode 100644 ff-base/target/classes/com/ff/base/system/domain/SysPost.class create mode 100644 ff-base/target/classes/com/ff/base/system/domain/SysRole.class create mode 100644 ff-base/target/classes/com/ff/base/system/domain/SysRoleDept.class create mode 100644 ff-base/target/classes/com/ff/base/system/domain/SysRoleMenu.class create mode 100644 ff-base/target/classes/com/ff/base/system/domain/SysUser.class create mode 100644 ff-base/target/classes/com/ff/base/system/domain/SysUserOnline.class create mode 100644 ff-base/target/classes/com/ff/base/system/domain/SysUserPost.class create mode 100644 ff-base/target/classes/com/ff/base/system/domain/SysUserRole.class create mode 100644 ff-base/target/classes/com/ff/base/system/domain/vo/MetaVo.class create mode 100644 ff-base/target/classes/com/ff/base/system/domain/vo/RouterVo.class create mode 100644 ff-base/target/classes/com/ff/base/system/mapper/SysConfigMapper.class create mode 100644 ff-base/target/classes/com/ff/base/system/mapper/SysDatasourceMapper.class create mode 100644 ff-base/target/classes/com/ff/base/system/mapper/SysDeptMapper.class create mode 100644 ff-base/target/classes/com/ff/base/system/mapper/SysDictDataMapper.class create mode 100644 ff-base/target/classes/com/ff/base/system/mapper/SysDictTypeMapper.class create mode 100644 ff-base/target/classes/com/ff/base/system/mapper/SysLogininforMapper.class create mode 100644 ff-base/target/classes/com/ff/base/system/mapper/SysMenuMapper.class create mode 100644 ff-base/target/classes/com/ff/base/system/mapper/SysOperLogMapper.class create mode 100644 ff-base/target/classes/com/ff/base/system/mapper/SysPostMapper.class create mode 100644 ff-base/target/classes/com/ff/base/system/mapper/SysRoleDeptMapper.class create mode 100644 ff-base/target/classes/com/ff/base/system/mapper/SysRoleMapper.class create mode 100644 ff-base/target/classes/com/ff/base/system/mapper/SysRoleMenuMapper.class create mode 100644 ff-base/target/classes/com/ff/base/system/mapper/SysUserMapper.class create mode 100644 ff-base/target/classes/com/ff/base/system/mapper/SysUserPostMapper.class create mode 100644 ff-base/target/classes/com/ff/base/system/mapper/SysUserRoleMapper.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/ISysConfigService.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/ISysDatasourceService.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/ISysDeptService.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/ISysDictDataService.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/ISysDictTypeService.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/ISysLogininforService.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/ISysMenuService.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/ISysOperLogService.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/ISysPostService.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/ISysRoleService.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/ISysUserOnlineService.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/ISysUserService.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/impl/SysConfigServiceImpl.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/impl/SysDatasourceServiceImpl.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/impl/SysDeptServiceImpl.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/impl/SysDictDataServiceImpl.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/impl/SysDictTypeServiceImpl.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/impl/SysLogininforServiceImpl.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/impl/SysMenuServiceImpl.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/impl/SysOperLogServiceImpl.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/impl/SysPostServiceImpl.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/impl/SysRoleServiceImpl.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/impl/SysUserOnlineServiceImpl.class create mode 100644 ff-base/target/classes/com/ff/base/system/service/impl/SysUserServiceImpl.class create mode 100644 ff-base/target/classes/com/ff/base/utils/Arith.class create mode 100644 ff-base/target/classes/com/ff/base/utils/DateUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/DesensitizedUtil.class create mode 100644 ff-base/target/classes/com/ff/base/utils/DictUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/ExceptionUtil.class create mode 100644 ff-base/target/classes/com/ff/base/utils/JsonUtil.class create mode 100644 ff-base/target/classes/com/ff/base/utils/LogUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/MessageUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/NumberUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/PageUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/SecurityUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/ServletUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/SnowflakeIdGenerator.class create mode 100644 ff-base/target/classes/com/ff/base/utils/StringUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/TenantUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/Threads.class create mode 100644 ff-base/target/classes/com/ff/base/utils/bean/BeanUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/bean/BeanValidators.class create mode 100644 ff-base/target/classes/com/ff/base/utils/domain/DomainInfo$WhoisInfo.class create mode 100644 ff-base/target/classes/com/ff/base/utils/domain/DomainInfo.class create mode 100644 ff-base/target/classes/com/ff/base/utils/domain/DomainUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/file/FileTypeUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/file/FileUploadUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/file/FileUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/file/ImageUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/file/MimeTypeUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/html/EscapeUtil.class create mode 100644 ff-base/target/classes/com/ff/base/utils/html/HTMLFilter.class create mode 100644 ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils$1.class create mode 100644 ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils$TrustAllCerts.class create mode 100644 ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils$TrustAllHostnameVerifier.class create mode 100644 ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils$TrustAllX509TrustManager.class create mode 100644 ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/http/HttpHelper.class create mode 100644 ff-base/target/classes/com/ff/base/utils/http/HttpUtils$1.class create mode 100644 ff-base/target/classes/com/ff/base/utils/http/HttpUtils$TrustAnyHostnameVerifier.class create mode 100644 ff-base/target/classes/com/ff/base/utils/http/HttpUtils$TrustAnyTrustManager.class create mode 100644 ff-base/target/classes/com/ff/base/utils/http/HttpUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/ip/AddressUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/ip/IpUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/nginx/NginxUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/poi/ExcelHandlerAdapter.class create mode 100644 ff-base/target/classes/com/ff/base/utils/poi/ExcelUtil.class create mode 100644 ff-base/target/classes/com/ff/base/utils/qrcode/QRCodeGenerator.class create mode 100644 ff-base/target/classes/com/ff/base/utils/reflect/ReflectUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/sign/Base64.class create mode 100644 ff-base/target/classes/com/ff/base/utils/sign/Md5Utils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/spring/SpringUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/sql/SqlUtil.class create mode 100644 ff-base/target/classes/com/ff/base/utils/uuid/IdUtils.class create mode 100644 ff-base/target/classes/com/ff/base/utils/uuid/Seq.class create mode 100644 ff-base/target/classes/com/ff/base/utils/uuid/UUID$Holder.class create mode 100644 ff-base/target/classes/com/ff/base/utils/uuid/UUID.class create mode 100644 ff-base/target/classes/com/ff/base/web/domain/server/Cpu.class create mode 100644 ff-base/target/classes/com/ff/base/web/domain/server/Jvm.class create mode 100644 ff-base/target/classes/com/ff/base/web/domain/server/Mem.class create mode 100644 ff-base/target/classes/com/ff/base/web/domain/server/Sys.class create mode 100644 ff-base/target/classes/com/ff/base/web/domain/server/SysFile.class create mode 100644 ff-base/target/classes/com/ff/base/web/exception/GlobalExceptionHandler.class create mode 100644 ff-base/target/classes/com/ff/base/web/service/MemberDetailsServiceImpl.class create mode 100644 ff-base/target/classes/com/ff/base/web/service/PermissionService.class create mode 100644 ff-base/target/classes/com/ff/base/web/service/SysLoginService.class create mode 100644 ff-base/target/classes/com/ff/base/web/service/SysPasswordService.class create mode 100644 ff-base/target/classes/com/ff/base/web/service/SysPermissionService.class create mode 100644 ff-base/target/classes/com/ff/base/web/service/SysRegisterService.class create mode 100644 ff-base/target/classes/com/ff/base/web/service/TokenService.class create mode 100644 ff-base/target/classes/com/ff/base/web/service/UserDetailsServiceImpl.class create mode 100644 ff-base/target/classes/com/ff/base/xss/Xss.class create mode 100644 ff-base/target/classes/com/ff/base/xss/XssValidator.class create mode 100644 ff-base/target/classes/mapper/system/SysConfigMapper.xml create mode 100644 ff-base/target/classes/mapper/system/SysDatasourceMapper.xml create mode 100644 ff-base/target/classes/mapper/system/SysDeptMapper.xml create mode 100644 ff-base/target/classes/mapper/system/SysDictDataMapper.xml create mode 100644 ff-base/target/classes/mapper/system/SysDictTypeMapper.xml create mode 100644 ff-base/target/classes/mapper/system/SysLogininforMapper.xml create mode 100644 ff-base/target/classes/mapper/system/SysMenuMapper.xml create mode 100644 ff-base/target/classes/mapper/system/SysOperLogMapper.xml create mode 100644 ff-base/target/classes/mapper/system/SysPostMapper.xml create mode 100644 ff-base/target/classes/mapper/system/SysRoleDeptMapper.xml create mode 100644 ff-base/target/classes/mapper/system/SysRoleMapper.xml create mode 100644 ff-base/target/classes/mapper/system/SysRoleMenuMapper.xml create mode 100644 ff-base/target/classes/mapper/system/SysUserMapper.xml create mode 100644 ff-base/target/classes/mapper/system/SysUserPostMapper.xml create mode 100644 ff-base/target/classes/mapper/system/SysUserRoleMapper.xml create mode 100644 ff-gen/pom.xml create mode 100644 ff-gen/src/main/java/com/ff/gen/config/GenConfig.java create mode 100644 ff-gen/src/main/java/com/ff/gen/controller/GenController.java create mode 100644 ff-gen/src/main/java/com/ff/gen/domain/GenTable.java create mode 100644 ff-gen/src/main/java/com/ff/gen/domain/GenTableColumn.java create mode 100644 ff-gen/src/main/java/com/ff/gen/mapper/GenTableColumnMapper.java create mode 100644 ff-gen/src/main/java/com/ff/gen/mapper/GenTableMapper.java create mode 100644 ff-gen/src/main/java/com/ff/gen/service/GenTableColumnServiceImpl.java create mode 100644 ff-gen/src/main/java/com/ff/gen/service/GenTableServiceImpl.java create mode 100644 ff-gen/src/main/java/com/ff/gen/service/IGenTableColumnService.java create mode 100644 ff-gen/src/main/java/com/ff/gen/service/IGenTableService.java create mode 100644 ff-gen/src/main/java/com/ff/gen/util/GenUtils.java create mode 100644 ff-gen/src/main/java/com/ff/gen/util/VelocityInitializer.java create mode 100644 ff-gen/src/main/java/com/ff/gen/util/VelocityUtils.java create mode 100644 ff-gen/src/main/resources/generator.yml create mode 100644 ff-gen/src/main/resources/mapper/gen/GenTableColumnMapper.xml create mode 100644 ff-gen/src/main/resources/mapper/gen/GenTableMapper.xml create mode 100644 ff-gen/src/main/resources/vm/java/controller.java.vm create mode 100644 ff-gen/src/main/resources/vm/java/domain.java.vm create mode 100644 ff-gen/src/main/resources/vm/java/mapper.java.vm create mode 100644 ff-gen/src/main/resources/vm/java/service.java.vm create mode 100644 ff-gen/src/main/resources/vm/java/serviceImpl.java.vm create mode 100644 ff-gen/src/main/resources/vm/java/sub-domain.java.vm create mode 100644 ff-gen/src/main/resources/vm/js/api.js.vm create mode 100644 ff-gen/src/main/resources/vm/sql/sql.vm create mode 100644 ff-gen/src/main/resources/vm/vue/index-tree.vue.vm create mode 100644 ff-gen/src/main/resources/vm/vue/index.vue.vm create mode 100644 ff-gen/src/main/resources/vm/vue/v3/index-tree.vue.vm create mode 100644 ff-gen/src/main/resources/vm/vue/v3/index.vue.vm create mode 100644 ff-gen/src/main/resources/vm/xml/mapper.xml.vm create mode 100644 ff-gen/target/classes/com/ff/gen/config/GenConfig.class create mode 100644 ff-gen/target/classes/com/ff/gen/controller/GenController.class create mode 100644 ff-gen/target/classes/com/ff/gen/domain/GenTable.class create mode 100644 ff-gen/target/classes/com/ff/gen/domain/GenTableColumn.class create mode 100644 ff-gen/target/classes/com/ff/gen/mapper/GenTableColumnMapper.class create mode 100644 ff-gen/target/classes/com/ff/gen/mapper/GenTableMapper.class create mode 100644 ff-gen/target/classes/com/ff/gen/service/GenTableColumnServiceImpl.class create mode 100644 ff-gen/target/classes/com/ff/gen/service/GenTableServiceImpl.class create mode 100644 ff-gen/target/classes/com/ff/gen/service/IGenTableColumnService.class create mode 100644 ff-gen/target/classes/com/ff/gen/service/IGenTableService.class create mode 100644 ff-gen/target/classes/com/ff/gen/util/GenUtils.class create mode 100644 ff-gen/target/classes/com/ff/gen/util/VelocityInitializer.class create mode 100644 ff-gen/target/classes/com/ff/gen/util/VelocityUtils.class create mode 100644 ff-gen/target/classes/generator.yml create mode 100644 ff-gen/target/classes/mapper/gen/GenTableColumnMapper.xml create mode 100644 ff-gen/target/classes/mapper/gen/GenTableMapper.xml create mode 100644 ff-gen/target/classes/vm/java/controller.java.vm create mode 100644 ff-gen/target/classes/vm/java/domain.java.vm create mode 100644 ff-gen/target/classes/vm/java/mapper.java.vm create mode 100644 ff-gen/target/classes/vm/java/service.java.vm create mode 100644 ff-gen/target/classes/vm/java/serviceImpl.java.vm create mode 100644 ff-gen/target/classes/vm/java/sub-domain.java.vm create mode 100644 ff-gen/target/classes/vm/js/api.js.vm create mode 100644 ff-gen/target/classes/vm/sql/sql.vm create mode 100644 ff-gen/target/classes/vm/vue/index-tree.vue.vm create mode 100644 ff-gen/target/classes/vm/vue/index.vue.vm create mode 100644 ff-gen/target/classes/vm/vue/v3/index-tree.vue.vm create mode 100644 ff-gen/target/classes/vm/vue/v3/index.vue.vm create mode 100644 ff-gen/target/classes/vm/xml/mapper.xml.vm create mode 100644 pom.xml create mode 100644 sh/linux/create.sh create mode 100644 sh/linux/nginx.sh create mode 100644 sh/linux/publish.sh create mode 100644 sh/linux/start-manager-api.sh create mode 100644 sh/win/create.bat create mode 100644 sh/win/publish.bat create mode 100644 sh/win/start.bat create mode 100644 sql/ff-admin.sql create mode 100644 sql/update_liukang.sql create mode 100644 sql/update_shi.sql create mode 100644 sql/update_xiongshang.sql diff --git a/ff-admin/pom.xml b/ff-admin/pom.xml new file mode 100644 index 0000000..94f85f1 --- /dev/null +++ b/ff-admin/pom.xml @@ -0,0 +1,128 @@ + + + 4.0.0 + + ff + com.ff + 0.0.1 + + + com.ff + ff-admin + 0.0.1 + ff-admin + ff-admin + + + + + + + org.springframework.boot + spring-boot-devtools + true + + + + org.springframework + spring-context + + + + + io.springfox + springfox-boot-starter + + + + + io.swagger + swagger-models + 1.6.2 + + + + + mysql + mysql-connector-java + + + + + org.quartz-scheduler + quartz + + + com.mchange + c3p0 + + + + + + + com.ff + ff-base + + + + + com.ff + ff-gen + + + org.projectlombok + lombok + provided + + + io.netty + netty-all + 4.1.111.Final + + + + io.socket + socket.io-client + 1.0.0 + + + com.dtflys.forest + forest-spring-boot-starter + 1.6.3 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.5.15 + + true + + + + + repackage + + + + + + org.apache.maven.plugins + maven-war-plugin + 3.1.0 + + false + ${project.artifactId} + + + + ${project.artifactId} + + + diff --git a/ff-admin/src/main/java/com/ff/FFApplication.java b/ff-admin/src/main/java/com/ff/FFApplication.java new file mode 100644 index 0000000..3a511ff --- /dev/null +++ b/ff-admin/src/main/java/com/ff/FFApplication.java @@ -0,0 +1,44 @@ +package com.ff; + +import com.ff.base.config.IdGeneratorUtil; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.SpringBootVersion; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; + +/** + * 启动程序 + * + * @author ff + */ +@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) +@MapperScan({"com.ff.base.system.mapper","com.ff.quartz.mapper","com.ff.gen.mapper"}) +@ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = DaoAuthenticationProvider.class)}) +@EnableAsync +public class FFApplication implements CommandLineRunner +{ + @Autowired + private IdGeneratorUtil idGeneratorUtil; + + + public static void main(String[] args) + { + // System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(FFApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ FF启动成功 ლ(´ڡ`ლ)゙"+ SpringBootVersion.getVersion()); + + + } + + @Override + public void run(String... args) throws Exception { + idGeneratorUtil.init(); + } +} diff --git a/ff-admin/src/main/java/com/ff/FFServletInitializer.java b/ff-admin/src/main/java/com/ff/FFServletInitializer.java new file mode 100644 index 0000000..7e82010 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/FFServletInitializer.java @@ -0,0 +1,18 @@ +package com.ff; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * web容器中进行部署 + * + * @author ff + */ +public class FFServletInitializer extends SpringBootServletInitializer +{ + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) + { + return application.sources(FFApplication.class); + } +} diff --git a/ff-admin/src/main/java/com/ff/annotation/CheckHeader.java b/ff-admin/src/main/java/com/ff/annotation/CheckHeader.java new file mode 100644 index 0000000..99d28f6 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/annotation/CheckHeader.java @@ -0,0 +1,20 @@ +package com.ff.annotation; + +import lombok.Data; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 检查标题 + * + * @author shi + * @date 2025/02/10 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface CheckHeader { + // 该注解没有参数,直接标识类需要进行头部验证 +} \ No newline at end of file diff --git a/ff-admin/src/main/java/com/ff/annotation/HeaderCheckAspect.java b/ff-admin/src/main/java/com/ff/annotation/HeaderCheckAspect.java new file mode 100644 index 0000000..4d605b3 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/annotation/HeaderCheckAspect.java @@ -0,0 +1,69 @@ +package com.ff.annotation; + +import com.ff.base.constant.Constants; +import com.ff.config.KeyConfig; +import com.ff.base.utils.sign.Md5Utils; +import com.ff.common.domain.TenantSecretKey; +import com.ff.common.service.ITenantSecretKeyService; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; +import org.springframework.util.Assert; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; + +/** + * 标题检查方面 + * + * @author shi + * @date 2025/02/10 + */ +@Aspect +@Component +public class HeaderCheckAspect { + + @Resource + private ITenantSecretKeyService tenantSecretKeyService; + + @Resource + private KeyConfig keyUtils; + + + // 定义切点: 所有带 @CheckHeader 注解的类中的所有方法 + @Pointcut("@within(CheckHeader)") + public void checkHeaderPointcut() { + } + + + // 在方法执行前进行处理 + @Before("checkHeaderPointcut()") + public void beforeMethod() throws Exception { + // 获取当前请求的 HTTP 请求对象 + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + + // 32 位小写 md5(random+key+tenantSecret) + String sign = request.getHeader(Constants.SIGN); + Assert.notNull(sign, "签名不能为空"); + // 随机数 + String random = request.getHeader(Constants.RANDOM); + Assert.notNull(random, "随机数不能为空"); + Assert.isTrue( random.length() == 32, "随机数长度错误"); + + //key值 + String key = request.getHeader(Constants.KEY); + Assert.notNull(key, "key不能为空"); + + + TenantSecretKey tenantSecretKey = tenantSecretKeyService.selectTenantSecretKeyByTenantKey(key); + Assert.notNull(tenantSecretKey, "key不存在"); + + String keyG = Md5Utils.md5New(random + key + tenantSecretKey.getTenantSecret()); + Assert.isTrue(keyG.equals(sign), "签名错误"); + //保存 + keyUtils.set(tenantSecretKey); + } +} \ No newline at end of file diff --git a/ff-admin/src/main/java/com/ff/api/controller/ApiGameController.java b/ff-admin/src/main/java/com/ff/api/controller/ApiGameController.java new file mode 100644 index 0000000..b1fd8a4 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/api/controller/ApiGameController.java @@ -0,0 +1,119 @@ +package com.ff.api.controller; + + +import com.ff.annotation.CheckHeader; +import com.ff.api.request.GameLoginRequest; +import com.ff.api.request.MemberCreateApiRequest; +import com.ff.base.constant.Constants; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.utils.StringUtils; +import com.ff.common.domain.TenantSecretKey; +import com.ff.config.KeyConfig; +import com.ff.game.api.IGamesService; +import com.ff.game.api.request.CreateMemberRequestDTO; +import com.ff.game.api.request.GamesLogin; +import com.ff.game.api.request.MemberInfoRequestDTO; +import com.ff.game.domain.Game; +import com.ff.game.domain.GamePlatform; +import com.ff.game.domain.GameSecretKey; +import com.ff.game.service.IGamePlatformService; +import com.ff.game.service.IGameSecretKeyService; +import com.ff.game.service.IGameService; +import com.ff.member.domain.Member; +import com.ff.member.service.IMemberService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.Assert; +import org.springframework.validation.annotation.Validated; +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; + +import javax.annotation.Resource; +import java.util.Map; + +/** + * api控制器 + * + * @author shi + * @date 2025/02/10 + */ +@RestController +@CheckHeader +@RequestMapping("/api/game") +public class ApiGameController extends BaseController { + + + @Autowired + private Map gamesService; + + + @Resource + private IGameService gameService; + + + @Resource + private KeyConfig keyConfig; + + @Resource + private IGameSecretKeyService gameSecretKeyService; + + @Resource + private IMemberService memberService; + + @Resource + private IGamePlatformService gamePlatformService; + + + /** + * 登录 + * + * @param memberCreateApiRequest 成员创建api请求 + * @return {@link AjaxResult } + */ + @PostMapping("/login") + public AjaxResult login(@Validated @RequestBody GameLoginRequest memberCreateApiRequest) { + + Game game = gameService.selectGameById(memberCreateApiRequest.getGameId()); + Assert.notNull(game, "游戏不存在"); + + GamePlatform gamePlatform = gamePlatformService.selectGamePlatformById(game.getPlatformId()); + Assert.notNull(gamePlatform, "游戏平台不存在"); + + + IGamesService iGamesService = gamesService.get(gamePlatform.getPlatformCode() + Constants.SERVICE); + Assert.notNull(iGamesService, "平台不存在"); + + + TenantSecretKey tenantSecretKey = keyConfig.get(); + GameSecretKey gameSecretKey = gameSecretKeyService.findSecretKeyByPlatformAndSystemCode(gamePlatform.getPlatformCode(), memberCreateApiRequest.getCurrencyCode()); + Assert.notNull(gameSecretKey, "货币游戏平台不存在"); + + GameSecretKey gameSecretKeyLang = gameSecretKeyService.findByPlatformAndSystemLangCode(gamePlatform.getPlatformCode(), memberCreateApiRequest.getLangCode()); + Assert.notNull(gameSecretKeyLang, "当前语言不存在"); + + Member member = memberService.selectMemberByGameAccount(StringUtils.addSuffix(memberCreateApiRequest.getAccount(), memberCreateApiRequest.getCurrencyCode() + tenantSecretKey.getTenantSn())); + + GamesLogin gamesLogin = GamesLogin.builder() + .agentId(gameSecretKey.getCode()) + .agentKey(gameSecretKey.getKey()) + .account(member.getGameAccount()) + .gameId(game.getGameCode()) + .homeUrl(memberCreateApiRequest.getHomeUrl()) + .platform(memberCreateApiRequest.getPlatform()) + .disableFullScreen(memberCreateApiRequest.getDisableFullScreen()) + .lang(gameSecretKeyLang.getLang()) + .build(); + + String login = iGamesService.loginWithoutRedirect(gamesLogin); + + return AjaxResult.success(login); + } + + + + + +} diff --git a/ff-admin/src/main/java/com/ff/api/controller/ApiMemberController.java b/ff-admin/src/main/java/com/ff/api/controller/ApiMemberController.java new file mode 100644 index 0000000..c7f239d --- /dev/null +++ b/ff-admin/src/main/java/com/ff/api/controller/ApiMemberController.java @@ -0,0 +1,125 @@ +package com.ff.api.controller; + + +import com.ff.annotation.CheckHeader; +import com.ff.api.request.MemberCreateApiRequest; +import com.ff.base.constant.Constants; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.utils.StringUtils; +import com.ff.common.domain.TenantSecretKey; +import com.ff.config.KeyConfig; +import com.ff.game.api.IGamesService; +import com.ff.game.api.request.CreateMemberRequestDTO; +import com.ff.game.api.request.MemberInfoRequestDTO; +import com.ff.game.domain.GameSecretKey; +import com.ff.game.service.IGameSecretKeyService; +import com.ff.game.service.IGameService; +import com.ff.member.domain.Member; +import com.ff.member.service.IMemberService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.Assert; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.Map; + +/** + * api控制器 + * + * @author shi + * @date 2025/02/10 + */ +@RestController +@CheckHeader +@RequestMapping("/api/member") +public class ApiMemberController extends BaseController { + + + @Autowired + private Map gamesService; + + + @Resource + private IGameService gameService; + + + @Resource + private KeyConfig keyConfig; + + @Resource + private IGameSecretKeyService gameSecretKeyService; + + @Resource + private IMemberService memberService; + + + /** + * 创建成员 + * + * @param memberCreateApiRequest 创建成员api请求 + * @return {@link AjaxResult } + */ + @PostMapping("/create") + public AjaxResult createMember(@Validated @RequestBody MemberCreateApiRequest memberCreateApiRequest) { + + IGamesService iGamesService = gamesService.get(memberCreateApiRequest.getPlatformCode() + Constants.SERVICE); + Assert.notNull(iGamesService, "平台不存在"); + + + TenantSecretKey tenantSecretKey = keyConfig.get(); + GameSecretKey gameSecretKey = gameSecretKeyService.findSecretKeyByPlatformAndSystemCode(memberCreateApiRequest.getPlatformCode(), memberCreateApiRequest.getCurrencyCode()); + Assert.notNull(gameSecretKey, "货币游戏平台不存在"); + + String gameAccount = StringUtils.addSuffix(memberCreateApiRequest.getAccount(), memberCreateApiRequest.getCurrencyCode() + tenantSecretKey.getTenantSn()); + //向第三方注册账号 + CreateMemberRequestDTO gamesBaseRequestDTO = CreateMemberRequestDTO.builder() + .account(gameAccount) + .agentId(gameSecretKey.getCode()) + .agentKey(gameSecretKey.getKey()) + .build(); + Boolean result = iGamesService.createMember(gamesBaseRequestDTO); + Assert.isTrue(result, "建立游戏账号失败"); + //注册本地账号 + Member member = Member.builder() + .tenantKey(tenantSecretKey.getTenantSn()) + .memberAccount(memberCreateApiRequest.getAccount()) + .gameAccount(gameAccount) + .platformCode(memberCreateApiRequest.getPlatformCode()) + .currencyCode(memberCreateApiRequest.getCurrencyCode()) + .build(); + return toAjax(memberService.insertMember(member)); + } + + + /** + * 获取会员信息 + * + * @param memberCreateApiRequest 成员创建api请求 + * @return {@link AjaxResult } + */ + @PostMapping("/info") + public AjaxResult getMemberInfo(@Validated @RequestBody MemberCreateApiRequest memberCreateApiRequest) { + IGamesService iGamesService = gamesService.get(memberCreateApiRequest.getPlatformCode() + Constants.SERVICE); + Assert.notNull(iGamesService, "平台不存在"); + + + TenantSecretKey tenantSecretKey = keyConfig.get(); + GameSecretKey gameSecretKey = gameSecretKeyService.findSecretKeyByPlatformAndSystemCode(memberCreateApiRequest.getPlatformCode(), memberCreateApiRequest.getCurrencyCode()); + Assert.notNull(gameSecretKey, "货币游戏平台不存在"); + + Member member = memberService.selectMemberByGameAccount(StringUtils.addSuffix(memberCreateApiRequest.getAccount(), memberCreateApiRequest.getCurrencyCode() + tenantSecretKey.getTenantSn())); + Assert.notNull(member, "会员不存在"); + //向第三方查询账号 + MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder() + .accounts(member.getGameAccount()) + .agentId(gameSecretKey.getCode()) + .agentKey(gameSecretKey.getKey()) + .build(); + return AjaxResult.success(iGamesService.getMemberInfo(gamesBaseRequestDTO)); + } + + + +} diff --git a/ff-admin/src/main/java/com/ff/api/request/GameLoginRequest.java b/ff-admin/src/main/java/com/ff/api/request/GameLoginRequest.java new file mode 100644 index 0000000..c39eab4 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/api/request/GameLoginRequest.java @@ -0,0 +1,58 @@ +package com.ff.api.request; + +import com.dtflys.forest.annotation.NotNull; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + * 游戏登录请求 + * + * @author shi + * @date 2025/02/11 + */ +@Data +public class GameLoginRequest implements Serializable { + private final static long serialVersionUID = 7699430372422335056L; + + + + /** + * 货币代码 + */ + @NotBlank(message = "currencyCode不能为空") + private String currencyCode; + + /** + * 语种id + */ + @NotBlank(message = "langCode不能为空") + private String langCode; + + /** + * 账户 + */ + @NotBlank(message = "account不能为空") + private String account; + + /** + * 游戏id + */ + @NotBlank(message = "gameId不能为空") + private Long gameId; + + + /** + * 游戏回主页功能导向位置 + */ + private String homeUrl; + /** + * 带入 web 或是 app + */ + private String platform; + /** + * 带入 1 即关闭全屏幕模式 + */ + private Integer disableFullScreen; +} diff --git a/ff-admin/src/main/java/com/ff/api/request/MemberCreateApiRequest.java b/ff-admin/src/main/java/com/ff/api/request/MemberCreateApiRequest.java new file mode 100644 index 0000000..768e55d --- /dev/null +++ b/ff-admin/src/main/java/com/ff/api/request/MemberCreateApiRequest.java @@ -0,0 +1,32 @@ +package com.ff.api.request; + + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + * 创建成员请求 + * + * @author shi + * @date 2025/02/10 + */ +@Data +public class MemberCreateApiRequest implements Serializable{ + + private static final long serialVersionUID = 8071608271351542925L; + + @NotBlank(message = "account不能为空") + private String account; + + /** 平台编码 */ + @NotBlank(message = "platformCode不能为空") + private String platformCode; + + /** 币种编码 */ + @NotBlank(message = "currencyCode不能为空") + private String currencyCode; + +} diff --git a/ff-admin/src/main/java/com/ff/api/request/MemberInfoApiRequest.java b/ff-admin/src/main/java/com/ff/api/request/MemberInfoApiRequest.java new file mode 100644 index 0000000..2200a88 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/api/request/MemberInfoApiRequest.java @@ -0,0 +1,32 @@ +package com.ff.api.request; + + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + * 创建成员请求 + * + * @author shi + * @date 2025/02/10 + */ +@Data +public class MemberInfoApiRequest implements Serializable{ + + private static final long serialVersionUID = 8071608271351542925L; + + @NotBlank(message = "account不能为空") + private String account; + + /** 平台编码 */ + @NotBlank(message = "platformCode不能为空") + private String platformCode; + + /** 币种编码 */ + @NotBlank(message = "currencyCode不能为空") + private String currencyCode; + +} diff --git a/ff-admin/src/main/java/com/ff/common/controller/CaptchaController.java b/ff-admin/src/main/java/com/ff/common/controller/CaptchaController.java new file mode 100644 index 0000000..e56be31 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/controller/CaptchaController.java @@ -0,0 +1,95 @@ +package com.ff.common.controller; + +import com.ff.base.config.FFConfig; +import com.ff.base.constant.CacheConstants; +import com.ff.base.constant.Constants; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.redis.RedisCache; +import com.ff.base.system.service.ISysConfigService; +import com.ff.base.utils.sign.Base64; +import com.ff.base.utils.uuid.IdUtils; +import com.google.code.kaptcha.Producer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.FastByteArrayOutputStream; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.imageio.ImageIO; +import javax.servlet.http.HttpServletResponse; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +/** + * 验证码操作处理 + * + * @author ff + */ +@RestController +public class CaptchaController +{ + @Resource(name = "captchaProducer") + private Producer captchaProducer; + + @Resource(name = "captchaProducerMath") + private Producer captchaProducerMath; + + @Autowired + private RedisCache redisCache; + + @Autowired + private ISysConfigService configService; + /** + * 生成验证码 + */ + @GetMapping("/captchaImage") + public AjaxResult getCode(HttpServletResponse response) throws IOException + { + AjaxResult ajax = AjaxResult.success(); + boolean captchaEnabled = configService.selectCaptchaEnabled(); + ajax.put("captchaEnabled", captchaEnabled); + if (!captchaEnabled) + { + return ajax; + } + + // 保存验证码信息 + String uuid = IdUtils.simpleUUID(); + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; + + String capStr = null, code = null; + BufferedImage image = null; + + // 生成验证码 + String captchaType = FFConfig.getCaptchaType(); + if ("math".equals(captchaType)) + { + String capText = captchaProducerMath.createText(); + capStr = capText.substring(0, capText.lastIndexOf("@")); + code = capText.substring(capText.lastIndexOf("@") + 1); + image = captchaProducerMath.createImage(capStr); + } + else if ("char".equals(captchaType)) + { + capStr = code = captchaProducer.createText(); + image = captchaProducer.createImage(capStr); + } + + redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); + // 转换流信息写出 + FastByteArrayOutputStream os = new FastByteArrayOutputStream(); + try + { + ImageIO.write(image, "jpg", os); + } + catch (IOException e) + { + return AjaxResult.error(e.getMessage()); + } + + ajax.put("uuid", uuid); + ajax.put("img", Base64.encode(os.toByteArray())); + return ajax; + } +} diff --git a/ff-admin/src/main/java/com/ff/common/controller/CurrencyController.java b/ff-admin/src/main/java/com/ff/common/controller/CurrencyController.java new file mode 100644 index 0000000..871960e --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/controller/CurrencyController.java @@ -0,0 +1,104 @@ +package com.ff.common.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.common.domain.Currency; +import com.ff.common.service.ICurrencyService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 币种Controller + * + * @author shi + * @date 2025-02-10 + */ +@RestController +@RequestMapping("/common/currency") +public class CurrencyController extends BaseController +{ + @Autowired + private ICurrencyService currencyService; + + /** + * 查询币种列表 + */ + @PreAuthorize("@ss.hasPermi('common:currency:list')") + @GetMapping("/list") + public TableDataInfo list(Currency currency) + { + startPage(); + List list = currencyService.selectCurrencyList(currency); + return getDataTable(list); + } + + /** + * 导出币种列表 + */ + @PreAuthorize("@ss.hasPermi('common:currency:export')") + @Log(title = "币种", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, Currency currency) + { + List list = currencyService.selectCurrencyList(currency); + ExcelUtil util = new ExcelUtil(Currency.class); + util.exportExcel(response, list, "币种数据"); + } + + /** + * 获取币种详细信息 + */ + @PreAuthorize("@ss.hasPermi('common:currency:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(currencyService.selectCurrencyById(id)); + } + + /** + * 新增币种 + */ + @PreAuthorize("@ss.hasPermi('common:currency:add')") + @Log(title = "币种", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody Currency currency) + { + return toAjax(currencyService.insertCurrency(currency)); + } + + /** + * 修改币种 + */ + @PreAuthorize("@ss.hasPermi('common:currency:edit')") + @Log(title = "币种", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody Currency currency) + { + return toAjax(currencyService.updateCurrency(currency)); + } + + /** + * 删除币种 + */ + @PreAuthorize("@ss.hasPermi('common:currency:remove')") + @Log(title = "币种", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(currencyService.deleteCurrencyByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/common/controller/LangController.java b/ff-admin/src/main/java/com/ff/common/controller/LangController.java new file mode 100644 index 0000000..a0a8fab --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/controller/LangController.java @@ -0,0 +1,104 @@ +package com.ff.common.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.common.domain.Lang; +import com.ff.common.service.ILangService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 系统语种管理 Controller + * + * @author shi + * @date 2025-02-10 + */ +@RestController +@RequestMapping("/common/lang") +public class LangController extends BaseController +{ + @Autowired + private ILangService langService; + + /** + * 查询系统语种管理 列表 + */ + @PreAuthorize("@ss.hasPermi('common:lang:list')") + @GetMapping("/list") + public TableDataInfo list(Lang lang) + { + startPage(); + List list = langService.selectLangList(lang); + return getDataTable(list); + } + + /** + * 导出系统语种管理 列表 + */ + @PreAuthorize("@ss.hasPermi('common:lang:export')") + @Log(title = "系统语种管理 ", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, Lang lang) + { + List list = langService.selectLangList(lang); + ExcelUtil util = new ExcelUtil(Lang.class); + util.exportExcel(response, list, "系统语种管理 数据"); + } + + /** + * 获取系统语种管理 详细信息 + */ + @PreAuthorize("@ss.hasPermi('common:lang:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(langService.selectLangById(id)); + } + + /** + * 新增系统语种管理 + */ + @PreAuthorize("@ss.hasPermi('common:lang:add')") + @Log(title = "系统语种管理 ", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody Lang lang) + { + return toAjax(langService.insertLang(lang)); + } + + /** + * 修改系统语种管理 + */ + @PreAuthorize("@ss.hasPermi('common:lang:edit')") + @Log(title = "系统语种管理 ", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody Lang lang) + { + return toAjax(langService.updateLang(lang)); + } + + /** + * 删除系统语种管理 + */ + @PreAuthorize("@ss.hasPermi('common:lang:remove')") + @Log(title = "系统语种管理 ", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(langService.deleteLangByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/common/controller/TenantSecretKeyController.java b/ff-admin/src/main/java/com/ff/common/controller/TenantSecretKeyController.java new file mode 100644 index 0000000..5d60d8a --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/controller/TenantSecretKeyController.java @@ -0,0 +1,104 @@ +package com.ff.common.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.common.domain.TenantSecretKey; +import com.ff.common.service.ITenantSecretKeyService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 用户租户密钥Controller + * + * @author shi + * @date 2025-02-11 + */ +@RestController +@RequestMapping("/common/key") +public class TenantSecretKeyController extends BaseController +{ + @Autowired + private ITenantSecretKeyService tenantSecretKeyService; + + /** + * 查询用户租户密钥列表 + */ + @PreAuthorize("@ss.hasPermi('common:key:list')") + @GetMapping("/list") + public TableDataInfo list(TenantSecretKey tenantSecretKey) + { + startPage(); + List list = tenantSecretKeyService.selectTenantSecretKeyList(tenantSecretKey); + return getDataTable(list); + } + + /** + * 导出用户租户密钥列表 + */ + @PreAuthorize("@ss.hasPermi('common:key:export')") + @Log(title = "用户租户密钥", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, TenantSecretKey tenantSecretKey) + { + List list = tenantSecretKeyService.selectTenantSecretKeyList(tenantSecretKey); + ExcelUtil util = new ExcelUtil(TenantSecretKey.class); + util.exportExcel(response, list, "用户租户密钥数据"); + } + + /** + * 获取用户租户密钥详细信息 + */ + @PreAuthorize("@ss.hasPermi('common:key:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(tenantSecretKeyService.selectTenantSecretKeyById(id)); + } + + /** + * 新增用户租户密钥 + */ + @PreAuthorize("@ss.hasPermi('common:key:add')") + @Log(title = "用户租户密钥", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody TenantSecretKey tenantSecretKey) + { + return toAjax(tenantSecretKeyService.insertTenantSecretKey(tenantSecretKey)); + } + + /** + * 修改用户租户密钥 + */ + @PreAuthorize("@ss.hasPermi('common:key:edit')") + @Log(title = "用户租户密钥", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody TenantSecretKey tenantSecretKey) + { + return toAjax(tenantSecretKeyService.updateTenantSecretKey(tenantSecretKey)); + } + + /** + * 删除用户租户密钥 + */ + @PreAuthorize("@ss.hasPermi('common:key:remove')") + @Log(title = "用户租户密钥", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(tenantSecretKeyService.deleteTenantSecretKeyByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/common/domain/Currency.java b/ff-admin/src/main/java/com/ff/common/domain/Currency.java new file mode 100644 index 0000000..a573675 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/domain/Currency.java @@ -0,0 +1,54 @@ +package com.ff.common.domain; + +import java.math.BigDecimal; +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.Data; +/** + * 币种对象 ff_currency + * + * @author shi + * @date 2025-02-10 + */ +@Data +public class Currency extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 币种状态(0正常 1停用) */ + @Excel(name = "币种状态", readConverterExp = "0=正常,1=停用") + private String status; + + /** 币种国家 */ + @Excel(name = "币种国家") + private String country; + + /** 币种编码 */ + @Excel(name = "币种编码") + private String currencyCode; + + /** 币种符号 */ + @Excel(name = "币种符号") + private String currencySign; + + /** 汇率 */ + @Excel(name = "汇率") + private BigDecimal gameRate; + + /** 币种展示内容 */ + @Excel(name = "币种展示内容") + private String currencyDisplay; + + /** 币种名称 */ + @Excel(name = "币种名称") + private String currencyName; + + /** 币种全称 */ + @Excel(name = "币种全称") + private String fullName; + + +} diff --git a/ff-admin/src/main/java/com/ff/common/domain/Lang.java b/ff-admin/src/main/java/com/ff/common/domain/Lang.java new file mode 100644 index 0000000..a4799a3 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/domain/Lang.java @@ -0,0 +1,37 @@ +package com.ff.common.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.Data; +/** + * 系统语种管理 对象 ff_lang + * + * @author shi + * @date 2025-02-10 + */ +@Data +public class Lang extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 语言名称 */ + @Excel(name = "语言名称") + private String name; + + /** 国家代码 */ + @Excel(name = "国家代码") + private String country; + + /** 语种 */ + @Excel(name = "语种") + private String langCode; + + /** 语种开关 0 关闭 1 开启 */ + @Excel(name = "语种开关 0 关闭 1 开启") + private Boolean langStatus; + + +} diff --git a/ff-admin/src/main/java/com/ff/common/domain/TenantSecretKey.java b/ff-admin/src/main/java/com/ff/common/domain/TenantSecretKey.java new file mode 100644 index 0000000..15e313d --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/domain/TenantSecretKey.java @@ -0,0 +1,37 @@ +package com.ff.common.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.Data; +/** + * 用户租户密钥对象 ff_tenant_secret_key + * + * @author shi + * @date 2025-02-11 + */ +@Data +public class TenantSecretKey extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 租户key */ + @Excel(name = "租户key") + private String tenantKey; + + /** 商户后缀 */ + @Excel(name = "商户后缀") + private String tenantSn; + + /** 租户密钥 */ + @Excel(name = "租户密钥") + private String tenantSecret; + + /** 租户状态(0正常 1停用) */ + @Excel(name = "租户状态", readConverterExp = "0=正常,1=停用") + private String tenantStatus; + + +} diff --git a/ff-admin/src/main/java/com/ff/common/mapper/CurrencyMapper.java b/ff-admin/src/main/java/com/ff/common/mapper/CurrencyMapper.java new file mode 100644 index 0000000..5aaf2f4 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/mapper/CurrencyMapper.java @@ -0,0 +1,61 @@ +package com.ff.common.mapper; + +import java.util.List; +import com.ff.common.domain.Currency; + +/** + * 币种Mapper接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface CurrencyMapper +{ + /** + * 查询币种 + * + * @param id 币种主键 + * @return 币种 + */ + Currency selectCurrencyById(Long id); + + /** + * 查询币种列表 + * + * @param currency 币种 + * @return 币种集合 + */ + List selectCurrencyList(Currency currency); + + /** + * 新增币种 + * + * @param currency 币种 + * @return 结果 + */ + int insertCurrency(Currency currency); + + /** + * 修改币种 + * + * @param currency 币种 + * @return 结果 + */ + int updateCurrency(Currency currency); + + /** + * 删除币种 + * + * @param id 币种主键 + * @return 结果 + */ + int deleteCurrencyById(Long id); + + /** + * 批量删除币种 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteCurrencyByIds(Long[] ids); +} diff --git a/ff-admin/src/main/java/com/ff/common/mapper/LangMapper.java b/ff-admin/src/main/java/com/ff/common/mapper/LangMapper.java new file mode 100644 index 0000000..0e7eb31 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/mapper/LangMapper.java @@ -0,0 +1,61 @@ +package com.ff.common.mapper; + +import java.util.List; +import com.ff.common.domain.Lang; + +/** + * 系统语种管理 Mapper接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface LangMapper +{ + /** + * 查询系统语种管理 + * + * @param id 系统语种管理 主键 + * @return 系统语种管理 + */ + Lang selectLangById(Long id); + + /** + * 查询系统语种管理 列表 + * + * @param lang 系统语种管理 + * @return 系统语种管理 集合 + */ + List selectLangList(Lang lang); + + /** + * 新增系统语种管理 + * + * @param lang 系统语种管理 + * @return 结果 + */ + int insertLang(Lang lang); + + /** + * 修改系统语种管理 + * + * @param lang 系统语种管理 + * @return 结果 + */ + int updateLang(Lang lang); + + /** + * 删除系统语种管理 + * + * @param id 系统语种管理 主键 + * @return 结果 + */ + int deleteLangById(Long id); + + /** + * 批量删除系统语种管理 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteLangByIds(Long[] ids); +} diff --git a/ff-admin/src/main/java/com/ff/common/mapper/TenantSecretKeyMapper.java b/ff-admin/src/main/java/com/ff/common/mapper/TenantSecretKeyMapper.java new file mode 100644 index 0000000..9a445f9 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/mapper/TenantSecretKeyMapper.java @@ -0,0 +1,69 @@ +package com.ff.common.mapper; + +import java.util.List; +import com.ff.common.domain.TenantSecretKey; + +/** + * 用户租户密钥Mapper接口 + * + * @author shi + * @date 2025-02-11 + */ +public interface TenantSecretKeyMapper +{ + /** + * 查询用户租户密钥 + * + * @param id 用户租户密钥主键 + * @return 用户租户密钥 + */ + TenantSecretKey selectTenantSecretKeyById(Long id); + + /** + * 按租户密钥选择租户密钥 + * + * @param tenantKey 租户密钥 + * @return {@link TenantSecretKey } + */ + TenantSecretKey selectTenantSecretKeyByTenantKey(String tenantKey); + + /** + * 查询用户租户密钥列表 + * + * @param tenantSecretKey 用户租户密钥 + * @return 用户租户密钥集合 + */ + List selectTenantSecretKeyList(TenantSecretKey tenantSecretKey); + + /** + * 新增用户租户密钥 + * + * @param tenantSecretKey 用户租户密钥 + * @return 结果 + */ + int insertTenantSecretKey(TenantSecretKey tenantSecretKey); + + /** + * 修改用户租户密钥 + * + * @param tenantSecretKey 用户租户密钥 + * @return 结果 + */ + int updateTenantSecretKey(TenantSecretKey tenantSecretKey); + + /** + * 删除用户租户密钥 + * + * @param id 用户租户密钥主键 + * @return 结果 + */ + int deleteTenantSecretKeyById(Long id); + + /** + * 批量删除用户租户密钥 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteTenantSecretKeyByIds(Long[] ids); +} diff --git a/ff-admin/src/main/java/com/ff/common/service/ICurrencyService.java b/ff-admin/src/main/java/com/ff/common/service/ICurrencyService.java new file mode 100644 index 0000000..b8c94f4 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/service/ICurrencyService.java @@ -0,0 +1,61 @@ +package com.ff.common.service; + +import java.util.List; +import com.ff.common.domain.Currency; + +/** + * 币种Service接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface ICurrencyService +{ + /** + * 查询币种 + * + * @param id 币种主键 + * @return 币种 + */ + Currency selectCurrencyById(Long id); + + /** + * 查询币种列表 + * + * @param currency 币种 + * @return 币种集合 + */ + List selectCurrencyList(Currency currency); + + /** + * 新增币种 + * + * @param currency 币种 + * @return 结果 + */ + int insertCurrency(Currency currency); + + /** + * 修改币种 + * + * @param currency 币种 + * @return 结果 + */ + int updateCurrency(Currency currency); + + /** + * 批量删除币种 + * + * @param ids 需要删除的币种主键集合 + * @return 结果 + */ + int deleteCurrencyByIds(Long[] ids); + + /** + * 删除币种信息 + * + * @param id 币种主键 + * @return 结果 + */ + int deleteCurrencyById(Long id); +} diff --git a/ff-admin/src/main/java/com/ff/common/service/ILangService.java b/ff-admin/src/main/java/com/ff/common/service/ILangService.java new file mode 100644 index 0000000..d28a5d2 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/service/ILangService.java @@ -0,0 +1,61 @@ +package com.ff.common.service; + +import java.util.List; +import com.ff.common.domain.Lang; + +/** + * 系统语种管理 Service接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface ILangService +{ + /** + * 查询系统语种管理 + * + * @param id 系统语种管理 主键 + * @return 系统语种管理 + */ + Lang selectLangById(Long id); + + /** + * 查询系统语种管理 列表 + * + * @param lang 系统语种管理 + * @return 系统语种管理 集合 + */ + List selectLangList(Lang lang); + + /** + * 新增系统语种管理 + * + * @param lang 系统语种管理 + * @return 结果 + */ + int insertLang(Lang lang); + + /** + * 修改系统语种管理 + * + * @param lang 系统语种管理 + * @return 结果 + */ + int updateLang(Lang lang); + + /** + * 批量删除系统语种管理 + * + * @param ids 需要删除的系统语种管理 主键集合 + * @return 结果 + */ + int deleteLangByIds(Long[] ids); + + /** + * 删除系统语种管理 信息 + * + * @param id 系统语种管理 主键 + * @return 结果 + */ + int deleteLangById(Long id); +} diff --git a/ff-admin/src/main/java/com/ff/common/service/ITenantSecretKeyService.java b/ff-admin/src/main/java/com/ff/common/service/ITenantSecretKeyService.java new file mode 100644 index 0000000..b2fefc9 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/service/ITenantSecretKeyService.java @@ -0,0 +1,69 @@ +package com.ff.common.service; + +import java.util.List; +import com.ff.common.domain.TenantSecretKey; + +/** + * 用户租户密钥Service接口 + * + * @author shi + * @date 2025-02-11 + */ +public interface ITenantSecretKeyService +{ + /** + * 查询用户租户密钥 + * + * @param id 用户租户密钥主键 + * @return 用户租户密钥 + */ + TenantSecretKey selectTenantSecretKeyById(Long id); + + /** + * 按租户密钥选择租户密钥 + * + * @param tenantKey 租户密钥 + * @return {@link TenantSecretKey } + */ + TenantSecretKey selectTenantSecretKeyByTenantKey(String tenantKey); + + /** + * 查询用户租户密钥列表 + * + * @param tenantSecretKey 用户租户密钥 + * @return 用户租户密钥集合 + */ + List selectTenantSecretKeyList(TenantSecretKey tenantSecretKey); + + /** + * 新增用户租户密钥 + * + * @param tenantSecretKey 用户租户密钥 + * @return 结果 + */ + int insertTenantSecretKey(TenantSecretKey tenantSecretKey); + + /** + * 修改用户租户密钥 + * + * @param tenantSecretKey 用户租户密钥 + * @return 结果 + */ + int updateTenantSecretKey(TenantSecretKey tenantSecretKey); + + /** + * 批量删除用户租户密钥 + * + * @param ids 需要删除的用户租户密钥主键集合 + * @return 结果 + */ + int deleteTenantSecretKeyByIds(Long[] ids); + + /** + * 删除用户租户密钥信息 + * + * @param id 用户租户密钥主键 + * @return 结果 + */ + int deleteTenantSecretKeyById(Long id); +} diff --git a/ff-admin/src/main/java/com/ff/common/service/impl/CurrencyServiceImpl.java b/ff-admin/src/main/java/com/ff/common/service/impl/CurrencyServiceImpl.java new file mode 100644 index 0000000..45acbf0 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/service/impl/CurrencyServiceImpl.java @@ -0,0 +1,96 @@ +package com.ff.common.service.impl; + +import java.util.List; +import com.ff.base.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.common.mapper.CurrencyMapper; +import com.ff.common.domain.Currency; +import com.ff.common.service.ICurrencyService; + +/** + * 币种Service业务层处理 + * + * @author shi + * @date 2025-02-10 + */ +@Service +public class CurrencyServiceImpl implements ICurrencyService +{ + @Autowired + private CurrencyMapper currencyMapper; + + /** + * 查询币种 + * + * @param id 币种主键 + * @return 币种 + */ + @Override + public Currency selectCurrencyById(Long id) + { + return currencyMapper.selectCurrencyById(id); + } + + /** + * 查询币种列表 + * + * @param currency 币种 + * @return 币种 + */ + @Override + public List selectCurrencyList(Currency currency) + { + return currencyMapper.selectCurrencyList(currency); + } + + /** + * 新增币种 + * + * @param currency 币种 + * @return 结果 + */ + @Override + public int insertCurrency(Currency currency) + { + currency.setCreateTime(DateUtils.getNowDate()); + return currencyMapper.insertCurrency(currency); + } + + /** + * 修改币种 + * + * @param currency 币种 + * @return 结果 + */ + @Override + public int updateCurrency(Currency currency) + { + currency.setUpdateTime(DateUtils.getNowDate()); + return currencyMapper.updateCurrency(currency); + } + + /** + * 批量删除币种 + * + * @param ids 需要删除的币种主键 + * @return 结果 + */ + @Override + public int deleteCurrencyByIds(Long[] ids) + { + return currencyMapper.deleteCurrencyByIds(ids); + } + + /** + * 删除币种信息 + * + * @param id 币种主键 + * @return 结果 + */ + @Override + public int deleteCurrencyById(Long id) + { + return currencyMapper.deleteCurrencyById(id); + } +} diff --git a/ff-admin/src/main/java/com/ff/common/service/impl/LangServiceImpl.java b/ff-admin/src/main/java/com/ff/common/service/impl/LangServiceImpl.java new file mode 100644 index 0000000..28b62b6 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/service/impl/LangServiceImpl.java @@ -0,0 +1,96 @@ +package com.ff.common.service.impl; + +import java.util.List; +import com.ff.base.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.common.mapper.LangMapper; +import com.ff.common.domain.Lang; +import com.ff.common.service.ILangService; + +/** + * 系统语种管理 Service业务层处理 + * + * @author shi + * @date 2025-02-10 + */ +@Service +public class LangServiceImpl implements ILangService +{ + @Autowired + private LangMapper langMapper; + + /** + * 查询系统语种管理 + * + * @param id 系统语种管理 主键 + * @return 系统语种管理 + */ + @Override + public Lang selectLangById(Long id) + { + return langMapper.selectLangById(id); + } + + /** + * 查询系统语种管理 列表 + * + * @param lang 系统语种管理 + * @return 系统语种管理 + */ + @Override + public List selectLangList(Lang lang) + { + return langMapper.selectLangList(lang); + } + + /** + * 新增系统语种管理 + * + * @param lang 系统语种管理 + * @return 结果 + */ + @Override + public int insertLang(Lang lang) + { + lang.setCreateTime(DateUtils.getNowDate()); + return langMapper.insertLang(lang); + } + + /** + * 修改系统语种管理 + * + * @param lang 系统语种管理 + * @return 结果 + */ + @Override + public int updateLang(Lang lang) + { + lang.setUpdateTime(DateUtils.getNowDate()); + return langMapper.updateLang(lang); + } + + /** + * 批量删除系统语种管理 + * + * @param ids 需要删除的系统语种管理 主键 + * @return 结果 + */ + @Override + public int deleteLangByIds(Long[] ids) + { + return langMapper.deleteLangByIds(ids); + } + + /** + * 删除系统语种管理 信息 + * + * @param id 系统语种管理 主键 + * @return 结果 + */ + @Override + public int deleteLangById(Long id) + { + return langMapper.deleteLangById(id); + } +} diff --git a/ff-admin/src/main/java/com/ff/common/service/impl/TenantSecretKeyServiceImpl.java b/ff-admin/src/main/java/com/ff/common/service/impl/TenantSecretKeyServiceImpl.java new file mode 100644 index 0000000..e3d0fe6 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/service/impl/TenantSecretKeyServiceImpl.java @@ -0,0 +1,107 @@ +package com.ff.common.service.impl; + +import java.util.List; +import com.ff.base.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.common.mapper.TenantSecretKeyMapper; +import com.ff.common.domain.TenantSecretKey; +import com.ff.common.service.ITenantSecretKeyService; + +/** + * 用户租户密钥Service业务层处理 + * + * @author shi + * @date 2025-02-11 + */ +@Service +public class TenantSecretKeyServiceImpl implements ITenantSecretKeyService +{ + @Autowired + private TenantSecretKeyMapper tenantSecretKeyMapper; + + /** + * 查询用户租户密钥 + * + * @param id 用户租户密钥主键 + * @return 用户租户密钥 + */ + @Override + public TenantSecretKey selectTenantSecretKeyById(Long id) + { + return tenantSecretKeyMapper.selectTenantSecretKeyById(id); + } + + /** + * 按租户密钥选择租户密钥 + * + * @param tenantKey 租户密钥 + * @return {@link TenantSecretKey } + */ + @Override + public TenantSecretKey selectTenantSecretKeyByTenantKey(String tenantKey) { + return tenantSecretKeyMapper.selectTenantSecretKeyByTenantKey(tenantKey); + } + + /** + * 查询用户租户密钥列表 + * + * @param tenantSecretKey 用户租户密钥 + * @return 用户租户密钥 + */ + @Override + public List selectTenantSecretKeyList(TenantSecretKey tenantSecretKey) + { + return tenantSecretKeyMapper.selectTenantSecretKeyList(tenantSecretKey); + } + + /** + * 新增用户租户密钥 + * + * @param tenantSecretKey 用户租户密钥 + * @return 结果 + */ + @Override + public int insertTenantSecretKey(TenantSecretKey tenantSecretKey) + { + tenantSecretKey.setCreateTime(DateUtils.getNowDate()); + return tenantSecretKeyMapper.insertTenantSecretKey(tenantSecretKey); + } + + /** + * 修改用户租户密钥 + * + * @param tenantSecretKey 用户租户密钥 + * @return 结果 + */ + @Override + public int updateTenantSecretKey(TenantSecretKey tenantSecretKey) + { + tenantSecretKey.setUpdateTime(DateUtils.getNowDate()); + return tenantSecretKeyMapper.updateTenantSecretKey(tenantSecretKey); + } + + /** + * 批量删除用户租户密钥 + * + * @param ids 需要删除的用户租户密钥主键 + * @return 结果 + */ + @Override + public int deleteTenantSecretKeyByIds(Long[] ids) + { + return tenantSecretKeyMapper.deleteTenantSecretKeyByIds(ids); + } + + /** + * 删除用户租户密钥信息 + * + * @param id 用户租户密钥主键 + * @return 结果 + */ + @Override + public int deleteTenantSecretKeyById(Long id) + { + return tenantSecretKeyMapper.deleteTenantSecretKeyById(id); + } +} diff --git a/ff-admin/src/main/java/com/ff/config/ContentRefreshedEventListener.java b/ff-admin/src/main/java/com/ff/config/ContentRefreshedEventListener.java new file mode 100644 index 0000000..0b0d82b --- /dev/null +++ b/ff-admin/src/main/java/com/ff/config/ContentRefreshedEventListener.java @@ -0,0 +1,54 @@ +package com.ff.config; + +import com.ff.base.datasource.DynamicDataSource; +import com.ff.base.system.domain.SysDatasource; +import com.ff.base.system.mapper.SysDatasourceMapper; +import com.ff.base.system.service.ISysConfigService; +import com.ff.base.system.service.ISysDictTypeService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 启动项目时加载多数据源 + * + * @author liukang + */ +@Slf4j +@Component +public class ContentRefreshedEventListener implements ApplicationListener { + + @Resource + private DynamicDataSource dynamicDataSource; + + @Resource + private SysDatasourceMapper dataSourceMapper; + + @Resource + private ISysConfigService sysConfigService; + + @Resource + private ISysDictTypeService sysDictTypeService; + /** + * 项目加载时运行 + * + * @param event + */ + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + // 创建所有数据源 + SysDatasource sysDatasource = new SysDatasource(); + sysDatasource.setStatus("1"); + List dataourceList = dataSourceMapper.selectSysDatasourceList(sysDatasource); + if (!CollectionUtils.isEmpty(dataourceList)) { + dynamicDataSource.createDataSource(dataourceList); + } + sysConfigService.loadingConfigCache(); + sysDictTypeService.loadingDictCache(); + } +} diff --git a/ff-admin/src/main/java/com/ff/config/KeyConfig.java b/ff-admin/src/main/java/com/ff/config/KeyConfig.java new file mode 100644 index 0000000..287b8eb --- /dev/null +++ b/ff-admin/src/main/java/com/ff/config/KeyConfig.java @@ -0,0 +1,44 @@ +package com.ff.config; + +import com.ff.common.domain.TenantSecretKey; +import org.springframework.stereotype.Component; + +/** + * 关键 工具 + * + * @author shi + * @date 2025/02/11 + */ +@Component +public class KeyConfig { + + // 定义一个 ThreadLocal 变量,持有当前线程的全局变量 + private ThreadLocal threadLocalVariable = new ThreadLocal<>(); + + /** + * 设置 + * + * @param value 价值 + */ + public void set(TenantSecretKey value) { + threadLocalVariable.set(value); + } + + + /** + * 得到 + * + * @return {@link String } + */ + public TenantSecretKey get() { + return threadLocalVariable.get(); + } + + + /** + * 清楚 + */ + public void clear() { + threadLocalVariable.remove(); + } +} diff --git a/ff-admin/src/main/java/com/ff/config/SwaggerConfig.java b/ff-admin/src/main/java/com/ff/config/SwaggerConfig.java new file mode 100644 index 0000000..9a689b9 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/config/SwaggerConfig.java @@ -0,0 +1,121 @@ +package com.ff.config; + +import com.ff.base.config.FFConfig; +import io.swagger.annotations.ApiOperation; +import io.swagger.models.auth.In; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.*; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.Docket; + +import java.util.ArrayList; +import java.util.List; + +/** + * Swagger2的接口配置 + * + * @author ff + */ +@Configuration +public class SwaggerConfig +{ + /** 系统基础配置 */ + @Autowired + private FFConfig ffConfig; + + /** 是否开启swagger */ + @Value("${swagger.enabled}") + private boolean enabled; + + /** 设置请求的统一前缀 */ + @Value("${swagger.pathMapping}") + private String pathMapping; + + /** + * 创建API + */ + @Bean + public Docket createRestApi() + { + return new Docket(DocumentationType.OAS_30) + // 是否启用Swagger + .enable(enabled) + // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息) + .apiInfo(apiInfo()) + // 设置哪些接口暴露给Swagger展示 + .select() + // 扫描所有有注解的api,用这种方式更灵活 + .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) + // 扫描指定包中的swagger注解 + // .apis(RequestHandlerSelectors.basePackage("com.ff.project.tool.swagger")) + // 扫描所有 .apis(RequestHandlerSelectors.any()) + .paths(PathSelectors.any()) + .build() + /* 设置安全模式,swagger可以设置访问token */ + .securitySchemes(securitySchemes()) + .securityContexts(securityContexts()) + .pathMapping(pathMapping); + } + + /** + * 安全模式,这里指定token通过Authorization头请求头传递 + */ + private List securitySchemes() + { + List apiKeyList = new ArrayList(); + apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue())); + return apiKeyList; + } + + /** + * 安全上下文 + */ + private List securityContexts() + { + List securityContexts = new ArrayList<>(); + securityContexts.add( + SecurityContext.builder() + .securityReferences(defaultAuth()) + .operationSelector(o -> o.requestMappingPattern().matches("/.*")) + .build()); + return securityContexts; + } + + /** + * 默认的安全上引用 + */ + private List defaultAuth() + { + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; + authorizationScopes[0] = authorizationScope; + List securityReferences = new ArrayList<>(); + securityReferences.add(new SecurityReference("Authorization", authorizationScopes)); + return securityReferences; + } + + /** + * 添加摘要信息 + */ + private ApiInfo apiInfo() + { + // 用ApiInfoBuilder进行定制 + return new ApiInfoBuilder() + // 设置标题 + .title("标题:FF管理系统_接口文档") + // 描述 + .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...") + // 作者信息 + .contact(new Contact(ffConfig.getName(), null, null)) + // 版本 + .version("版本号:" + ffConfig.getVersion()) + .build(); + } +} diff --git a/ff-admin/src/main/java/com/ff/file/controller/FileController.java b/ff-admin/src/main/java/com/ff/file/controller/FileController.java new file mode 100644 index 0000000..ba36f07 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/file/controller/FileController.java @@ -0,0 +1,45 @@ +package com.ff.file.controller; + +import com.ff.base.annotation.Anonymous; +import com.ff.base.constant.Constants; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.exception.base.BaseException; +import com.ff.base.utils.MessageUtils; +import com.ff.file.service.ISysFileService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import java.util.Map; + +/** + * 文件管理 + * + * @author ff + */ +@RestController +@RequestMapping("/file") +public class FileController { + + @Autowired + private Map fileServiceMap; + + /** + * 通用上传请求(单个) + */ + @PostMapping("/upload/{service}") + @Anonymous + public AjaxResult uploadFile(MultipartFile file, @PathVariable String service) { + + ISysFileService sysFileService = fileServiceMap.get(service + Constants.SERVICE); + if (sysFileService == null) { + throw new BaseException(MessageUtils.message("upload.file.server.not.exist")); + } + return sysFileService.uploadFile(file); + + } + +} diff --git a/ff-admin/src/main/java/com/ff/file/service/ISysFileService.java b/ff-admin/src/main/java/com/ff/file/service/ISysFileService.java new file mode 100644 index 0000000..485a87a --- /dev/null +++ b/ff-admin/src/main/java/com/ff/file/service/ISysFileService.java @@ -0,0 +1,21 @@ +package com.ff.file.service; + +import com.ff.base.core.domain.AjaxResult; +import org.springframework.web.multipart.MultipartFile; + +/** + * 文件上传接口 + * + * @author ruoyi + */ +public interface ISysFileService +{ + /** + * 文件上传接口 + * + * @param file 上传的文件 + * @return 访问地址 + * @throws Exception + */ + public AjaxResult uploadFile(MultipartFile file) ; +} diff --git a/ff-admin/src/main/java/com/ff/file/service/impl/LocalSysFileServiceImpl.java b/ff-admin/src/main/java/com/ff/file/service/impl/LocalSysFileServiceImpl.java new file mode 100644 index 0000000..7001aa5 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/file/service/impl/LocalSysFileServiceImpl.java @@ -0,0 +1,48 @@ +package com.ff.file.service.impl; + +import com.ff.base.config.FFConfig; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.exception.base.BaseException; +import com.ff.base.utils.MessageUtils; +import com.ff.base.utils.file.FileUploadUtils; +import com.ff.base.utils.file.FileUtils; +import com.ff.file.service.ISysFileService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; + +/** + * 本地文件存储 + * + * @author ruoyi + */ +@Service("localSysFileService") +@Slf4j +public class LocalSysFileServiceImpl implements ISysFileService { + /** + * 本地文件上传接口 + * + * @param file 上传的文件 + * @return 访问地址 + * @throws Exception + */ + @Override + public AjaxResult uploadFile(MultipartFile file) { + try { + // 上传文件路径 + String filePath = FFConfig.getUploadPath(); + // 上传并返回新文件名称 + String fileName = FileUploadUtils.upload(filePath, file); + AjaxResult ajax = AjaxResult.success(); + ajax.put("url", fileName); + ajax.put("fileName", FileUtils.getName(fileName)); + ajax.put("originalFilename", file.getOriginalFilename()); + return ajax; + } catch (IOException e) { + log.error("本地文件上传异常,{}", e); + throw new BaseException(MessageUtils.message("upload.file.exception"), e.getMessage()); + } + } +} diff --git a/ff-admin/src/main/java/com/ff/game/api/IGamesService.java b/ff-admin/src/main/java/com/ff/game/api/IGamesService.java new file mode 100644 index 0000000..6722464 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/IGamesService.java @@ -0,0 +1,139 @@ +package com.ff.game.api; + + + +import com.ff.game.api.request.*; +import com.ff.game.domain.GameBettingDetails; +import com.ff.game.domain.GameFreeRecord; + +import java.util.List; + +/** + * 游戏数据解析服务 + * + * @author shi + * @date 2024/10/21 + */ +public interface IGamesService { + + + /** + * 获取密钥 + * + * @param gamesBaseRequestDTO 游戏请求dto + * @return {@link String } + */ + String getKey(GamesBaseRequestDTO gamesBaseRequestDTO); + + /** + * 创建成员 + * + * @param createMemberRequestDTO 创建成员请求dto + * @return {@link Boolean } + */ + Boolean createMember(CreateMemberRequestDTO createMemberRequestDTO); + + + /** + * 获取会员信息 + * + * @param memberInfoRequestDTO 会员信息请求dto + * @return {@link MemberInfoResponseDTO } + */ + MemberInfoResponseDTO getMemberInfo(MemberInfoRequestDTO memberInfoRequestDTO); + + /** + * 无重定向登录 + * + * @param gamesLogin 游戏登录 + * @return {@link String } + */ + String loginWithoutRedirect(GamesLogin gamesLogin); + + + + /** + * 获取游戏列表 + * + * @param gamesBaseRequestDTO 游戏请求dto + * @return {@link String } + */ + String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO); + + + /** + * 按代理id进行交换转账 + * + * @param exchangeTransferMoneyRequestDTO 外汇转账moeny dto + * @return {@link Long } + */ + Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO); + + /** + * 按时间获取投注记录 + * + * @param betRecordByTimeDTO 按时间dto投注记录 + * @return {@link List }<{@link GameBettingDetails }> + */ + List getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO); + + + /** + * 赠送免费局数 + * + * @param createFreeSpinRequest 创建自由旋转请求 + * @return {@link Boolean } + */ + Boolean createFreeSpin(CreateFreeSpinRequestDTO createFreeSpinRequest); + + /** + * 获取游戏详细信息 + * + * @param getGameDetailRequestDTO 获取游戏详细信息请求dto + * @return {@link GetGameDetailResponseDTO } + */ + GetGameDetailResponseDTO getGameDetail(GetGameDetailRequestDTO getGameDetailRequestDTO); + + + /** + * 强制会员从游戏注销 + * + * @param kickMemberRequestDTO 踢会员请求dto + * @return {@link Boolean } + */ + Boolean kickMember(KickMemberRequestDTO kickMemberRequestDTO); + + /** + * 踢成员全部 + * + * @param kickMemberAllDTO 踢成员全部dto + * @return {@link Boolean } + */ + Boolean kickMemberAll(KickMemberAllDTO kickMemberAllDTO); + /** + * 免费游戏玩家使用的纪录 + * + * @param getFreeSpinDashflowRequestDTO 获取自由旋转dashflow请求dto + * @return {@link List }<{@link GameFreeRecord }> + */ + List getFreeSpinDashflow(GetFreeSpinDashflowRequestDTO getFreeSpinDashflowRequestDTO); + + /** + * 取消赠送免费局数 + * + * @param cancelFreeSpinRequestDTO 取消免费旋转请求 + * @return {@link Boolean } + */ + Boolean cancelFreeSpin(CancelFreeSpinRequestDTO cancelFreeSpinRequestDTO); + + + + /** + * 数据构建 + * + * @param gamesDataBuildDTO 数据 + * @return {@link GameBettingDetails } + */ + GameBettingDetails dataBuild(GamesDataBuildDTO gamesDataBuildDTO); + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/address/MyJILIAddressSource.java b/ff-admin/src/main/java/com/ff/game/api/jili/address/MyJILIAddressSource.java new file mode 100644 index 0000000..d27b734 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/address/MyJILIAddressSource.java @@ -0,0 +1,33 @@ +package com.ff.game.api.jili.address; + +import com.dtflys.forest.callback.AddressSource; +import com.dtflys.forest.http.ForestAddress; +import com.dtflys.forest.http.ForestRequest; +import com.ff.base.constant.Constants; +import com.ff.base.system.service.ISysConfigService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Random; + + +/** + * 我jili address来源 + * + * @author shi + * @date 2025/02/10 + */ +@Component +public class MyJILIAddressSource implements AddressSource { + + @Resource + private ISysConfigService configService; + + + @Override + public ForestAddress getAddress(ForestRequest request) { + String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL); + return new ForestAddress("https",apiBaseUrl, 443,"api1"); + } +} \ No newline at end of file diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/client/JILIClient.java b/ff-admin/src/main/java/com/ff/game/api/jili/client/JILIClient.java new file mode 100644 index 0000000..6d93e57 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/client/JILIClient.java @@ -0,0 +1,56 @@ +package com.ff.game.api.jili.client; + +import com.dtflys.forest.annotation.Address; +import com.dtflys.forest.annotation.Get; +import com.dtflys.forest.annotation.Request; +import com.dtflys.forest.annotation.Var; +import com.ff.game.api.jili.address.MyJILIAddressSource; +import com.ff.game.api.jili.dto.JILICreateMemberResponseDTO; +import com.ff.game.api.jili.dto.JILIGamesDTO; +import com.ff.game.api.jili.dto.JILILoginWithoutRedirectResponseDTO; +import com.ff.game.api.jili.dto.JILIMemberInfoDTO; + +/** + * jili 请求 + * + * @author shi + * @date 2025/02/10 + */ +@Address(source = MyJILIAddressSource.class) +public interface JILIClient { + /** + * 创建成员 + * + * @param parameters 参数 + * @return {@link String } + */ + @Get("/CreateMember?${parameters}") + JILICreateMemberResponseDTO createMember(@Var("parameters") String parameters); + + /** + * 获取会员信息 + * + * @param parameters 参数 + * @return {@link JILIMemberInfoDTO } + */ + @Get("/GetMemberInfo?${parameters}") + JILIMemberInfoDTO getMemberInfo(@Var("parameters") String parameters); + + /** + * 无重定向登录 + * + * @param parameters 参数 + * @return {@link JILILoginWithoutRedirectResponseDTO } + */ + @Get("/LoginWithoutRedirect?${parameters}") + JILILoginWithoutRedirectResponseDTO loginWithoutRedirect(@Var("parameters") String parameters); + + /** + * 获取游戏列表 + * + * @param parameters 参数 + * @return {@link JILIGamesDTO } + */ + @Get("/GetGameList?${parameters}") + JILIGamesDTO getGameList(@Var("parameters") String parameters); +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIBetRecordDataResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIBetRecordDataResponseDTO.java new file mode 100644 index 0000000..2ea7665 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIBetRecordDataResponseDTO.java @@ -0,0 +1,89 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + + +/** + * JiLi游戏纪录查询返回数据类型 + * + * @author shi + * @date 2024/10/21 + */ +@NoArgsConstructor +@Data +public class JILIBetRecordDataResponseDTO { + /** + * 账户 + */ + @JsonProperty("Account") + private String account; + /** + * 投注id + */ + @JsonProperty("WagersId") + private long wagersId; + /** + * 游戏id + */ + @JsonProperty("GameId") + private int gameId; + /** + * 下注时间 + */ + @JsonProperty("WagersTime") + private Long wagersTime; + /** + * 投注金额 + */ + @JsonProperty("BetAmount") + private BigDecimal betAmount; + /** + * 回报时间 + */ + @JsonProperty("PayoffTime") + private Long payoffTime; + /** + * 支付金额 + */ + @JsonProperty("PayoffAmount") + private BigDecimal payoffAmount; + /** + * 注单状态 1: 赢 2: 输 3: 平局 + */ + @JsonProperty("Status") + private int status; + /** + * 结算时间 + */ + @JsonProperty("SettlementTime") + private Long settlementTime; + /** + * 游戏类别id + */ + @JsonProperty("GameCategoryId") + private int gameCategoryId; + /** + * 类型 + */ + @JsonProperty("Type") + private int type; + /** + * 代理id + */ + @JsonProperty("AgentId") + private String agentId; + /** + * 有效投注金额 + */ + @JsonProperty("Turnover") + private BigDecimal turnover; + /** + * 圆形指数 + */ + @JsonProperty("RoundIndex") + private long roundIndex; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIBetRecordResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIBetRecordResponseDTO.java new file mode 100644 index 0000000..11c4567 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIBetRecordResponseDTO.java @@ -0,0 +1,62 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * JiLi游戏纪录查询返回值 + * + * @author shi + * @date 2024/10/21 + */ +@NoArgsConstructor +@Data +public class JILIBetRecordResponseDTO { + + + @JsonProperty("ErrorCode") + private int errorCode; + @JsonProperty("Message") + private String message; + @JsonProperty("Data") + private DataBean data; + + @NoArgsConstructor + @Data + public static class DataBean { + @JsonProperty("Result") + private List result; + @JsonProperty("Pagination") + private PaginationBean pagination; + + @NoArgsConstructor + @Data + public static class PaginationBean { + /** + * 当前页面 + */ + @JsonProperty("CurrentPage") + private int currentPage; + /** + * 总页数 + */ + @JsonProperty("TotalPages") + private int totalPages; + /** + * 页数限制 + */ + @JsonProperty("PageLimit") + private int pageLimit; + /** + * 总数 + */ + @JsonProperty("TotalNumber") + private int totalNumber; + } + + + } +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICancelFreeSpinResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICancelFreeSpinResponseDTO.java new file mode 100644 index 0000000..8723ddb --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICancelFreeSpinResponseDTO.java @@ -0,0 +1,23 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * jilicancel自由自旋响应 + * + * @author shi + * @date 2024/11/11 + */ +@NoArgsConstructor +@Data +public class JILICancelFreeSpinResponseDTO { + + @JsonProperty("ErrorCode") + private int errorCode; + @JsonProperty("Message") + private String message; + @JsonProperty("CancelTime") + private int cancelTime; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICreateFreeSpinResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICreateFreeSpinResponseDTO.java new file mode 100644 index 0000000..80f25f8 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICreateFreeSpinResponseDTO.java @@ -0,0 +1,31 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * jilicreate自由旋转响应dto + * + * @author shi + * @date 2024/11/11 + */ +@NoArgsConstructor +@Data +public class JILICreateFreeSpinResponseDTO { + /** + * 错误代码 + */ + @JsonProperty("ErrorCode") + private Integer errorCode; + /** + * 消息 + */ + @JsonProperty("Message") + private String message; + /** + * 创造时间 + */ + @JsonProperty("CreateTime") + private Integer createTime; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICreateMemberResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICreateMemberResponseDTO.java new file mode 100644 index 0000000..db07ebf --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICreateMemberResponseDTO.java @@ -0,0 +1,28 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.ff.game.api.request.GamesBaseRequestDTO; +import lombok.Data; + + +/** + * 创建成员响应dto + * + * @author shi + * @date 2024/10/22 + */ +@Data +public class JILICreateMemberResponseDTO extends GamesBaseRequestDTO { + + /** + * 错误代码 + */ + @JsonProperty("ErrorCode") + private int errorCode; + /** + * 消息 + */ + @JsonProperty("Message") + private String message; + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIExchangeMoneyResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIExchangeMoneyResponseDTO.java new file mode 100644 index 0000000..2098f01 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIExchangeMoneyResponseDTO.java @@ -0,0 +1,72 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * jiliexchange货币回应 + * + * @author shi + * @date 2024/10/22 + */ +@Data +public class JILIExchangeMoneyResponseDTO { + + + /** + * 错误代码 + */ + @JsonProperty("ErrorCode") + private int errorCode; + /** + * 消息 + */ + @JsonProperty("Message") + private String message; + + + + @JsonProperty("Data") + private BeanData data; + + @Data + public class BeanData{ + /** + * 交易序号,额度转移纪录唯一值, 长度上限 50 + */ + @JsonProperty("TransactionId") + private String transactionId; + /** + * 转账前金额(游戏币) + */ + @JsonProperty("CoinBefore") + private BigDecimal coinBefore; + /** + * 转账后金额(游戏币) + */ + @JsonProperty("CoinAfter") + private BigDecimal coinAfter; + /** + * 转账前金额(指定货币) + */ + @JsonProperty("CurrencyBefore") + private BigDecimal currencyBefore; + /** + * 转账后金额(指定货币) + */ + @JsonProperty("CurrencyAfter") + private BigDecimal currencyAfter; + /** + * 状态: + * 1: 成功 + * 2: 失败 + */ + @JsonProperty("Status") + private Integer status; + } + + + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGamesDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGamesDTO.java new file mode 100644 index 0000000..e4707d1 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGamesDTO.java @@ -0,0 +1,38 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * 游戏 + * + * @author shi + * @date 2024/10/22 + */ + +@NoArgsConstructor +@Data +public class JILIGamesDTO { + + + /** + * 错误代码 + */ + @JsonProperty("ErrorCode") + private int errorCode; + /** + * 消息 + */ + @JsonProperty("Message") + private String message; + /** + * 数据 + */ + @JsonProperty("Data") + private List data; + + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGamesDataDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGamesDataDTO.java new file mode 100644 index 0000000..c2ba812 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGamesDataDTO.java @@ -0,0 +1,66 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * jiligames数据dto + * + * @author shi + * @date 2024/10/22 + */ +@NoArgsConstructor +@Data +public class JILIGamesDataDTO { + /** + * 游戏id + */ + @JsonProperty("GameId") + private int gameId; + + /** + *自己系统游戏id + */ + private Long systemGameId; + + /** + * 名称 + */ + private NameBean name; + /** + * 游戏类别id + */ + @JsonProperty("GameCategoryId") + private int gameCategoryId; + /** + * jp + */ + @JsonProperty("JP") + private boolean jP; + /** + * freespin + */ + @JsonProperty("Freespin") + private boolean freespin; + + @NoArgsConstructor + @Data + public static class NameBean { + /** + * en-us + */ + @JsonProperty("en-US") + private String enUS; + /** + * zh cn + */ + @JsonProperty("zh-CN") + private String zhCN; + /** + * zh-tw + */ + @JsonProperty("zh-TW") + private String zhTW; + } +} \ No newline at end of file diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGetFreeSpinDashflowResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGetFreeSpinDashflowResponseDTO.java new file mode 100644 index 0000000..469cec7 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGetFreeSpinDashflowResponseDTO.java @@ -0,0 +1,74 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * jiliget自由旋转气流响应dto + * + * @author shi + * @date 2024/11/11 + */ +@NoArgsConstructor +@Data +public class JILIGetFreeSpinDashflowResponseDTO { + /** 错误码 */ + @JsonProperty("ErrorCode") + private int errorCode; + + /** 错误信息 */ + @JsonProperty("Message") + private String message; + + /** 数据列表 */ + @JsonProperty("Data") + private List data; + + /** + * 内部类 DataBean + */ + @NoArgsConstructor + @Data + public static class DataBean { + + /** 用户账号 */ + @JsonProperty("Account") + private String account; + + /** 参考ID */ + @JsonProperty("ReferenceID") + private String referenceID; + + /** 发送时间 */ + @JsonProperty("SendTime") + private Long sendTime; + + /** 过期时间 */ + @JsonProperty("ExpiredTime") + private Long expiredTime; + + /** 更新时间 */ + @JsonProperty("UpdateTime") + private Long updateTime; + + /** 发送金额 */ + @JsonProperty("SendAmount") + private int sendAmount; + + /** 已使用金额 */ + @JsonProperty("UsedAmount") + private int usedAmount; + + /** 未使用金额 */ + @JsonProperty("UnusedAmount") + private int unusedAmount; + + /** 可领取的游戏 */ + @JsonProperty("ClaimGame") + private int claimGame; + } + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGetGameDetailResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGetGameDetailResponseDTO.java new file mode 100644 index 0000000..2dd7594 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGetGameDetailResponseDTO.java @@ -0,0 +1,31 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 获取游戏详细信息请求dto + * + * @author shi + * @date 2024/11/12 + */ +@NoArgsConstructor +@Data +public class JILIGetGameDetailResponseDTO { + + + @JsonProperty("ErrorCode") + private int errorCode; + @JsonProperty("Message") + private String message; + @JsonProperty("Data") + private DataBean data; + + @NoArgsConstructor + @Data + public static class DataBean { + @JsonProperty("Url") + private String url; + } +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIKickMemberAllDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIKickMemberAllDTO.java new file mode 100644 index 0000000..fc7a3b6 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIKickMemberAllDTO.java @@ -0,0 +1,21 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * jilikick会员全部dto + * + * @author shi + * @date 2024/11/12 + */ +@NoArgsConstructor +@Data +public class JILIKickMemberAllDTO { + + @JsonProperty("ErrorCode") + private int errorCode; + @JsonProperty("Message") + private String message; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIKickMemberDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIKickMemberDTO.java new file mode 100644 index 0000000..9f40b74 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIKickMemberDTO.java @@ -0,0 +1,15 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Data +public class JILIKickMemberDTO { + + @JsonProperty("ErrorCode") + private int errorCode; + @JsonProperty("Message") + private String message; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILILoginWithoutRedirectResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILILoginWithoutRedirectResponseDTO.java new file mode 100644 index 0000000..1d85aa9 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILILoginWithoutRedirectResponseDTO.java @@ -0,0 +1,23 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 登录时不重定向响应dto + * + * @author shi + * @date 2024/10/22 + */ +@NoArgsConstructor +@Data +public class JILILoginWithoutRedirectResponseDTO { + + @JsonProperty("ErrorCode") + private int errorCode; + @JsonProperty("Message") + private String message; + @JsonProperty("Data") + private String data; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIMemberInfoDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIMemberInfoDTO.java new file mode 100644 index 0000000..72465d2 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIMemberInfoDTO.java @@ -0,0 +1,62 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 会员信息dto + * + * @author shi + * @date 2024/10/30 + */ +@NoArgsConstructor +@Data +public class JILIMemberInfoDTO { + + + /** + * 错误代码 + */ + @JsonProperty("ErrorCode") + private int errorCode; + /** + * 消息 + */ + @JsonProperty("Message") + private String message; + /** + * 数据 + */ + @JsonProperty("Data") + private List data; + + /** + * 数据bean + * + * @author shi + * @date 2024/10/30 + */ + @NoArgsConstructor + @Data + public static class DataBean { + /** + * 账户 + */ + @JsonProperty("Account") + private String account; + /** + * 平衡 + */ + @JsonProperty("Balance") + private BigDecimal balance; + /** + * 地位 + */ + @JsonProperty("Status") + private Integer status; + } +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/service/impl/GamesJILIServiceImpl.java b/ff-admin/src/main/java/com/ff/game/api/jili/service/impl/GamesJILIServiceImpl.java new file mode 100644 index 0000000..dd06303 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/service/impl/GamesJILIServiceImpl.java @@ -0,0 +1,763 @@ +package com.ff.game.api.jili.service.impl; + +import cn.hutool.core.util.NumberUtil; +import com.alibaba.fastjson2.JSON; +import com.ff.base.constant.CacheConstants; +import com.ff.base.constant.Constants; +import com.ff.base.core.redis.RedisCache; +import com.ff.base.enums.FreeStatus; +import com.ff.base.enums.GamePlatforms; +import com.ff.base.enums.GameStatus; +import com.ff.base.enums.JILIGameType; +import com.ff.base.exception.base.BaseException; +import com.ff.base.system.service.ISysConfigService; +import com.ff.base.utils.DateUtils; +import com.ff.base.utils.JsonUtil; +import com.ff.base.utils.MessageUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.http.HttpClientSslUtils; +import com.ff.base.utils.http.HttpUtils; +import com.ff.base.utils.sign.Md5Utils; +import com.ff.base.utils.uuid.IdUtils; +import com.ff.game.api.IGamesService; +import com.ff.game.api.jili.client.JILIClient; +import com.ff.game.api.jili.dto.*; +import com.ff.game.api.request.*; +import com.ff.game.domain.*; +import com.ff.game.service.*; +import com.ff.member.domain.Member; +import com.ff.member.service.IMemberService; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.entity.ContentType; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + + +/** + * 游戏数据解析服务 + * + * @author shi + * @date 2024/10/21 + */ +@Service("JILIService") +@Slf4j +public class GamesJILIServiceImpl implements IGamesService { + + + @Resource + private ISysConfigService configService; + + @Resource + private RedisCache redisCache; + + @Resource + private IGameExchangeMoneyService gameExchangeMoneyService; + + + @Resource + private IGamePlatformService gamePlatformService; + + + @Resource + private IGameService gameService; + + + @Resource + private IMemberService memberService; + + @Resource + private IGameFreeRecordService gameFreeRecordService; + + @Resource + private IGameSecretKeyService gameSecretKeyService; + + @Resource + private JILIClient jiliClient; + + /** + * 获得就是成功 + * + * @param errorCode 错误代码 + * @return {@link Boolean } + */ + private Boolean getIsSuccess(Integer errorCode) { + return 0 == errorCode; + } + + + /** + * 获取密钥 + * + * @param gamesBaseRequestDTO 游戏请求dto + * @return {@link String } + */ + @Override + public String getKey(GamesBaseRequestDTO gamesBaseRequestDTO) { + Random random = new Random(); + //取出对应的key跟密钥跟请求参数 + String agentKey = gamesBaseRequestDTO.getAgentKey(); + String agentId = gamesBaseRequestDTO.getAgentId(); + String query = gamesBaseRequestDTO.getQuery(); + + String now = DateUtils.getFormattedDate(); + String keyG = Md5Utils.md5New(now + agentId + agentKey); + + String md5string = Md5Utils.md5New(query + keyG); + Integer randomText1 = 100000 + random.nextInt(900000); + Integer randomText2 = 100000 + random.nextInt(900000); + String key = randomText1 + md5string + randomText2; + return key; + } + + /** + * 创建成员 + * + * @param createMemberRequestDTO 创建成员请求dto + * @return {@link Boolean } + */ + @Override + public Boolean createMember(CreateMemberRequestDTO createMemberRequestDTO) { + String query = "Account=" + createMemberRequestDTO.getAccount() + "&AgentId=" + createMemberRequestDTO.getAgentId(); + log.info("GamesJILIServiceImpl [createMember] 请求参数 {}", query); + createMemberRequestDTO.setQuery(query); + String key = this.getKey(createMemberRequestDTO); + JILICreateMemberResponseDTO createMemberResponseDTO = jiliClient.createMember(query + "&Key=" + key); + Boolean isSuccess = this.getIsSuccess(createMemberResponseDTO.getErrorCode()); + if (!isSuccess) { + throw new BaseException(createMemberResponseDTO.getMessage()); + } + //判断是否获取成功 + return isSuccess; + } + + + /** + * 获取会员信息 + * + * @param memberInfoRequestDTO 会员信息请求dto + * @return {@link MemberInfoResponseDTO } + */ + @Override + public MemberInfoResponseDTO getMemberInfo(MemberInfoRequestDTO memberInfoRequestDTO) { + String query = "Accounts=" + memberInfoRequestDTO.getAccounts() + "&AgentId=" + memberInfoRequestDTO.getAgentId(); + log.info("GamesJILIServiceImpl [getMemberInfo] 请求参数 {}", query); + memberInfoRequestDTO.setQuery(query); + String key = this.getKey(memberInfoRequestDTO); + JILIMemberInfoDTO jiliMemberInfoDTO = jiliClient.getMemberInfo(query + "&Key=" + key); + //判断是否获取成功 + if (this.getIsSuccess(jiliMemberInfoDTO.getErrorCode())) { + List memberInfoResponseDTOS = new ArrayList<>(); + jiliMemberInfoDTO.getData().forEach(e -> { + memberInfoResponseDTOS.add(MemberInfoResponseDTO.builder() + .status(e.getStatus()) + .balance(e.getBalance()) + .account(e.getAccount()) + .build()); + }); + return memberInfoResponseDTOS.get(0); + } else { + throw new BaseException(jiliMemberInfoDTO.getMessage()); + } + } + + /** + * 无重定向登录 + * + * @param gamesLogin 游戏登录 + * @return {@link String } + */ + @Override + public String loginWithoutRedirect(GamesLogin gamesLogin) { + String query = "Account=" + gamesLogin.getAccount() + "&GameId=" + gamesLogin.getGameId() + "&Lang=" + gamesLogin.getLang() + "&AgentId=" + gamesLogin.getAgentId(); + log.info("GamesJILIServiceImpl [loginWithoutRedirect] 请求参数 {}", query); + gamesLogin.setQuery(query); + String key = this.getKey(gamesLogin); + +// if (!StringUtils.isEmpty(gamesLogin.getHomeUrl())) { +// query += "&HomeUrl=" + gamesLogin.getHomeUrl(); +// } + if (!StringUtils.isEmpty(gamesLogin.getPlatform())) { + query += "&platform=" + gamesLogin.getPlatform(); + } + if (!ObjectUtils.isEmpty(gamesLogin.getDisableFullScreen())) { + query += "&disableFullScreen=" + gamesLogin.getDisableFullScreen(); + } + + JILILoginWithoutRedirectResponseDTO loginWithoutRedirectResponseDTO = jiliClient.loginWithoutRedirect(query + "&AgentId=" + gamesLogin.getAgentId() + "&Key=" + key); + //判断是否获取成功 + if (this.getIsSuccess(loginWithoutRedirectResponseDTO.getErrorCode())) { + return loginWithoutRedirectResponseDTO.getData(); + } else { + throw new BaseException(loginWithoutRedirectResponseDTO.getMessage()); + } + + } + + + /** + * 获取游戏列表 + * + * @param gamesBaseRequestDTO 游戏请求dto + * @return {@link String } + */ + @Transactional + @Override + public String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO) { + + List gamesDatas = redisCache.getCacheList(CacheConstants.JILI_GAMES); + if (!CollectionUtils.isEmpty(gamesDatas)) { + return CacheConstants.JILI_GAMES; + } + + + gamesBaseRequestDTO.setQuery("AgentId=" + gamesBaseRequestDTO.getAgentId()); + String key = this.getKey(gamesBaseRequestDTO); + JILIGamesDTO jiliGames = jiliClient.getGameList("AgentId=" + gamesBaseRequestDTO.getAgentId() + "&Key=" + key); + //判断是否获取成功 + if (this.getIsSuccess(jiliGames.getErrorCode())) { + + for (JILIGamesDataDTO gamesDataDTO : jiliGames.getData()) { + if (JILIGameType.GAME_HALL.getCode().equals(gamesDataDTO.getGameCategoryId())) { + continue; + } + + GamePlatform gamePlatform = GamePlatform.builder() + .platformType(JILIGameType.findSystemByCode(gamesDataDTO.getGameCategoryId())) + .platformCode(GamePlatforms.JILI.getCode()) + .build(); + List gamePlatforms = gamePlatformService.selectGamePlatformList(gamePlatform); + //没有此平台就新增一个平台 + if (CollectionUtils.isEmpty(gamePlatforms)) { + gamePlatform.setPlatformName(GamePlatforms.JILI.getInfo() + JILIGameType.findInfoByCode(gamesDataDTO.getGameCategoryId())); + gamePlatform.setSortNo(gamePlatformService.selectMaxSortNo() + 1); + gamePlatform.setCreateBy(Constants.SYSTEM); + gamePlatformService.insertGamePlatform(gamePlatform); + } else { + gamePlatform = gamePlatforms.get(0); + } + Game game = Game.builder() + .platformId(gamePlatform.getId()) + .gameCode(gamesDataDTO.getGameId()) + .build(); + List games = gameService.selectGameList(game); + //不存在这个游戏 + if (CollectionUtils.isEmpty(games)) { + game.setFreespin(gamesDataDTO.isFreespin()); + game.setSortNo(gameService.selectMaxSortNoByPlatformId(gamePlatform.getId()) + 1); + game.setGameName(gamesDataDTO.getName().getZhCN()); + game.setCreateBy(Constants.SYSTEM); + gameService.insertGame(game); + } else { + game = games.get(0); + } + gamesDataDTO.setSystemGameId(game.getId()); + + + } + + redisCache.deleteObject(CacheConstants.JILI_GAMES); + redisCache.setCacheList(CacheConstants.JILI_GAMES, jiliGames.getData()); + redisCache.expire(CacheConstants.JILI_GAMES, 5L, TimeUnit.HOURS); + } else { + log.error("GameBettingDataJILIServiceImpl [getGameList] 获取游戏列表失败,错误代码{},错误信息{}", jiliGames.getErrorCode(), jiliGames.getMessage()); + throw new BaseException(MessageUtils.message("game.list.retrieve.failed")); + + } + + return CacheConstants.JILI_GAMES; + } + + /** + * 按代理id进行交换转账 + * + * @param exchangeTransferMoneyRequestDTO 外汇转账moeny dto + * @return {@link Long } + */ + @Override + @Transactional + public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) { + String systemByCode = gameSecretKeyService.findSystemByCode(exchangeTransferMoneyRequestDTO.getAgentId(), GamePlatforms.JILI.getInfo()); + Member member = memberService.selectMemberByMemberAccount(exchangeTransferMoneyRequestDTO.getAccount()); + String transactionId = exchangeTransferMoneyRequestDTO.getTransactionId(); + //如果没有自定义单号 + if (!StringUtils.hasText(exchangeTransferMoneyRequestDTO.getTransactionId())) { + transactionId = GamePlatforms.JILI.getCode() + IdUtils.simpleUUID(); + } + + //获取下一个自增id + GameExchangeMoney exchangeMoney = GameExchangeMoney + .builder() + .quota(exchangeTransferMoneyRequestDTO.getQuota()) + .platformId(exchangeTransferMoneyRequestDTO.getPlatformId()) + .balance(exchangeTransferMoneyRequestDTO.getAmount()) + .exchangeType(exchangeTransferMoneyRequestDTO.getTransferType()) + .currencyCode(systemByCode) + .memberId(member.getId()) + .platformCode(GamePlatforms.JILI.getCode()) + .build(); + exchangeMoney.setCreateBy(Constants.SYSTEM); + //接口限制限制50字符 + exchangeMoney.setTransactionId(transactionId); + String query = "Account=" + exchangeTransferMoneyRequestDTO.getAccount() + + "&TransactionId=" + exchangeMoney.getTransactionId() + + "&Amount=" + exchangeTransferMoneyRequestDTO.getAmount() + + "&TransferType=" + exchangeTransferMoneyRequestDTO.getTransferType() + + "&AgentId=" + exchangeTransferMoneyRequestDTO.getAgentId(); + log.info("GamesJILIServiceImpl [exchangeTransferByAgentId] 请求参数 {}", query); + exchangeTransferMoneyRequestDTO.setQuery(query); + + String key = this.getKey(exchangeTransferMoneyRequestDTO); + String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL); + try { + String result = HttpClientSslUtils.doPost(apiBaseUrl + "/ExchangeTransferByAgentId?" + query + "&Key=" + key, "AgentId=" + exchangeTransferMoneyRequestDTO.getAgentId(), ContentType.APPLICATION_FORM_URLENCODED); + + JILIExchangeMoneyResponseDTO exchangeMoneyResponse = JsonUtil.stringToObj(result, JILIExchangeMoneyResponseDTO.class); + //判断是否转移成功 + if (this.getIsSuccess(exchangeMoneyResponse.getErrorCode())) { + JILIExchangeMoneyResponseDTO.BeanData exchangeMoneyResponseData = exchangeMoneyResponse.getData(); + //更新数据 + exchangeMoney.setBalance(NumberUtil.sub(exchangeMoneyResponseData.getCurrencyAfter(), exchangeMoneyResponseData.getCurrencyBefore()).abs()); + exchangeMoney.setCoinBefore(exchangeMoneyResponseData.getCoinBefore()); + exchangeMoney.setCoinAfter(exchangeMoneyResponseData.getCoinAfter()); + exchangeMoney.setCurrencyBefore(exchangeMoneyResponseData.getCurrencyBefore()); + exchangeMoney.setCurrencyAfter(exchangeMoneyResponseData.getCurrencyAfter()); + exchangeMoney.setStatus(exchangeMoneyResponseData.getStatus()); + gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney); + } else { + log.error("GameBettingDataJILIServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误代码{},错误信息{}", exchangeMoneyResponse.getErrorCode(), exchangeMoneyResponse.getMessage()); + throw new BaseException(MessageUtils.message("game.account.balance.transfer.failed")); + + } + } catch (Exception e) { + log.error("GameBettingDataJILIServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.account.balance.transfer.failed")); + + } + + return exchangeMoney.getId(); + } + + + /** + * 按时间获取投注记录 + * + * @param betRecordByTimeDTO 按时间dto投注记录 + * @return {@link List }<{@link GameBettingDetails }> + */ + @Override + public List getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) { + String startTime = DateUtils.formatDateToGMT4(new Date(betRecordByTimeDTO.getStartTime())); + String endTime = DateUtils.formatDateToGMT4(new Date(betRecordByTimeDTO.getEndTime())); + List gameBettingDetails = new ArrayList<>(); + //请求参数 + String query = "StartTime=" + startTime + "&EndTime=" + endTime + "&Page=" + betRecordByTimeDTO.getPage() + "&PageLimit=" + betRecordByTimeDTO.getPageLimit() + "&AgentId=" + betRecordByTimeDTO.getAgentId(); + log.info("GamesJILIServiceImpl [getBetRecordByTime] 请求参数 {}", query); + betRecordByTimeDTO.setQuery(query); + //获取key + String key = this.getKey(betRecordByTimeDTO); + String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL); + String result = null; + try { + result = HttpClientSslUtils.doPost(apiBaseUrl + "/GetBetRecordByTime?" + query + "&Key=" + key, "AgentId=" + betRecordByTimeDTO.getAgentId(), ContentType.APPLICATION_FORM_URLENCODED); + + JILIBetRecordResponseDTO betRecordJILIResponse = JSON.parseObject(result, JILIBetRecordResponseDTO.class); + + //判断是否获取成功 + if (this.getIsSuccess(betRecordJILIResponse.getErrorCode())) { + //数据组装 + JILIBetRecordResponseDTO.DataBean dataBean = betRecordJILIResponse.getData(); + for (JILIBetRecordDataResponseDTO jiliBetRecordDataResponseDTO : dataBean.getResult()) { + GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(jiliBetRecordDataResponseDTO).gamesKey(key).build()); + if (!ObjectUtils.isEmpty(bettingDetails)) { + gameBettingDetails.add(bettingDetails); + } + + } + + //获取下一页数据 + while (dataBean.getPagination().getCurrentPage() != dataBean.getPagination().getTotalPages() && dataBean.getPagination().getTotalPages() > 0) { + betRecordByTimeDTO.setPage(dataBean.getPagination().getCurrentPage() + 1); + //请求参数 + query = "StartTime=" + startTime + "&EndTime=" + endTime + "&Page=" + betRecordByTimeDTO.getPage() + "&PageLimit=" + betRecordByTimeDTO.getPageLimit() + "&AgentId=" + betRecordByTimeDTO.getAgentId(); + log.info("GamesJILIServiceImpl [getBetRecordByTime] 请求参数 {}", query); + betRecordByTimeDTO.setQuery(query); + key = this.getKey(betRecordByTimeDTO); + result = HttpUtils.sendPost(apiBaseUrl + "/GetBetRecordByTime?" + query + "&Key=" + key, ""); + betRecordJILIResponse = JsonUtil.stringToObj(result, JILIBetRecordResponseDTO.class); + dataBean = betRecordJILIResponse.getData(); + for (JILIBetRecordDataResponseDTO jiliBetRecordDataResponseDTO : dataBean.getResult()) { + GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(jiliBetRecordDataResponseDTO).gamesKey(key).build()); + if (!ObjectUtils.isEmpty(bettingDetails)) { + gameBettingDetails.add(bettingDetails); + } + } + } + + + return gameBettingDetails; + } else { + log.error("GameBettingDataJILIServiceImpl [getBetRecordByTime] 获取投注记录失败,错误代码{},错误信息{}", betRecordJILIResponse.getErrorCode(), betRecordJILIResponse.getMessage()); + throw new BaseException(MessageUtils.message("game.bet.record.retrieve.failed")); + + } + } catch (Exception e) { + log.error("GameBettingDataJILIServiceImpl [getBetRecordByTime] 获取投注记录失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.bet.record.retrieve.failed")); + + } + + } + + /** + * 赠送免费局数 + * + * @param createFreeSpinRequest 创建自由旋转请求 + * @return {@link Boolean } + */ + @Override + public Boolean createFreeSpin(CreateFreeSpinRequestDTO createFreeSpinRequest) { + + String freeSpinValidity = DateUtils.formatDateToGMT4(new Date(createFreeSpinRequest.getFreeSpinValidity())); + + + List gameIds = createFreeSpinRequest.getGameIds(); + GameUniqueDTO gameUniqueDTO = new GameUniqueDTO(); + gameUniqueDTO.setGameIds(gameIds); + List gameList = gameService.selectGameUniqueList(gameUniqueDTO); + String gameCodes = gameList.stream() + .map(Game::getGameCode) + .map(String::valueOf) + .collect(Collectors.joining(",")); + String referenceId = GamePlatforms.JILI.getCode() + IdUtils.simpleUUID(); + //请求参数 + String query = "Account=" + createFreeSpinRequest.getAccount() + + "&Currency=" + createFreeSpinRequest.getCurrency() + + "&ReferenceId=" + referenceId + + "&FreeSpinValidity=" + freeSpinValidity + + "&NumberOfRounds=" + createFreeSpinRequest.getNumberOfRounds() + + "&GameIds=" + gameCodes; + //判断是否有免费游戏局数可使用的开始时间 + if (!ObjectUtils.isEmpty(createFreeSpinRequest.getStartTime())) { + String startTime = DateUtils.formatDateToGMT4(new Date(createFreeSpinRequest.getStartTime())); + query += "&StartTime=" + startTime; + } + query += "&AgentId=" + createFreeSpinRequest.getAgentId(); + ; + log.info("GamesJILIServiceImpl [createFreeSpin] 请求参数 {}", query); + createFreeSpinRequest.setQuery(query); + //获取key + String key = this.getKey(createFreeSpinRequest); + String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL); + String result = null; + try { + result = HttpClientSslUtils.doPost(apiBaseUrl + "/CreateFreeSpin?" + query + "&Key=" + key, "AgentId=" + createFreeSpinRequest.getAgentId(), ContentType.APPLICATION_FORM_URLENCODED); + + JILICreateFreeSpinResponseDTO createFreeSpinResponseDTO = JSON.parseObject(result, JILICreateFreeSpinResponseDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(createFreeSpinResponseDTO.getErrorCode())) { + Member member = memberService.selectMemberByMemberAccount(createFreeSpinRequest.getAccount()); + if (ObjectUtils.isEmpty(member)) { + member = new Member(); + } + for (Game game : gameList) { + GameFreeRecord gameFreeRecord = GameFreeRecord.builder() + .currencyCode(gameSecretKeyService.findSystemByCode(createFreeSpinRequest.getAgentId(), GamePlatforms.JILI.getInfo())) + .referenceId(referenceId) + .memberId(member.getId()) + .memberAccount(createFreeSpinRequest.getAccount()) + .gameId(game.getId()) + .sendTime(createFreeSpinRequest.getStartTime()) + .expiredTime(createFreeSpinRequest.getFreeSpinValidity()) + .freeUpdateTime(DateUtils.getNowDate()) + .sendGame(game.getGameName()) + .sendAmount(createFreeSpinRequest.getNumberOfRounds()) + .unusedAmount(createFreeSpinRequest.getNumberOfRounds()) + .build(); + gameFreeRecord.setCreateBy(Constants.SYSTEM); + gameFreeRecordService.insertGameFreeRecord(gameFreeRecord); + } + + return Boolean.TRUE; + } else { + log.error("GameBettingDataJILIServiceImpl [createFreeSpin] 赠送免费局数,错误代码{},错误信息{}", createFreeSpinResponseDTO.getErrorCode(), createFreeSpinResponseDTO.getMessage()); + throw new BaseException(createFreeSpinResponseDTO.getMessage()); + } + } catch (Exception e) { + log.error("GameBettingDataJILIServiceImpl [createFreeSpin] 赠送免费局数,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.free.round.gift.failed")); + + } + + } + + /** + * 获取游戏详细信息 + * + * @param getGameDetailRequestDTO 获取游戏详细信息请求dto + * @return {@link GetGameDetailResponseDTO } + */ + @Override + public GetGameDetailResponseDTO getGameDetail(GetGameDetailRequestDTO getGameDetailRequestDTO) { + String query = "WagersId=" + getGameDetailRequestDTO.getWagersId(); + + getGameDetailRequestDTO.setQuery(query + "&AgentId=" + getGameDetailRequestDTO.getAgentId()); + String key = this.getKey(getGameDetailRequestDTO); + if (StringUtils.hasText(getGameDetailRequestDTO.getLang())) { + query += "&Lang=" + getGameDetailRequestDTO.getLang(); + } + getGameDetailRequestDTO.setQuery(query); + log.info("GamesJILIServiceImpl [getGameDetail] 请求参数 {}", query); + + String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL); + try { + + String result = HttpClientSslUtils.doGet(apiBaseUrl + "/GetGameDetailUrl?" + query + "&AgentId=" + getGameDetailRequestDTO.getAgentId() + "&Key=" + key); + JILIGetGameDetailResponseDTO jiliGetGameDetailResponseDTO = JsonUtil.stringToObj(result, JILIGetGameDetailResponseDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(jiliGetGameDetailResponseDTO.getErrorCode())) { + GetGameDetailResponseDTO getGameDetailResponseDTO = new GetGameDetailResponseDTO(); + getGameDetailResponseDTO.setUrl(jiliGetGameDetailResponseDTO.getData().getUrl()); + return getGameDetailResponseDTO; + } else { + log.error("GameBettingDataJILIServiceImpl [getGameDetail] 获取游戏游玩详情失败,错误代码{},错误信息{}", jiliGetGameDetailResponseDTO.getErrorCode(), jiliGetGameDetailResponseDTO.getMessage()); + throw new BaseException(MessageUtils.message("game.play.details.retrieve.failed")); + + } + } catch (Exception e) { + log.error("GameBettingDataJILIServiceImpl [getGameDetail] 获取游戏游玩详情失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.play.details.retrieve.failed")); + + } + } + + /** + * 强制会员从游戏注销 + * + * @param kickMemberRequestDTO 踢会员请求dto + * @return {@link Boolean } + */ + @Override + public Boolean kickMember(KickMemberRequestDTO kickMemberRequestDTO) { + String query = "Account=" + kickMemberRequestDTO.getAccount(); + + kickMemberRequestDTO.setQuery(query + "&AgentId=" + kickMemberRequestDTO.getAgentId()); + String key = this.getKey(kickMemberRequestDTO); + log.info("GamesJILIServiceImpl [kickMember] 请求参数 {}", query); + + String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL); + try { + + String result = HttpClientSslUtils.doGet(apiBaseUrl + "/KickMember?" + query + "&AgentId=" + kickMemberRequestDTO.getAgentId() + "&Key=" + key); + JILIKickMemberDTO jiliKickMemberDTO = JsonUtil.stringToObj(result, JILIKickMemberDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(jiliKickMemberDTO.getErrorCode())) { + return Boolean.TRUE; + } else { + log.error("GameBettingDataJILIServiceImpl [kickMember] 强制会员从游戏注销失败,错误代码{},错误信息{}", jiliKickMemberDTO.getErrorCode(), jiliKickMemberDTO.getMessage()); + throw new BaseException(MessageUtils.message("game.member.force.logout.failed")); + + } + } catch (Exception e) { + log.error("GameBettingDataJILIServiceImpl [kickMember] 强制会员从游戏注销失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.member.force.logout.failed")); + + } + } + + /** + * 踢成员全部 + * + * @param kickMemberAllDTO 踢成员全部dto + * @return {@link Boolean } + */ + @Override + public Boolean kickMemberAll(KickMemberAllDTO kickMemberAllDTO) { + String query = "AgentId=" + kickMemberAllDTO.getAgentId(); + if (!ObjectUtils.isEmpty(kickMemberAllDTO.getGameId())) { + query = "GameId=" + kickMemberAllDTO.getGameId() + "&" + query; + } + + + kickMemberAllDTO.setQuery(query); + String key = this.getKey(kickMemberAllDTO); + log.info("GamesJILIServiceImpl [kickMemberAll] 请求参数 {}", query); + + String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL); + try { + + String result = HttpClientSslUtils.doGet(apiBaseUrl + "/KickMemberAll?" + query + "&Key=" + key); + JILIKickMemberAllDTO jiliKickMemberAllDTO = JsonUtil.stringToObj(result, JILIKickMemberAllDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(jiliKickMemberAllDTO.getErrorCode())) { + return Boolean.TRUE; + } else { + log.error("GameBettingDataJILIServiceImpl [kickMemberAll] 强制全部会员从游戏注销失败,错误代码{},错误信息{}", jiliKickMemberAllDTO.getErrorCode(), jiliKickMemberAllDTO.getMessage()); + throw new BaseException(MessageUtils.message("game.members.force.logout.failed")); + + } + } catch (Exception e) { + log.error("GameBettingDataJILIServiceImpl [kickMemberAll] 强制全部会员从游戏注销失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.members.force.logout.failed")); + + } + } + + /** + * 免费游戏玩家使用的纪录 + * + * @param getFreeSpinDashflowRequestDTO 获取自由旋转dashflow请求dto + * @return {@link List }<{@link GameFreeRecord }> + */ + @Override + public List getFreeSpinDashflow(GetFreeSpinDashflowRequestDTO getFreeSpinDashflowRequestDTO) { + List gameFreeRecordsResult = new ArrayList<>(); + //请求参数 + String query = "UpdateTime=" + DateUtils.formatDateToGMT4(new Date(getFreeSpinDashflowRequestDTO.getStartTime())) + + "&AgentId=" + getFreeSpinDashflowRequestDTO.getAgentId(); + + log.info("GamesJILIServiceImpl [getFreeSpinDashflow] 请求参数 {}", query); + getFreeSpinDashflowRequestDTO.setQuery(query); + //获取key + String key = this.getKey(getFreeSpinDashflowRequestDTO); + String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL); + String result = null; + try { + result = HttpClientSslUtils.doPost(apiBaseUrl + "/GetFreeSpinDashflow?" + query + "&Key=" + key, "AgentId=" + getFreeSpinDashflowRequestDTO.getAgentId(), ContentType.APPLICATION_FORM_URLENCODED); + + JILIGetFreeSpinDashflowResponseDTO getFreeSpinDashflowResponseDTO = JSON.parseObject(result, JILIGetFreeSpinDashflowResponseDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(getFreeSpinDashflowResponseDTO.getErrorCode())) { + for (JILIGetFreeSpinDashflowResponseDTO.DataBean data : getFreeSpinDashflowResponseDTO.getData()) { + List gameFreeRecords = gameFreeRecordService.selectGameFreeRecordList(GameFreeRecord.builder() + .referenceId(data.getReferenceID()) + .build()); + for (GameFreeRecord gameFreeRecord : gameFreeRecords) { + gameFreeRecord.setSendTime(data.getSendTime()); + gameFreeRecord.setExpiredTime(data.getExpiredTime()); + gameFreeRecord.setFreeUpdateTime(data.getUpdateTime()); + gameFreeRecord.setSendAmount(data.getSendAmount()); + gameFreeRecord.setUsedAmount(data.getUsedAmount()); + gameFreeRecord.setUnusedAmount(data.getUnusedAmount()); + gameFreeRecordService.updateGameFreeRecord(gameFreeRecord); + gameFreeRecordsResult.add(gameFreeRecord); + } + } + + return gameFreeRecordsResult; + } else { + log.error("GameBettingDataJILIServiceImpl [getFreeSpinDashflow] 查询免费游戏玩家使用的纪录,错误代码{},错误信息{}", getFreeSpinDashflowResponseDTO.getErrorCode(), getFreeSpinDashflowResponseDTO.getMessage()); + throw new BaseException(getFreeSpinDashflowResponseDTO.getMessage()); + } + } catch (Exception e) { + log.error("GameBettingDataJILIServiceImpl [getFreeSpinDashflow] 查询免费游戏玩家使用的纪录,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.free.play.record.query.failed")); + + } + } + + /** + * 取消赠送免费局数 + * + * @param cancelFreeSpinRequestDTO 取消免费旋转请求 + * @return {@link Boolean } + */ + @Override + public Boolean cancelFreeSpin(CancelFreeSpinRequestDTO cancelFreeSpinRequestDTO) { + //请求参数 + String query = "ReferenceId=" + cancelFreeSpinRequestDTO.getReferenceId() + + "&AgentId=" + cancelFreeSpinRequestDTO.getAgentId(); + ; + log.info("GamesJILIServiceImpl [cancelFreeSpin] 请求参数 {}", query); + cancelFreeSpinRequestDTO.setQuery(query); + //获取key + String key = this.getKey(cancelFreeSpinRequestDTO); + String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL); + String result = null; + try { + result = HttpClientSslUtils.doPost(apiBaseUrl + "/CancelFreeSpin?" + query + "&Key=" + key, "AgentId=" + cancelFreeSpinRequestDTO.getAgentId(), ContentType.APPLICATION_FORM_URLENCODED); + + JILICancelFreeSpinResponseDTO cancelFreeSpinResponseDTO = JSON.parseObject(result, JILICancelFreeSpinResponseDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(cancelFreeSpinResponseDTO.getErrorCode())) { + List gameFreeRecords = gameFreeRecordService.selectGameFreeRecordList(GameFreeRecord.builder() + .referenceId(cancelFreeSpinRequestDTO.getReferenceId()) + .build()); + for (GameFreeRecord gameFreeRecord : gameFreeRecords) { + gameFreeRecord.setFreeStatus(FreeStatus.CANCEL.getCode()); + gameFreeRecordService.updateGameFreeRecord(gameFreeRecord); + } + return Boolean.TRUE; + } else { + log.error("GameBettingDataJILIServiceImpl [cancelFreeSpin] 取消赠送免费局数,错误代码{},错误信息{}", cancelFreeSpinResponseDTO.getErrorCode(), cancelFreeSpinResponseDTO.getMessage()); + throw new BaseException(cancelFreeSpinResponseDTO.getMessage()); + } + } catch (Exception e) { + log.error("GameBettingDataJILIServiceImpl [cancelFreeSpin] 取消赠送免费局数,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.free.round.cancel.failed")); + + } + } + + + /** + * 数据构建 + * + * @param gamesDataBuildDTO 数据 + * @return {@link GameBettingDetails } + */ + @Override + public GameBettingDetails dataBuild(GamesDataBuildDTO gamesDataBuildDTO) { + + //转化类 + JILIBetRecordDataResponseDTO jiliBetRecordDataResponseDTO = (JILIBetRecordDataResponseDTO) gamesDataBuildDTO.getData(); + String systemByCode = gameSecretKeyService.findSystemByCode(jiliBetRecordDataResponseDTO.getAgentId(), GamePlatforms.JILI.getInfo()); + Member member = memberService.selectMemberByMemberAccount(jiliBetRecordDataResponseDTO.getAccount()); + if (ObjectUtils.isEmpty(member)) { + return null; + } + List gamesDatas = redisCache.getCacheList(CacheConstants.JILI_GAMES); + Map dataDTOMap = gamesDatas.stream().collect(Collectors.toMap(JILIGamesDataDTO::getGameId, e -> e)); + JILIGamesDataDTO gamesDataDTO = dataDTOMap.get(jiliBetRecordDataResponseDTO.getGameId()); + BigDecimal payoffAmount = BigDecimal.ZERO; + if (GameStatus.WIN.getCode().equals(jiliBetRecordDataResponseDTO.getStatus())) { + payoffAmount = NumberUtil.sub(jiliBetRecordDataResponseDTO.getPayoffAmount(), jiliBetRecordDataResponseDTO.getTurnover()); + } else if (GameStatus.FAIL.getCode().equals(jiliBetRecordDataResponseDTO.getStatus())) { + payoffAmount = NumberUtil.sub(jiliBetRecordDataResponseDTO.getPayoffAmount(), jiliBetRecordDataResponseDTO.getTurnover()).negate(); + } + + //数据构造 + GameBettingDetails gameBettingDetails = GameBettingDetails.builder() + //保存我们的币种id + .currencyCode(systemByCode) + .memberId(member.getId()) + .gameCode(jiliBetRecordDataResponseDTO.getGameId()) + .gameType(JILIGameType.findSystemByCode(jiliBetRecordDataResponseDTO.getGameCategoryId())) + .platformCode(GamePlatforms.JILI.getCode()) + .gameId(gamesDataDTO.getSystemGameId()) + .gameName(gamesDataDTO.getName().getZhCN()) + .gameStatus(jiliBetRecordDataResponseDTO.getStatus()) + .gameStatusType(jiliBetRecordDataResponseDTO.getType()) + .gameCurrencyCode(jiliBetRecordDataResponseDTO.getAgentId()) + .account(String.valueOf(jiliBetRecordDataResponseDTO.getAccount())) + .wagersId(jiliBetRecordDataResponseDTO.getWagersId()) + .wagersTime(jiliBetRecordDataResponseDTO.getWagersTime()) + .betAmount(jiliBetRecordDataResponseDTO.getBetAmount().abs()) + .payoffTime(jiliBetRecordDataResponseDTO.getPayoffTime()) + .payoffAmount(payoffAmount) + .settlementTime(jiliBetRecordDataResponseDTO.getSettlementTime()) + .turnover(jiliBetRecordDataResponseDTO.getTurnover()) + .orderNo(String.valueOf(jiliBetRecordDataResponseDTO.getRoundIndex())) + .build(); + gameBettingDetails.setCreateBy(Constants.SYSTEM); + gameBettingDetails.setCreateTime(DateUtils.getNowDate()); + return gameBettingDetails; + } +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/BetRecordByTimeDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/BetRecordByTimeDTO.java new file mode 100644 index 0000000..c2cc3f6 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/BetRecordByTimeDTO.java @@ -0,0 +1,40 @@ +package com.ff.game.api.request; + +import lombok.Data; + +/** + * 按时间dto投注记录 + * + * @author shi + * @date 2024/10/22 + */ +@Data +public class BetRecordByTimeDTO extends GamesBaseRequestDTO { + /** + * 开始时间 + */ + private Long startTime; + /** + * 结束时间 + */ + private Long endTime; + /** + * 页数 + */ + private Integer page; + /** + * 每页资料笔数 + */ + private Integer pageLimit; + /** + * 游戏id + */ + private Integer gameId; + /** + * 指定平台 + */ + private String gamePlatform; + + + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/CancelFreeSpinRequestDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/CancelFreeSpinRequestDTO.java new file mode 100644 index 0000000..f7297ae --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/CancelFreeSpinRequestDTO.java @@ -0,0 +1,17 @@ +package com.ff.game.api.request; + +import lombok.Data; + +/** + * 取消免费旋转请求 + * + * @author shi + * @date 2024/11/11 + */ +@Data +public class CancelFreeSpinRequestDTO extends GamesBaseRequestDTO { + /** + * 取消免费赠送游戏id + */ + private String referenceId; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/CreateFreeSpinRequestDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/CreateFreeSpinRequestDTO.java new file mode 100644 index 0000000..795e7de --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/CreateFreeSpinRequestDTO.java @@ -0,0 +1,62 @@ +package com.ff.game.api.request; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 创建自由旋转请求dto + * + * @author shi + * @date 2024/11/11 + */ +@Data +public class CreateFreeSpinRequestDTO extends GamesBaseRequestDTO { + + /** + * 玩家账号 (JILI 新玩家则会自动创立账号) + */ + private String account; + + /** + * 玩家使用货币。转账钱包这项请填空字符串。 + */ + private String currency; + + /** + * 免费局数序号, 长度上限 50 + */ + private String referenceId; + + /** + * 有效期限 + * + * + */ + private Long freeSpinValidity; + + /** + * 局数 + */ + private Integer numberOfRounds; + + /** + * 可使用游戏 ID, 超过一笔时以逗号分隔; 系统内游戏id + * 长度 上限 200 + */ + private List gameIds; + + /** + * 指定投注额; + * 未指定时, 一律使用游戏中的最小投注额 + */ + private BigDecimal betValue; + + /** + * 免费游戏局数可使用的开始时间 + * 未带此参数时, 赠送后玩家可以立即使用 + */ + private Long startTime; + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/CreateMemberRequestDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/CreateMemberRequestDTO.java new file mode 100644 index 0000000..46ec0ab --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/CreateMemberRequestDTO.java @@ -0,0 +1,26 @@ +package com.ff.game.api.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +/** + * 创建成员请求dto + * + * @author shi + * @date 2024/10/22 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@SuperBuilder +public class CreateMemberRequestDTO extends GamesBaseRequestDTO { + /** + * 账户 + */ + private String account; + + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/ExchangeTransferMoneyRequestDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/ExchangeTransferMoneyRequestDTO.java new file mode 100644 index 0000000..a1a29ab --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/ExchangeTransferMoneyRequestDTO.java @@ -0,0 +1,52 @@ +package com.ff.game.api.request; + +import com.ff.base.annotation.Excel; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 外汇转账 + * + * @author shi + * @date 2024/10/22 + */ +@Data +public class ExchangeTransferMoneyRequestDTO extends GamesBaseRequestDTO { + + + /** + * 账户 + */ + private String account; + + + /** 游戏平台id */ + @Excel(name = "游戏平台id") + private Long platformId; + /** + * 金额 + */ + private BigDecimal amount; + + + /** + * 租户额度 + */ + private BigDecimal quota; + + + /** + * 转账类型 + * 1: 从 游戏商 转移额度到 平台商 (不看 amount 值,全 + * 部转出) + * 2: 从 平台商 转移额度到 游戏商 + * 3: 从 游戏商 转移额度到 平台商 + */ + private Integer transferType; + + /** + * 交易id + */ + private String transactionId; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/GameUniqueDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/GameUniqueDTO.java new file mode 100644 index 0000000..dc1de1d --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/GameUniqueDTO.java @@ -0,0 +1,19 @@ +package com.ff.game.api.request; + + +import com.ff.game.domain.Game; +import lombok.Data; + +import java.util.List; + +/** + * 游戏独有dto + * + * @author shi + * @date 2024/11/11 + */ +@Data +public class GameUniqueDTO extends Game { + + private List gameIds; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/GamesBaseRequestDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/GamesBaseRequestDTO.java new file mode 100644 index 0000000..e5025ff --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/GamesBaseRequestDTO.java @@ -0,0 +1,37 @@ +package com.ff.game.api.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import java.io.Serializable; + +/** + * 游戏请求dto + * + * @author shi + * @date 2024/10/22 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@SuperBuilder +public class GamesBaseRequestDTO implements Serializable { + private static final long serialVersionUID = 5139311242800113436L; + /** + * 代理id + */ + private String agentId; + + /** + * 代理密钥 + */ + private String agentKey; + + /** + * 查询 + */ + private String query; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/GamesDataBuildDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/GamesDataBuildDTO.java new file mode 100644 index 0000000..17efcd6 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/GamesDataBuildDTO.java @@ -0,0 +1,31 @@ +package com.ff.game.api.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 游戏数据构建dto + * + * @author shi + * @date 2024/10/22 + */ +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Data +public class GamesDataBuildDTO +{ + + /** + * 数据 + */ + private Object data; + + /** + * 游戏列表key + */ + private String gamesKey; + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/GamesLogin.java b/ff-admin/src/main/java/com/ff/game/api/request/GamesLogin.java new file mode 100644 index 0000000..061450d --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/GamesLogin.java @@ -0,0 +1,44 @@ +package com.ff.game.api.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +/** + * 游戏登录 + * + * @author shi + * @date 2024/10/22 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@SuperBuilder +public class GamesLogin extends GamesBaseRequestDTO{ + /** + * 账户 + */ + private String account; + /** + * 游戏唯一识别值(同等 GameList 各游戏的 GameId) + */ + private Integer gameId; + /** + * UI 语系, 请参考 附录 – 语系参数 + */ + private String lang; + /** + * 不列入 md5 加密,游戏回主页功能导向位置 + */ + private String homeUrl; + /** + * 不列入 md5 加密,带入 web 或是 app + */ + private String platform; + /** + * 不列入 md5 加密, 带入 1 即关闭全屏幕模式 + */ + private Integer disableFullScreen; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/GetFreeSpinDashflowRequestDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/GetFreeSpinDashflowRequestDTO.java new file mode 100644 index 0000000..d0418ac --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/GetFreeSpinDashflowRequestDTO.java @@ -0,0 +1,19 @@ +package com.ff.game.api.request; + +import lombok.Data; + +/** + * 获取自由旋转dashflow请求dto + * + * @author shi + * @date 2024/11/11 + */ +@Data +public class GetFreeSpinDashflowRequestDTO extends GamesBaseRequestDTO { + + /** + * 开始时间 + */ + private Long startTime; + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/GetGameDetailRequestDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/GetGameDetailRequestDTO.java new file mode 100644 index 0000000..7c082c3 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/GetGameDetailRequestDTO.java @@ -0,0 +1,22 @@ +package com.ff.game.api.request; + +import lombok.Data; + +/** + * 获取游戏详细信息请求dto + * + * @author shi + * @date 2024/11/12 + */ +@Data +public class GetGameDetailRequestDTO extends GamesBaseRequestDTO { + + /** + * 投注id + */ + private Long wagersId; + /** + * 郎 + */ + private String lang; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/GetGameDetailResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/GetGameDetailResponseDTO.java new file mode 100644 index 0000000..373d4ed --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/GetGameDetailResponseDTO.java @@ -0,0 +1,21 @@ +package com.ff.game.api.request; + +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 获取游戏详细信息请求dto + * + * @author shi + * @date 2024/11/12 + */ +@NoArgsConstructor +@Data +public class GetGameDetailResponseDTO { + + + /** + * url + */ + private String url; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/KickMemberAllDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/KickMemberAllDTO.java new file mode 100644 index 0000000..1d4fd8c --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/KickMemberAllDTO.java @@ -0,0 +1,15 @@ +package com.ff.game.api.request; + +import lombok.Data; + +/** + * 踢成员全部dto + * + * @author shi + * @date 2024/11/12 + */ +@Data +public class KickMemberAllDTO extends GamesBaseRequestDTO { + private Long gameId; + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/KickMemberRequestDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/KickMemberRequestDTO.java new file mode 100644 index 0000000..dbf144b --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/KickMemberRequestDTO.java @@ -0,0 +1,18 @@ +package com.ff.game.api.request; + +import lombok.Data; + +/** + * 踢会员请求dto + * + * @author shi + * @date 2024/11/12 + */ +@Data +public class KickMemberRequestDTO extends GamesBaseRequestDTO { + + /** + * 账户 + */ + private String account; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/MemberInfoRequestDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/MemberInfoRequestDTO.java new file mode 100644 index 0000000..40a3182 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/MemberInfoRequestDTO.java @@ -0,0 +1,25 @@ +package com.ff.game.api.request; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +/** + * 创建成员请求dto + * + * @author shi + * @date 2024/10/22 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@SuperBuilder +public class MemberInfoRequestDTO extends GamesBaseRequestDTO { + /** + * 账户 + */ + private String accounts; + + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/MemberInfoResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/MemberInfoResponseDTO.java new file mode 100644 index 0000000..4d5ec47 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/MemberInfoResponseDTO.java @@ -0,0 +1,39 @@ +package com.ff.game.api.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + + +/** + * 成员信息响应dto + * + * @author shi + * @date 2024/10/30 + */ +@NoArgsConstructor +@Data +@AllArgsConstructor +@Builder +public class MemberInfoResponseDTO { + + + /** + * 账户 + */ + private String account; + /** + * 余额 + */ + private BigDecimal balance; + /** + * 状态: + * 1: 在线 + * 2: 脱机 + * 3: 账号不存在 + */ + private Integer status; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKBetRecordResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKBetRecordResponseDTO.java new file mode 100644 index 0000000..f605858 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKBetRecordResponseDTO.java @@ -0,0 +1,54 @@ +package com.ff.game.api.xk.dto; + +import io.jsonwebtoken.lang.Collections; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +@NoArgsConstructor +@Data +public class XKBetRecordResponseDTO { + + private Integer code; + private String msg; + private DataBean data; + + @NoArgsConstructor + @Data + public static class DataBean { + private Integer currentPage; + private Integer totalPages; + private Integer pageLimit; + private Integer totalNumber; + private List result; + + public List getResult() { + if (Collections.isEmpty(result)) { + return new ArrayList<>(); + } + return result; + } + + @NoArgsConstructor + @Data + public static class ResultBean { + private String account; + private Long wagersId; + private Integer gameId; + private Long wagersTime; + private BigDecimal betAmount; + private Long payoffTime; + private BigDecimal payoffAmount; + private Integer status; + private Long settlementTime; + private Integer gameCategoryId; + private Integer type; + private String agentId; + private BigDecimal turnover; + private Long roundIndex; + } + } +} diff --git a/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKCreateMemberResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKCreateMemberResponseDTO.java new file mode 100644 index 0000000..f573bd2 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKCreateMemberResponseDTO.java @@ -0,0 +1,32 @@ +package com.ff.game.api.xk.dto; + + +import com.ff.game.api.request.GamesBaseRequestDTO; +import lombok.Data; +import lombok.NoArgsConstructor; + + +/** + * 创建成员响应dto + * + * @author shi + * @date 2024/10/22 + */ +@NoArgsConstructor +@Data +public class XKCreateMemberResponseDTO extends GamesBaseRequestDTO { + + + /** + * 代码 + */ + private int code; + /** + * 数据 + */ + private String data; + /** + * msg + */ + private String msg; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKExchangeMoneyResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKExchangeMoneyResponseDTO.java new file mode 100644 index 0000000..47601d3 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKExchangeMoneyResponseDTO.java @@ -0,0 +1,46 @@ +package com.ff.game.api.xk.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +@NoArgsConstructor +@Data +public class XKExchangeMoneyResponseDTO { + + private int code; + private String msg; + private DataBean data; + + @NoArgsConstructor + @Data + public static class DataBean { + /** + * 交易序号,额度转移纪录唯一值, 长度上限 50 + */ + private String transactionId; + /** + * 转账前金额(游戏币) + */ + private BigDecimal coinBefore; + /** + * 转账后金额(游戏币) + */ + private BigDecimal coinAfter; + /** + * 转账前金额(指定货币) + */ + private BigDecimal currencyBefore; + /** + * 转账后金额(指定货币) + */ + private BigDecimal currencyAfter; + /** + * 状态: + * 1: 成功 + * 2: 失败 + */ + private Integer status; + } +} diff --git a/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKGamesDTO.java b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKGamesDTO.java new file mode 100644 index 0000000..3cf5c87 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKGamesDTO.java @@ -0,0 +1,56 @@ +package com.ff.game.api.xk.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * xkgames数据 + * + * @author shi + * @date 2024/11/13 + */ +@NoArgsConstructor +@Data +public class XKGamesDTO { + + private int code; + /** + * msg + */ + private String msg; + /** + * 数据 + */ + private List data; + + @NoArgsConstructor + @Data + public static class DataBean { + /** + * 游戏id + */ + private int gameId; + /** + * 名称 + */ + private String name; + /** + * 游戏类别id + */ + private int gameCategoryId; + /** + *自己系统游戏id + */ + private Long systemGameId; + /** + * jp + */ + private boolean jp; + /** + * 是否免费 + */ + private boolean freeSpin; + } +} diff --git a/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKKickMemberAllDTO.java b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKKickMemberAllDTO.java new file mode 100644 index 0000000..227532b --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKKickMemberAllDTO.java @@ -0,0 +1,27 @@ +package com.ff.game.api.xk.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * xkkick会员全部dto + * + * @author shi + * @date 2024/11/13 + */ +@Data +@NoArgsConstructor +public class XKKickMemberAllDTO { + /** + * 代码 + */ + private int code; + /** + * 数据 + */ + private String data; + /** + * msg + */ + private String msg; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKKickMemberDTO.java b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKKickMemberDTO.java new file mode 100644 index 0000000..24b7f2f --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKKickMemberDTO.java @@ -0,0 +1,13 @@ +package com.ff.game.api.xk.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Data +public class XKKickMemberDTO { + + private int code; + private String msg; + private Object data; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKLoginWithoutRedirectResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKLoginWithoutRedirectResponseDTO.java new file mode 100644 index 0000000..c2254b5 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKLoginWithoutRedirectResponseDTO.java @@ -0,0 +1,29 @@ +package com.ff.game.api.xk.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 登录时不重定向响应dto + * + * @author shi + * @date 2024/10/22 + */ +@NoArgsConstructor +@Data +public class XKLoginWithoutRedirectResponseDTO { + + + /** + * 代码 + */ + private int code; + /** + * 数据 + */ + private String data; + /** + * msg + */ + private String msg; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKMemberInfoDTO.java b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKMemberInfoDTO.java new file mode 100644 index 0000000..0199d0f --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKMemberInfoDTO.java @@ -0,0 +1,49 @@ +package com.ff.game.api.xk.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 会员信息dto + * + * @author shi + * @date 2024/10/30 + */ +@NoArgsConstructor +@Data +public class XKMemberInfoDTO { + + + /** + * 代码 + */ + private Integer code; + /** + * msg + */ + private String msg; + /** + * 数据 + */ + private List data; + + @NoArgsConstructor + @Data + public static class DataBean { + /** + * 账户 + */ + private String account; + /** + * 平衡 + */ + private BigDecimal balance; + /** + * 地位 + */ + private Integer status; + } +} diff --git a/ff-admin/src/main/java/com/ff/game/api/xk/service/impl/GamesXKServiceImpl.java b/ff-admin/src/main/java/com/ff/game/api/xk/service/impl/GamesXKServiceImpl.java new file mode 100644 index 0000000..d0b3a6a --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/xk/service/impl/GamesXKServiceImpl.java @@ -0,0 +1,618 @@ +package com.ff.game.api.xk.service.impl; + +import cn.hutool.core.util.NumberUtil; +import com.alibaba.fastjson2.JSON; +import com.ff.base.constant.CacheConstants; +import com.ff.base.constant.Constants; +import com.ff.base.core.redis.RedisCache; +import com.ff.base.enums.GamePlatforms; +import com.ff.base.enums.GameStatus; +import com.ff.base.enums.XKGameType; +import com.ff.base.exception.base.BaseException; +import com.ff.base.system.service.ISysConfigService; +import com.ff.base.utils.DateUtils; +import com.ff.base.utils.JsonUtil; +import com.ff.base.utils.MessageUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.http.HttpClientSslUtils; +import com.ff.base.utils.sign.Md5Utils; +import com.ff.base.utils.uuid.IdUtils; +import com.ff.game.api.IGamesService; +import com.ff.game.api.request.*; +import com.ff.game.api.xk.dto.*; +import com.ff.game.domain.*; +import com.ff.game.service.*; +import com.ff.member.domain.Member; +import com.ff.member.service.IMemberService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + + +/** + * XK 游戏 impl + * + * @author shi + * @date 2024/11/12 + */ +@Service("XKService") +@Slf4j +public class GamesXKServiceImpl implements IGamesService { + + + @Resource + private ISysConfigService configService; + + @Resource + private RedisCache redisCache; + + @Resource + private IGameExchangeMoneyService gameExchangeMoneyService; + + + @Resource + private IGamePlatformService gamePlatformService; + + + @Resource + private IGameService gameService; + + + + + @Resource + private IMemberService memberService; + + @Resource + private IGameFreeRecordService gameFreeRecordService; + @Resource + private IGameSecretKeyService gameSecretKeyService; + /** + * 获得就是成功 + * + * @param errorCode 错误代码 + * @return {@link Boolean } + */ + private Boolean getIsSuccess(Integer errorCode) { + return 0 == errorCode; + } + + + /** + * 获取密钥 + * + * @param gamesBaseRequestDTO 游戏请求dto + * @return {@link String } + */ + @Override + public String getKey(GamesBaseRequestDTO gamesBaseRequestDTO) { + Random random = new Random(); + //取出对应的key跟密钥跟请求参数 + String agentKey = gamesBaseRequestDTO.getAgentKey(); + String agentId = gamesBaseRequestDTO.getAgentId(); + String query = gamesBaseRequestDTO.getQuery(); + + String now = DateUtils.getFormattedDate(); + String keyG = Md5Utils.md5New(now + agentId + agentKey); + + String md5string = Md5Utils.md5New(query + keyG); + Integer randomText1 = 100000 + random.nextInt(900000); + Integer randomText2 = 100000 + random.nextInt(900000); + String key = randomText1 + md5string + randomText2; + return key; + } + + /** + * 创建成员 + * + * @param createMemberRequestDTO 创建成员请求dto + * @return {@link Boolean } + */ + @Override + public Boolean createMember(CreateMemberRequestDTO createMemberRequestDTO) { + log.info("GamesXKServiceImpl [createMember] 请求参数 {}", createMemberRequestDTO); + + String apiBaseUrl = configService.selectConfigByKey(Constants.XK_API_BASE_URL); + Map params = new LinkedHashMap<>(); + params.put("account", createMemberRequestDTO.getAccount()); + params.put("agentId", createMemberRequestDTO.getAgentId()); + String query = JsonUtil.mapToQueryString(params); + createMemberRequestDTO.setQuery(query); + String key = this.getKey(createMemberRequestDTO); + params.put("key", key); + try { + String result = HttpClientSslUtils.doPost(apiBaseUrl + "/api/createMember", JsonUtil.objToPrettyString(params)); + XKCreateMemberResponseDTO xkCreateMemberResponseDTO = JsonUtil.stringToObj(result, XKCreateMemberResponseDTO.class); + //判断是否获取成功 + return !this.getIsSuccess(xkCreateMemberResponseDTO.getCode()); + + } catch (Exception e) { + log.error("GamesXKServiceImpl [createMember] 建立游戏账号,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.account.create.failed")); + } + } + + + /** + * 获取会员信息 + * + * @param memberInfoRequestDTO 会员信息请求dto + * @return {@link MemberInfoResponseDTO } + */ + @Override + public MemberInfoResponseDTO getMemberInfo(MemberInfoRequestDTO memberInfoRequestDTO) { + log.info("GamesXKServiceImpl [getMemberInfo] 请求参数 {}", memberInfoRequestDTO); + Map params = new LinkedHashMap<>(); + params.put("accounts", memberInfoRequestDTO.getAccounts()); + params.put("agentId", memberInfoRequestDTO.getAgentId()); + String query = JsonUtil.mapToQueryString(params); + memberInfoRequestDTO.setQuery(query); + String key = this.getKey(memberInfoRequestDTO); + params.put("key", key); + String apiBaseUrl = configService.selectConfigByKey(Constants.XK_API_BASE_URL); + try { + String result = HttpClientSslUtils.doPost(apiBaseUrl + "/api/getMemberInfo", JsonUtil.objToPrettyString(params)); + XKMemberInfoDTO xkMemberInfoDTO = JsonUtil.stringToObj(result, XKMemberInfoDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(xkMemberInfoDTO.getCode())) { + List memberInfoResponseDTOS = new ArrayList<>(); + xkMemberInfoDTO.getData().forEach(e -> { + memberInfoResponseDTOS.add(MemberInfoResponseDTO.builder() + .status(e.getStatus()) + .balance(e.getBalance()) + .account(e.getAccount()) + .build()); + }); + return memberInfoResponseDTOS.get(0); + } else { + log.error("GamesXKServiceImpl [getMemberInfo] 查询游戏账号信息失败,错误代码{},错误信息{}", xkMemberInfoDTO.getCode(), xkMemberInfoDTO.getMsg()); + throw new BaseException(MessageUtils.message("game.account.query.failed")); + } + + } catch (Exception e) { + log.error("GamesXKServiceImpl [getMemberInfo] 查询游戏账号信息失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.account.query.failed")); + } + + } + + /** + * 无重定向登录 + * + * @param gamesLogin 游戏登录 + * @return {@link String } + */ + @Override + public String loginWithoutRedirect(GamesLogin gamesLogin) { + log.info("GamesXKServiceImpl [loginWithoutRedirect] 请求参数 {}", gamesLogin); + + Map params = new LinkedHashMap<>(); + params.put("account", gamesLogin.getAccount()); + params.put("gameId", gamesLogin.getGameId()); + params.put("lang", gamesLogin.getLang()); + params.put("agentId", gamesLogin.getAgentId()); + String query = JsonUtil.mapToQueryString(params); + gamesLogin.setQuery(query); + String key = this.getKey(gamesLogin); + params.put("key", key); + params.put("disableFullScreen", gamesLogin.getDisableFullScreen()); + params.put("homeUrl", gamesLogin.getHomeUrl()); + params.put("platform", gamesLogin.getPlatform()); + String apiBaseUrl = configService.selectConfigByKey(Constants.XK_API_BASE_URL); + try { + + String result = HttpClientSslUtils.doPost(apiBaseUrl + "/api/loginWithoutRedirect", JsonUtil.objToPrettyString(params)); + XKLoginWithoutRedirectResponseDTO xkLoginWithoutRedirectResponseDTO = JsonUtil.stringToObj(result, XKLoginWithoutRedirectResponseDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(xkLoginWithoutRedirectResponseDTO.getCode())) { + return xkLoginWithoutRedirectResponseDTO.getData(); + } else { + log.error("GamesXKServiceImpl [loginWithoutRedirect] 游戏登录失败,错误代码{},错误信息{}", xkLoginWithoutRedirectResponseDTO.getCode(), xkLoginWithoutRedirectResponseDTO.getMsg()); + throw new BaseException(MessageUtils.message("game.login.failed")); + } + } catch (Exception e) { + log.error("GamesXKServiceImpl [loginWithoutRedirect] 游戏登录失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.login.failed")); + } + } + + + /** + * 获取游戏列表 + * + * @param gamesBaseRequestDTO 游戏请求dto + * @return {@link String } + */ + @Transactional + @Override + public String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO) { + List gamesDatas = redisCache.getCacheList(CacheConstants.XK_GAMES); + if (!CollectionUtils.isEmpty(gamesDatas)) { + return CacheConstants.XK_GAMES; + } + + Map params = new LinkedHashMap<>(); + params.put("agentId", gamesBaseRequestDTO.getAgentId()); + String query = JsonUtil.mapToQueryString(params); + gamesBaseRequestDTO.setQuery(query); + String key = this.getKey(gamesBaseRequestDTO); + params.put("key", key); + String apiBaseUrl = configService.selectConfigByKey(Constants.XK_API_BASE_URL); + try { + + + String result = HttpClientSslUtils.doPost(apiBaseUrl + "/api/getGameList", JsonUtil.objToPrettyString(params)); + XKGamesDTO xkGamesDTO = JsonUtil.stringToObj(result, XKGamesDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(xkGamesDTO.getCode())) { + + Map gamePlatformMap = new HashMap<>(); + + for (XKGamesDTO.DataBean gamesDataDTO : xkGamesDTO.getData()) { + if (XKGameType.GAME_HALL.getCode().equals(gamesDataDTO.getGameCategoryId())) { + continue; + } + + GamePlatform gamePlatform = GamePlatform.builder() + .platformType(XKGameType.findSystemByCode(gamesDataDTO.getGameCategoryId())) + .platformCode(GamePlatforms.XK.getCode()) + .build(); + List gamePlatforms = gamePlatformService.selectGamePlatformList(gamePlatform); + //没有此平台就新增一个平台 + if (CollectionUtils.isEmpty(gamePlatforms)) { + gamePlatform.setPlatformName(GamePlatforms.XK.getInfo() + XKGameType.findInfoByCode(gamesDataDTO.getGameCategoryId())); + gamePlatform.setSortNo(gamePlatformService.selectMaxSortNo() + 1); + gamePlatform.setCreateBy(Constants.SYSTEM); + gamePlatformService.insertGamePlatform(gamePlatform); + } else { + gamePlatform = gamePlatforms.get(0); + } + Game game = Game.builder() + .platformId(gamePlatform.getId()) + .gameCode(gamesDataDTO.getGameId()) + .build(); + List games = gameService.selectGameList(game); + //不存在这个游戏 + if (CollectionUtils.isEmpty(games)) { + game.setFreespin(gamesDataDTO.isFreeSpin()); + game.setSortNo(gameService.selectMaxSortNoByPlatformId(gamePlatform.getId()) + 1); + game.setGameName(gamesDataDTO.getName()); + game.setCreateBy(Constants.SYSTEM); + gameService.insertGame(game); + } else { + game = games.get(0); + } + gamesDataDTO.setSystemGameId(game.getId()); + + + } + + + + redisCache.deleteObject(CacheConstants.XK_GAMES); + redisCache.setCacheList(CacheConstants.XK_GAMES, xkGamesDTO.getData()); + redisCache.expire(CacheConstants.XK_GAMES, 5L, TimeUnit.HOURS); + } else { + log.error("GamesXKServiceImpl [getGameList] 获取游戏列表失败,错误代码{},错误信息{}", xkGamesDTO.getCode(), xkGamesDTO.getMsg()); + throw new BaseException(MessageUtils.message("game.list.retrieve.failed")); + } + } catch (Exception e) { + log.error("GamesXKServiceImpl [getGameList] 获取游戏列表失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.list.retrieve.failed")); + } + return CacheConstants.JILI_GAMES; + } + + /** + * 按代理id进行交换转账 + * + * @param exchangeTransferMoneyRequestDTO 外汇转账moeny dto + * @return {@link Long } + */ + @Override + @Transactional + public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) { + log.info("GamesXKServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO); + String systemByCode = gameSecretKeyService.findSystemByCode(exchangeTransferMoneyRequestDTO.getAgentId(),GamePlatforms.XK.getInfo()); + Member member = memberService.selectMemberByMemberAccount(exchangeTransferMoneyRequestDTO.getAccount()); + //获取下一个自增id + GameExchangeMoney exchangeMoney = GameExchangeMoney + .builder() + .quota(exchangeTransferMoneyRequestDTO.getQuota()) + .platformId(exchangeTransferMoneyRequestDTO.getPlatformId()) + .balance(exchangeTransferMoneyRequestDTO.getAmount()) + .exchangeType(exchangeTransferMoneyRequestDTO.getTransferType()) + .currencyCode(systemByCode) + .memberId(member.getId()) + .platformCode(GamePlatforms.XK.getCode()) + .build(); + exchangeMoney.setCreateBy(Constants.SYSTEM); + //接口限制限制50字符 + exchangeMoney.setTransactionId(GamePlatforms.XK.getCode() + IdUtils.simpleUUID()); + Map params = new LinkedHashMap<>(); + params.put("account", exchangeTransferMoneyRequestDTO.getAccount()); + params.put("transactionId", exchangeMoney.getTransactionId()); + params.put("amount", exchangeTransferMoneyRequestDTO.getAmount().stripTrailingZeros().toString()); + params.put("transferType", exchangeTransferMoneyRequestDTO.getTransferType()); + params.put("agentId", exchangeTransferMoneyRequestDTO.getAgentId()); + String query = JsonUtil.mapToQueryString(params); + exchangeTransferMoneyRequestDTO.setQuery(query); + String key = this.getKey(exchangeTransferMoneyRequestDTO); + params.put("key", key); + String apiBaseUrl = configService.selectConfigByKey(Constants.XK_API_BASE_URL); + try { + String result = HttpClientSslUtils.doPost(apiBaseUrl + "/api/exchangeTransferByAgentId", JsonUtil.objToPrettyString(params)); + + XKExchangeMoneyResponseDTO exchangeMoneyResponse = JsonUtil.stringToObj(result, XKExchangeMoneyResponseDTO.class); + //判断是否转移成功 + if (this.getIsSuccess(exchangeMoneyResponse.getCode())) { + XKExchangeMoneyResponseDTO.DataBean exchangeMoneyResponseData = exchangeMoneyResponse.getData(); + //更新数据 + exchangeMoney.setBalance(NumberUtil.sub(exchangeMoneyResponseData.getCurrencyAfter(), exchangeMoneyResponseData.getCurrencyBefore()).abs()); + exchangeMoney.setCoinBefore(exchangeMoneyResponseData.getCoinBefore()); + exchangeMoney.setCoinAfter(exchangeMoneyResponseData.getCoinAfter()); + exchangeMoney.setCurrencyBefore(exchangeMoneyResponseData.getCurrencyBefore()); + exchangeMoney.setCurrencyAfter(exchangeMoneyResponseData.getCurrencyAfter()); + exchangeMoney.setStatus(exchangeMoneyResponseData.getStatus()); + gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney); + } else { + log.error("GamesXKServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误代码{},错误信息{}", exchangeMoneyResponse.getCode(), exchangeMoneyResponse.getMsg()); + throw new BaseException(MessageUtils.message("game.account.balance.transfer.failed")); + } + } catch (Exception e) { + log.error("GamesXKServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.account.balance.transfer.failed")); + } + + return exchangeMoney.getId(); + } + + + /** + * 按时间获取投注记录 + * + * @param betRecordByTimeDTO 按时间dto投注记录 + * @return {@link List }<{@link GameBettingDetails }> + */ + @Override + public List getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) { + List gameBettingDetails = new ArrayList<>(); + //请求参数 + log.info("GamesXKServiceImpl [getBetRecordByTime] 请求参数 {}", betRecordByTimeDTO); + Map params = new LinkedHashMap<>(); + params.put("startTime", betRecordByTimeDTO.getStartTime()); + params.put("endTime", betRecordByTimeDTO.getEndTime()); + params.put("page", betRecordByTimeDTO.getPage()); + params.put("pageLimit", betRecordByTimeDTO.getPageLimit()); + params.put("agentId", betRecordByTimeDTO.getAgentId()); + String query = JsonUtil.mapToQueryString(params); + betRecordByTimeDTO.setQuery(query); + String key = this.getKey(betRecordByTimeDTO); + params.put("key", key); + String apiBaseUrl = configService.selectConfigByKey(Constants.XK_API_BASE_URL); + String result = null; + try { + result = HttpClientSslUtils.doPost(apiBaseUrl + "/api/getGameRecordByTime", JsonUtil.objToPrettyString(params)); + + XKBetRecordResponseDTO betRecordJILIResponse = JSON.parseObject(result, XKBetRecordResponseDTO.class); + + //判断是否获取成功 + if (this.getIsSuccess(betRecordJILIResponse.getCode())) { + //数据组装 + XKBetRecordResponseDTO.DataBean dataBean = betRecordJILIResponse.getData(); + for (XKBetRecordResponseDTO.DataBean.ResultBean bean : dataBean.getResult()) { + GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(bean).gamesKey(key).build()); + gameBettingDetails.add(bettingDetails); + } + + //获取下一页数据 + while (!Objects.equals(dataBean.getCurrentPage(), dataBean.getTotalPages())&&dataBean.getTotalPages()>0) { + betRecordByTimeDTO.setPage(dataBean.getCurrentPage() + 1); + //请求参数 + params = new LinkedHashMap<>(); + params.put("startTime", betRecordByTimeDTO.getStartTime()); + params.put("endTime", betRecordByTimeDTO.getEndTime()); + params.put("page", betRecordByTimeDTO.getPage()); + params.put("pageLimit", betRecordByTimeDTO.getPageLimit()); + params.put("agentId", betRecordByTimeDTO.getAgentId()); + query = JsonUtil.mapToQueryString(params); + betRecordByTimeDTO.setQuery(query); + key = this.getKey(betRecordByTimeDTO); + params.put("key", key); + result = HttpClientSslUtils.doPost(apiBaseUrl + "/api/getGameRecordByTime", JsonUtil.objToPrettyString(params)); + betRecordJILIResponse = JsonUtil.stringToObj(result, XKBetRecordResponseDTO.class); + dataBean = betRecordJILIResponse.getData(); + for (XKBetRecordResponseDTO.DataBean.ResultBean bean : dataBean.getResult()) { + GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(bean).gamesKey(key).build()); + gameBettingDetails.add(bettingDetails); + } + } + + + return gameBettingDetails; + } else { + log.error("GamesXKServiceImpl [getBetRecordByTime] 获取投注记录失败,错误代码{},错误信息{}", betRecordJILIResponse.getCode(), betRecordJILIResponse.getMsg()); + throw new BaseException(MessageUtils.message("game.bet.record.retrieve.failed")); + } + } catch (Exception e) { + log.error("GamesXKServiceImpl [getBetRecordByTime] 获取投注记录失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.bet.record.retrieve.failed")); + } + + } + + /** + * 赠送免费局数 + * + * @param createFreeSpinRequest 创建自由旋转请求 + * @return {@link Boolean } + */ + @Override + public Boolean createFreeSpin(CreateFreeSpinRequestDTO createFreeSpinRequest) { + return Boolean.FALSE; + } + + /** + * 获取游戏详细信息 + * + * @param getGameDetailRequestDTO 获取游戏详细信息请求dto + * @return {@link GetGameDetailResponseDTO } + */ + @Override + public GetGameDetailResponseDTO getGameDetail(GetGameDetailRequestDTO getGameDetailRequestDTO) { + return new GetGameDetailResponseDTO(); + } + + /** + * 强制会员从游戏注销 + * + * @param kickMemberRequestDTO 踢会员请求dto + * @return {@link Boolean } + */ + @Override + public Boolean kickMember(KickMemberRequestDTO kickMemberRequestDTO) { + log.info("GamesXKServiceImpl [kickMember] 请求参数 {}", kickMemberRequestDTO); + Map params = new LinkedHashMap<>(); + params.put("account", kickMemberRequestDTO.getAccount()); + params.put("agentId", kickMemberRequestDTO.getAgentId()); + String query = JsonUtil.mapToQueryString(params); + kickMemberRequestDTO.setQuery(query); + String key = this.getKey(kickMemberRequestDTO); + params.put("key", key); + + String apiBaseUrl = configService.selectConfigByKey(Constants.XK_API_BASE_URL); + try { + + String result = HttpClientSslUtils.doPost(apiBaseUrl + "/api/kickMember", JsonUtil.objToPrettyString(params)); + XKKickMemberDTO xkKickMemberDTO = JsonUtil.stringToObj(result, XKKickMemberDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(xkKickMemberDTO.getCode())) { + return Boolean.TRUE; + } else { + log.error("GamesXKServiceImpl [kickMember] 强制会员从游戏注销失败,错误代码{},错误信息{}", xkKickMemberDTO.getCode(), xkKickMemberDTO.getMsg()); + throw new BaseException(MessageUtils.message("game.member.force.logout.failed")); + } + } catch (Exception e) { + log.error("GamesXKServiceImpl [kickMember] 强制会员从游戏注销失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.member.force.logout.failed")); + } + } + + /** + * 踢成员全部 + * + * @param kickMemberAllDTO 踢成员全部dto + * @return {@link Boolean } + */ + @Override + public Boolean kickMemberAll(KickMemberAllDTO kickMemberAllDTO) { + log.info("GamesXKServiceImpl [kickMemberAll] 请求参数 {}", kickMemberAllDTO); + Map params = new LinkedHashMap<>(); + params.put("agentId", kickMemberAllDTO.getAgentId()); + if (!ObjectUtils.isEmpty(kickMemberAllDTO.getGameId())) { + params.put("gameId", kickMemberAllDTO.getGameId()); + } + String query = JsonUtil.mapToQueryString(params); + kickMemberAllDTO.setQuery(query); + String key = this.getKey(kickMemberAllDTO); + params.put("key", key); + kickMemberAllDTO.setQuery(query); + String apiBaseUrl = configService.selectConfigByKey(Constants.XK_API_BASE_URL); + try { + + String result = HttpClientSslUtils.doPost(apiBaseUrl + "/api/kickMemberAll", JsonUtil.objToPrettyString(params)); + XKKickMemberAllDTO xkKickMemberAllDTO = JsonUtil.stringToObj(result, XKKickMemberAllDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(xkKickMemberAllDTO.getCode())) { + return Boolean.TRUE; + } else { + log.error("GamesXKServiceImpl [kickMemberAll] 强制全部会员从游戏注销失败,错误代码{},错误信息{}", xkKickMemberAllDTO.getCode(), xkKickMemberAllDTO.getMsg()); + throw new BaseException(MessageUtils.message("game.members.force.logout.failed")); + } + } catch (Exception e) { + log.error("GamesXKServiceImpl [kickMemberAll] 强制全部会员从游戏注销失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.members.force.logout.failed")); + } + } + + /** + * 免费游戏玩家使用的纪录 + * + * @param getFreeSpinDashflowRequestDTO 获取自由旋转dashflow请求dto + * @return {@link List }<{@link GameFreeRecord }> + */ + @Override + public List getFreeSpinDashflow(GetFreeSpinDashflowRequestDTO getFreeSpinDashflowRequestDTO) { + return new ArrayList<>(); + } + + /** + * 取消赠送免费局数 + * + * @param cancelFreeSpinRequestDTO 取消免费旋转请求 + * @return {@link Boolean } + */ + @Override + public Boolean cancelFreeSpin(CancelFreeSpinRequestDTO cancelFreeSpinRequestDTO) { + return Boolean.TRUE; + } + + + /** + * 数据构建 + * + * @param gamesDataBuildDTO 数据 + * @return {@link GameBettingDetails } + */ + @Override + public GameBettingDetails dataBuild(GamesDataBuildDTO gamesDataBuildDTO) { + //转化类 + XKBetRecordResponseDTO.DataBean.ResultBean resultBean = (XKBetRecordResponseDTO.DataBean.ResultBean) gamesDataBuildDTO.getData(); + String systemByCode = gameSecretKeyService.findSystemByCode(resultBean.getAgentId(),GamePlatforms.XK.getInfo()); + Member member = memberService.selectMemberByMemberAccount(resultBean.getAccount()); + List gamesDatas = redisCache.getCacheList(CacheConstants.XK_GAMES); + Map dataDTOMap = gamesDatas.stream().collect(Collectors.toMap(XKGamesDTO.DataBean::getGameId, e -> e)); + XKGamesDTO.DataBean gamesDataDTO = dataDTOMap.get(resultBean.getGameId()); + BigDecimal payoffAmount=BigDecimal.ZERO; + + if (GameStatus.WIN.getCode().equals(resultBean.getStatus())) { + payoffAmount = NumberUtil.sub(resultBean.getPayoffAmount(), resultBean.getTurnover()); + } else if (GameStatus.FAIL.getCode().equals(resultBean.getStatus())){ + payoffAmount = NumberUtil.sub(resultBean.getPayoffAmount(), resultBean.getTurnover()).negate(); + } + //数据构造 + GameBettingDetails gameBettingDetails = GameBettingDetails.builder() + //保存我们的币种id + .currencyCode(systemByCode) + .memberId(member.getId()) + .gameCode(resultBean.getGameId()) + .gameType(XKGameType.findSystemByCode(resultBean.getGameCategoryId())) + .platformCode(GamePlatforms.XK.getCode()) + .gameId(gamesDataDTO.getSystemGameId()) + .gameName(gamesDataDTO.getName()) + .gameStatus(resultBean.getStatus()) + .gameStatusType(resultBean.getType()) + .gameCurrencyCode(resultBean.getAgentId()) + .account(String.valueOf(resultBean.getAccount())) + .wagersId(resultBean.getWagersId()) + .wagersTime(resultBean.getWagersTime()) + .betAmount(resultBean.getBetAmount().abs()) + .payoffTime(resultBean.getPayoffTime()) + .payoffAmount(payoffAmount) + .settlementTime(resultBean.getSettlementTime()) + .turnover(resultBean.getTurnover()) + .orderNo(String.valueOf(resultBean.getRoundIndex())) + .build(); + gameBettingDetails.setCreateBy(Constants.SYSTEM); + gameBettingDetails.setCreateTime(DateUtils.getNowDate()); + return gameBettingDetails; + } +} diff --git a/ff-admin/src/main/java/com/ff/game/controller/GameBettingDetailsController.java b/ff-admin/src/main/java/com/ff/game/controller/GameBettingDetailsController.java new file mode 100644 index 0000000..9b46dc9 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/controller/GameBettingDetailsController.java @@ -0,0 +1,104 @@ +package com.ff.game.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.game.domain.GameBettingDetails; +import com.ff.game.service.IGameBettingDetailsService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 会员投注细目Controller + * + * @author shi + * @date 2025-02-10 + */ +@RestController +@RequestMapping("/game/details") +public class GameBettingDetailsController extends BaseController +{ + @Autowired + private IGameBettingDetailsService gameBettingDetailsService; + + /** + * 查询会员投注细目列表 + */ + @PreAuthorize("@ss.hasPermi('game:details:list')") + @GetMapping("/list") + public TableDataInfo list(GameBettingDetails gameBettingDetails) + { + startPage(); + List list = gameBettingDetailsService.selectGameBettingDetailsList(gameBettingDetails); + return getDataTable(list); + } + + /** + * 导出会员投注细目列表 + */ + @PreAuthorize("@ss.hasPermi('game:details:export')") + @Log(title = "会员投注细目", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, GameBettingDetails gameBettingDetails) + { + List list = gameBettingDetailsService.selectGameBettingDetailsList(gameBettingDetails); + ExcelUtil util = new ExcelUtil(GameBettingDetails.class); + util.exportExcel(response, list, "会员投注细目数据"); + } + + /** + * 获取会员投注细目详细信息 + */ + @PreAuthorize("@ss.hasPermi('game:details:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(gameBettingDetailsService.selectGameBettingDetailsById(id)); + } + + /** + * 新增会员投注细目 + */ + @PreAuthorize("@ss.hasPermi('game:details:add')") + @Log(title = "会员投注细目", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody GameBettingDetails gameBettingDetails) + { + return toAjax(gameBettingDetailsService.insertGameBettingDetails(gameBettingDetails)); + } + + /** + * 修改会员投注细目 + */ + @PreAuthorize("@ss.hasPermi('game:details:edit')") + @Log(title = "会员投注细目", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody GameBettingDetails gameBettingDetails) + { + return toAjax(gameBettingDetailsService.updateGameBettingDetails(gameBettingDetails)); + } + + /** + * 删除会员投注细目 + */ + @PreAuthorize("@ss.hasPermi('game:details:remove')") + @Log(title = "会员投注细目", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(gameBettingDetailsService.deleteGameBettingDetailsByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/controller/GameController.java b/ff-admin/src/main/java/com/ff/game/controller/GameController.java new file mode 100644 index 0000000..5dde5a0 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/controller/GameController.java @@ -0,0 +1,104 @@ +package com.ff.game.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.game.domain.Game; +import com.ff.game.service.IGameService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 平台子游戏管理Controller + * + * @author shi + * @date 2025-02-10 + */ +@RestController +@RequestMapping("/game/game") +public class GameController extends BaseController +{ + @Autowired + private IGameService gameService; + + /** + * 查询平台子游戏管理列表 + */ + @PreAuthorize("@ss.hasPermi('game:game:list')") + @GetMapping("/list") + public TableDataInfo list(Game game) + { + startPage(); + List list = gameService.selectGameList(game); + return getDataTable(list); + } + + /** + * 导出平台子游戏管理列表 + */ + @PreAuthorize("@ss.hasPermi('game:game:export')") + @Log(title = "平台子游戏管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, Game game) + { + List list = gameService.selectGameList(game); + ExcelUtil util = new ExcelUtil(Game.class); + util.exportExcel(response, list, "平台子游戏管理数据"); + } + + /** + * 获取平台子游戏管理详细信息 + */ + @PreAuthorize("@ss.hasPermi('game:game:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(gameService.selectGameById(id)); + } + + /** + * 新增平台子游戏管理 + */ + @PreAuthorize("@ss.hasPermi('game:game:add')") + @Log(title = "平台子游戏管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody Game game) + { + return toAjax(gameService.insertGame(game)); + } + + /** + * 修改平台子游戏管理 + */ + @PreAuthorize("@ss.hasPermi('game:game:edit')") + @Log(title = "平台子游戏管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody Game game) + { + return toAjax(gameService.updateGame(game)); + } + + /** + * 删除平台子游戏管理 + */ + @PreAuthorize("@ss.hasPermi('game:game:remove')") + @Log(title = "平台子游戏管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(gameService.deleteGameByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/controller/GameExchangeMoneyController.java b/ff-admin/src/main/java/com/ff/game/controller/GameExchangeMoneyController.java new file mode 100644 index 0000000..61c681b --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/controller/GameExchangeMoneyController.java @@ -0,0 +1,104 @@ +package com.ff.game.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.game.domain.GameExchangeMoney; +import com.ff.game.service.IGameExchangeMoneyService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 会员金额转移记录Controller + * + * @author shi + * @date 2025-02-10 + */ +@RestController +@RequestMapping("/game/money") +public class GameExchangeMoneyController extends BaseController +{ + @Autowired + private IGameExchangeMoneyService gameExchangeMoneyService; + + /** + * 查询会员金额转移记录列表 + */ + @PreAuthorize("@ss.hasPermi('game:money:list')") + @GetMapping("/list") + public TableDataInfo list(GameExchangeMoney gameExchangeMoney) + { + startPage(); + List list = gameExchangeMoneyService.selectGameExchangeMoneyList(gameExchangeMoney); + return getDataTable(list); + } + + /** + * 导出会员金额转移记录列表 + */ + @PreAuthorize("@ss.hasPermi('game:money:export')") + @Log(title = "会员金额转移记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, GameExchangeMoney gameExchangeMoney) + { + List list = gameExchangeMoneyService.selectGameExchangeMoneyList(gameExchangeMoney); + ExcelUtil util = new ExcelUtil(GameExchangeMoney.class); + util.exportExcel(response, list, "会员金额转移记录数据"); + } + + /** + * 获取会员金额转移记录详细信息 + */ + @PreAuthorize("@ss.hasPermi('game:money:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(gameExchangeMoneyService.selectGameExchangeMoneyById(id)); + } + + /** + * 新增会员金额转移记录 + */ + @PreAuthorize("@ss.hasPermi('game:money:add')") + @Log(title = "会员金额转移记录", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody GameExchangeMoney gameExchangeMoney) + { + return toAjax(gameExchangeMoneyService.insertGameExchangeMoney(gameExchangeMoney)); + } + + /** + * 修改会员金额转移记录 + */ + @PreAuthorize("@ss.hasPermi('game:money:edit')") + @Log(title = "会员金额转移记录", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody GameExchangeMoney gameExchangeMoney) + { + return toAjax(gameExchangeMoneyService.updateGameExchangeMoney(gameExchangeMoney)); + } + + /** + * 删除会员金额转移记录 + */ + @PreAuthorize("@ss.hasPermi('game:money:remove')") + @Log(title = "会员金额转移记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(gameExchangeMoneyService.deleteGameExchangeMoneyByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/controller/GameFreeRecordController.java b/ff-admin/src/main/java/com/ff/game/controller/GameFreeRecordController.java new file mode 100644 index 0000000..8c9f9fb --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/controller/GameFreeRecordController.java @@ -0,0 +1,104 @@ +package com.ff.game.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.game.domain.GameFreeRecord; +import com.ff.game.service.IGameFreeRecordService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 免费赠送游戏记录Controller + * + * @author shi + * @date 2025-02-10 + */ +@RestController +@RequestMapping("/game/record") +public class GameFreeRecordController extends BaseController +{ + @Autowired + private IGameFreeRecordService gameFreeRecordService; + + /** + * 查询免费赠送游戏记录列表 + */ + @PreAuthorize("@ss.hasPermi('game:record:list')") + @GetMapping("/list") + public TableDataInfo list(GameFreeRecord gameFreeRecord) + { + startPage(); + List list = gameFreeRecordService.selectGameFreeRecordList(gameFreeRecord); + return getDataTable(list); + } + + /** + * 导出免费赠送游戏记录列表 + */ + @PreAuthorize("@ss.hasPermi('game:record:export')") + @Log(title = "免费赠送游戏记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, GameFreeRecord gameFreeRecord) + { + List list = gameFreeRecordService.selectGameFreeRecordList(gameFreeRecord); + ExcelUtil util = new ExcelUtil(GameFreeRecord.class); + util.exportExcel(response, list, "免费赠送游戏记录数据"); + } + + /** + * 获取免费赠送游戏记录详细信息 + */ + @PreAuthorize("@ss.hasPermi('game:record:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(gameFreeRecordService.selectGameFreeRecordById(id)); + } + + /** + * 新增免费赠送游戏记录 + */ + @PreAuthorize("@ss.hasPermi('game:record:add')") + @Log(title = "免费赠送游戏记录", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody GameFreeRecord gameFreeRecord) + { + return toAjax(gameFreeRecordService.insertGameFreeRecord(gameFreeRecord)); + } + + /** + * 修改免费赠送游戏记录 + */ + @PreAuthorize("@ss.hasPermi('game:record:edit')") + @Log(title = "免费赠送游戏记录", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody GameFreeRecord gameFreeRecord) + { + return toAjax(gameFreeRecordService.updateGameFreeRecord(gameFreeRecord)); + } + + /** + * 删除免费赠送游戏记录 + */ + @PreAuthorize("@ss.hasPermi('game:record:remove')") + @Log(title = "免费赠送游戏记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(gameFreeRecordService.deleteGameFreeRecordByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/controller/GamePlatformController.java b/ff-admin/src/main/java/com/ff/game/controller/GamePlatformController.java new file mode 100644 index 0000000..265e783 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/controller/GamePlatformController.java @@ -0,0 +1,104 @@ +package com.ff.game.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.game.domain.GamePlatform; +import com.ff.game.service.IGamePlatformService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 平台管理Controller + * + * @author shi + * @date 2025-02-10 + */ +@RestController +@RequestMapping("/game/platform") +public class GamePlatformController extends BaseController +{ + @Autowired + private IGamePlatformService gamePlatformService; + + /** + * 查询平台管理列表 + */ + @PreAuthorize("@ss.hasPermi('game:platform:list')") + @GetMapping("/list") + public TableDataInfo list(GamePlatform gamePlatform) + { + startPage(); + List list = gamePlatformService.selectGamePlatformList(gamePlatform); + return getDataTable(list); + } + + /** + * 导出平台管理列表 + */ + @PreAuthorize("@ss.hasPermi('game:platform:export')") + @Log(title = "平台管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, GamePlatform gamePlatform) + { + List list = gamePlatformService.selectGamePlatformList(gamePlatform); + ExcelUtil util = new ExcelUtil(GamePlatform.class); + util.exportExcel(response, list, "平台管理数据"); + } + + /** + * 获取平台管理详细信息 + */ + @PreAuthorize("@ss.hasPermi('game:platform:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(gamePlatformService.selectGamePlatformById(id)); + } + + /** + * 新增平台管理 + */ + @PreAuthorize("@ss.hasPermi('game:platform:add')") + @Log(title = "平台管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody GamePlatform gamePlatform) + { + return toAjax(gamePlatformService.insertGamePlatform(gamePlatform)); + } + + /** + * 修改平台管理 + */ + @PreAuthorize("@ss.hasPermi('game:platform:edit')") + @Log(title = "平台管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody GamePlatform gamePlatform) + { + return toAjax(gamePlatformService.updateGamePlatform(gamePlatform)); + } + + /** + * 删除平台管理 + */ + @PreAuthorize("@ss.hasPermi('game:platform:remove')") + @Log(title = "平台管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(gamePlatformService.deleteGamePlatformByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/controller/GameSecretKeyController.java b/ff-admin/src/main/java/com/ff/game/controller/GameSecretKeyController.java new file mode 100644 index 0000000..627fc8d --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/controller/GameSecretKeyController.java @@ -0,0 +1,104 @@ +package com.ff.game.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.game.domain.GameSecretKey; +import com.ff.game.service.IGameSecretKeyService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 游戏平台密钥管理Controller + * + * @author shi + * @date 2025-02-10 + */ +@RestController +@RequestMapping("/game/key") +public class GameSecretKeyController extends BaseController +{ + @Autowired + private IGameSecretKeyService gameSecretKeyService; + + /** + * 查询游戏平台密钥管理列表 + */ + @PreAuthorize("@ss.hasPermi('game:key:list')") + @GetMapping("/list") + public TableDataInfo list(GameSecretKey gameSecretKey) + { + startPage(); + List list = gameSecretKeyService.selectGameSecretKeyList(gameSecretKey); + return getDataTable(list); + } + + /** + * 导出游戏平台密钥管理列表 + */ + @PreAuthorize("@ss.hasPermi('game:key:export')") + @Log(title = "游戏平台密钥管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, GameSecretKey gameSecretKey) + { + List list = gameSecretKeyService.selectGameSecretKeyList(gameSecretKey); + ExcelUtil util = new ExcelUtil(GameSecretKey.class); + util.exportExcel(response, list, "游戏平台密钥管理数据"); + } + + /** + * 获取游戏平台密钥管理详细信息 + */ + @PreAuthorize("@ss.hasPermi('game:key:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(gameSecretKeyService.selectGameSecretKeyById(id)); + } + + /** + * 新增游戏平台密钥管理 + */ + @PreAuthorize("@ss.hasPermi('game:key:add')") + @Log(title = "游戏平台密钥管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody GameSecretKey gameSecretKey) + { + return toAjax(gameSecretKeyService.insertGameSecretKey(gameSecretKey)); + } + + /** + * 修改游戏平台密钥管理 + */ + @PreAuthorize("@ss.hasPermi('game:key:edit')") + @Log(title = "游戏平台密钥管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody GameSecretKey gameSecretKey) + { + return toAjax(gameSecretKeyService.updateGameSecretKey(gameSecretKey)); + } + + /** + * 删除游戏平台密钥管理 + */ + @PreAuthorize("@ss.hasPermi('game:key:remove')") + @Log(title = "游戏平台密钥管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(gameSecretKeyService.deleteGameSecretKeyByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/domain/Game.java b/ff-admin/src/main/java/com/ff/game/domain/Game.java new file mode 100644 index 0000000..1095607 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/domain/Game.java @@ -0,0 +1,64 @@ +package com.ff.game.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 平台子游戏管理对象 ff_game + * + * @author shi + * @date 2025-02-10 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Game extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 排序 */ + @Excel(name = "排序") + private Integer sortNo; + + /** 游戏平台id */ + @Excel(name = "游戏平台id") + private Long platformId; + + /** 游戏第三方id */ + @Excel(name = "游戏第三方id") + private Integer gameCode; + + /** 第三方来源分类 */ + @Excel(name = "第三方来源分类") + private Integer gameSourceType; + + /** 游戏名称 */ + @Excel(name = "游戏名称") + private String gameName; + + /** 是否支持免费游戏 1 支持 0 不支持 */ + @Excel(name = "是否支持免费游戏 1 支持 0 不支持") + private Boolean freespin; + + /** 是否支持试玩 0关闭 1开启 */ + @Excel(name = "是否支持试玩 0关闭 1开启") + private Boolean demoStatus; + + /** 维护开关 维护状态 0关闭 1开启 */ + @Excel(name = "维护开关 维护状态 0关闭 1开启") + private Boolean stopStatus; + + /** 游戏开关 平台开关状态 0关闭 1开启 */ + @Excel(name = "游戏开关 平台开关状态 0关闭 1开启") + private Boolean gameStatus; + + +} diff --git a/ff-admin/src/main/java/com/ff/game/domain/GameBettingDetails.java b/ff-admin/src/main/java/com/ff/game/domain/GameBettingDetails.java new file mode 100644 index 0000000..5c708ab --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/domain/GameBettingDetails.java @@ -0,0 +1,109 @@ +package com.ff.game.domain; + +import java.math.BigDecimal; +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 会员投注细目对象 ff_game_betting_details + * + * @author shi + * @date 2025-02-10 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class GameBettingDetails extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 币种编码 */ + @Excel(name = "币种编码") + private String currencyCode; + + /** 会员id */ + @Excel(name = "会员id") + private Long memberId; + + /** 游戏id */ + @Excel(name = "游戏id ") + private Integer gameCode; + + /** 游戏id */ + @Excel(name = "游戏id") + private Long gameId; + + /** 游戏类型 ff_game_type 字典 */ + @Excel(name = "游戏类型 ff_game_type 字典") + private Long gameType; + + /** 游戏平台 */ + @Excel(name = "游戏平台 ") + private String platformCode; + + /** 游戏名称 */ + @Excel(name = "游戏名称") + private String gameName; + + /** 注单状态 1: 赢 2: 输 3: 平局 */ + @Excel(name = "注单状态 1: 赢 2: 输 3: 平局") + private Integer gameStatus; + + /** 注单类型 */ + @Excel(name = "注单类型") + private Integer gameStatusType; + + /** 游戏币种类型 */ + @Excel(name = "游戏币种类型") + private String gameCurrencyCode; + + /** 游戏账号 */ + @Excel(name = "游戏账号") + private String account; + + /** 游戏注单唯一值 */ + @Excel(name = "游戏注单唯一值") + private Long wagersId; + + /** 投注时间 (Unix 时间戳) */ + @Excel(name = "投注时间 (Unix 时间戳)") + private Long wagersTime; + + /** 投注金额 */ + @Excel(name = "投注金额") + private BigDecimal betAmount; + + /** 派彩时间 (Unix 时间戳) */ + @Excel(name = "派彩时间 (Unix 时间戳)") + private Long payoffTime; + + /** 派彩金额 */ + @Excel(name = "派彩金额") + private BigDecimal payoffAmount; + + /** 对帐时间 (Unix 时间戳) */ + @Excel(name = "对帐时间 (Unix 时间戳)") + private Long settlementTime; + + /** 有效投注金额 ※注 1 */ + @Excel(name = "有效投注金额 ※注 1") + private BigDecimal turnover; + + /** 订单id */ + @Excel(name = "订单id") + private String orderNo; + + /** 结算状态 1 未结算 2已结算 3 已撤单 */ + @Excel(name = "结算状态 1 未结算 2已结算 3 已撤单") + private Integer settlementStatus; + + +} diff --git a/ff-admin/src/main/java/com/ff/game/domain/GameExchangeMoney.java b/ff-admin/src/main/java/com/ff/game/domain/GameExchangeMoney.java new file mode 100644 index 0000000..6251d64 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/domain/GameExchangeMoney.java @@ -0,0 +1,81 @@ +package com.ff.game.domain; + +import java.math.BigDecimal; +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 会员金额转移记录对象 ff_game_exchange_money + * + * @author shi + * @date 2025-02-10 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class GameExchangeMoney extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 币种编码 */ + @Excel(name = "币种编码") + private String currencyCode; + + /** 交易id */ + @Excel(name = "交易id") + private String transactionId; + + /** 会员id */ + @Excel(name = "会员id") + private Long memberId; + + /** 游戏平台 */ + @Excel(name = "游戏平台 ") + private String platformCode; + + /** 平台id */ + @Excel(name = "平台id") + private Long platformId; + + /** 操作金额 */ + @Excel(name = "操作金额") + private BigDecimal balance; + + /** 租户操作额度 */ + @Excel(name = "租户操作额度") + private BigDecimal quota; + + /** 转账前金额(游戏币) */ + @Excel(name = " 转账前金额(游戏币)") + private BigDecimal coinBefore; + + /** 转账后金额(游戏币) */ + @Excel(name = "转账后金额(游戏币)") + private BigDecimal coinAfter; + + /** 转账前金额(指定货币) */ + @Excel(name = "转账前金额(指定货币)") + private BigDecimal currencyBefore; + + /** 转账后金额(指定货币) */ + @Excel(name = "转账后金额(指定货币)") + private BigDecimal currencyAfter; + + /** 转出类型 1游戏商转入到用户全部转出 2 用户转移到游戏商 3 游戏商转移额度到平台商 */ + @Excel(name = "转出类型 1游戏商转入到用户全部转出 2 用户转移到游戏商 3 游戏商转移额度到平台商") + private Integer exchangeType; + + /** 状态 1 成功 2失败 */ + @Excel(name = "状态 1 成功 2失败") + private Integer status; + + +} diff --git a/ff-admin/src/main/java/com/ff/game/domain/GameFreeRecord.java b/ff-admin/src/main/java/com/ff/game/domain/GameFreeRecord.java new file mode 100644 index 0000000..0636a82 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/domain/GameFreeRecord.java @@ -0,0 +1,83 @@ +package com.ff.game.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 免费赠送游戏记录对象 ff_game_free_record + * + * @author shi + * @date 2025-02-10 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class GameFreeRecord extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 币种编码 */ + @Excel(name = "币种编码") + private String currencyCode; + + /** 免费局数序号(唯一标识符) */ + @Excel(name = "免费局数序号", readConverterExp = "唯=一标识符") + private String referenceId; + + /** 会员id */ + @Excel(name = "会员id") + private Long memberId; + + /** 用户账号 */ + @Excel(name = "用户账号") + private String memberAccount; + + /** 游戏id */ + @Excel(name = "游戏id ") + private Long gameId; + + /** 免费游戏局数可使用的开始时间 */ + @Excel(name = "免费游戏局数可使用的开始时间") + private Long sendTime; + + /** 免费局数过期时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "免费局数过期时间", width = 30, dateFormat = "yyyy-MM-dd") + private Long expiredTime; + + /** 免费局数记录更新时间 */ + @Excel(name = "免费局数记录更新时间") + private Long freeUpdateTime; + + /** 免费局数赠送的游戏名称 */ + @Excel(name = "免费局数赠送的游戏名称") + private String sendGame; + + /** 免费局数赠送的数量 */ + @Excel(name = "免费局数赠送的数量") + private Integer sendAmount; + + /** 已使用的免费局数数量 */ + @Excel(name = "已使用的免费局数数量") + private Integer usedAmount; + + /** 未使用的免费局数数量 */ + @Excel(name = "未使用的免费局数数量") + private Integer unusedAmount; + + /** 免费状态 1正常 0 取消 */ + @Excel(name = "免费状态 1正常 0 取消 ") + private Integer freeStatus; + + +} diff --git a/ff-admin/src/main/java/com/ff/game/domain/GamePlatform.java b/ff-admin/src/main/java/com/ff/game/domain/GamePlatform.java new file mode 100644 index 0000000..a24b3c1 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/domain/GamePlatform.java @@ -0,0 +1,54 @@ +package com.ff.game.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 平台管理对象 ff_game_platform + * + * @author shi + * @date 2025-02-10 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class GamePlatform extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 排序 */ + @Excel(name = "排序") + private Integer sortNo; + + /** 平台编码 */ + @Excel(name = "平台编码") + private String platformCode; + + /** 平台类型 ff_game_type 字典 */ + @Excel(name = "平台类型 ff_game_platform_type 字典") + private Long platformType; + + /** 平台名称 */ + @Excel(name = "平台名称") + private String platformName; + + /** 维护开关 维护状态 1 开启 2关闭 */ + @Excel(name = "维护开关 维护状态 1 开启 2关闭") + private Integer stopStatus; + + /** 平台开关 平台开关状态 1 开启 2关闭 */ + @Excel(name = "平台开关 平台开关状态 1 开启 2关闭") + private Integer platformStatus; + + + + +} diff --git a/ff-admin/src/main/java/com/ff/game/domain/GameSecretKey.java b/ff-admin/src/main/java/com/ff/game/domain/GameSecretKey.java new file mode 100644 index 0000000..9ea4ae6 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/domain/GameSecretKey.java @@ -0,0 +1,49 @@ +package com.ff.game.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.Data; +/** + * 游戏平台密钥管理对象 ff_game_secret_key + * + * @author shi + * @date 2025-02-10 + */ +@Data +public class GameSecretKey extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 平台 */ + @Excel(name = "平台") + private String platform; + + /** 代码 */ + @Excel(name = "代码") + private String code; + + /** 密钥 */ + @Excel(name = "密钥") + private String key; + + /** 系统代码 */ + @Excel(name = "系统代码") + private String systemCode; + + /** 语言 */ + @Excel(name = "语言") + private String lang; + + /** 系统语种id */ + @Excel(name = "系统语种id") + private String systemLangCode; + + /** 信息 */ + @Excel(name = "信息") + private String info; + + +} diff --git a/ff-admin/src/main/java/com/ff/game/mapper/GameBettingDetailsMapper.java b/ff-admin/src/main/java/com/ff/game/mapper/GameBettingDetailsMapper.java new file mode 100644 index 0000000..aa9bb9c --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/mapper/GameBettingDetailsMapper.java @@ -0,0 +1,61 @@ +package com.ff.game.mapper; + +import java.util.List; +import com.ff.game.domain.GameBettingDetails; + +/** + * 会员投注细目Mapper接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface GameBettingDetailsMapper +{ + /** + * 查询会员投注细目 + * + * @param id 会员投注细目主键 + * @return 会员投注细目 + */ + GameBettingDetails selectGameBettingDetailsById(Long id); + + /** + * 查询会员投注细目列表 + * + * @param gameBettingDetails 会员投注细目 + * @return 会员投注细目集合 + */ + List selectGameBettingDetailsList(GameBettingDetails gameBettingDetails); + + /** + * 新增会员投注细目 + * + * @param gameBettingDetails 会员投注细目 + * @return 结果 + */ + int insertGameBettingDetails(GameBettingDetails gameBettingDetails); + + /** + * 修改会员投注细目 + * + * @param gameBettingDetails 会员投注细目 + * @return 结果 + */ + int updateGameBettingDetails(GameBettingDetails gameBettingDetails); + + /** + * 删除会员投注细目 + * + * @param id 会员投注细目主键 + * @return 结果 + */ + int deleteGameBettingDetailsById(Long id); + + /** + * 批量删除会员投注细目 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteGameBettingDetailsByIds(Long[] ids); +} diff --git a/ff-admin/src/main/java/com/ff/game/mapper/GameExchangeMoneyMapper.java b/ff-admin/src/main/java/com/ff/game/mapper/GameExchangeMoneyMapper.java new file mode 100644 index 0000000..089132c --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/mapper/GameExchangeMoneyMapper.java @@ -0,0 +1,61 @@ +package com.ff.game.mapper; + +import java.util.List; +import com.ff.game.domain.GameExchangeMoney; + +/** + * 会员金额转移记录Mapper接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface GameExchangeMoneyMapper +{ + /** + * 查询会员金额转移记录 + * + * @param id 会员金额转移记录主键 + * @return 会员金额转移记录 + */ + GameExchangeMoney selectGameExchangeMoneyById(Long id); + + /** + * 查询会员金额转移记录列表 + * + * @param gameExchangeMoney 会员金额转移记录 + * @return 会员金额转移记录集合 + */ + List selectGameExchangeMoneyList(GameExchangeMoney gameExchangeMoney); + + /** + * 新增会员金额转移记录 + * + * @param gameExchangeMoney 会员金额转移记录 + * @return 结果 + */ + int insertGameExchangeMoney(GameExchangeMoney gameExchangeMoney); + + /** + * 修改会员金额转移记录 + * + * @param gameExchangeMoney 会员金额转移记录 + * @return 结果 + */ + int updateGameExchangeMoney(GameExchangeMoney gameExchangeMoney); + + /** + * 删除会员金额转移记录 + * + * @param id 会员金额转移记录主键 + * @return 结果 + */ + int deleteGameExchangeMoneyById(Long id); + + /** + * 批量删除会员金额转移记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteGameExchangeMoneyByIds(Long[] ids); +} diff --git a/ff-admin/src/main/java/com/ff/game/mapper/GameFreeRecordMapper.java b/ff-admin/src/main/java/com/ff/game/mapper/GameFreeRecordMapper.java new file mode 100644 index 0000000..63a5d78 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/mapper/GameFreeRecordMapper.java @@ -0,0 +1,61 @@ +package com.ff.game.mapper; + +import java.util.List; +import com.ff.game.domain.GameFreeRecord; + +/** + * 免费赠送游戏记录Mapper接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface GameFreeRecordMapper +{ + /** + * 查询免费赠送游戏记录 + * + * @param id 免费赠送游戏记录主键 + * @return 免费赠送游戏记录 + */ + GameFreeRecord selectGameFreeRecordById(Long id); + + /** + * 查询免费赠送游戏记录列表 + * + * @param gameFreeRecord 免费赠送游戏记录 + * @return 免费赠送游戏记录集合 + */ + List selectGameFreeRecordList(GameFreeRecord gameFreeRecord); + + /** + * 新增免费赠送游戏记录 + * + * @param gameFreeRecord 免费赠送游戏记录 + * @return 结果 + */ + int insertGameFreeRecord(GameFreeRecord gameFreeRecord); + + /** + * 修改免费赠送游戏记录 + * + * @param gameFreeRecord 免费赠送游戏记录 + * @return 结果 + */ + int updateGameFreeRecord(GameFreeRecord gameFreeRecord); + + /** + * 删除免费赠送游戏记录 + * + * @param id 免费赠送游戏记录主键 + * @return 结果 + */ + int deleteGameFreeRecordById(Long id); + + /** + * 批量删除免费赠送游戏记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteGameFreeRecordByIds(Long[] ids); +} diff --git a/ff-admin/src/main/java/com/ff/game/mapper/GameMapper.java b/ff-admin/src/main/java/com/ff/game/mapper/GameMapper.java new file mode 100644 index 0000000..c843375 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/mapper/GameMapper.java @@ -0,0 +1,82 @@ +package com.ff.game.mapper; + +import java.util.List; + +import com.ff.game.api.request.GameUniqueDTO; +import com.ff.game.domain.Game; + +/** + * 平台子游戏管理Mapper接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface GameMapper +{ + /** + * 查询平台子游戏管理 + * + * @param id 平台子游戏管理主键 + * @return 平台子游戏管理 + */ + Game selectGameById(Long id); + + /** + * 查询平台子游戏管理列表 + * + * @param game 平台子游戏管理 + * @return 平台子游戏管理集合 + */ + List selectGameList(Game game); + + /** + * 新增平台子游戏管理 + * + * @param game 平台子游戏管理 + * @return 结果 + */ + int insertGame(Game game); + + /** + * 修改平台子游戏管理 + * + * @param game 平台子游戏管理 + * @return 结果 + */ + int updateGame(Game game); + + /** + * 删除平台子游戏管理 + * + * @param id 平台子游戏管理主键 + * @return 结果 + */ + int deleteGameById(Long id); + + /** + * 批量删除平台子游戏管理 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteGameByIds(Long[] ids); + + + /** + * 按平台id选择最大排序号 + * + * @param platformId 平台id + * @return {@link Integer } + */ + Integer selectMaxSortNoByPlatformId(Long platformId); + + + /** + * 选择游戏唯一列表 + * + * @param gameUniqueDTO 游戏独有dto + * @return {@link List }<{@link Game }> + */ + List selectGameUniqueList(GameUniqueDTO gameUniqueDTO); + +} diff --git a/ff-admin/src/main/java/com/ff/game/mapper/GamePlatformMapper.java b/ff-admin/src/main/java/com/ff/game/mapper/GamePlatformMapper.java new file mode 100644 index 0000000..e938093 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/mapper/GamePlatformMapper.java @@ -0,0 +1,70 @@ +package com.ff.game.mapper; + +import java.util.List; +import com.ff.game.domain.GamePlatform; + +/** + * 平台管理Mapper接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface GamePlatformMapper +{ + /** + * 查询平台管理 + * + * @param id 平台管理主键 + * @return 平台管理 + */ + GamePlatform selectGamePlatformById(Long id); + + /** + * 查询平台管理列表 + * + * @param gamePlatform 平台管理 + * @return 平台管理集合 + */ + List selectGamePlatformList(GamePlatform gamePlatform); + + /** + * 新增平台管理 + * + * @param gamePlatform 平台管理 + * @return 结果 + */ + int insertGamePlatform(GamePlatform gamePlatform); + + /** + * 修改平台管理 + * + * @param gamePlatform 平台管理 + * @return 结果 + */ + int updateGamePlatform(GamePlatform gamePlatform); + + /** + * 删除平台管理 + * + * @param id 平台管理主键 + * @return 结果 + */ + int deleteGamePlatformById(Long id); + + /** + * 批量删除平台管理 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteGamePlatformByIds(Long[] ids); + + + /** + * 选择最大排序号 + * + * @return {@link Integer } + */ + Integer selectMaxSortNo(); + +} diff --git a/ff-admin/src/main/java/com/ff/game/mapper/GameSecretKeyMapper.java b/ff-admin/src/main/java/com/ff/game/mapper/GameSecretKeyMapper.java new file mode 100644 index 0000000..1f88f31 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/mapper/GameSecretKeyMapper.java @@ -0,0 +1,90 @@ +package com.ff.game.mapper; + +import java.util.List; + +import com.ff.common.domain.TenantSecretKey; +import com.ff.game.domain.GameSecretKey; +import org.apache.ibatis.annotations.Param; + +/** + * 游戏平台密钥管理Mapper接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface GameSecretKeyMapper +{ + /** + * 查询游戏平台密钥管理 + * + * @param id 游戏平台密钥管理主键 + * @return 游戏平台密钥管理 + */ + GameSecretKey selectGameSecretKeyById(Long id); + + /** + * 查询游戏平台密钥管理列表 + * + * @param gameSecretKey 游戏平台密钥管理 + * @return 游戏平台密钥管理集合 + */ + List selectGameSecretKeyList(GameSecretKey gameSecretKey); + + /** + * 新增游戏平台密钥管理 + * + * @param gameSecretKey 游戏平台密钥管理 + * @return 结果 + */ + int insertGameSecretKey(GameSecretKey gameSecretKey); + + /** + * 修改游戏平台密钥管理 + * + * @param gameSecretKey 游戏平台密钥管理 + * @return 结果 + */ + int updateGameSecretKey(GameSecretKey gameSecretKey); + + /** + * 删除游戏平台密钥管理 + * + * @param id 游戏平台密钥管理主键 + * @return 结果 + */ + int deleteGameSecretKeyById(Long id); + + /** + * 批量删除游戏平台密钥管理 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteGameSecretKeyByIds(Long[] ids); + + /** + * 按代码查找系统 + * + * @param code 代码 + * @return {@link String } + */ + String findSystemByCode(@Param("code") String code, @Param("platform")String platform); + + /** + * 通过平台和系统代码查找密钥 + * + * @param platform 平台 + * @param systemCode 系统代码 + * @return {@link TenantSecretKey } + */ + GameSecretKey findSecretKeyByPlatformAndSystemCode(@Param("platform") String platform, @Param("systemCode") String systemCode); + + /** + * 按平台和系统查找lang代码 + * + * @param platform 平台 + * @param systemLangCode 系统语言代码 + * @return {@link GameSecretKey } + */ + GameSecretKey findByPlatformAndSystemLangCode(@Param("platform") String platform, @Param("systemLangCode") String systemLangCode); +} diff --git a/ff-admin/src/main/java/com/ff/game/service/IGameBettingDetailsService.java b/ff-admin/src/main/java/com/ff/game/service/IGameBettingDetailsService.java new file mode 100644 index 0000000..affec19 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/IGameBettingDetailsService.java @@ -0,0 +1,61 @@ +package com.ff.game.service; + +import java.util.List; +import com.ff.game.domain.GameBettingDetails; + +/** + * 会员投注细目Service接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface IGameBettingDetailsService +{ + /** + * 查询会员投注细目 + * + * @param id 会员投注细目主键 + * @return 会员投注细目 + */ + GameBettingDetails selectGameBettingDetailsById(Long id); + + /** + * 查询会员投注细目列表 + * + * @param gameBettingDetails 会员投注细目 + * @return 会员投注细目集合 + */ + List selectGameBettingDetailsList(GameBettingDetails gameBettingDetails); + + /** + * 新增会员投注细目 + * + * @param gameBettingDetails 会员投注细目 + * @return 结果 + */ + int insertGameBettingDetails(GameBettingDetails gameBettingDetails); + + /** + * 修改会员投注细目 + * + * @param gameBettingDetails 会员投注细目 + * @return 结果 + */ + int updateGameBettingDetails(GameBettingDetails gameBettingDetails); + + /** + * 批量删除会员投注细目 + * + * @param ids 需要删除的会员投注细目主键集合 + * @return 结果 + */ + int deleteGameBettingDetailsByIds(Long[] ids); + + /** + * 删除会员投注细目信息 + * + * @param id 会员投注细目主键 + * @return 结果 + */ + int deleteGameBettingDetailsById(Long id); +} diff --git a/ff-admin/src/main/java/com/ff/game/service/IGameExchangeMoneyService.java b/ff-admin/src/main/java/com/ff/game/service/IGameExchangeMoneyService.java new file mode 100644 index 0000000..b40b050 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/IGameExchangeMoneyService.java @@ -0,0 +1,61 @@ +package com.ff.game.service; + +import java.util.List; +import com.ff.game.domain.GameExchangeMoney; + +/** + * 会员金额转移记录Service接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface IGameExchangeMoneyService +{ + /** + * 查询会员金额转移记录 + * + * @param id 会员金额转移记录主键 + * @return 会员金额转移记录 + */ + GameExchangeMoney selectGameExchangeMoneyById(Long id); + + /** + * 查询会员金额转移记录列表 + * + * @param gameExchangeMoney 会员金额转移记录 + * @return 会员金额转移记录集合 + */ + List selectGameExchangeMoneyList(GameExchangeMoney gameExchangeMoney); + + /** + * 新增会员金额转移记录 + * + * @param gameExchangeMoney 会员金额转移记录 + * @return 结果 + */ + int insertGameExchangeMoney(GameExchangeMoney gameExchangeMoney); + + /** + * 修改会员金额转移记录 + * + * @param gameExchangeMoney 会员金额转移记录 + * @return 结果 + */ + int updateGameExchangeMoney(GameExchangeMoney gameExchangeMoney); + + /** + * 批量删除会员金额转移记录 + * + * @param ids 需要删除的会员金额转移记录主键集合 + * @return 结果 + */ + int deleteGameExchangeMoneyByIds(Long[] ids); + + /** + * 删除会员金额转移记录信息 + * + * @param id 会员金额转移记录主键 + * @return 结果 + */ + int deleteGameExchangeMoneyById(Long id); +} diff --git a/ff-admin/src/main/java/com/ff/game/service/IGameFreeRecordService.java b/ff-admin/src/main/java/com/ff/game/service/IGameFreeRecordService.java new file mode 100644 index 0000000..3c5f3b3 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/IGameFreeRecordService.java @@ -0,0 +1,61 @@ +package com.ff.game.service; + +import java.util.List; +import com.ff.game.domain.GameFreeRecord; + +/** + * 免费赠送游戏记录Service接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface IGameFreeRecordService +{ + /** + * 查询免费赠送游戏记录 + * + * @param id 免费赠送游戏记录主键 + * @return 免费赠送游戏记录 + */ + GameFreeRecord selectGameFreeRecordById(Long id); + + /** + * 查询免费赠送游戏记录列表 + * + * @param gameFreeRecord 免费赠送游戏记录 + * @return 免费赠送游戏记录集合 + */ + List selectGameFreeRecordList(GameFreeRecord gameFreeRecord); + + /** + * 新增免费赠送游戏记录 + * + * @param gameFreeRecord 免费赠送游戏记录 + * @return 结果 + */ + int insertGameFreeRecord(GameFreeRecord gameFreeRecord); + + /** + * 修改免费赠送游戏记录 + * + * @param gameFreeRecord 免费赠送游戏记录 + * @return 结果 + */ + int updateGameFreeRecord(GameFreeRecord gameFreeRecord); + + /** + * 批量删除免费赠送游戏记录 + * + * @param ids 需要删除的免费赠送游戏记录主键集合 + * @return 结果 + */ + int deleteGameFreeRecordByIds(Long[] ids); + + /** + * 删除免费赠送游戏记录信息 + * + * @param id 免费赠送游戏记录主键 + * @return 结果 + */ + int deleteGameFreeRecordById(Long id); +} diff --git a/ff-admin/src/main/java/com/ff/game/service/IGamePlatformService.java b/ff-admin/src/main/java/com/ff/game/service/IGamePlatformService.java new file mode 100644 index 0000000..a616d2a --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/IGamePlatformService.java @@ -0,0 +1,71 @@ +package com.ff.game.service; + +import java.util.List; +import com.ff.game.domain.GamePlatform; + +/** + * 平台管理Service接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface IGamePlatformService +{ + /** + * 查询平台管理 + * + * @param id 平台管理主键 + * @return 平台管理 + */ + GamePlatform selectGamePlatformById(Long id); + + /** + * 查询平台管理列表 + * + * @param gamePlatform 平台管理 + * @return 平台管理集合 + */ + List selectGamePlatformList(GamePlatform gamePlatform); + + /** + * 新增平台管理 + * + * @param gamePlatform 平台管理 + * @return 结果 + */ + int insertGamePlatform(GamePlatform gamePlatform); + + /** + * 修改平台管理 + * + * @param gamePlatform 平台管理 + * @return 结果 + */ + int updateGamePlatform(GamePlatform gamePlatform); + + /** + * 批量删除平台管理 + * + * @param ids 需要删除的平台管理主键集合 + * @return 结果 + */ + int deleteGamePlatformByIds(Long[] ids); + + /** + * 删除平台管理信息 + * + * @param id 平台管理主键 + * @return 结果 + */ + int deleteGamePlatformById(Long id); + + + /** + * 选择最大排序号 + * + * @return {@link Integer } + */ + Integer selectMaxSortNo(); + + +} diff --git a/ff-admin/src/main/java/com/ff/game/service/IGameSecretKeyService.java b/ff-admin/src/main/java/com/ff/game/service/IGameSecretKeyService.java new file mode 100644 index 0000000..2260294 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/IGameSecretKeyService.java @@ -0,0 +1,94 @@ +package com.ff.game.service; + +import java.util.List; + +import com.ff.common.domain.TenantSecretKey; +import com.ff.game.domain.GameSecretKey; + +/** + * 游戏平台密钥管理Service接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface IGameSecretKeyService +{ + /** + * 查询游戏平台密钥管理 + * + * @param id 游戏平台密钥管理主键 + * @return 游戏平台密钥管理 + */ + GameSecretKey selectGameSecretKeyById(Long id); + + /** + * 查询游戏平台密钥管理列表 + * + * @param gameSecretKey 游戏平台密钥管理 + * @return 游戏平台密钥管理集合 + */ + List selectGameSecretKeyList(GameSecretKey gameSecretKey); + + /** + * 新增游戏平台密钥管理 + * + * @param gameSecretKey 游戏平台密钥管理 + * @return 结果 + */ + int insertGameSecretKey(GameSecretKey gameSecretKey); + + /** + * 修改游戏平台密钥管理 + * + * @param gameSecretKey 游戏平台密钥管理 + * @return 结果 + */ + int updateGameSecretKey(GameSecretKey gameSecretKey); + + /** + * 批量删除游戏平台密钥管理 + * + * @param ids 需要删除的游戏平台密钥管理主键集合 + * @return 结果 + */ + int deleteGameSecretKeyByIds(Long[] ids); + + /** + * 删除游戏平台密钥管理信息 + * + * @param id 游戏平台密钥管理主键 + * @return 结果 + */ + int deleteGameSecretKeyById(Long id); + + + + /** + * 按代码查找系统 + * + * @param code 代码 + * @param platform 平台 + * @return {@link String } + */ + String findSystemByCode( String code,String platform); + + /** + * 通过平台和系统代码查找密钥 + * + * @param platform 平台 + * @param systemCode 系统代码 + * @return {@link GameSecretKey } + */ + GameSecretKey findSecretKeyByPlatformAndSystemCode(String platform, String systemCode); + + + /** + * 按平台和系统查找lang代码 + * + * @param platform 平台 + * @param systemLangCode 系统语言代码 + * @return {@link GameSecretKey } + */ + GameSecretKey findByPlatformAndSystemLangCode( String platform,String systemLangCode); + +} diff --git a/ff-admin/src/main/java/com/ff/game/service/IGameService.java b/ff-admin/src/main/java/com/ff/game/service/IGameService.java new file mode 100644 index 0000000..6ab7108 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/IGameService.java @@ -0,0 +1,81 @@ +package com.ff.game.service; + +import java.util.List; + +import com.ff.game.api.request.GameUniqueDTO; +import com.ff.game.domain.Game; + +/** + * 平台子游戏管理Service接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface IGameService +{ + /** + * 查询平台子游戏管理 + * + * @param id 平台子游戏管理主键 + * @return 平台子游戏管理 + */ + Game selectGameById(Long id); + + /** + * 查询平台子游戏管理列表 + * + * @param game 平台子游戏管理 + * @return 平台子游戏管理集合 + */ + List selectGameList(Game game); + + /** + * 新增平台子游戏管理 + * + * @param game 平台子游戏管理 + * @return 结果 + */ + int insertGame(Game game); + + /** + * 修改平台子游戏管理 + * + * @param game 平台子游戏管理 + * @return 结果 + */ + int updateGame(Game game); + + /** + * 批量删除平台子游戏管理 + * + * @param ids 需要删除的平台子游戏管理主键集合 + * @return 结果 + */ + int deleteGameByIds(Long[] ids); + + /** + * 删除平台子游戏管理信息 + * + * @param id 平台子游戏管理主键 + * @return 结果 + */ + int deleteGameById(Long id); + + /** + * 按平台id选择最大排序号 + * + * @param platformId 平台id + * @return {@link Integer } + */ + Integer selectMaxSortNoByPlatformId(Long platformId); + + /** + * 选择游戏唯一列表 + * + * @param gameUniqueDTO 游戏独有dto + * @return {@link List }<{@link Game }> + */ + List selectGameUniqueList(GameUniqueDTO gameUniqueDTO); + + +} diff --git a/ff-admin/src/main/java/com/ff/game/service/impl/GameBettingDetailsServiceImpl.java b/ff-admin/src/main/java/com/ff/game/service/impl/GameBettingDetailsServiceImpl.java new file mode 100644 index 0000000..23c1286 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/impl/GameBettingDetailsServiceImpl.java @@ -0,0 +1,96 @@ +package com.ff.game.service.impl; + +import java.util.List; +import com.ff.base.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.game.mapper.GameBettingDetailsMapper; +import com.ff.game.domain.GameBettingDetails; +import com.ff.game.service.IGameBettingDetailsService; + +/** + * 会员投注细目Service业务层处理 + * + * @author shi + * @date 2025-02-10 + */ +@Service +public class GameBettingDetailsServiceImpl implements IGameBettingDetailsService +{ + @Autowired + private GameBettingDetailsMapper gameBettingDetailsMapper; + + /** + * 查询会员投注细目 + * + * @param id 会员投注细目主键 + * @return 会员投注细目 + */ + @Override + public GameBettingDetails selectGameBettingDetailsById(Long id) + { + return gameBettingDetailsMapper.selectGameBettingDetailsById(id); + } + + /** + * 查询会员投注细目列表 + * + * @param gameBettingDetails 会员投注细目 + * @return 会员投注细目 + */ + @Override + public List selectGameBettingDetailsList(GameBettingDetails gameBettingDetails) + { + return gameBettingDetailsMapper.selectGameBettingDetailsList(gameBettingDetails); + } + + /** + * 新增会员投注细目 + * + * @param gameBettingDetails 会员投注细目 + * @return 结果 + */ + @Override + public int insertGameBettingDetails(GameBettingDetails gameBettingDetails) + { + gameBettingDetails.setCreateTime(DateUtils.getNowDate()); + return gameBettingDetailsMapper.insertGameBettingDetails(gameBettingDetails); + } + + /** + * 修改会员投注细目 + * + * @param gameBettingDetails 会员投注细目 + * @return 结果 + */ + @Override + public int updateGameBettingDetails(GameBettingDetails gameBettingDetails) + { + gameBettingDetails.setUpdateTime(DateUtils.getNowDate()); + return gameBettingDetailsMapper.updateGameBettingDetails(gameBettingDetails); + } + + /** + * 批量删除会员投注细目 + * + * @param ids 需要删除的会员投注细目主键 + * @return 结果 + */ + @Override + public int deleteGameBettingDetailsByIds(Long[] ids) + { + return gameBettingDetailsMapper.deleteGameBettingDetailsByIds(ids); + } + + /** + * 删除会员投注细目信息 + * + * @param id 会员投注细目主键 + * @return 结果 + */ + @Override + public int deleteGameBettingDetailsById(Long id) + { + return gameBettingDetailsMapper.deleteGameBettingDetailsById(id); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/service/impl/GameExchangeMoneyServiceImpl.java b/ff-admin/src/main/java/com/ff/game/service/impl/GameExchangeMoneyServiceImpl.java new file mode 100644 index 0000000..dc6559f --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/impl/GameExchangeMoneyServiceImpl.java @@ -0,0 +1,96 @@ +package com.ff.game.service.impl; + +import java.util.List; +import com.ff.base.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.game.mapper.GameExchangeMoneyMapper; +import com.ff.game.domain.GameExchangeMoney; +import com.ff.game.service.IGameExchangeMoneyService; + +/** + * 会员金额转移记录Service业务层处理 + * + * @author shi + * @date 2025-02-10 + */ +@Service +public class GameExchangeMoneyServiceImpl implements IGameExchangeMoneyService +{ + @Autowired + private GameExchangeMoneyMapper gameExchangeMoneyMapper; + + /** + * 查询会员金额转移记录 + * + * @param id 会员金额转移记录主键 + * @return 会员金额转移记录 + */ + @Override + public GameExchangeMoney selectGameExchangeMoneyById(Long id) + { + return gameExchangeMoneyMapper.selectGameExchangeMoneyById(id); + } + + /** + * 查询会员金额转移记录列表 + * + * @param gameExchangeMoney 会员金额转移记录 + * @return 会员金额转移记录 + */ + @Override + public List selectGameExchangeMoneyList(GameExchangeMoney gameExchangeMoney) + { + return gameExchangeMoneyMapper.selectGameExchangeMoneyList(gameExchangeMoney); + } + + /** + * 新增会员金额转移记录 + * + * @param gameExchangeMoney 会员金额转移记录 + * @return 结果 + */ + @Override + public int insertGameExchangeMoney(GameExchangeMoney gameExchangeMoney) + { + gameExchangeMoney.setCreateTime(DateUtils.getNowDate()); + return gameExchangeMoneyMapper.insertGameExchangeMoney(gameExchangeMoney); + } + + /** + * 修改会员金额转移记录 + * + * @param gameExchangeMoney 会员金额转移记录 + * @return 结果 + */ + @Override + public int updateGameExchangeMoney(GameExchangeMoney gameExchangeMoney) + { + gameExchangeMoney.setUpdateTime(DateUtils.getNowDate()); + return gameExchangeMoneyMapper.updateGameExchangeMoney(gameExchangeMoney); + } + + /** + * 批量删除会员金额转移记录 + * + * @param ids 需要删除的会员金额转移记录主键 + * @return 结果 + */ + @Override + public int deleteGameExchangeMoneyByIds(Long[] ids) + { + return gameExchangeMoneyMapper.deleteGameExchangeMoneyByIds(ids); + } + + /** + * 删除会员金额转移记录信息 + * + * @param id 会员金额转移记录主键 + * @return 结果 + */ + @Override + public int deleteGameExchangeMoneyById(Long id) + { + return gameExchangeMoneyMapper.deleteGameExchangeMoneyById(id); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/service/impl/GameFreeRecordServiceImpl.java b/ff-admin/src/main/java/com/ff/game/service/impl/GameFreeRecordServiceImpl.java new file mode 100644 index 0000000..039bc1e --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/impl/GameFreeRecordServiceImpl.java @@ -0,0 +1,96 @@ +package com.ff.game.service.impl; + +import java.util.List; +import com.ff.base.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.game.mapper.GameFreeRecordMapper; +import com.ff.game.domain.GameFreeRecord; +import com.ff.game.service.IGameFreeRecordService; + +/** + * 免费赠送游戏记录Service业务层处理 + * + * @author shi + * @date 2025-02-10 + */ +@Service +public class GameFreeRecordServiceImpl implements IGameFreeRecordService +{ + @Autowired + private GameFreeRecordMapper gameFreeRecordMapper; + + /** + * 查询免费赠送游戏记录 + * + * @param id 免费赠送游戏记录主键 + * @return 免费赠送游戏记录 + */ + @Override + public GameFreeRecord selectGameFreeRecordById(Long id) + { + return gameFreeRecordMapper.selectGameFreeRecordById(id); + } + + /** + * 查询免费赠送游戏记录列表 + * + * @param gameFreeRecord 免费赠送游戏记录 + * @return 免费赠送游戏记录 + */ + @Override + public List selectGameFreeRecordList(GameFreeRecord gameFreeRecord) + { + return gameFreeRecordMapper.selectGameFreeRecordList(gameFreeRecord); + } + + /** + * 新增免费赠送游戏记录 + * + * @param gameFreeRecord 免费赠送游戏记录 + * @return 结果 + */ + @Override + public int insertGameFreeRecord(GameFreeRecord gameFreeRecord) + { + gameFreeRecord.setCreateTime(DateUtils.getNowDate()); + return gameFreeRecordMapper.insertGameFreeRecord(gameFreeRecord); + } + + /** + * 修改免费赠送游戏记录 + * + * @param gameFreeRecord 免费赠送游戏记录 + * @return 结果 + */ + @Override + public int updateGameFreeRecord(GameFreeRecord gameFreeRecord) + { + gameFreeRecord.setUpdateTime(DateUtils.getNowDate()); + return gameFreeRecordMapper.updateGameFreeRecord(gameFreeRecord); + } + + /** + * 批量删除免费赠送游戏记录 + * + * @param ids 需要删除的免费赠送游戏记录主键 + * @return 结果 + */ + @Override + public int deleteGameFreeRecordByIds(Long[] ids) + { + return gameFreeRecordMapper.deleteGameFreeRecordByIds(ids); + } + + /** + * 删除免费赠送游戏记录信息 + * + * @param id 免费赠送游戏记录主键 + * @return 结果 + */ + @Override + public int deleteGameFreeRecordById(Long id) + { + return gameFreeRecordMapper.deleteGameFreeRecordById(id); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/service/impl/GamePlatformServiceImpl.java b/ff-admin/src/main/java/com/ff/game/service/impl/GamePlatformServiceImpl.java new file mode 100644 index 0000000..00471e3 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/impl/GamePlatformServiceImpl.java @@ -0,0 +1,108 @@ +package com.ff.game.service.impl; + +import java.util.List; +import com.ff.base.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.game.mapper.GamePlatformMapper; +import com.ff.game.domain.GamePlatform; +import com.ff.game.service.IGamePlatformService; + +/** + * 平台管理Service业务层处理 + * + * @author shi + * @date 2025-02-10 + */ +@Service +public class GamePlatformServiceImpl implements IGamePlatformService +{ + @Autowired + private GamePlatformMapper gamePlatformMapper; + + /** + * 查询平台管理 + * + * @param id 平台管理主键 + * @return 平台管理 + */ + @Override + public GamePlatform selectGamePlatformById(Long id) + { + return gamePlatformMapper.selectGamePlatformById(id); + } + + /** + * 查询平台管理列表 + * + * @param gamePlatform 平台管理 + * @return 平台管理 + */ + @Override + public List selectGamePlatformList(GamePlatform gamePlatform) + { + return gamePlatformMapper.selectGamePlatformList(gamePlatform); + } + + /** + * 新增平台管理 + * + * @param gamePlatform 平台管理 + * @return 结果 + */ + @Override + public int insertGamePlatform(GamePlatform gamePlatform) + { + gamePlatform.setCreateTime(DateUtils.getNowDate()); + return gamePlatformMapper.insertGamePlatform(gamePlatform); + } + + /** + * 修改平台管理 + * + * @param gamePlatform 平台管理 + * @return 结果 + */ + @Override + public int updateGamePlatform(GamePlatform gamePlatform) + { + gamePlatform.setUpdateTime(DateUtils.getNowDate()); + return gamePlatformMapper.updateGamePlatform(gamePlatform); + } + + /** + * 批量删除平台管理 + * + * @param ids 需要删除的平台管理主键 + * @return 结果 + */ + @Override + public int deleteGamePlatformByIds(Long[] ids) + { + return gamePlatformMapper.deleteGamePlatformByIds(ids); + } + + /** + * 删除平台管理信息 + * + * @param id 平台管理主键 + * @return 结果 + */ + @Override + public int deleteGamePlatformById(Long id) + { + return gamePlatformMapper.deleteGamePlatformById(id); + } + + + + /** + * 选择最大排序号 + * + * @return {@link Integer } + */ + @Override + public Integer selectMaxSortNo() { + return gamePlatformMapper.selectMaxSortNo(); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/service/impl/GameSecretKeyServiceImpl.java b/ff-admin/src/main/java/com/ff/game/service/impl/GameSecretKeyServiceImpl.java new file mode 100644 index 0000000..da84490 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/impl/GameSecretKeyServiceImpl.java @@ -0,0 +1,134 @@ +package com.ff.game.service.impl; + +import java.util.List; +import com.ff.base.utils.DateUtils; +import com.ff.common.domain.TenantSecretKey; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.game.mapper.GameSecretKeyMapper; +import com.ff.game.domain.GameSecretKey; +import com.ff.game.service.IGameSecretKeyService; + +/** + * 游戏平台密钥管理Service业务层处理 + * + * @author shi + * @date 2025-02-10 + */ +@Service +public class GameSecretKeyServiceImpl implements IGameSecretKeyService +{ + @Autowired + private GameSecretKeyMapper gameSecretKeyMapper; + + /** + * 查询游戏平台密钥管理 + * + * @param id 游戏平台密钥管理主键 + * @return 游戏平台密钥管理 + */ + @Override + public GameSecretKey selectGameSecretKeyById(Long id) + { + return gameSecretKeyMapper.selectGameSecretKeyById(id); + } + + /** + * 查询游戏平台密钥管理列表 + * + * @param gameSecretKey 游戏平台密钥管理 + * @return 游戏平台密钥管理 + */ + @Override + public List selectGameSecretKeyList(GameSecretKey gameSecretKey) + { + return gameSecretKeyMapper.selectGameSecretKeyList(gameSecretKey); + } + + /** + * 新增游戏平台密钥管理 + * + * @param gameSecretKey 游戏平台密钥管理 + * @return 结果 + */ + @Override + public int insertGameSecretKey(GameSecretKey gameSecretKey) + { + gameSecretKey.setCreateTime(DateUtils.getNowDate()); + return gameSecretKeyMapper.insertGameSecretKey(gameSecretKey); + } + + /** + * 修改游戏平台密钥管理 + * + * @param gameSecretKey 游戏平台密钥管理 + * @return 结果 + */ + @Override + public int updateGameSecretKey(GameSecretKey gameSecretKey) + { + gameSecretKey.setUpdateTime(DateUtils.getNowDate()); + return gameSecretKeyMapper.updateGameSecretKey(gameSecretKey); + } + + /** + * 批量删除游戏平台密钥管理 + * + * @param ids 需要删除的游戏平台密钥管理主键 + * @return 结果 + */ + @Override + public int deleteGameSecretKeyByIds(Long[] ids) + { + return gameSecretKeyMapper.deleteGameSecretKeyByIds(ids); + } + + /** + * 删除游戏平台密钥管理信息 + * + * @param id 游戏平台密钥管理主键 + * @return 结果 + */ + @Override + public int deleteGameSecretKeyById(Long id) + { + return gameSecretKeyMapper.deleteGameSecretKeyById(id); + } + + + /** + * 按代码查找系统 + * + * @param code 代码 + * @param platform 平台 + * @return {@link String } + */ + @Override + public String findSystemByCode(String code,String platform) { + return gameSecretKeyMapper.findSystemByCode(code,platform); + } + + /** + * 通过平台和系统代码查找密钥 + * + * @param platform 平台 + * @param systemCode 系统代码 + * @return {@link GameSecretKey } + */ + @Override + public GameSecretKey findSecretKeyByPlatformAndSystemCode(String platform, String systemCode) { + return gameSecretKeyMapper.findSecretKeyByPlatformAndSystemCode(platform,systemCode); + } + + /** + * 按平台和系统查找lang代码 + * + * @param platform 平台 + * @param systemLangCode 系统语言代码 + * @return {@link GameSecretKey } + */ + @Override + public GameSecretKey findByPlatformAndSystemLangCode(String platform, String systemLangCode) { + return gameSecretKeyMapper.findByPlatformAndSystemLangCode(platform,systemLangCode); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/service/impl/GameServiceImpl.java b/ff-admin/src/main/java/com/ff/game/service/impl/GameServiceImpl.java new file mode 100644 index 0000000..62c1a0b --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/impl/GameServiceImpl.java @@ -0,0 +1,132 @@ +package com.ff.game.service.impl; + +import java.util.List; + +import com.ff.base.constant.ConfigConstants; +import com.ff.base.utils.DateUtils; +import com.ff.game.api.request.GameUniqueDTO; +import com.ff.member.service.IMemberService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.game.mapper.GameMapper; +import com.ff.game.domain.Game; +import com.ff.game.service.IGameService; + +import javax.annotation.Resource; + +/** + * 平台子游戏管理Service业务层处理 + * + * @author shi + * @date 2025-02-10 + */ +@Service +public class GameServiceImpl implements IGameService +{ + @Autowired + private GameMapper gameMapper; + + @Resource + private IMemberService memberService; + + /** + * 查询平台子游戏管理 + * + * @param id 平台子游戏管理主键 + * @return 平台子游戏管理 + */ + @Override + public Game selectGameById(Long id) + { + return gameMapper.selectGameById(id); + } + + /** + * 查询平台子游戏管理列表 + * + * @param game 平台子游戏管理 + * @return 平台子游戏管理 + */ + @Override + public List selectGameList(Game game) + { + return gameMapper.selectGameList(game); + } + + /** + * 新增平台子游戏管理 + * + * @param game 平台子游戏管理 + * @return 结果 + */ + @Override + public int insertGame(Game game) + { + game.setCreateTime(DateUtils.getNowDate()); + return gameMapper.insertGame(game); + } + + /** + * 修改平台子游戏管理 + * + * @param game 平台子游戏管理 + * @return 结果 + */ + @Override + public int updateGame(Game game) + { + game.setUpdateTime(DateUtils.getNowDate()); + return gameMapper.updateGame(game); + } + + /** + * 批量删除平台子游戏管理 + * + * @param ids 需要删除的平台子游戏管理主键 + * @return 结果 + */ + @Override + public int deleteGameByIds(Long[] ids) + { + return gameMapper.deleteGameByIds(ids); + } + + /** + * 删除平台子游戏管理信息 + * + * @param id 平台子游戏管理主键 + * @return 结果 + */ + @Override + public int deleteGameById(Long id) + { + return gameMapper.deleteGameById(id); + } + + + /** + * 按平台id选择最大排序号 + * + * @param platformId 平台id + * @return {@link Integer } + */ + @Override + public Integer selectMaxSortNoByPlatformId(Long platformId) { + return gameMapper.selectMaxSortNoByPlatformId(platformId); + } + + + + /** + * 选择游戏唯一列表 + * + * @param gameUniqueDTO 游戏独有dto + * @return {@link List }<{@link Game }> + */ + @Override + public List selectGameUniqueList(GameUniqueDTO gameUniqueDTO) { + return gameMapper.selectGameUniqueList(gameUniqueDTO); + } + + +} diff --git a/ff-admin/src/main/java/com/ff/member/controller/MemberController.java b/ff-admin/src/main/java/com/ff/member/controller/MemberController.java new file mode 100644 index 0000000..03ff24a --- /dev/null +++ b/ff-admin/src/main/java/com/ff/member/controller/MemberController.java @@ -0,0 +1,104 @@ +package com.ff.member.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.member.domain.Member; +import com.ff.member.service.IMemberService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 会员Controller + * + * @author shi + * @date 2025-02-10 + */ +@RestController +@RequestMapping("/member/member") +public class MemberController extends BaseController +{ + @Autowired + private IMemberService memberService; + + /** + * 查询会员列表 + */ + @PreAuthorize("@ss.hasPermi('member:member:list')") + @GetMapping("/list") + public TableDataInfo list(Member member) + { + startPage(); + List list = memberService.selectMemberList(member); + return getDataTable(list); + } + + /** + * 导出会员列表 + */ + @PreAuthorize("@ss.hasPermi('member:member:export')") + @Log(title = "会员", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, Member member) + { + List list = memberService.selectMemberList(member); + ExcelUtil util = new ExcelUtil(Member.class); + util.exportExcel(response, list, "会员数据"); + } + + /** + * 获取会员详细信息 + */ + @PreAuthorize("@ss.hasPermi('member:member:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(memberService.selectMemberById(id)); + } + + /** + * 新增会员 + */ + @PreAuthorize("@ss.hasPermi('member:member:add')") + @Log(title = "会员", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody Member member) + { + return toAjax(memberService.insertMember(member)); + } + + /** + * 修改会员 + */ + @PreAuthorize("@ss.hasPermi('member:member:edit')") + @Log(title = "会员", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody Member member) + { + return toAjax(memberService.updateMember(member)); + } + + /** + * 删除会员 + */ + @PreAuthorize("@ss.hasPermi('member:member:remove')") + @Log(title = "会员", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(memberService.deleteMemberByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/member/domain/Member.java b/ff-admin/src/main/java/com/ff/member/domain/Member.java new file mode 100644 index 0000000..3f271a2 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/member/domain/Member.java @@ -0,0 +1,48 @@ +package com.ff.member.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 会员对象 ff_member + * + * @author shi + * @date 2025-02-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Member extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 租户key */ + @Excel(name = "租户key") + private String tenantKey; + + /** 会员账号 */ + @Excel(name = "会员账号") + private String memberAccount; + + /** 游戏账号 */ + @Excel(name = "游戏账号") + private String gameAccount; + + /** 平台编码 */ + @Excel(name = "平台编码") + private String platformCode; + + /** 币种编码 */ + @Excel(name = "币种编码") + private String currencyCode; + + +} diff --git a/ff-admin/src/main/java/com/ff/member/mapper/MemberMapper.java b/ff-admin/src/main/java/com/ff/member/mapper/MemberMapper.java new file mode 100644 index 0000000..59989ab --- /dev/null +++ b/ff-admin/src/main/java/com/ff/member/mapper/MemberMapper.java @@ -0,0 +1,79 @@ +package com.ff.member.mapper; + +import java.util.List; +import com.ff.member.domain.Member; + +/** + * 会员Mapper接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface MemberMapper +{ + /** + * 查询会员 + * + * @param id 会员主键 + * @return 会员 + */ + Member selectMemberById(Long id); + + /** + * 查询会员列表 + * + * @param member 会员 + * @return 会员集合 + */ + List selectMemberList(Member member); + + /** + * 新增会员 + * + * @param member 会员 + * @return 结果 + */ + int insertMember(Member member); + + /** + * 修改会员 + * + * @param member 会员 + * @return 结果 + */ + int updateMember(Member member); + + /** + * 删除会员 + * + * @param id 会员主键 + * @return 结果 + */ + int deleteMemberById(Long id); + + /** + * 批量删除会员 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteMemberByIds(Long[] ids); + + + /** + * 按成员帐户选择成员 + * + * @param memberAccount 会员帐户 + * @return {@link Member } + */ + Member selectMemberByMemberAccount(String memberAccount); + + + /** + * 按游戏帐户选择成员 + * + * @param gameAccount 游戏账号 + * @return {@link Member } + */ + Member selectMemberByGameAccount(String gameAccount); +} diff --git a/ff-admin/src/main/java/com/ff/member/service/IMemberService.java b/ff-admin/src/main/java/com/ff/member/service/IMemberService.java new file mode 100644 index 0000000..5a9e2ff --- /dev/null +++ b/ff-admin/src/main/java/com/ff/member/service/IMemberService.java @@ -0,0 +1,77 @@ +package com.ff.member.service; + +import java.util.List; +import com.ff.member.domain.Member; + +/** + * 会员Service接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface IMemberService +{ + /** + * 查询会员 + * + * @param id 会员主键 + * @return 会员 + */ + Member selectMemberById(Long id); + + /** + * 查询会员列表 + * + * @param member 会员 + * @return 会员集合 + */ + List selectMemberList(Member member); + + /** + * 新增会员 + * + * @param member 会员 + * @return 结果 + */ + int insertMember(Member member); + + /** + * 修改会员 + * + * @param member 会员 + * @return 结果 + */ + int updateMember(Member member); + + /** + * 批量删除会员 + * + * @param ids 需要删除的会员主键集合 + * @return 结果 + */ + int deleteMemberByIds(Long[] ids); + + /** + * 删除会员信息 + * + * @param id 会员主键 + * @return 结果 + */ + int deleteMemberById(Long id); + + /** + * 按成员帐户选择成员 + * + * @param memberAccount 会员帐户 + * @return {@link Member } + */ + Member selectMemberByMemberAccount(String memberAccount); + + /** + * 按游戏帐户选择成员 + * + * @param gameAccount 游戏账号 + * @return {@link Member } + */ + Member selectMemberByGameAccount(String gameAccount); +} diff --git a/ff-admin/src/main/java/com/ff/member/service/impl/MemberServiceImpl.java b/ff-admin/src/main/java/com/ff/member/service/impl/MemberServiceImpl.java new file mode 100644 index 0000000..c8985ad --- /dev/null +++ b/ff-admin/src/main/java/com/ff/member/service/impl/MemberServiceImpl.java @@ -0,0 +1,119 @@ +package com.ff.member.service.impl; + +import java.util.List; +import com.ff.base.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.member.mapper.MemberMapper; +import com.ff.member.domain.Member; +import com.ff.member.service.IMemberService; + +/** + * 会员Service业务层处理 + * + * @author shi + * @date 2025-02-10 + */ +@Service +public class MemberServiceImpl implements IMemberService +{ + @Autowired + private MemberMapper memberMapper; + + /** + * 查询会员 + * + * @param id 会员主键 + * @return 会员 + */ + @Override + public Member selectMemberById(Long id) + { + return memberMapper.selectMemberById(id); + } + + /** + * 查询会员列表 + * + * @param member 会员 + * @return 会员 + */ + @Override + public List selectMemberList(Member member) + { + return memberMapper.selectMemberList(member); + } + + /** + * 新增会员 + * + * @param member 会员 + * @return 结果 + */ + @Override + public int insertMember(Member member) + { + member.setCreateTime(DateUtils.getNowDate()); + return memberMapper.insertMember(member); + } + + /** + * 修改会员 + * + * @param member 会员 + * @return 结果 + */ + @Override + public int updateMember(Member member) + { + member.setUpdateTime(DateUtils.getNowDate()); + return memberMapper.updateMember(member); + } + + /** + * 批量删除会员 + * + * @param ids 需要删除的会员主键 + * @return 结果 + */ + @Override + public int deleteMemberByIds(Long[] ids) + { + return memberMapper.deleteMemberByIds(ids); + } + + /** + * 删除会员信息 + * + * @param id 会员主键 + * @return 结果 + */ + @Override + public int deleteMemberById(Long id) + { + return memberMapper.deleteMemberById(id); + } + + + /** + * 按成员帐户选择成员 + * + * @param memberAccount 会员帐户 + * @return {@link Member } + */ + @Override + public Member selectMemberByMemberAccount(String memberAccount) { + return memberMapper.selectMemberByMemberAccount(memberAccount); + } + + /** + * 按游戏帐户选择成员 + * + * @param gameAccount 游戏账号 + * @return {@link Member } + */ + @Override + public Member selectMemberByGameAccount(String gameAccount) { + return memberMapper.selectMemberByGameAccount(gameAccount); + } +} diff --git a/ff-admin/src/main/java/com/ff/monitor/SysLogininforController.java b/ff-admin/src/main/java/com/ff/monitor/SysLogininforController.java new file mode 100644 index 0000000..00954c7 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/monitor/SysLogininforController.java @@ -0,0 +1,78 @@ +package com.ff.monitor; + +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.web.service.SysPasswordService; +import com.ff.base.system.domain.SysLogininfor; +import com.ff.base.system.service.ISysLogininforService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 系统访问记录 + * + * @author ff + */ +@RestController +@RequestMapping("/monitor/logininfor") +public class SysLogininforController extends BaseController +{ + @Autowired + private ISysLogininforService logininforService; + + @Autowired + private SysPasswordService passwordService; + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:list')") + @GetMapping("/list") + public TableDataInfo list(SysLogininfor logininfor) + { + startPage(); + List list = logininforService.selectLogininforList(logininfor); + return getDataTable(list); + } + + @Log(title = "登录日志", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('monitor:logininfor:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysLogininfor logininfor) + { + List list = logininforService.selectLogininforList(logininfor); + ExcelUtil util = new ExcelUtil(SysLogininfor.class); + util.exportExcel(response, list, "登录日志"); + } + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')") + @Log(title = "登录日志", businessType = BusinessType.DELETE) + @DeleteMapping("/{infoIds}") + public AjaxResult remove(@PathVariable Long[] infoIds) + { + return toAjax(logininforService.deleteLogininforByIds(infoIds)); + } + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')") + @Log(title = "登录日志", businessType = BusinessType.CLEAN) + @DeleteMapping("/clean") + public AjaxResult clean() + { + logininforService.cleanLogininfor(); + return success(); + } + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:unlock')") + @Log(title = "账户解锁", businessType = BusinessType.OTHER) + @GetMapping("/unlock/{userName}") + public AjaxResult unlock(@PathVariable("userName") String userName) + { + passwordService.clearLoginRecordCache(userName); + return success(); + } +} diff --git a/ff-admin/src/main/java/com/ff/monitor/SysOperlogController.java b/ff-admin/src/main/java/com/ff/monitor/SysOperlogController.java new file mode 100644 index 0000000..dd08069 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/monitor/SysOperlogController.java @@ -0,0 +1,65 @@ +package com.ff.monitor; + +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.system.domain.SysOperLog; +import com.ff.base.system.service.ISysOperLogService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 操作日志记录 + * + * @author ff + */ +@RestController +@RequestMapping("/monitor/operlog") +public class SysOperlogController extends BaseController +{ + @Autowired + private ISysOperLogService operLogService; + + @PreAuthorize("@ss.hasPermi('monitor:operlog:list')") + @GetMapping("/list") + public TableDataInfo list(SysOperLog operLog) + { + startPage(); + List list = operLogService.selectOperLogList(operLog); + return getDataTable(list); + } + + @Log(title = "操作日志", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('monitor:operlog:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysOperLog operLog) + { + List list = operLogService.selectOperLogList(operLog); + ExcelUtil util = new ExcelUtil(SysOperLog.class); + util.exportExcel(response, list, "操作日志"); + } + + @Log(title = "操作日志", businessType = BusinessType.DELETE) + @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')") + @DeleteMapping("/{operIds}") + public AjaxResult remove(@PathVariable Long[] operIds) + { + return toAjax(operLogService.deleteOperLogByIds(operIds)); + } + + @Log(title = "操作日志", businessType = BusinessType.CLEAN) + @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')") + @DeleteMapping("/clean") + public AjaxResult clean() + { + operLogService.cleanOperLog(); + return success(); + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/config/ScheduleConfig.java b/ff-admin/src/main/java/com/ff/quartz/config/ScheduleConfig.java new file mode 100644 index 0000000..c56e1bc --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/config/ScheduleConfig.java @@ -0,0 +1,57 @@ +package com.ff.quartz.config;//package com.ff.quartz.config; +// +//import org.springframework.context.annotation.Bean; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.scheduling.quartz.SchedulerFactoryBean; +//import javax.sql.DataSource; +//import java.util.Properties; +// +///** +// * 定时任务配置(单机部署建议删除此类和qrtz数据库表,默认走内存会最高效) +// * +// * @author ff +// */ +//@Configuration +//public class ScheduleConfig +//{ +// @Bean +// public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) +// { +// SchedulerFactoryBean factory = new SchedulerFactoryBean(); +// factory.setDataSource(dataSource); +// +// // quartz参数 +// Properties prop = new Properties(); +// prop.put("org.quartz.scheduler.instanceName", "ffScheduler"); +// prop.put("org.quartz.scheduler.instanceId", "AUTO"); +// // 线程池配置 +// prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); +// prop.put("org.quartz.threadPool.threadCount", "20"); +// prop.put("org.quartz.threadPool.threadPriority", "5"); +// // JobStore配置 +// prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore"); +// // 集群配置 +// prop.put("org.quartz.jobStore.isClustered", "true"); +// prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); +// prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "10"); +// prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true"); +// +// // sqlserver 启用 +// // prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); +// prop.put("org.quartz.jobStore.misfireThreshold", "12000"); +// prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_"); +// factory.setQuartzProperties(prop); +// +// factory.setSchedulerName("ffScheduler"); +// // 延时启动 +// factory.setStartupDelay(1); +// factory.setApplicationContextSchedulerContextKey("applicationContextKey"); +// // 可选,QuartzScheduler +// // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 +// factory.setOverwriteExistingJobs(true); +// // 设置自动启动,默认为true +// factory.setAutoStartup(true); +// +// return factory; +// } +//} diff --git a/ff-admin/src/main/java/com/ff/quartz/controller/SysJobController.java b/ff-admin/src/main/java/com/ff/quartz/controller/SysJobController.java new file mode 100644 index 0000000..fe850b4 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/controller/SysJobController.java @@ -0,0 +1,179 @@ +package com.ff.quartz.controller; + +import com.ff.base.annotation.Log; +import com.ff.base.constant.Constants; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.exception.job.TaskException; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.quartz.domain.SysJob; +import com.ff.quartz.service.ISysJobService; +import com.ff.quartz.util.CronUtils; +import com.ff.quartz.util.ScheduleUtils; +import org.quartz.SchedulerException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 调度任务信息操作处理 + * + * @author ff + */ +@RestController +@RequestMapping("/monitor/job") +public class SysJobController extends BaseController +{ + @Autowired + private ISysJobService jobService; + + /** + * 查询定时任务列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:list')") + @GetMapping("/list") + public TableDataInfo list(SysJob sysJob) + { + startPage(); + List list = jobService.selectJobList(sysJob); + return getDataTable(list); + } + + /** + * 导出定时任务列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:export')") + @Log(title = "定时任务", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysJob sysJob) + { + List list = jobService.selectJobList(sysJob); + ExcelUtil util = new ExcelUtil(SysJob.class); + util.exportExcel(response, list, "定时任务"); + } + + /** + * 获取定时任务详细信息 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:query')") + @GetMapping(value = "/{jobId}") + public AjaxResult getInfo(@PathVariable("jobId") Long jobId) + { + return success(jobService.selectJobById(jobId)); + } + + /** + * 新增定时任务 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:add')") + @Log(title = "定时任务", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysJob job) throws SchedulerException, TaskException + { + if (!CronUtils.isValid(job.getCronExpression())) + { + return error("新增任务'" + job.getJobName() + "'失败,Cron表达式不正确"); + } + else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS })) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串存在违规"); + } + else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不在白名单内"); + } + job.setCreateBy(getUsername()); + return toAjax(jobService.insertJob(job)); + } + + /** + * 修改定时任务 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:edit')") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysJob job) throws SchedulerException, TaskException + { + if (!CronUtils.isValid(job.getCronExpression())) + { + return error("修改任务'" + job.getJobName() + "'失败,Cron表达式不正确"); + } + else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS })) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串存在违规"); + } + else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不在白名单内"); + } + job.setUpdateBy(getUsername()); + return toAjax(jobService.updateJob(job)); + } + + /** + * 定时任务状态修改 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysJob job) throws SchedulerException + { + SysJob newJob = jobService.selectJobById(job.getJobId()); + newJob.setStatus(job.getStatus()); + return toAjax(jobService.changeStatus(newJob)); + } + + /** + * 定时任务立即执行一次 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping("/run") + public AjaxResult run(@RequestBody SysJob job) throws SchedulerException + { + boolean result = jobService.run(job); + return result ? success() : error("任务不存在或已过期!"); + } + + /** + * 删除定时任务 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:remove')") + @Log(title = "定时任务", businessType = BusinessType.DELETE) + @DeleteMapping("/{jobIds}") + public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException + { + jobService.deleteJobByIds(jobIds); + return success(); + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/controller/SysJobLogController.java b/ff-admin/src/main/java/com/ff/quartz/controller/SysJobLogController.java new file mode 100644 index 0000000..2ea8a1e --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/controller/SysJobLogController.java @@ -0,0 +1,88 @@ +package com.ff.quartz.controller; + +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.quartz.domain.SysJobLog; +import com.ff.quartz.service.ISysJobLogService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 调度日志操作处理 + * + * @author ff + */ +@RestController +@RequestMapping("/monitor/jobLog") +public class SysJobLogController extends BaseController +{ + @Autowired + private ISysJobLogService jobLogService; + + /** + * 查询定时任务调度日志列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:list')") + @GetMapping("/list") + public TableDataInfo list(SysJobLog sysJobLog) + { + startPage(); + List list = jobLogService.selectJobLogList(sysJobLog); + return getDataTable(list); + } + + /** + * 导出定时任务调度日志列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:export')") + @Log(title = "任务调度日志", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysJobLog sysJobLog) + { + List list = jobLogService.selectJobLogList(sysJobLog); + ExcelUtil util = new ExcelUtil(SysJobLog.class); + util.exportExcel(response, list, "调度日志"); + } + + /** + * 根据调度编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:query')") + @GetMapping(value = "/{jobLogId}") + public AjaxResult getInfo(@PathVariable Long jobLogId) + { + return success(jobLogService.selectJobLogById(jobLogId)); + } + + + /** + * 删除定时任务调度日志 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:remove')") + @Log(title = "定时任务调度日志", businessType = BusinessType.DELETE) + @DeleteMapping("/{jobLogIds}") + public AjaxResult remove(@PathVariable Long[] jobLogIds) + { + return toAjax(jobLogService.deleteJobLogByIds(jobLogIds)); + } + + /** + * 清空定时任务调度日志 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:remove')") + @Log(title = "调度日志", businessType = BusinessType.CLEAN) + @DeleteMapping("/clean") + public AjaxResult clean() + { + jobLogService.cleanJobLog(); + return success(); + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/domain/SysJob.java b/ff-admin/src/main/java/com/ff/quartz/domain/SysJob.java new file mode 100644 index 0000000..7e8451b --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/domain/SysJob.java @@ -0,0 +1,172 @@ +package com.ff.quartz.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ff.base.annotation.Excel; +import com.ff.base.annotation.Excel.ColumnType; +import com.ff.base.constant.ScheduleConstants; +import com.ff.base.core.domain.BaseEntity; +import com.ff.base.utils.StringUtils; +import com.ff.quartz.util.CronUtils; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.util.Date; + +/** + * 定时任务调度表 sys_job + * + * @author ff + */ +public class SysJob extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 任务ID */ + @Excel(name = "任务序号", cellType = ColumnType.NUMERIC) + private Long jobId; + + /** 任务名称 */ + @Excel(name = "任务名称") + private String jobName; + + /** 任务组名 */ + @Excel(name = "任务组名") + private String jobGroup; + + /** 调用目标字符串 */ + @Excel(name = "调用目标字符串") + private String invokeTarget; + + /** cron执行表达式 */ + @Excel(name = "执行表达式 ") + private String cronExpression; + + /** cron计划策略 */ + @Excel(name = "计划策略 ", readConverterExp = "0=默认,1=立即触发执行,2=触发一次执行,3=不触发立即执行") + private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT; + + /** 是否并发执行(0允许 1禁止) */ + @Excel(name = "并发执行", readConverterExp = "0=允许,1=禁止") + private String concurrent; + + /** 任务状态(0正常 1暂停) */ + @Excel(name = "任务状态", readConverterExp = "0=正常,1=暂停") + private String status; + + public Long getJobId() + { + return jobId; + } + + public void setJobId(Long jobId) + { + this.jobId = jobId; + } + + @NotBlank(message = "任务名称不能为空") + @Size(min = 0, max = 64, message = "任务名称不能超过64个字符") + public String getJobName() + { + return jobName; + } + + public void setJobName(String jobName) + { + this.jobName = jobName; + } + + public String getJobGroup() + { + return jobGroup; + } + + public void setJobGroup(String jobGroup) + { + this.jobGroup = jobGroup; + } + + @NotBlank(message = "调用目标字符串不能为空") + @Size(min = 0, max = 500, message = "调用目标字符串长度不能超过500个字符") + public String getInvokeTarget() + { + return invokeTarget; + } + + public void setInvokeTarget(String invokeTarget) + { + this.invokeTarget = invokeTarget; + } + + @NotBlank(message = "Cron执行表达式不能为空") + @Size(min = 0, max = 255, message = "Cron执行表达式不能超过255个字符") + public String getCronExpression() + { + return cronExpression; + } + + public void setCronExpression(String cronExpression) + { + this.cronExpression = cronExpression; + } + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + public Date getNextValidTime() + { + if (StringUtils.isNotEmpty(cronExpression)) + { + return CronUtils.getNextExecution(cronExpression); + } + return null; + } + + public String getMisfirePolicy() + { + return misfirePolicy; + } + + public void setMisfirePolicy(String misfirePolicy) + { + this.misfirePolicy = misfirePolicy; + } + + public String getConcurrent() + { + return concurrent; + } + + public void setConcurrent(String concurrent) + { + this.concurrent = concurrent; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("jobId", getJobId()) + .append("jobName", getJobName()) + .append("jobGroup", getJobGroup()) + .append("cronExpression", getCronExpression()) + .append("nextValidTime", getNextValidTime()) + .append("misfirePolicy", getMisfirePolicy()) + .append("concurrent", getConcurrent()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/domain/SysJobLog.java b/ff-admin/src/main/java/com/ff/quartz/domain/SysJobLog.java new file mode 100644 index 0000000..cd08116 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/domain/SysJobLog.java @@ -0,0 +1,156 @@ +package com.ff.quartz.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; + +/** + * 定时任务调度日志表 sys_job_log + * + * @author ff + */ +public class SysJobLog extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** ID */ + @Excel(name = "日志序号") + private Long jobLogId; + + /** 任务名称 */ + @Excel(name = "任务名称") + private String jobName; + + /** 任务组名 */ + @Excel(name = "任务组名") + private String jobGroup; + + /** 调用目标字符串 */ + @Excel(name = "调用目标字符串") + private String invokeTarget; + + /** 日志信息 */ + @Excel(name = "日志信息") + private String jobMessage; + + /** 执行状态(0正常 1失败) */ + @Excel(name = "执行状态", readConverterExp = "0=正常,1=失败") + private String status; + + /** 异常信息 */ + @Excel(name = "异常信息") + private String exceptionInfo; + + /** 开始时间 */ + private Date startTime; + + /** 停止时间 */ + private Date stopTime; + + public Long getJobLogId() + { + return jobLogId; + } + + public void setJobLogId(Long jobLogId) + { + this.jobLogId = jobLogId; + } + + public String getJobName() + { + return jobName; + } + + public void setJobName(String jobName) + { + this.jobName = jobName; + } + + public String getJobGroup() + { + return jobGroup; + } + + public void setJobGroup(String jobGroup) + { + this.jobGroup = jobGroup; + } + + public String getInvokeTarget() + { + return invokeTarget; + } + + public void setInvokeTarget(String invokeTarget) + { + this.invokeTarget = invokeTarget; + } + + public String getJobMessage() + { + return jobMessage; + } + + public void setJobMessage(String jobMessage) + { + this.jobMessage = jobMessage; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getExceptionInfo() + { + return exceptionInfo; + } + + public void setExceptionInfo(String exceptionInfo) + { + this.exceptionInfo = exceptionInfo; + } + + public Date getStartTime() + { + return startTime; + } + + public void setStartTime(Date startTime) + { + this.startTime = startTime; + } + + public Date getStopTime() + { + return stopTime; + } + + public void setStopTime(Date stopTime) + { + this.stopTime = stopTime; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("jobLogId", getJobLogId()) + .append("jobName", getJobName()) + .append("jobGroup", getJobGroup()) + .append("jobMessage", getJobMessage()) + .append("status", getStatus()) + .append("exceptionInfo", getExceptionInfo()) + .append("startTime", getStartTime()) + .append("stopTime", getStopTime()) + .toString(); + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/mapper/SysJobLogMapper.java b/ff-admin/src/main/java/com/ff/quartz/mapper/SysJobLogMapper.java new file mode 100644 index 0000000..86c9fb4 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/mapper/SysJobLogMapper.java @@ -0,0 +1,65 @@ +package com.ff.quartz.mapper; + +import com.ff.quartz.domain.SysJobLog; + +import java.util.List; + +/** + * 调度任务日志信息 数据层 + * + * @author ff + */ +public interface SysJobLogMapper +{ + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + public List selectJobLogList(SysJobLog jobLog); + + /** + * 查询所有调度任务日志 + * + * @return 调度任务日志列表 + */ + public List selectJobLogAll(); + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + public SysJobLog selectJobLogById(Long jobLogId); + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + * @return 结果 + */ + public int insertJobLog(SysJobLog jobLog); + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的数据ID + * @return 结果 + */ + public int deleteJobLogByIds(Long[] logIds); + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + * @return 结果 + */ + public int deleteJobLogById(Long jobId); + + /** + * 清空任务日志 + */ + public void cleanJobLog(); +} diff --git a/ff-admin/src/main/java/com/ff/quartz/mapper/SysJobMapper.java b/ff-admin/src/main/java/com/ff/quartz/mapper/SysJobMapper.java new file mode 100644 index 0000000..3aac4d2 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/mapper/SysJobMapper.java @@ -0,0 +1,68 @@ +package com.ff.quartz.mapper; + +import com.ff.quartz.domain.SysJob; + +import java.util.List; + +/** + * 调度任务信息 数据层 + * + * @author ff + */ +public interface SysJobMapper +{ + /** + * 查询调度任务日志集合 + * + * @param job 调度信息 + * @return 操作日志集合 + */ + public List selectJobList(SysJob job); + + /** + * 查询所有调度任务 + * + * @return 调度任务列表 + */ + public List selectJobAll(); + + /** + * 通过调度ID查询调度任务信息 + * + * @param jobId 调度ID + * @return 角色对象信息 + */ + public SysJob selectJobById(Long jobId); + + /** + * 通过调度ID删除调度任务信息 + * + * @param jobId 调度ID + * @return 结果 + */ + public int deleteJobById(Long jobId); + + /** + * 批量删除调度任务信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteJobByIds(Long[] ids); + + /** + * 修改调度任务信息 + * + * @param job 调度任务信息 + * @return 结果 + */ + public int updateJob(SysJob job); + + /** + * 新增调度任务信息 + * + * @param job 调度任务信息 + * @return 结果 + */ + public int insertJob(SysJob job); +} diff --git a/ff-admin/src/main/java/com/ff/quartz/service/ISysJobLogService.java b/ff-admin/src/main/java/com/ff/quartz/service/ISysJobLogService.java new file mode 100644 index 0000000..fc43da0 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/service/ISysJobLogService.java @@ -0,0 +1,57 @@ +package com.ff.quartz.service; + +import com.ff.quartz.domain.SysJobLog; + +import java.util.List; + +/** + * 定时任务调度日志信息信息 服务层 + * + * @author ff + */ +public interface ISysJobLogService +{ + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + public List selectJobLogList(SysJobLog jobLog); + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + public SysJobLog selectJobLogById(Long jobLogId); + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + */ + public void addJobLog(SysJobLog jobLog); + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的日志ID + * @return 结果 + */ + public int deleteJobLogByIds(Long[] logIds); + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + * @return 结果 + */ + public int deleteJobLogById(Long jobId); + + /** + * 清空任务日志 + */ + public void cleanJobLog(); +} diff --git a/ff-admin/src/main/java/com/ff/quartz/service/ISysJobService.java b/ff-admin/src/main/java/com/ff/quartz/service/ISysJobService.java new file mode 100644 index 0000000..374d375 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/service/ISysJobService.java @@ -0,0 +1,103 @@ +package com.ff.quartz.service; + +import com.ff.base.exception.job.TaskException; +import com.ff.quartz.domain.SysJob; +import org.quartz.SchedulerException; + +import java.util.List; + +/** + * 定时任务调度信息信息 服务层 + * + * @author ff + */ +public interface ISysJobService +{ + /** + * 获取quartz调度器的计划任务 + * + * @param job 调度信息 + * @return 调度任务集合 + */ + public List selectJobList(SysJob job); + + /** + * 通过调度任务ID查询调度信息 + * + * @param jobId 调度任务ID + * @return 调度任务对象信息 + */ + public SysJob selectJobById(Long jobId); + + /** + * 暂停任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int pauseJob(SysJob job) throws SchedulerException; + + /** + * 恢复任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int resumeJob(SysJob job) throws SchedulerException; + + /** + * 删除任务后,所对应的trigger也将被删除 + * + * @param job 调度信息 + * @return 结果 + */ + public int deleteJob(SysJob job) throws SchedulerException; + + /** + * 批量删除调度信息 + * + * @param jobIds 需要删除的任务ID + * @return 结果 + */ + public void deleteJobByIds(Long[] jobIds) throws SchedulerException; + + /** + * 任务调度状态修改 + * + * @param job 调度信息 + * @return 结果 + */ + public int changeStatus(SysJob job) throws SchedulerException; + + /** + * 立即运行任务 + * + * @param job 调度信息 + * @return 结果 + */ + public boolean run(SysJob job) throws SchedulerException; + + /** + * 新增任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int insertJob(SysJob job) throws SchedulerException, TaskException; + + /** + * 更新任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int updateJob(SysJob job) throws SchedulerException, TaskException; + + /** + * 校验cron表达式是否有效 + * + * @param cronExpression 表达式 + * @return 结果 + */ + public boolean checkCronExpressionIsValid(String cronExpression); +} diff --git a/ff-admin/src/main/java/com/ff/quartz/service/impl/SysJobLogServiceImpl.java b/ff-admin/src/main/java/com/ff/quartz/service/impl/SysJobLogServiceImpl.java new file mode 100644 index 0000000..0b951ec --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/service/impl/SysJobLogServiceImpl.java @@ -0,0 +1,88 @@ +package com.ff.quartz.service.impl; + +import com.ff.quartz.domain.SysJobLog; +import com.ff.quartz.mapper.SysJobLogMapper; +import com.ff.quartz.service.ISysJobLogService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 定时任务调度日志信息 服务层 + * + * @author ff + */ +@Service +public class SysJobLogServiceImpl implements ISysJobLogService +{ + @Autowired + private SysJobLogMapper jobLogMapper; + + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + @Override + public List selectJobLogList(SysJobLog jobLog) + { + return jobLogMapper.selectJobLogList(jobLog); + } + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + @Override + public SysJobLog selectJobLogById(Long jobLogId) + { + return jobLogMapper.selectJobLogById(jobLogId); + } + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + */ + @Override + public void addJobLog(SysJobLog jobLog) + { + jobLogMapper.insertJobLog(jobLog); + } + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的数据ID + * @return 结果 + */ + @Override + public int deleteJobLogByIds(Long[] logIds) + { + return jobLogMapper.deleteJobLogByIds(logIds); + } + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + */ + @Override + public int deleteJobLogById(Long jobId) + { + return jobLogMapper.deleteJobLogById(jobId); + } + + /** + * 清空任务日志 + */ + @Override + public void cleanJobLog() + { + jobLogMapper.cleanJobLog(); + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/service/impl/SysJobServiceImpl.java b/ff-admin/src/main/java/com/ff/quartz/service/impl/SysJobServiceImpl.java new file mode 100644 index 0000000..5e14476 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/service/impl/SysJobServiceImpl.java @@ -0,0 +1,262 @@ +package com.ff.quartz.service.impl; + +import com.ff.base.constant.ScheduleConstants; +import com.ff.base.exception.job.TaskException; +import com.ff.quartz.domain.SysJob; +import com.ff.quartz.mapper.SysJobMapper; +import com.ff.quartz.service.ISysJobService; +import com.ff.quartz.util.CronUtils; +import com.ff.quartz.util.ScheduleUtils; +import org.quartz.JobDataMap; +import org.quartz.JobKey; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.PostConstruct; +import java.util.List; + +/** + * 定时任务调度信息 服务层 + * + * @author ff + */ +@Service +public class SysJobServiceImpl implements ISysJobService +{ + @Autowired + private Scheduler scheduler; + + @Autowired + private SysJobMapper jobMapper; + + /** + * 项目启动时,初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理(注:不能手动修改数据库ID和任务组名,否则会导致脏数据) + */ + @PostConstruct + public void init() throws SchedulerException, TaskException + { + scheduler.clear(); + List jobList = jobMapper.selectJobAll(); + for (SysJob job : jobList) + { + ScheduleUtils.createScheduleJob(scheduler, job); + } + } + + /** + * 获取quartz调度器的计划任务列表 + * + * @param job 调度信息 + * @return + */ + @Override + public List selectJobList(SysJob job) + { + return jobMapper.selectJobList(job); + } + + /** + * 通过调度任务ID查询调度信息 + * + * @param jobId 调度任务ID + * @return 调度任务对象信息 + */ + @Override + public SysJob selectJobById(Long jobId) + { + return jobMapper.selectJobById(jobId); + } + + /** + * 暂停任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int pauseJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 恢复任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int resumeJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + job.setStatus(ScheduleConstants.Status.NORMAL.getValue()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + scheduler.resumeJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 删除任务后,所对应的trigger也将被删除 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + int rows = jobMapper.deleteJobById(jobId); + if (rows > 0) + { + scheduler.deleteJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 批量删除调度信息 + * + * @param jobIds 需要删除的任务ID + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteJobByIds(Long[] jobIds) throws SchedulerException + { + for (Long jobId : jobIds) + { + SysJob job = jobMapper.selectJobById(jobId); + deleteJob(job); + } + } + + /** + * 任务调度状态修改 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int changeStatus(SysJob job) throws SchedulerException + { + int rows = 0; + String status = job.getStatus(); + if (ScheduleConstants.Status.NORMAL.getValue().equals(status)) + { + rows = resumeJob(job); + } + else if (ScheduleConstants.Status.PAUSE.getValue().equals(status)) + { + rows = pauseJob(job); + } + return rows; + } + + /** + * 立即运行任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean run(SysJob job) throws SchedulerException + { + boolean result = false; + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + SysJob properties = selectJobById(job.getJobId()); + // 参数 + JobDataMap dataMap = new JobDataMap(); + dataMap.put(ScheduleConstants.TASK_PROPERTIES, properties); + JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup); + if (scheduler.checkExists(jobKey)) + { + result = true; + scheduler.triggerJob(jobKey, dataMap); + } + return result; + } + + /** + * 新增任务 + * + * @param job 调度信息 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int insertJob(SysJob job) throws SchedulerException, TaskException + { + job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); + int rows = jobMapper.insertJob(job); + if (rows > 0) + { + ScheduleUtils.createScheduleJob(scheduler, job); + } + return rows; + } + + /** + * 更新任务的时间表达式 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int updateJob(SysJob job) throws SchedulerException, TaskException + { + SysJob properties = selectJobById(job.getJobId()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + updateSchedulerJob(job, properties.getJobGroup()); + } + return rows; + } + + /** + * 更新任务 + * + * @param job 任务对象 + * @param jobGroup 任务组名 + */ + public void updateSchedulerJob(SysJob job, String jobGroup) throws SchedulerException, TaskException + { + Long jobId = job.getJobId(); + // 判断是否存在 + JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup); + if (scheduler.checkExists(jobKey)) + { + // 防止创建时存在数据问题 先移除,然后在执行创建操作 + scheduler.deleteJob(jobKey); + } + ScheduleUtils.createScheduleJob(scheduler, job); + } + + /** + * 校验cron表达式是否有效 + * + * @param cronExpression 表达式 + * @return 结果 + */ + @Override + public boolean checkCronExpressionIsValid(String cronExpression) + { + return CronUtils.isValid(cronExpression); + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/task/RyTask.java b/ff-admin/src/main/java/com/ff/quartz/task/RyTask.java new file mode 100644 index 0000000..2253a81 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/task/RyTask.java @@ -0,0 +1,34 @@ +package com.ff.quartz.task; + +import com.ff.base.datasource.DynamicDataSourceContextHolder; +import com.ff.base.utils.StringUtils; +import org.springframework.stereotype.Component; + +import javax.sql.DataSource; +import java.util.Map; + +/** + * 定时任务调度测试 + * + * @author ff + */ +@Component("ryTask") +public class RyTask { + public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) { + System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i)); + } + + public void ryParams(String params) { + System.out.println("执行有参方法:" + params); + } + + public void ryNoParams() { + Map resolvedDataSources = DynamicDataSourceContextHolder.getAllDataSource(); + for (Map.Entry entry : resolvedDataSources.entrySet()) { + Object key = entry.getKey(); + // 设置数据源类型 + DynamicDataSourceContextHolder.setDataSourceType(key.toString()); + System.out.println("执行无参方法"); + } + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/util/AbstractQuartzJob.java b/ff-admin/src/main/java/com/ff/quartz/util/AbstractQuartzJob.java new file mode 100644 index 0000000..e53fcf7 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/util/AbstractQuartzJob.java @@ -0,0 +1,100 @@ +package com.ff.quartz.util; + +import com.ff.base.constant.Constants; +import com.ff.base.constant.ScheduleConstants; +import com.ff.base.datasource.DynamicDataSourceContextHolder; +import com.ff.base.utils.ExceptionUtil; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.bean.BeanUtils; +import com.ff.base.utils.spring.SpringUtils; +import com.ff.quartz.domain.SysJob; +import com.ff.quartz.domain.SysJobLog; +import com.ff.quartz.service.ISysJobLogService; +import org.quartz.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; + +import javax.sql.DataSource; +import java.util.Date; +import java.util.Map; + +/** + * 抽象quartz调用 + * + * @author ff + */ +public abstract class AbstractQuartzJob implements Job { + private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class); + + /** + * 线程本地变量 + */ + private static ThreadLocal threadLocal = new ThreadLocal<>(); + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + SysJob sysJob = new SysJob(); + BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES)); + try { + before(context, sysJob); + if (sysJob != null) { + doExecute(context, sysJob); + } + after(context, sysJob, null); + } catch (Exception e) { + log.error("任务执行异常 - :", e); + after(context, sysJob, e); + } + + } + + /** + * 执行前 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + */ + protected void before(JobExecutionContext context, SysJob sysJob) { + threadLocal.set(new Date()); + } + + /** + * 执行后 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + */ + protected void after(JobExecutionContext context, SysJob sysJob, Exception e) { + Date startTime = threadLocal.get(); + threadLocal.remove(); + + final SysJobLog sysJobLog = new SysJobLog(); + sysJobLog.setJobName(sysJob.getJobName()); + sysJobLog.setJobGroup(sysJob.getJobGroup()); + sysJobLog.setInvokeTarget(sysJob.getInvokeTarget()); + sysJobLog.setStartTime(startTime); + sysJobLog.setStopTime(new Date()); + long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime(); + sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒"); + if (e != null) { + sysJobLog.setStatus(Constants.FAIL); + String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000); + sysJobLog.setExceptionInfo(errorMsg); + } else { + sysJobLog.setStatus(Constants.SUCCESS); + } + + // 写入数据库当中 + SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog); + } + + /** + * 执行方法,由子类重载 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + * @throws Exception 执行过程中的异常 + */ + protected abstract void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception; +} diff --git a/ff-admin/src/main/java/com/ff/quartz/util/CronUtils.java b/ff-admin/src/main/java/com/ff/quartz/util/CronUtils.java new file mode 100644 index 0000000..d550083 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/util/CronUtils.java @@ -0,0 +1,64 @@ +package com.ff.quartz.util; + +import org.quartz.CronExpression; + +import java.text.ParseException; +import java.util.Date; + +/** + * cron表达式工具类 + * + * @author ff + * + */ +public class CronUtils +{ + /** + * 返回一个布尔值代表一个给定的Cron表达式的有效性 + * + * @param cronExpression Cron表达式 + * @return boolean 表达式是否有效 + */ + public static boolean isValid(String cronExpression) + { + return CronExpression.isValidExpression(cronExpression); + } + + /** + * 返回一个字符串值,表示该消息无效Cron表达式给出有效性 + * + * @param cronExpression Cron表达式 + * @return String 无效时返回表达式错误描述,如果有效返回null + */ + public static String getInvalidMessage(String cronExpression) + { + try + { + new CronExpression(cronExpression); + return null; + } + catch (ParseException pe) + { + return pe.getMessage(); + } + } + + /** + * 返回下一个执行时间根据给定的Cron表达式 + * + * @param cronExpression Cron表达式 + * @return Long 下次Cron表达式执行时间 + */ + public static Date getNextExecution(String cronExpression) + { + try + { + CronExpression cron = new CronExpression(cronExpression); + return cron.getNextValidTimeAfter(new Date(System.currentTimeMillis())); + } + catch (ParseException e) + { + throw new IllegalArgumentException(e.getMessage()); + } + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/util/JobInvokeUtil.java b/ff-admin/src/main/java/com/ff/quartz/util/JobInvokeUtil.java new file mode 100644 index 0000000..7403739 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/util/JobInvokeUtil.java @@ -0,0 +1,183 @@ +package com.ff.quartz.util; + +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.spring.SpringUtils; +import com.ff.quartz.domain.SysJob; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.List; + +/** + * 任务执行工具 + * + * @author ff + */ +public class JobInvokeUtil +{ + /** + * 执行方法 + * + * @param sysJob 系统任务 + */ + public static void invokeMethod(SysJob sysJob) throws Exception + { + String invokeTarget = sysJob.getInvokeTarget(); + String beanName = getBeanName(invokeTarget); + String methodName = getMethodName(invokeTarget); + List methodParams = getMethodParams(invokeTarget); + + if (!isValidClassName(beanName)) + { + Object bean = SpringUtils.getBean(beanName); + invokeMethod(bean, methodName, methodParams); + } + else + { + Object bean = Class.forName(beanName).getDeclaredConstructor().newInstance(); + invokeMethod(bean, methodName, methodParams); + } + } + + /** + * 调用任务方法 + * + * @param bean 目标对象 + * @param methodName 方法名称 + * @param methodParams 方法参数 + */ + private static void invokeMethod(Object bean, String methodName, List methodParams) + throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, + InvocationTargetException + { + if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0) + { + Method method = bean.getClass().getMethod(methodName, getMethodParamsType(methodParams)); + method.invoke(bean, getMethodParamsValue(methodParams)); + } + else + { + Method method = bean.getClass().getMethod(methodName); + method.invoke(bean); + } + } + + /** + * 校验是否为为class包名 + * + * @param invokeTarget 名称 + * @return true是 false否 + */ + public static boolean isValidClassName(String invokeTarget) + { + return StringUtils.countMatches(invokeTarget, ".") > 1; + } + + /** + * 获取bean名称 + * + * @param invokeTarget 目标字符串 + * @return bean名称 + */ + public static String getBeanName(String invokeTarget) + { + String beanName = StringUtils.substringBefore(invokeTarget, "("); + return StringUtils.substringBeforeLast(beanName, "."); + } + + /** + * 获取bean方法 + * + * @param invokeTarget 目标字符串 + * @return method方法 + */ + public static String getMethodName(String invokeTarget) + { + String methodName = StringUtils.substringBefore(invokeTarget, "("); + return StringUtils.substringAfterLast(methodName, "."); + } + + /** + * 获取method方法参数相关列表 + * + * @param invokeTarget 目标字符串 + * @return method方法相关参数列表 + */ + public static List getMethodParams(String invokeTarget) + { + String methodStr = StringUtils.substringBetween(invokeTarget, "(", ")"); + if (StringUtils.isEmpty(methodStr)) + { + return null; + } + String[] methodParams = methodStr.split(",(?=([^\"']*[\"'][^\"']*[\"'])*[^\"']*$)"); + List classs = new LinkedList<>(); + for (int i = 0; i < methodParams.length; i++) + { + String str = StringUtils.trimToEmpty(methodParams[i]); + // String字符串类型,以'或"开头 + if (StringUtils.startsWithAny(str, "'", "\"")) + { + classs.add(new Object[] { StringUtils.substring(str, 1, str.length() - 1), String.class }); + } + // boolean布尔类型,等于true或者false + else if ("true".equalsIgnoreCase(str) || "false".equalsIgnoreCase(str)) + { + classs.add(new Object[] { Boolean.valueOf(str), Boolean.class }); + } + // long长整形,以L结尾 + else if (StringUtils.endsWith(str, "L")) + { + classs.add(new Object[] { Long.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Long.class }); + } + // double浮点类型,以D结尾 + else if (StringUtils.endsWith(str, "D")) + { + classs.add(new Object[] { Double.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Double.class }); + } + // 其他类型归类为整形 + else + { + classs.add(new Object[] { Integer.valueOf(str), Integer.class }); + } + } + return classs; + } + + /** + * 获取参数类型 + * + * @param methodParams 参数相关列表 + * @return 参数类型列表 + */ + public static Class[] getMethodParamsType(List methodParams) + { + Class[] classs = new Class[methodParams.size()]; + int index = 0; + for (Object[] os : methodParams) + { + classs[index] = (Class) os[1]; + index++; + } + return classs; + } + + /** + * 获取参数值 + * + * @param methodParams 参数相关列表 + * @return 参数值列表 + */ + public static Object[] getMethodParamsValue(List methodParams) + { + Object[] classs = new Object[methodParams.size()]; + int index = 0; + for (Object[] os : methodParams) + { + classs[index] = (Object) os[0]; + index++; + } + return classs; + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/util/QuartzDisallowConcurrentExecution.java b/ff-admin/src/main/java/com/ff/quartz/util/QuartzDisallowConcurrentExecution.java new file mode 100644 index 0000000..5ec7ff5 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/util/QuartzDisallowConcurrentExecution.java @@ -0,0 +1,23 @@ +package com.ff.quartz.util; + +import com.ff.quartz.domain.SysJob; +import com.ff.quartz.util.AbstractQuartzJob; +import com.ff.quartz.util.JobInvokeUtil; +import org.quartz.DisallowConcurrentExecution; +import org.quartz.JobExecutionContext; + +/** + * 定时任务处理(禁止并发执行) + * + * @author ff + * + */ +@DisallowConcurrentExecution +public class QuartzDisallowConcurrentExecution extends AbstractQuartzJob +{ + @Override + protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception + { + JobInvokeUtil.invokeMethod(sysJob); + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/util/QuartzJobExecution.java b/ff-admin/src/main/java/com/ff/quartz/util/QuartzJobExecution.java new file mode 100644 index 0000000..18f99f8 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/util/QuartzJobExecution.java @@ -0,0 +1,21 @@ +package com.ff.quartz.util; + +import com.ff.quartz.domain.SysJob; +import com.ff.quartz.util.AbstractQuartzJob; +import com.ff.quartz.util.JobInvokeUtil; +import org.quartz.JobExecutionContext; + +/** + * 定时任务处理(允许并发执行) + * + * @author ff + * + */ +public class QuartzJobExecution extends AbstractQuartzJob +{ + @Override + protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception + { + JobInvokeUtil.invokeMethod(sysJob); + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/util/ScheduleUtils.java b/ff-admin/src/main/java/com/ff/quartz/util/ScheduleUtils.java new file mode 100644 index 0000000..6a966b8 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/util/ScheduleUtils.java @@ -0,0 +1,132 @@ +package com.ff.quartz.util; + +import com.ff.base.constant.Constants; +import com.ff.base.constant.ScheduleConstants; +import com.ff.base.exception.job.TaskException; +import com.ff.base.exception.job.TaskException.Code; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.spring.SpringUtils; +import com.ff.quartz.domain.SysJob; +import org.quartz.*; + +/** + * 定时任务工具类 + * + * @author ff + * + */ +public class ScheduleUtils +{ + /** + * 得到quartz任务类 + * + * @param sysJob 执行计划 + * @return 具体执行任务类 + */ + private static Class getQuartzJobClass(SysJob sysJob) + { + boolean isConcurrent = "0".equals(sysJob.getConcurrent()); + return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class; + } + + /** + * 构建任务触发对象 + */ + public static TriggerKey getTriggerKey(Long jobId, String jobGroup) + { + return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); + } + + /** + * 构建任务键对象 + */ + public static JobKey getJobKey(Long jobId, String jobGroup) + { + return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); + } + + /** + * 创建定时任务 + */ + public static void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException + { + Class jobClass = getQuartzJobClass(job); + // 构建job信息 + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(jobId, jobGroup)).build(); + + // 表达式调度构建器 + CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); + cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder); + + // 按新的cronExpression表达式构建一个新的trigger + CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup)) + .withSchedule(cronScheduleBuilder).build(); + + // 放入参数,运行时的方法可以获取 + jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job); + + // 判断是否存在 + if (scheduler.checkExists(getJobKey(jobId, jobGroup))) + { + // 防止创建时存在数据问题 先移除,然后在执行创建操作 + scheduler.deleteJob(getJobKey(jobId, jobGroup)); + } + + // 判断任务是否过期 + if (StringUtils.isNotNull(CronUtils.getNextExecution(job.getCronExpression()))) + { + // 执行调度任务 + scheduler.scheduleJob(jobDetail, trigger); + } + + // 暂停任务 + if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) + { + scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + } + + /** + * 设置定时任务策略 + */ + public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb) + throws TaskException + { + switch (job.getMisfirePolicy()) + { + case ScheduleConstants.MISFIRE_DEFAULT: + return cb; + case ScheduleConstants.MISFIRE_IGNORE_MISFIRES: + return cb.withMisfireHandlingInstructionIgnoreMisfires(); + case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED: + return cb.withMisfireHandlingInstructionFireAndProceed(); + case ScheduleConstants.MISFIRE_DO_NOTHING: + return cb.withMisfireHandlingInstructionDoNothing(); + default: + throw new TaskException("The task misfire policy '" + job.getMisfirePolicy() + + "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR); + } + } + + /** + * 检查包名是否为白名单配置 + * + * @param invokeTarget 目标字符串 + * @return 结果 + */ + public static boolean whiteList(String invokeTarget) + { + String packageName = StringUtils.substringBefore(invokeTarget, "("); + int count = StringUtils.countMatches(packageName, "."); + if (count > 1) + { + return StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR); + } + Object obj = SpringUtils.getBean(StringUtils.split(invokeTarget, ".")[0]); + String beanPackageName = obj.getClass().getPackage().getName(); + return StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_WHITELIST_STR) + && !StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_ERROR_STR); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysConfigController.java b/ff-admin/src/main/java/com/ff/system/SysConfigController.java new file mode 100644 index 0000000..94311f2 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysConfigController.java @@ -0,0 +1,129 @@ +package com.ff.system; + +import com.ff.base.annotation.Anonymous; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.system.domain.SysConfig; +import com.ff.base.system.service.ISysConfigService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 参数配置 信息操作处理 + * + * @author ff + */ +@RestController +@RequestMapping("/system/config") +public class SysConfigController extends BaseController +{ + @Autowired + private ISysConfigService configService; + + /** + * 获取参数配置列表 + */ + @PreAuthorize("@ss.hasPermi('system:config:list')") + @GetMapping("/list") + public TableDataInfo list(SysConfig config) + { + startPage(); + List list = configService.selectConfigList(config); + return getDataTable(list); + } + + @Log(title = "参数管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:config:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysConfig config) + { + List list = configService.selectConfigList(config); + ExcelUtil util = new ExcelUtil(SysConfig.class); + util.exportExcel(response, list, "参数数据"); + } + + /** + * 根据参数编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:config:query')") + @GetMapping(value = "/{configId}") + public AjaxResult getInfo(@PathVariable Long configId) + { + return success(configService.selectConfigById(configId)); + } + + /** + * 根据参数键名查询参数值 + */ + @Anonymous + @GetMapping(value = "/configKey/{configKey}") + public AjaxResult getConfigKey(@PathVariable String configKey) + { + return success(configService.selectConfigByKey(configKey)); + } + + /** + * 新增参数配置 + */ + @PreAuthorize("@ss.hasPermi('system:config:add')") + @Log(title = "参数管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysConfig config) + { + if (!configService.checkConfigKeyUnique(config)) + { + return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在"); + } + config.setCreateBy(getUsername()); + return toAjax(configService.insertConfig(config)); + } + + /** + * 修改参数配置 + */ + @PreAuthorize("@ss.hasPermi('system:config:edit')") + @Log(title = "参数管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysConfig config) + { + if (!configService.checkConfigKeyUnique(config)) + { + return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在"); + } + config.setUpdateBy(getUsername()); + return toAjax(configService.updateConfig(config)); + } + + /** + * 删除参数配置 + */ + @PreAuthorize("@ss.hasPermi('system:config:remove')") + @Log(title = "参数管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{configIds}") + public AjaxResult remove(@PathVariable Long[] configIds) + { + configService.deleteConfigByIds(configIds); + return success(); + } + + /** + * 刷新参数缓存 + */ + @PreAuthorize("@ss.hasPermi('system:config:remove')") + @Log(title = "参数管理", businessType = BusinessType.CLEAN) + @DeleteMapping("/refreshCache") + public AjaxResult refreshCache() + { + configService.resetConfigCache(); + return success(); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysDatasourceController.java b/ff-admin/src/main/java/com/ff/system/SysDatasourceController.java new file mode 100644 index 0000000..0372b26 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysDatasourceController.java @@ -0,0 +1,105 @@ +package com.ff.system; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.ff.base.system.domain.SysDatasource; +import com.ff.base.system.service.ISysDatasourceService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 租户数据源Controller + * + * @author liukang + * @date 2024-11-20 + */ +@RestController +@RequestMapping("/system/datasource") +public class SysDatasourceController extends BaseController +{ + @Autowired + private ISysDatasourceService sysDatasourceService; + + /** + * 查询租户数据源列表 + */ + @PreAuthorize("@ss.hasPermi('system:datasource:list')") + @GetMapping("/list") + public TableDataInfo list(SysDatasource sysDatasource) + { + startPage(); + List list = sysDatasourceService.selectSysDatasourceList(sysDatasource); + return getDataTable(list); + } + + /** + * 导出租户数据源列表 + */ + @PreAuthorize("@ss.hasPermi('system:datasource:export')") + @Log(title = "租户数据源", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysDatasource sysDatasource) + { + List list = sysDatasourceService.selectSysDatasourceList(sysDatasource); + ExcelUtil util = new ExcelUtil(SysDatasource.class); + util.exportExcel(response, list, "租户数据源数据"); + } + + /** + * 获取租户数据源详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:datasource:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(sysDatasourceService.selectSysDatasourceById(id)); + } + + /** + * 新增租户数据源 + */ + @PreAuthorize("@ss.hasPermi('system:datasource:add')") + @Log(title = "租户数据源", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysDatasource sysDatasource) + { + return toAjax(sysDatasourceService.insertSysDatasource(sysDatasource)); + } + + /** + * 修改租户数据源 + */ + @PreAuthorize("@ss.hasPermi('system:datasource:edit')") + @Log(title = "租户数据源", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysDatasource sysDatasource) + { + return toAjax(sysDatasourceService.updateSysDatasource(sysDatasource)); + } + + /** + * 删除租户数据源 + */ + @PreAuthorize("@ss.hasPermi('system:datasource:remove')") + @Log(title = "租户数据源", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(sysDatasourceService.deleteSysDatasourceByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysDeptController.java b/ff-admin/src/main/java/com/ff/system/SysDeptController.java new file mode 100644 index 0000000..9438ab4 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysDeptController.java @@ -0,0 +1,126 @@ +package com.ff.system; + +import com.ff.base.annotation.Log; +import com.ff.base.constant.UserConstants; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.system.domain.SysDept; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.StringUtils; +import com.ff.base.system.service.ISysDeptService; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 部门信息 + * + * @author ff + */ +@RestController +@RequestMapping("/system/dept") +public class SysDeptController extends BaseController +{ + @Autowired + private ISysDeptService deptService; + + /** + * 获取部门列表 + */ + @PreAuthorize("@ss.hasPermi('system:dept:list')") + @GetMapping("/list") + public AjaxResult list(SysDept dept) + { + List depts = deptService.selectDeptList(dept); + return success(depts); + } + + /** + * 查询部门列表(排除节点) + */ + @PreAuthorize("@ss.hasPermi('system:dept:list')") + @GetMapping("/list/exclude/{deptId}") + public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) + { + List depts = deptService.selectDeptList(new SysDept()); + depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + "")); + return success(depts); + } + + /** + * 根据部门编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:dept:query')") + @GetMapping(value = "/{deptId}") + public AjaxResult getInfo(@PathVariable Long deptId) + { + deptService.checkDeptDataScope(deptId); + return success(deptService.selectDeptById(deptId)); + } + + /** + * 新增部门 + */ + @PreAuthorize("@ss.hasPermi('system:dept:add')") + @Log(title = "部门管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDept dept) + { + if (!deptService.checkDeptNameUnique(dept)) + { + return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在"); + } + dept.setCreateBy(getUsername()); + return toAjax(deptService.insertDept(dept)); + } + + /** + * 修改部门 + */ + @PreAuthorize("@ss.hasPermi('system:dept:edit')") + @Log(title = "部门管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDept dept) + { + Long deptId = dept.getDeptId(); + deptService.checkDeptDataScope(deptId); + if (!deptService.checkDeptNameUnique(dept)) + { + return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在"); + } + else if (dept.getParentId().equals(deptId)) + { + return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己"); + } + else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0) + { + return error("该部门包含未停用的子部门!"); + } + dept.setUpdateBy(getUsername()); + return toAjax(deptService.updateDept(dept)); + } + + /** + * 删除部门 + */ + @PreAuthorize("@ss.hasPermi('system:dept:remove')") + @Log(title = "部门管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{deptId}") + public AjaxResult remove(@PathVariable Long deptId) + { + if (deptService.hasChildByDeptId(deptId)) + { + return warn("存在下级部门,不允许删除"); + } + if (deptService.checkDeptExistUser(deptId)) + { + return warn("部门存在用户,不允许删除"); + } + deptService.checkDeptDataScope(deptId); + return toAjax(deptService.deleteDeptById(deptId)); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysDictDataController.java b/ff-admin/src/main/java/com/ff/system/SysDictDataController.java new file mode 100644 index 0000000..8c07d02 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysDictDataController.java @@ -0,0 +1,126 @@ +package com.ff.system; + +import com.fasterxml.jackson.annotation.JsonView; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.system.domain.SysDictData; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.system.service.ISysDictDataService; +import com.ff.base.system.service.ISysDictTypeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.List; + +/** + * 数据字典信息 + * + * @author ff + */ +@RestController +@RequestMapping("/system/dict/data") +public class SysDictDataController extends BaseController +{ + @Autowired + private ISysDictDataService dictDataService; + + @Autowired + private ISysDictTypeService dictTypeService; + + @PreAuthorize("@ss.hasPermi('system:dict:list')") + @GetMapping("/allList") + @JsonView(SysDictData.DictDataSimpleView.class) + public AjaxResult allList(SysDictData dictData) + { + dictData.setStatus("0"); + List list = dictDataService.selectDictDataList(dictData); + return AjaxResult.success(list); + } + + @PreAuthorize("@ss.hasPermi('system:dict:list')") + @GetMapping("/list") + public TableDataInfo list(SysDictData dictData) + { + startPage(); + List list = dictDataService.selectDictDataList(dictData); + return getDataTable(list); + } + + @Log(title = "字典数据", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:dict:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysDictData dictData) + { + List list = dictDataService.selectDictDataList(dictData); + ExcelUtil util = new ExcelUtil(SysDictData.class); + util.exportExcel(response, list, "字典数据"); + } + + /** + * 查询字典数据详细 + */ + @PreAuthorize("@ss.hasPermi('system:dict:query')") + @GetMapping(value = "/{dictCode}") + public AjaxResult getInfo(@PathVariable Long dictCode) + { + return success(dictDataService.selectDictDataById(dictCode)); + } + + /** + * 根据字典类型查询字典数据信息 + */ + @GetMapping(value = "/type/{dictType}") + public AjaxResult dictType(@PathVariable String dictType) + { + List data = dictTypeService.selectDictDataByType(dictType); + if (StringUtils.isNull(data)) + { + data = new ArrayList(); + } + return success(data); + } + + /** + * 新增字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:add')") + @Log(title = "字典数据", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDictData dict) + { + dict.setCreateBy(getUsername()); + return toAjax(dictDataService.insertDictData(dict)); + } + + /** + * 修改保存字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:edit')") + @Log(title = "字典数据", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDictData dict) + { + dict.setUpdateBy(getUsername()); + return toAjax(dictDataService.updateDictData(dict)); + } + + /** + * 删除字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @Log(title = "字典类型", businessType = BusinessType.DELETE) + @DeleteMapping("/{dictCodes}") + public AjaxResult remove(@PathVariable Long[] dictCodes) + { + dictDataService.deleteDictDataByIds(dictCodes); + return success(); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysDictTypeController.java b/ff-admin/src/main/java/com/ff/system/SysDictTypeController.java new file mode 100644 index 0000000..7406791 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysDictTypeController.java @@ -0,0 +1,125 @@ +package com.ff.system; + +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.system.domain.SysDictType; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.system.service.ISysDictTypeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 数据字典信息 + * + * @author ff + */ +@RestController +@RequestMapping("/system/dict/type") +public class SysDictTypeController extends BaseController +{ + @Autowired + private ISysDictTypeService dictTypeService; + + @PreAuthorize("@ss.hasPermi('system:dict:list')") + @GetMapping("/list") + public TableDataInfo list(SysDictType dictType) + { + startPage(); + List list = dictTypeService.selectDictTypeList(dictType); + return getDataTable(list); + } + + @Log(title = "字典类型", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:dict:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysDictType dictType) + { + List list = dictTypeService.selectDictTypeList(dictType); + ExcelUtil util = new ExcelUtil(SysDictType.class); + util.exportExcel(response, list, "字典类型"); + } + + /** + * 查询字典类型详细 + */ + @PreAuthorize("@ss.hasPermi('system:dict:query')") + @GetMapping(value = "/{dictId}") + public AjaxResult getInfo(@PathVariable Long dictId) + { + return success(dictTypeService.selectDictTypeById(dictId)); + } + + /** + * 新增字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:add')") + @Log(title = "字典类型", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDictType dict) + { + if (!dictTypeService.checkDictTypeUnique(dict)) + { + return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在"); + } + dict.setCreateBy(getUsername()); + return toAjax(dictTypeService.insertDictType(dict)); + } + + /** + * 修改字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:edit')") + @Log(title = "字典类型", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDictType dict) + { + if (!dictTypeService.checkDictTypeUnique(dict)) + { + return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在"); + } + dict.setUpdateBy(getUsername()); + return toAjax(dictTypeService.updateDictType(dict)); + } + + /** + * 删除字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @Log(title = "字典类型", businessType = BusinessType.DELETE) + @DeleteMapping("/{dictIds}") + public AjaxResult remove(@PathVariable Long[] dictIds) + { + dictTypeService.deleteDictTypeByIds(dictIds); + return success(); + } + + /** + * 刷新字典缓存 + */ + @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @Log(title = "字典类型", businessType = BusinessType.CLEAN) + @DeleteMapping("/refreshCache") + public AjaxResult refreshCache() + { + dictTypeService.resetDictCache(); + return success(); + } + + /** + * 获取字典选择框列表 + */ + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + List dictTypes = dictTypeService.selectDictTypeAll(); + return success(dictTypes); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysIndexController.java b/ff-admin/src/main/java/com/ff/system/SysIndexController.java new file mode 100644 index 0000000..2b2afb5 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysIndexController.java @@ -0,0 +1,29 @@ +package com.ff.system; + +import com.ff.base.config.FFConfig; +import com.ff.base.utils.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 首页 + * + * @author ff + */ +@RestController +public class SysIndexController +{ + /** 系统基础配置 */ + @Autowired + private FFConfig FfConfig; + + /** + * 访问首页,提示语 + */ + @RequestMapping("/") + public String index() + { + return StringUtils.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。", FfConfig.getName(), FfConfig.getVersion()); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysLoginController.java b/ff-admin/src/main/java/com/ff/system/SysLoginController.java new file mode 100644 index 0000000..5de7522 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysLoginController.java @@ -0,0 +1,99 @@ +package com.ff.system; + +import com.ff.base.constant.Constants; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.domain.model.LoginBody; +import com.ff.base.system.domain.SysMenu; +import com.ff.base.system.domain.SysUser; +import com.ff.base.system.service.ISysDatasourceService; +import com.ff.base.system.service.ISysMenuService; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.web.service.SysLoginService; +import com.ff.base.web.service.SysPermissionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.List; +import java.util.Set; + +/** + * 登录验证 + * + * @author ff + */ +@RestController +public class SysLoginController +{ + @Autowired + private SysLoginService loginService; + + @Autowired + private ISysMenuService menuService; + + @Autowired + private SysPermissionService permissionService; + + @Resource + private ISysDatasourceService datasourceService; + + /** + * 登录方法 + * + * @param loginBody 登录信息 + * @return 结果 + */ + @PostMapping("/login") + public AjaxResult login(@RequestBody LoginBody loginBody) + { + AjaxResult ajax = AjaxResult.success(); + // 生成令牌 + String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), + loginBody.getUuid()); + ajax.put(Constants.TOKEN, token); + return ajax; + } + + /** + * 获取用户信息 + * + * @return 用户信息 + */ + @GetMapping("getInfo") + public AjaxResult getInfo(HttpServletRequest request) + { + SysUser user = SecurityUtils.getLoginUser().getUser(); + // 角色集合 + Set roles = permissionService.getRolePermission(user); + // 权限集合 + Set permissions = permissionService.getMenuPermission(user); + + // 切换数据源 + String tenantId = request.getHeader(Constants.TENANT_ID); + + AjaxResult ajax = AjaxResult.success(); + ajax.put("user", user); + ajax.put("roles", roles); + ajax.put("permissions", permissions); + ajax.put("timeZone", datasourceService.selectSysDatasourceByTenantId(tenantId)); + ajax.put("timeZoneName", datasourceService.selectTimeZoneNameByTenantId(tenantId)); + return ajax; + } + + /** + * 获取路由信息 + * + * @return 路由信息 + */ + @GetMapping("getRouters") + public AjaxResult getRouters() + { + Long userId = SecurityUtils.getUserId(); + List menus = menuService.selectMenuTreeByUserId(userId); + return AjaxResult.success(menuService.buildMenus(menus)); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysMenuController.java b/ff-admin/src/main/java/com/ff/system/SysMenuController.java new file mode 100644 index 0000000..bdac1fd --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysMenuController.java @@ -0,0 +1,136 @@ +package com.ff.system; + +import com.ff.base.annotation.Log; +import com.ff.base.constant.UserConstants; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.system.domain.SysMenu; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.StringUtils; +import com.ff.base.system.service.ISysMenuService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 菜单信息 + * + * @author ff + */ +@RestController +@RequestMapping("/system/menu") +public class SysMenuController extends BaseController +{ + @Autowired + private ISysMenuService menuService; + + /** + * 获取菜单列表 + */ + @PreAuthorize("@ss.hasPermi('system:menu:list')") + @GetMapping("/list") + public AjaxResult list(SysMenu menu) + { + List menus = menuService.selectMenuList(menu, getUserId()); + return success(menus); + } + + /** + * 根据菜单编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:menu:query')") + @GetMapping(value = "/{menuId}") + public AjaxResult getInfo(@PathVariable Long menuId) + { + return success(menuService.selectMenuById(menuId)); + } + + /** + * 获取菜单下拉树列表 + */ + @GetMapping("/treeselect") + public AjaxResult treeselect(SysMenu menu) + { + List menus = menuService.selectMenuList(menu, getUserId()); + return success(menuService.buildMenuTreeSelect(menus)); + } + + /** + * 加载对应角色菜单列表树 + */ + @GetMapping(value = "/roleMenuTreeselect/{roleId}") + public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId) + { + List menus = menuService.selectMenuList(getUserId()); + AjaxResult ajax = AjaxResult.success(); + ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId)); + ajax.put("menus", menuService.buildMenuTreeSelect(menus)); + return ajax; + } + + /** + * 新增菜单 + */ + @PreAuthorize("@ss.hasPermi('system:menu:add')") + @Log(title = "菜单管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysMenu menu) + { + if (!menuService.checkMenuNameUnique(menu)) + { + return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } + else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) + { + return error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); + } + menu.setCreateBy(getUsername()); + return toAjax(menuService.insertMenu(menu)); + } + + /** + * 修改菜单 + */ + @PreAuthorize("@ss.hasPermi('system:menu:edit')") + @Log(title = "菜单管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysMenu menu) + { + if (!menuService.checkMenuNameUnique(menu)) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } + else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); + } + else if (menu.getMenuId().equals(menu.getParentId())) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己"); + } + menu.setUpdateBy(getUsername()); + return toAjax(menuService.updateMenu(menu)); + } + + /** + * 删除菜单 + */ + @PreAuthorize("@ss.hasPermi('system:menu:remove')") + @Log(title = "菜单管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{menuId}") + public AjaxResult remove(@PathVariable("menuId") Long menuId) + { + if (menuService.hasChildByMenuId(menuId)) + { + return warn("存在子菜单,不允许删除"); + } + if (menuService.checkMenuExistRole(menuId)) + { + return warn("菜单已分配,不允许删除"); + } + return toAjax(menuService.deleteMenuById(menuId)); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysPostController.java b/ff-admin/src/main/java/com/ff/system/SysPostController.java new file mode 100644 index 0000000..b00990e --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysPostController.java @@ -0,0 +1,123 @@ +package com.ff.system; + +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.system.domain.SysPost; +import com.ff.base.system.service.ISysPostService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 岗位信息操作处理 + * + * @author ff + */ +@RestController +@RequestMapping("/system/post") +public class SysPostController extends BaseController +{ + @Autowired + private ISysPostService postService; + + /** + * 获取岗位列表 + */ + @PreAuthorize("@ss.hasPermi('system:post:list')") + @GetMapping("/list") + public TableDataInfo list(SysPost post) + { + startPage(); + List list = postService.selectPostList(post); + return getDataTable(list); + } + + @Log(title = "岗位管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:post:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysPost post) + { + List list = postService.selectPostList(post); + ExcelUtil util = new ExcelUtil(SysPost.class); + util.exportExcel(response, list, "岗位数据"); + } + + /** + * 根据岗位编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:post:query')") + @GetMapping(value = "/{postId}") + public AjaxResult getInfo(@PathVariable Long postId) + { + return success(postService.selectPostById(postId)); + } + + /** + * 新增岗位 + */ + @PreAuthorize("@ss.hasPermi('system:post:add')") + @Log(title = "岗位管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysPost post) + { + if (!postService.checkPostNameUnique(post)) + { + return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在"); + } + else if (!postService.checkPostCodeUnique(post)) + { + return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在"); + } + post.setCreateBy(getUsername()); + return toAjax(postService.insertPost(post)); + } + + /** + * 修改岗位 + */ + @PreAuthorize("@ss.hasPermi('system:post:edit')") + @Log(title = "岗位管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysPost post) + { + if (!postService.checkPostNameUnique(post)) + { + return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在"); + } + else if (!postService.checkPostCodeUnique(post)) + { + return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在"); + } + post.setUpdateBy(getUsername()); + return toAjax(postService.updatePost(post)); + } + + /** + * 删除岗位 + */ + @PreAuthorize("@ss.hasPermi('system:post:remove')") + @Log(title = "岗位管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{postIds}") + public AjaxResult remove(@PathVariable Long[] postIds) + { + return toAjax(postService.deletePostByIds(postIds)); + } + + /** + * 获取岗位选择框列表 + */ + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + List posts = postService.selectPostAll(); + return success(posts); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysProfileController.java b/ff-admin/src/main/java/com/ff/system/SysProfileController.java new file mode 100644 index 0000000..60fbc5d --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysProfileController.java @@ -0,0 +1,131 @@ +package com.ff.system; + +import com.ff.base.annotation.Log; +import com.ff.base.config.FFConfig; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.system.domain.SysUser; +import com.ff.base.core.domain.model.LoginUser; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.file.FileUploadUtils; +import com.ff.base.utils.file.MimeTypeUtils; +import com.ff.base.web.service.TokenService; +import com.ff.base.system.service.ISysUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +/** + * 个人信息 业务处理 + * + * @author ff + */ +@RestController +@RequestMapping("/system/user/profile") +public class SysProfileController extends BaseController +{ + @Autowired + private ISysUserService userService; + + @Autowired + private TokenService tokenService; + + /** + * 个人信息 + */ + @GetMapping + public AjaxResult profile() + { + LoginUser loginUser = getLoginUser(); + SysUser user = loginUser.getUser(); + AjaxResult ajax = AjaxResult.success(user); + ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername())); + ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername())); + return ajax; + } + + /** + * 修改用户 + */ + @Log(title = "个人信息", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult updateProfile(@RequestBody SysUser user) + { + LoginUser loginUser = getLoginUser(); + SysUser currentUser = loginUser.getUser(); + currentUser.setNickName(user.getNickName()); + currentUser.setEmail(user.getEmail()); + currentUser.setPhonenumber(user.getPhonenumber()); + currentUser.setSex(user.getSex()); + if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser)) + { + return error("修改用户'" + loginUser.getUsername() + "'失败,手机号码已存在"); + } + if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser)) + { + return error("修改用户'" + loginUser.getUsername() + "'失败,邮箱账号已存在"); + } + if (userService.updateUserProfile(currentUser) > 0) + { + // 更新缓存用户信息 + tokenService.setLoginUser(loginUser); + return success(); + } + return error("修改个人信息异常,请联系管理员"); + } + + /** + * 重置密码 + */ + @Log(title = "个人信息", businessType = BusinessType.UPDATE) + @PutMapping("/updatePwd") + public AjaxResult updatePwd(String oldPassword, String newPassword) + { + LoginUser loginUser = getLoginUser(); + String userName = loginUser.getUsername(); + String password = loginUser.getPassword(); + if (!SecurityUtils.matchesPassword(oldPassword, password)) + { + return error("修改密码失败,旧密码错误"); + } + if (SecurityUtils.matchesPassword(newPassword, password)) + { + return error("新密码不能与旧密码相同"); + } + newPassword = SecurityUtils.encryptPassword(newPassword); + if (userService.resetUserPwd(userName, newPassword) > 0) + { + // 更新缓存用户密码 + loginUser.getUser().setPassword(newPassword); + tokenService.setLoginUser(loginUser); + return success(); + } + return error("修改密码异常,请联系管理员"); + } + + /** + * 头像上传 + */ + @Log(title = "用户头像", businessType = BusinessType.UPDATE) + @PostMapping("/avatar") + public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception + { + if (!file.isEmpty()) + { + LoginUser loginUser = getLoginUser(); + String avatar = FileUploadUtils.upload(FFConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION); + if (userService.updateUserAvatar(loginUser.getUsername(), avatar)) + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("imgUrl", avatar); + // 更新缓存用户头像 + loginUser.getUser().setAvatar(avatar); + tokenService.setLoginUser(loginUser); + return ajax; + } + } + return error("上传图片异常,请联系管理员"); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysRegisterController.java b/ff-admin/src/main/java/com/ff/system/SysRegisterController.java new file mode 100644 index 0000000..8067487 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysRegisterController.java @@ -0,0 +1,38 @@ +package com.ff.system; + +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.domain.model.RegisterBody; +import com.ff.base.utils.StringUtils; +import com.ff.base.web.service.SysRegisterService; +import com.ff.base.system.service.ISysConfigService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * 注册验证 + * + * @author ff + */ +@RestController +public class SysRegisterController extends BaseController +{ + @Autowired + private SysRegisterService registerService; + + @Autowired + private ISysConfigService configService; + + @PostMapping("/register") + public AjaxResult register(@RequestBody RegisterBody user) + { + if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) + { + return error("当前系统没有开启注册功能!"); + } + String msg = registerService.register(user); + return StringUtils.isEmpty(msg) ? success() : error(msg); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysRoleController.java b/ff-admin/src/main/java/com/ff/system/SysRoleController.java new file mode 100644 index 0000000..31bb249 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysRoleController.java @@ -0,0 +1,256 @@ +package com.ff.system; + +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.system.domain.SysDept; +import com.ff.base.system.domain.SysRole; +import com.ff.base.system.domain.SysUser; +import com.ff.base.core.domain.model.LoginUser; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.web.service.SysPermissionService; +import com.ff.base.web.service.TokenService; +import com.ff.base.system.domain.SysUserRole; +import com.ff.base.system.service.ISysDeptService; +import com.ff.base.system.service.ISysRoleService; +import com.ff.base.system.service.ISysUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 角色信息 + * + * @author ff + */ +@RestController +@RequestMapping("/system/role") +public class SysRoleController extends BaseController +{ + @Autowired + private ISysRoleService roleService; + + @Autowired + private TokenService tokenService; + + @Autowired + private SysPermissionService permissionService; + + @Autowired + private ISysUserService userService; + + @Autowired + private ISysDeptService deptService; + + @PreAuthorize("@ss.hasPermi('system:role:list')") + @GetMapping("/list") + public TableDataInfo list(SysRole role) + { + startPage(); + List list = roleService.selectRoleList(role); + return getDataTable(list); + } + + @Log(title = "角色管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:role:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysRole role) + { + List list = roleService.selectRoleList(role); + ExcelUtil util = new ExcelUtil(SysRole.class); + util.exportExcel(response, list, "角色数据"); + } + + /** + * 根据角色编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:role:query')") + @GetMapping(value = "/{roleId}") + public AjaxResult getInfo(@PathVariable Long roleId) + { + roleService.checkRoleDataScope(roleId); + return success(roleService.selectRoleById(roleId)); + } + + /** + * 新增角色 + */ + @PreAuthorize("@ss.hasPermi('system:role:add')") + @Log(title = "角色管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysRole role) + { + if (!roleService.checkRoleNameUnique(role)) + { + return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在"); + } + else if (!roleService.checkRoleKeyUnique(role)) + { + return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在"); + } + role.setCreateBy(getUsername()); + return toAjax(roleService.insertRole(role)); + + } + + /** + * 修改保存角色 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + if (!roleService.checkRoleNameUnique(role)) + { + return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在"); + } + else if (!roleService.checkRoleKeyUnique(role)) + { + return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在"); + } + role.setUpdateBy(getUsername()); + + if (roleService.updateRole(role) > 0) + { + // 更新缓存用户权限 + LoginUser loginUser = getLoginUser(); + if (StringUtils.isNotNull(loginUser.getUser()) && !loginUser.getUser().isAdmin()) + { + loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser())); + loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName())); + tokenService.setLoginUser(loginUser); + } + return success(); + } + return error("修改角色'" + role.getRoleName() + "'失败,请联系管理员"); + } + + /** + * 修改保存数据权限 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping("/dataScope") + public AjaxResult dataScope(@RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + return toAjax(roleService.authDataScope(role)); + } + + /** + * 状态修改 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + role.setUpdateBy(getUsername()); + return toAjax(roleService.updateRoleStatus(role)); + } + + /** + * 删除角色 + */ + @PreAuthorize("@ss.hasPermi('system:role:remove')") + @Log(title = "角色管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{roleIds}") + public AjaxResult remove(@PathVariable Long[] roleIds) + { + return toAjax(roleService.deleteRoleByIds(roleIds)); + } + + /** + * 获取角色选择框列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:query')") + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + return success(roleService.selectRoleAll()); + } + + /** + * 查询已分配用户角色列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:list')") + @GetMapping("/authUser/allocatedList") + public TableDataInfo allocatedList(SysUser user) + { + startPage(); + List list = userService.selectAllocatedList(user); + return getDataTable(list); + } + + /** + * 查询未分配用户角色列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:list')") + @GetMapping("/authUser/unallocatedList") + public TableDataInfo unallocatedList(SysUser user) + { + startPage(); + List list = userService.selectUnallocatedList(user); + return getDataTable(list); + } + + /** + * 取消授权用户 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/cancel") + public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole) + { + return toAjax(roleService.deleteAuthUser(userRole)); + } + + /** + * 批量取消授权用户 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/cancelAll") + public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds) + { + return toAjax(roleService.deleteAuthUsers(roleId, userIds)); + } + + /** + * 批量选择用户授权 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/selectAll") + public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds) + { + roleService.checkRoleDataScope(roleId); + return toAjax(roleService.insertAuthUsers(roleId, userIds)); + } + + /** + * 获取对应角色部门树列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:query')") + @GetMapping(value = "/deptTree/{roleId}") + public AjaxResult deptTree(@PathVariable("roleId") Long roleId) + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId)); + ajax.put("depts", deptService.selectDeptTreeList(new SysDept())); + return ajax; + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysUserController.java b/ff-admin/src/main/java/com/ff/system/SysUserController.java new file mode 100644 index 0000000..2ab59fc --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysUserController.java @@ -0,0 +1,250 @@ +package com.ff.system; + +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.system.domain.SysDept; +import com.ff.base.system.domain.SysRole; +import com.ff.base.system.domain.SysUser; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.system.service.ISysDeptService; +import com.ff.base.system.service.ISysPostService; +import com.ff.base.system.service.ISysRoleService; +import com.ff.base.system.service.ISysUserService; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 用户信息 + * + * @author ff + */ +@RestController +@RequestMapping("/system/user") +public class SysUserController extends BaseController +{ + @Autowired + private ISysUserService userService; + + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysDeptService deptService; + + @Autowired + private ISysPostService postService; + + /** + * 获取用户列表 + */ + @PreAuthorize("@ss.hasPermi('system:user:list')") + @GetMapping("/list") + public TableDataInfo list(SysUser user) + { + startPage(); + List list = userService.selectUserList(user); + return getDataTable(list); + } + + @Log(title = "用户管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:user:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysUser user) + { + List list = userService.selectUserList(user); + ExcelUtil util = new ExcelUtil(SysUser.class); + util.exportExcel(response, list, "用户数据"); + } + + @Log(title = "用户管理", businessType = BusinessType.IMPORT) + @PreAuthorize("@ss.hasPermi('system:user:import')") + @PostMapping("/importData") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception + { + ExcelUtil util = new ExcelUtil(SysUser.class); + List userList = util.importExcel(file.getInputStream()); + String operName = getUsername(); + String message = userService.importUser(userList, updateSupport, operName); + return success(message); + } + + @PostMapping("/importTemplate") + public void importTemplate(HttpServletResponse response) + { + ExcelUtil util = new ExcelUtil(SysUser.class); + util.importTemplateExcel(response, "用户数据"); + } + + /** + * 根据用户编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:user:query')") + @GetMapping(value = { "/", "/{userId}" }) + public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) + { + userService.checkUserDataScope(userId); + AjaxResult ajax = AjaxResult.success(); + List roles = roleService.selectRoleAll(); + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + ajax.put("posts", postService.selectPostAll()); + if (StringUtils.isNotNull(userId)) + { + SysUser sysUser = userService.selectUserById(userId); + ajax.put(AjaxResult.DATA_TAG, sysUser); + ajax.put("postIds", postService.selectPostListByUserId(userId)); + ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList())); + } + return ajax; + } + + /** + * 新增用户 + */ + @PreAuthorize("@ss.hasPermi('system:user:add')") + @Log(title = "用户管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysUser user) + { + deptService.checkDeptDataScope(user.getDeptId()); + roleService.checkRoleDataScope(user.getRoleIds()); + if (!userService.checkUserNameUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); + } + else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setCreateBy(getUsername()); + user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + return toAjax(userService.insertUser(user)); + } + + /** + * 修改用户 + */ + @PreAuthorize("@ss.hasPermi('system:user:edit')") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + deptService.checkDeptDataScope(user.getDeptId()); + roleService.checkRoleDataScope(user.getRoleIds()); + if (!userService.checkUserNameUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在"); + } + else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setUpdateBy(getUsername()); + return toAjax(userService.updateUser(user)); + } + + /** + * 删除用户 + */ + @PreAuthorize("@ss.hasPermi('system:user:remove')") + @Log(title = "用户管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{userIds}") + public AjaxResult remove(@PathVariable Long[] userIds) + { + if (ArrayUtils.contains(userIds, getUserId())) + { + return error("当前用户不能删除"); + } + return toAjax(userService.deleteUserByIds(userIds)); + } + + /** + * 重置密码 + */ + @PreAuthorize("@ss.hasPermi('system:user:resetPwd')") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping("/resetPwd") + public AjaxResult resetPwd(@RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + user.setUpdateBy(getUsername()); + return toAjax(userService.resetPwd(user)); + } + + /** + * 状态修改 + */ + @PreAuthorize("@ss.hasPermi('system:user:edit')") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + user.setUpdateBy(getUsername()); + return toAjax(userService.updateUserStatus(user)); + } + + /** + * 根据用户编号获取授权角色 + */ + @PreAuthorize("@ss.hasPermi('system:user:query')") + @GetMapping("/authRole/{userId}") + public AjaxResult authRole(@PathVariable("userId") Long userId) + { + AjaxResult ajax = AjaxResult.success(); + SysUser user = userService.selectUserById(userId); + List roles = roleService.selectRolesByUserId(userId); + ajax.put("user", user); + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + return ajax; + } + + /** + * 用户授权角色 + */ + @PreAuthorize("@ss.hasPermi('system:user:edit')") + @Log(title = "用户管理", businessType = BusinessType.GRANT) + @PutMapping("/authRole") + public AjaxResult insertAuthRole(Long userId, Long[] roleIds) + { + userService.checkUserDataScope(userId); + roleService.checkRoleDataScope(roleIds); + userService.insertUserAuth(userId, roleIds); + return success(); + } + + /** + * 获取部门树列表 + */ + @PreAuthorize("@ss.hasPermi('system:user:list')") + @GetMapping("/deptTree") + public AjaxResult deptTree(SysDept dept) + { + return success(deptService.selectDeptTreeList(dept)); + } +} diff --git a/ff-admin/src/main/resources/META-INF/spring-devtools.properties b/ff-admin/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 0000000..37e7b58 --- /dev/null +++ b/ff-admin/src/main/resources/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.json=/com.alibaba.fastjson2.*.jar \ No newline at end of file diff --git a/ff-admin/src/main/resources/application-druid.yml b/ff-admin/src/main/resources/application-druid.yml new file mode 100644 index 0000000..d86c02e --- /dev/null +++ b/ff-admin/src/main/resources/application-druid.yml @@ -0,0 +1,95 @@ +# 数据源配置 +spring: + # redis 配置 + redis: + # 地址 + host: 127.0.0.1 + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 1 + # 密码 + password: + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 主库数据源 + master: + url: jdbc:mysql://192.168.1.11:3306/ff-game?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true + username: root + password: 123456 + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置连接超时时间 + connectTimeout: 30000 + # 配置网络超时时间 + socketTimeout: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ff + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + +forest: + backend: okhttp3 # 后端HTTP框架(默认为 okhttp3) + max-connections: 1000 # 连接池最大连接数(默认为 500) + max-route-connections: 500 # 每个路由的最大连接数(默认为 500) + max-request-queue-size: 100 # [自v1.5.22版本起可用] 最大请求等待队列大小 + max-async-thread-size: 300 # [自v1.5.21版本起可用] 最大异步线程数 + max-async-queue-size: 16 # [自v1.5.22版本起可用] 最大异步线程池队列大小 + timeout: 3000 # [已不推荐使用] 请求超时时间,单位为毫秒(默认为 3000) + connect-timeout: 3000 # 连接超时时间,单位为毫秒(默认为 timeout) + read-timeout: 3000 # 数据读取超时时间,单位为毫秒(默认为 timeout) + max-retry-count: 0 # 请求失败后重试次数(默认为 0 次不重试) + ssl-protocol: TLS # 单向验证的HTTPS的默认TLS协议(默认为 TLS) + log-enabled: true # 打开或关闭日志(默认为 true) + log-request: true # 打开/关闭Forest请求日志(默认为 true) + log-response-status: true # 打开/关闭Forest响应状态日志(默认为 true) + log-response-content: true # 打开/关闭Forest响应内容日志(默认为 false) + async-mode: platform # [自v1.5.27版本起可用] 异步模式(默认为 platform) diff --git a/ff-admin/src/main/resources/application-prod.yml b/ff-admin/src/main/resources/application-prod.yml new file mode 100644 index 0000000..18e7937 --- /dev/null +++ b/ff-admin/src/main/resources/application-prod.yml @@ -0,0 +1,97 @@ +# 项目相关配置 +ff: + # 文件路径 示例( Windows配置D:/ff/uploadPath,Linux配置 /home/ff/uploadPath) + profile: D:/opt/sever/dist/ff-admin/uploadPath +# 开发环境配置 +server: + # 服务器的HTTP端口,默认为8080 + port: 28080 + servlet: + # 应用的访问路径 + context-path: /ff-api + +# 日志配置 +logging: + level: + com.ff: debug + org.springframework: warn + file: + path: D:/opt/sever/dist/ff-admin/logs + +# 数据源配置 +spring: + # redis 配置 + redis: + # 地址 + host: 127.0.0.1 + # 端口,默认为6379 + port: 26379 + # 数据库索引 + database: 0 + # 密码 + password: reAa123456 + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 主库数据源 + master: + url: jdbc:mysql://192.168.1.11:23306/ff-admin?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true + username: root + password: myAa123456 + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置连接超时时间 + connectTimeout: 30000 + # 配置网络超时时间 + socketTimeout: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ff + login-password: ff_prod + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true diff --git a/ff-admin/src/main/resources/application.yml b/ff-admin/src/main/resources/application.yml new file mode 100644 index 0000000..73d1cb4 --- /dev/null +++ b/ff-admin/src/main/resources/application.yml @@ -0,0 +1,138 @@ +# 项目相关配置 +ff: + # 名称 + name: FF + # 版本 + version: 0.0.1 + # 版权年份 + copyrightYear: 2024 + # 文件路径 示例( Windows配置D:/ff/uploadPath,Linux配置 /home/ff/uploadPath) + profile: D:/ff/uploadPath + # 获取ip地址开关 + addressEnabled: false + # 验证码类型 math 数字计算 char 字符验证 + captchaType: math + +# 开发环境配置 +server: + # 服务器的HTTP端口,默认为8080 + port: 9080 + servlet: + # 应用的访问路径 + context-path: / + tomcat: + # tomcat的URI编码 + uri-encoding: UTF-8 + # 连接数满后的排队数,默认为100 + accept-count: 1000 + threads: + # tomcat最大线程数,默认为200 + max: 800 + # Tomcat启动初始化的线程数,默认值10 + min-spare: 100 + +# 日志配置 +logging: + level: + com.ff: debug + org.springframework: warn + +# 用户配置 +user: + password: + # 密码最大错误次数 + maxRetryCount: 5 + # 密码锁定时间(默认10分钟) + lockTime: 10 + +# 跑批处理配置 +batchProcessing: + # 批量数量 + commissionBatchSize: 20 + agentLevelBatchSize: 50 + bettingDataBatchSize: 1000 + +# Spring配置 +spring: + mvc: + pathmatch: + matching-strategy: ant_path_matcher + # 资源信息 + messages: + # 国际化资源文件路径 + basename: i18n/messages + profiles: + active: druid + # 文件上传 + servlet: + multipart: + # 单个文件大小 + max-file-size: 20MB + # 设置总上传的文件大小 + max-request-size: 20MB + # 服务模块 + devtools: + restart: + # 热部署开关 + enabled: false + +# token配置 +token: + # 令牌自定义标识 + header: Authorization + # 令牌密钥 + secret: abcdefghijklmnopqrstuvwxyz + # 令牌有效期(默认10080分钟 七天) + expireTime: 10080 + +# MyBatis配置 +mybatis: + # 搜索指定包别名 + typeAliasesPackage: com.ff.**.domain + # 配置mapper的扫描,找到所有的mapper.xml映射文件 + mapperLocations: classpath*:mapper/**/*Mapper.xml + # 加载全局的配置文件 + configLocation: classpath:mybatis/mybatis-config.xml + +# PageHelper分页插件 +pagehelper: + helperDialect: mysql + supportMethodsArguments: true + params: count=countSql + +# Swagger配置 +swagger: + # 是否开启swagger + enabled: true + # 请求前缀 + pathMapping: / + +# 防止XSS攻击 +xss: + # 过滤开关 + enabled: true + # 排除链接(多个用逗号分隔) + excludes: /system/notice + # 匹配链接 + urlPatterns: /system/*,/monitor/*,/tool/* + +#雪花算法id生成器配置 +snowflake: + worker: + id: 1 + datacenter: + id: 1 + +#aes密钥 +encrypt: + body: + aes-key: gktsdFKqo7lJi3Kc #AES加密秘钥 + +netty: + app: + port: 9820 + + web: + port: 9821 + + diff --git a/ff-admin/src/main/resources/i18n/messages.properties b/ff-admin/src/main/resources/i18n/messages.properties new file mode 100644 index 0000000..094f953 --- /dev/null +++ b/ff-admin/src/main/resources/i18n/messages.properties @@ -0,0 +1,44 @@ +#错误消息 +opration.success=操作成功 +opration.fail=操作失败 +not.null=* 必须填写 +user.jcaptcha.error=验证码错误 +user.jcaptcha.expire=验证码已失效 +user.not.exists=用户不存在/密码错误 +user.password.not.match=用户不存在/密码错误 +user.password.retry.limit.count=密码输入错误{0}次 +user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟 +user.password.delete=对不起,您的账号已被删除 +user.blocked=用户已封禁,请联系管理员 +role.blocked=角色已封禁,请联系管理员 +login.blocked=很遗憾,访问IP已被列入系统黑名单 +user.logout.success=退出成功 + +length.not.valid=长度必须在{min}到{max}个字符之间 + +user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头 +user.password.not.valid=* 5-50个字符 + +user.email.not.valid=邮箱格式错误 +user.mobile.phone.number.not.valid=手机号格式错误 +user.login.success=登录成功 +user.register.success=注册成功 +user.notfound=请重新登录 +user.forcelogout=管理员强制退出,请重新登录 +user.unknown.error=未知错误,请重新登录 + +##文件上传消息 +upload.exceed.maxSize=上传的文件大小超出限制的文件大小!
允许的文件最大大小是:{0}MB! +upload.filename.exceed.length=上传的文件名最长{0}个字符 +upload.file.exception=本地文件上传异常 +upload.file.server.not.exist=文件服务不存在 + +##权限 +no.permission=您没有数据的权限,请联系管理员添加权限 [{0}] +no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}] +no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}] +no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}] +no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}] +no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}] + + diff --git a/ff-admin/src/main/resources/logback.xml b/ff-admin/src/main/resources/logback.xml new file mode 100644 index 0000000..b94939f --- /dev/null +++ b/ff-admin/src/main/resources/logback.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/sys-info.log + + + + ${log.path}/sys-info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/sys-error.log + + + + ${log.path}/sys-error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + ${log.path}/sys-user.log + + + ${log.path}/sys-user.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ff-admin/src/main/resources/mapper/common/CurrencyMapper.xml b/ff-admin/src/main/resources/mapper/common/CurrencyMapper.xml new file mode 100644 index 0000000..b5687d3 --- /dev/null +++ b/ff-admin/src/main/resources/mapper/common/CurrencyMapper.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + select id, status, country, currency_code, currency_sign, game_rate, currency_display, currency_name, full_name, create_by, create_time, update_by, update_time, remark from ff_currency + + + + + + + + insert into ff_currency + + status, + country, + currency_code, + currency_sign, + game_rate, + currency_display, + currency_name, + full_name, + create_by, + create_time, + update_by, + update_time, + remark, + + + #{status}, + #{country}, + #{currencyCode}, + #{currencySign}, + #{gameRate}, + #{currencyDisplay}, + #{currencyName}, + #{fullName}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{remark}, + + + + + update ff_currency + + status = #{status}, + country = #{country}, + currency_code = #{currencyCode}, + currency_sign = #{currencySign}, + game_rate = #{gameRate}, + currency_display = #{currencyDisplay}, + currency_name = #{currencyName}, + full_name = #{fullName}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + remark = #{remark}, + + where id = #{id} + + + + delete from ff_currency where id = #{id} + + + + delete from ff_currency where id in + + #{id} + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/common/LangMapper.xml b/ff-admin/src/main/resources/mapper/common/LangMapper.xml new file mode 100644 index 0000000..62f8ad5 --- /dev/null +++ b/ff-admin/src/main/resources/mapper/common/LangMapper.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + select id, name, country, lang_code, lang_status, create_by, create_time, update_by, update_time from ff_lang + + + + + + + + insert into ff_lang + + name, + country, + lang_code, + lang_status, + create_by, + create_time, + update_by, + update_time, + + + #{name}, + #{country}, + #{langCode}, + #{langStatus}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_lang + + name = #{name}, + country = #{country}, + lang_code = #{langCode}, + lang_status = #{langStatus}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_lang where id = #{id} + + + + delete from ff_lang where id in + + #{id} + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/common/TenantSecretKeyMapper.xml b/ff-admin/src/main/resources/mapper/common/TenantSecretKeyMapper.xml new file mode 100644 index 0000000..839ebc0 --- /dev/null +++ b/ff-admin/src/main/resources/mapper/common/TenantSecretKeyMapper.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + select id, tenant_key, tenant_sn, tenant_secret, tenant_status, create_by, create_time, update_by, update_time from ff_tenant_secret_key + + + + + + + + + + insert into ff_tenant_secret_key + + tenant_key, + tenant_sn, + tenant_secret, + tenant_status, + create_by, + create_time, + update_by, + update_time, + + + #{tenantKey}, + #{tenantSn}, + #{tenantSecret}, + #{tenantStatus}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_tenant_secret_key + + tenant_key = #{tenantKey}, + tenant_sn = #{tenantSn}, + tenant_secret = #{tenantSecret}, + tenant_status = #{tenantStatus}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_tenant_secret_key where id = #{id} + + + + delete from ff_tenant_secret_key where id in + + #{id} + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/game/GameBettingDetailsMapper.xml b/ff-admin/src/main/resources/mapper/game/GameBettingDetailsMapper.xml new file mode 100644 index 0000000..282e764 --- /dev/null +++ b/ff-admin/src/main/resources/mapper/game/GameBettingDetailsMapper.xml @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, currency_code, member_id, game_code, game_id, game_type, platform_code, game_name, game_status, game_status_type, game_currency_code, account, wagers_id, wagers_time, bet_amount, payoff_time, payoff_amount, settlement_time, turnover, order_no, settlement_status, create_by, create_time, update_by, update_time from ff_game_betting_details + + + + + + + + insert into ff_game_betting_details + + currency_code, + member_id, + game_code, + game_id, + game_type, + platform_code, + game_name, + game_status, + game_status_type, + game_currency_code, + account, + wagers_id, + wagers_time, + bet_amount, + payoff_time, + payoff_amount, + settlement_time, + turnover, + order_no, + settlement_status, + create_by, + create_time, + update_by, + update_time, + + + #{currencyCode}, + #{memberId}, + #{gameCode}, + #{gameId}, + #{gameType}, + #{platformCode}, + #{gameName}, + #{gameStatus}, + #{gameStatusType}, + #{gameCurrencyCode}, + #{account}, + #{wagersId}, + #{wagersTime}, + #{betAmount}, + #{payoffTime}, + #{payoffAmount}, + #{settlementTime}, + #{turnover}, + #{orderNo}, + #{settlementStatus}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_game_betting_details + + currency_code = #{currencyCode}, + member_id = #{memberId}, + game_code = #{gameCode}, + game_id = #{gameId}, + game_type = #{gameType}, + platform_code = #{platformCode}, + game_name = #{gameName}, + game_status = #{gameStatus}, + game_status_type = #{gameStatusType}, + game_currency_code = #{gameCurrencyCode}, + account = #{account}, + wagers_id = #{wagersId}, + wagers_time = #{wagersTime}, + bet_amount = #{betAmount}, + payoff_time = #{payoffTime}, + payoff_amount = #{payoffAmount}, + settlement_time = #{settlementTime}, + turnover = #{turnover}, + order_no = #{orderNo}, + settlement_status = #{settlementStatus}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_game_betting_details where id = #{id} + + + + delete from ff_game_betting_details where id in + + #{id} + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/game/GameExchangeMoneyMapper.xml b/ff-admin/src/main/resources/mapper/game/GameExchangeMoneyMapper.xml new file mode 100644 index 0000000..b9f1c25 --- /dev/null +++ b/ff-admin/src/main/resources/mapper/game/GameExchangeMoneyMapper.xml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, currency_code, transaction_id, member_id, platform_code, platform_id, balance, quota, coin_before, coin_after, currency_before, currency_after, exchange_type, status, create_by, create_time, update_by, update_time from ff_game_exchange_money + + + + + + + + insert into ff_game_exchange_money + + currency_code, + transaction_id, + member_id, + platform_code, + platform_id, + balance, + quota, + coin_before, + coin_after, + currency_before, + currency_after, + exchange_type, + status, + create_by, + create_time, + update_by, + update_time, + + + #{currencyCode}, + #{transactionId}, + #{memberId}, + #{platformCode}, + #{platformId}, + #{balance}, + #{quota}, + #{coinBefore}, + #{coinAfter}, + #{currencyBefore}, + #{currencyAfter}, + #{exchangeType}, + #{status}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_game_exchange_money + + currency_code = #{currencyCode}, + transaction_id = #{transactionId}, + member_id = #{memberId}, + platform_code = #{platformCode}, + platform_id = #{platformId}, + balance = #{balance}, + quota = #{quota}, + coin_before = #{coinBefore}, + coin_after = #{coinAfter}, + currency_before = #{currencyBefore}, + currency_after = #{currencyAfter}, + exchange_type = #{exchangeType}, + status = #{status}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_game_exchange_money where id = #{id} + + + + delete from ff_game_exchange_money where id in + + #{id} + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/game/GameFreeRecordMapper.xml b/ff-admin/src/main/resources/mapper/game/GameFreeRecordMapper.xml new file mode 100644 index 0000000..fb12de8 --- /dev/null +++ b/ff-admin/src/main/resources/mapper/game/GameFreeRecordMapper.xml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, currency_code, reference_id, member_id, member_account, game_id, send_time, expired_time, free_update_time, send_game, send_amount, used_amount, unused_amount, free_status, create_by, create_time, update_by, update_time from ff_game_free_record + + + + + + + + insert into ff_game_free_record + + currency_code, + reference_id, + member_id, + member_account, + game_id, + send_time, + expired_time, + free_update_time, + send_game, + send_amount, + used_amount, + unused_amount, + free_status, + create_by, + create_time, + update_by, + update_time, + + + #{currencyCode}, + #{referenceId}, + #{memberId}, + #{memberAccount}, + #{gameId}, + #{sendTime}, + #{expiredTime}, + #{freeUpdateTime}, + #{sendGame}, + #{sendAmount}, + #{usedAmount}, + #{unusedAmount}, + #{freeStatus}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_game_free_record + + currency_code = #{currencyCode}, + reference_id = #{referenceId}, + member_id = #{memberId}, + member_account = #{memberAccount}, + game_id = #{gameId}, + send_time = #{sendTime}, + expired_time = #{expiredTime}, + free_update_time = #{freeUpdateTime}, + send_game = #{sendGame}, + send_amount = #{sendAmount}, + used_amount = #{usedAmount}, + unused_amount = #{unusedAmount}, + free_status = #{freeStatus}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_game_free_record where id = #{id} + + + + delete from ff_game_free_record where id in + + #{id} + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/game/GameMapper.xml b/ff-admin/src/main/resources/mapper/game/GameMapper.xml new file mode 100644 index 0000000..5c91e38 --- /dev/null +++ b/ff-admin/src/main/resources/mapper/game/GameMapper.xml @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + select id, sort_no, platform_id, game_code, game_source_type, game_name, freespin, demo_status, stop_status, game_status, create_by, create_time, update_by, update_time from ff_game + + + + + + + + insert into ff_game + + sort_no, + platform_id, + game_code, + game_source_type, + game_name, + freespin, + demo_status, + stop_status, + game_status, + create_by, + create_time, + update_by, + update_time, + + + #{sortNo}, + #{platformId}, + #{gameCode}, + #{gameSourceType}, + #{gameName}, + #{freespin}, + #{demoStatus}, + #{stopStatus}, + #{gameStatus}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_game + + sort_no = #{sortNo}, + platform_id = #{platformId}, + game_code = #{gameCode}, + game_source_type = #{gameSourceType}, + game_name = #{gameName}, + freespin = #{freespin}, + demo_status = #{demoStatus}, + stop_status = #{stopStatus}, + game_status = #{gameStatus}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_game where id = #{id} + + + + delete from ff_game where id in + + #{id} + + + + + + + + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/game/GamePlatformMapper.xml b/ff-admin/src/main/resources/mapper/game/GamePlatformMapper.xml new file mode 100644 index 0000000..3a733cd --- /dev/null +++ b/ff-admin/src/main/resources/mapper/game/GamePlatformMapper.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + select id, sort_no, platform_code, platform_type, platform_name, stop_status, platform_status, create_by, create_time, update_by, update_time from ff_game_platform + + + + + + + + insert into ff_game_platform + + sort_no, + platform_code, + platform_type, + platform_name, + stop_status, + platform_status, + create_by, + create_time, + update_by, + update_time, + + + #{sortNo}, + #{platformCode}, + #{platformType}, + #{platformName}, + #{stopStatus}, + #{platformStatus}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_game_platform + + sort_no = #{sortNo}, + platform_code = #{platformCode}, + platform_type = #{platformType}, + platform_name = #{platformName}, + stop_status = #{stopStatus}, + platform_status = #{platformStatus}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_game_platform where id = #{id} + + + + delete from ff_game_platform where id in + + #{id} + + + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/game/GameSecretKeyMapper.xml b/ff-admin/src/main/resources/mapper/game/GameSecretKeyMapper.xml new file mode 100644 index 0000000..e5968a2 --- /dev/null +++ b/ff-admin/src/main/resources/mapper/game/GameSecretKeyMapper.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + select id, platform, code, `key`, system_code, lang, system_lang_code, info, create_by, create_time, update_by, update_time from ff_game_secret_key + + + + + + + + insert into ff_game_secret_key + + platform, + code, + `key`, + system_code, + lang, + system_lang_code, + info, + create_by, + create_time, + update_by, + update_time, + + + #{platform}, + #{code}, + #{key}, + #{systemCode}, + #{lang}, + #{systemLangCode}, + #{info}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_game_secret_key + + platform = #{platform}, + code = #{code}, + `key` = #{key}, + system_code = #{systemCode}, + lang = #{lang}, + system_lang_code = #{systemLangCode}, + info = #{info}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_game_secret_key where id = #{id} + + + + delete from ff_game_secret_key where id in + + #{id} + + + + + + + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/member/MemberMapper.xml b/ff-admin/src/main/resources/mapper/member/MemberMapper.xml new file mode 100644 index 0000000..a5441ee --- /dev/null +++ b/ff-admin/src/main/resources/mapper/member/MemberMapper.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + select id, tenant_key, member_account, game_account, platform_code, currency_code, create_by, create_time, update_by, update_time from ff_member + + + + + + + + insert into ff_member + + tenant_key, + member_account, + game_account, + platform_code, + currency_code, + create_by, + create_time, + update_by, + update_time, + + + #{tenantKey}, + #{memberAccount}, + #{gameAccount}, + #{platformCode}, + #{currencyCode}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_member + + tenant_key = #{tenantKey}, + member_account = #{memberAccount}, + game_account = #{gameAccount}, + platform_code = #{platformCode}, + currency_code = #{currencyCode}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_member where id = #{id} + + + + delete from ff_member where id in + + #{id} + + + + + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/quartz/SysJobLogMapper.xml b/ff-admin/src/main/resources/mapper/quartz/SysJobLogMapper.xml new file mode 100644 index 0000000..2a05f6c --- /dev/null +++ b/ff-admin/src/main/resources/mapper/quartz/SysJobLogMapper.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + select job_log_id, job_name, job_group, invoke_target, job_message, status, exception_info, create_time + from sys_job_log + + + + + + + + + + delete from sys_job_log where job_log_id = #{jobLogId} + + + + delete from sys_job_log where job_log_id in + + #{jobLogId} + + + + + truncate table sys_job_log + + + + insert into sys_job_log( + job_log_id, + job_name, + job_group, + invoke_target, + job_message, + status, + exception_info, + create_time + )values( + #{jobLogId}, + #{jobName}, + #{jobGroup}, + #{invokeTarget}, + #{jobMessage}, + #{status}, + #{exceptionInfo}, + UNIX_TIMESTAMP() * 1000 + ) + + + diff --git a/ff-admin/src/main/resources/mapper/quartz/SysJobMapper.xml b/ff-admin/src/main/resources/mapper/quartz/SysJobMapper.xml new file mode 100644 index 0000000..948b5aa --- /dev/null +++ b/ff-admin/src/main/resources/mapper/quartz/SysJobMapper.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + select job_id, job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark + from sys_job + + + + + + + + + + delete from sys_job where job_id = #{jobId} + + + + delete from sys_job where job_id in + + #{jobId} + + + + + update sys_job + + job_name = #{jobName}, + job_group = #{jobGroup}, + invoke_target = #{invokeTarget}, + cron_expression = #{cronExpression}, + misfire_policy = #{misfirePolicy}, + concurrent = #{concurrent}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = UNIX_TIMESTAMP() * 1000 + + where job_id = #{jobId} + + + + insert into sys_job( + job_id, + job_name, + job_group, + invoke_target, + cron_expression, + misfire_policy, + concurrent, + status, + remark, + create_by, + create_time + )values( + #{jobId}, + #{jobName}, + #{jobGroup}, + #{invokeTarget}, + #{cronExpression}, + #{misfirePolicy}, + #{concurrent}, + #{status}, + #{remark}, + #{createBy}, + UNIX_TIMESTAMP() * 1000 + ) + + + diff --git a/ff-admin/src/main/resources/mybatis/mybatis-config.xml b/ff-admin/src/main/resources/mybatis/mybatis-config.xml new file mode 100644 index 0000000..ac47c03 --- /dev/null +++ b/ff-admin/src/main/resources/mybatis/mybatis-config.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/ff-admin/target/classes/META-INF/spring-devtools.properties b/ff-admin/target/classes/META-INF/spring-devtools.properties new file mode 100644 index 0000000..37e7b58 --- /dev/null +++ b/ff-admin/target/classes/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.json=/com.alibaba.fastjson2.*.jar \ No newline at end of file diff --git a/ff-admin/target/classes/application-druid.yml b/ff-admin/target/classes/application-druid.yml new file mode 100644 index 0000000..d86c02e --- /dev/null +++ b/ff-admin/target/classes/application-druid.yml @@ -0,0 +1,95 @@ +# 数据源配置 +spring: + # redis 配置 + redis: + # 地址 + host: 127.0.0.1 + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 1 + # 密码 + password: + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 主库数据源 + master: + url: jdbc:mysql://192.168.1.11:3306/ff-game?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true + username: root + password: 123456 + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置连接超时时间 + connectTimeout: 30000 + # 配置网络超时时间 + socketTimeout: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ff + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + +forest: + backend: okhttp3 # 后端HTTP框架(默认为 okhttp3) + max-connections: 1000 # 连接池最大连接数(默认为 500) + max-route-connections: 500 # 每个路由的最大连接数(默认为 500) + max-request-queue-size: 100 # [自v1.5.22版本起可用] 最大请求等待队列大小 + max-async-thread-size: 300 # [自v1.5.21版本起可用] 最大异步线程数 + max-async-queue-size: 16 # [自v1.5.22版本起可用] 最大异步线程池队列大小 + timeout: 3000 # [已不推荐使用] 请求超时时间,单位为毫秒(默认为 3000) + connect-timeout: 3000 # 连接超时时间,单位为毫秒(默认为 timeout) + read-timeout: 3000 # 数据读取超时时间,单位为毫秒(默认为 timeout) + max-retry-count: 0 # 请求失败后重试次数(默认为 0 次不重试) + ssl-protocol: TLS # 单向验证的HTTPS的默认TLS协议(默认为 TLS) + log-enabled: true # 打开或关闭日志(默认为 true) + log-request: true # 打开/关闭Forest请求日志(默认为 true) + log-response-status: true # 打开/关闭Forest响应状态日志(默认为 true) + log-response-content: true # 打开/关闭Forest响应内容日志(默认为 false) + async-mode: platform # [自v1.5.27版本起可用] 异步模式(默认为 platform) diff --git a/ff-admin/target/classes/application-prod.yml b/ff-admin/target/classes/application-prod.yml new file mode 100644 index 0000000..18e7937 --- /dev/null +++ b/ff-admin/target/classes/application-prod.yml @@ -0,0 +1,97 @@ +# 项目相关配置 +ff: + # 文件路径 示例( Windows配置D:/ff/uploadPath,Linux配置 /home/ff/uploadPath) + profile: D:/opt/sever/dist/ff-admin/uploadPath +# 开发环境配置 +server: + # 服务器的HTTP端口,默认为8080 + port: 28080 + servlet: + # 应用的访问路径 + context-path: /ff-api + +# 日志配置 +logging: + level: + com.ff: debug + org.springframework: warn + file: + path: D:/opt/sever/dist/ff-admin/logs + +# 数据源配置 +spring: + # redis 配置 + redis: + # 地址 + host: 127.0.0.1 + # 端口,默认为6379 + port: 26379 + # 数据库索引 + database: 0 + # 密码 + password: reAa123456 + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 主库数据源 + master: + url: jdbc:mysql://192.168.1.11:23306/ff-admin?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true + username: root + password: myAa123456 + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置连接超时时间 + connectTimeout: 30000 + # 配置网络超时时间 + socketTimeout: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ff + login-password: ff_prod + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true diff --git a/ff-admin/target/classes/application.yml b/ff-admin/target/classes/application.yml new file mode 100644 index 0000000..73d1cb4 --- /dev/null +++ b/ff-admin/target/classes/application.yml @@ -0,0 +1,138 @@ +# 项目相关配置 +ff: + # 名称 + name: FF + # 版本 + version: 0.0.1 + # 版权年份 + copyrightYear: 2024 + # 文件路径 示例( Windows配置D:/ff/uploadPath,Linux配置 /home/ff/uploadPath) + profile: D:/ff/uploadPath + # 获取ip地址开关 + addressEnabled: false + # 验证码类型 math 数字计算 char 字符验证 + captchaType: math + +# 开发环境配置 +server: + # 服务器的HTTP端口,默认为8080 + port: 9080 + servlet: + # 应用的访问路径 + context-path: / + tomcat: + # tomcat的URI编码 + uri-encoding: UTF-8 + # 连接数满后的排队数,默认为100 + accept-count: 1000 + threads: + # tomcat最大线程数,默认为200 + max: 800 + # Tomcat启动初始化的线程数,默认值10 + min-spare: 100 + +# 日志配置 +logging: + level: + com.ff: debug + org.springframework: warn + +# 用户配置 +user: + password: + # 密码最大错误次数 + maxRetryCount: 5 + # 密码锁定时间(默认10分钟) + lockTime: 10 + +# 跑批处理配置 +batchProcessing: + # 批量数量 + commissionBatchSize: 20 + agentLevelBatchSize: 50 + bettingDataBatchSize: 1000 + +# Spring配置 +spring: + mvc: + pathmatch: + matching-strategy: ant_path_matcher + # 资源信息 + messages: + # 国际化资源文件路径 + basename: i18n/messages + profiles: + active: druid + # 文件上传 + servlet: + multipart: + # 单个文件大小 + max-file-size: 20MB + # 设置总上传的文件大小 + max-request-size: 20MB + # 服务模块 + devtools: + restart: + # 热部署开关 + enabled: false + +# token配置 +token: + # 令牌自定义标识 + header: Authorization + # 令牌密钥 + secret: abcdefghijklmnopqrstuvwxyz + # 令牌有效期(默认10080分钟 七天) + expireTime: 10080 + +# MyBatis配置 +mybatis: + # 搜索指定包别名 + typeAliasesPackage: com.ff.**.domain + # 配置mapper的扫描,找到所有的mapper.xml映射文件 + mapperLocations: classpath*:mapper/**/*Mapper.xml + # 加载全局的配置文件 + configLocation: classpath:mybatis/mybatis-config.xml + +# PageHelper分页插件 +pagehelper: + helperDialect: mysql + supportMethodsArguments: true + params: count=countSql + +# Swagger配置 +swagger: + # 是否开启swagger + enabled: true + # 请求前缀 + pathMapping: / + +# 防止XSS攻击 +xss: + # 过滤开关 + enabled: true + # 排除链接(多个用逗号分隔) + excludes: /system/notice + # 匹配链接 + urlPatterns: /system/*,/monitor/*,/tool/* + +#雪花算法id生成器配置 +snowflake: + worker: + id: 1 + datacenter: + id: 1 + +#aes密钥 +encrypt: + body: + aes-key: gktsdFKqo7lJi3Kc #AES加密秘钥 + +netty: + app: + port: 9820 + + web: + port: 9821 + + diff --git a/ff-admin/target/classes/com/ff/FFApplication.class b/ff-admin/target/classes/com/ff/FFApplication.class new file mode 100644 index 0000000000000000000000000000000000000000..894457e6d4d6d42ab14fbba18ea0641172b568c1 GIT binary patch literal 2280 zcmbVOO;cM{7=CW}xDX?4DNxa>6tD)gT(z}S(^di{h)pRrKt=pIxj6|JlY8U+px{c! zjdsBwXWThD9oo?uoN?(-a3?dk?LTmQ&P_;yM%(Ek=iKw2^FHr$-mjD2{`zSf zz$v^FMHj|(oQdKkyxfTd&gwW9MH|LDa9+)?L@|M+`kIVl3Ku#N!E_WU%;@j1NwQ2^wwwz}S?MkaTGP;-c1%%R60W7zRbi{YYSDb(-VIWzWVu|l%#ats zTT8;SxgTFiuZeYG6op+dGQOgj2(1aXK>fo_wn@khs2iQ$Fl9Nsr;gXS&NzW<%9It7 z+GlV~+0bylxicKcHv}(Uad6;DBNO^-k{kP3>vF>^2FeYy_Y1X_%bLao;fo48<>09> zkO2eD7||D_Ay#QKOMzF7Rbx;tiE>%G8B?gkZR?^KkU&3EV=SK^Q>iiLZF;^ejg`WK z8hWaG9|XenKdgxlRmBBq*JP)g-h-a-`&AxYRaem6zH~huX=Y4i zp&>SFGm)o?!t*4fc>d45{M z#ilr(Gy~W2Sq_1}%6nFG)yN5l@pBls2I;)(tXnzh5`Vlonz<@-L6Pa)=)`GTl}OUt zw9P~eJ?O2(N|pG&eARI&h9@zn<8lo1cwNJhe^$w4U=>M#_TxKWe7p1c*E=8m!g1v8 z_GfpuZw?HkQoA?4-@X3bpP$~?z5dm}z`!4$d>Q}s*6-iE#}A&m8N(H1bS%WMh@}{= zVoApvF)ZWF7!Kl)j+GeRQVb8)O<&HgNz-S>Hf<`Zj+iDTVdqqnU{_)iu!igUwTjj8 zwuVGAlzXLKH7ov)L#28fDpx}`-q2>kyi7FdEF(=rxyPthwkm}6W=6596=p(%qcUMZ zvQs$$-PKz$ZaKz08=TKJCq;=0?W$hwoQ4yP^!B=71LKOQ8geTBxBu&%Yl&6K{=&Xk zkbZ5^6Ce2(E&)4yr($C-T>H6d&{aqDi-hZK#+C2GAiK*w-YQnIdQvo;dXUKD7@y28 zu%h{ks2t_o&F8nB^I^^{oLN&G`?xYVYn}0IM0L_eU)=nn$!rL{i;sqDYV$Ph~7tVi@*SDt^0Gn7YqJT*oQ#PiHn8B=#IUDl~g>4n6c!wchT|H*7 z_Vk%#s5mN+2T8}3=190cMaCWN3IA9amHNG)6`!k!Vaf4yhqqe1(P&C@<;!@Vm`eES zR+<{akf(!|YA1#`H&sWQHjhH1f_BS@j=a|9lDk^R+)b2!CJk?9$=xvYl_z4QgL*en zTkWHlp(H+u47I*k#imY-CmSl&X70DSH!j4LD8t4e$(i1{FM>AT^F>6GO@1i$WlS3j zWh`QeVc{eFQ&5KeKNY-|E|0n^;87BW+QdCI>m=}RtgSy;|80Z8jxrHwoWts=^KHhy zmW34z&q$u*xYM@Fe+WH(OH(_XICTnIu_~H-o zU%2dQi>~Ez`O*KR%YA1;41uOB^WomPkF(D?`#f&``sdf*0nB4JjZ3(rVIhqK?)2h) zHGh!85ElFJA(qlu#)?|5rtuLzR$q7f@CiOuU&TJGVO_($G#8&~_&kjbl+?+lhWi?} z1iEToRbaU2`BfvRRpxh%qF1d-KQAy;K6FjTwwBG%EO~prB?YoY%X5rM#n?6jX_R>q zL?^~_`&|NzZS1+B?Z_=Vu(xY+(RIDh3~kR11g;c!&3*I0Fq@mkhK#W&IjE3hooi;j zE`0&xgy!Hd2&H2<(VxVO=&+W?qESCPAE@g6-Pj0{PBNkoDw}SEe}^inc4)_nd9%Z<=H%3WR0WwoKnv z>&9j>+_6bn?pUoAIc3n+P`crUtoSn6k>!j2g?7zQJG?Sd^jaxo;2JdM+wK<5t#?6bE`_G`h{+Y9 zu^=^kAu!vS&UXGI4ton$t&t6>l3jJpaL;Gxe~itmnQqm%x4kQ^FyE2n7VP7o7di@b zimmc69T(iHtrBs(V|Goe;#J)sY8!32#Q6Er3rRc^$*FrTQ!1}x9M=SHw6>29p%xIc zI=;jM9k1Y34G(pEg|9VyqvKnAr{iUeY4~1;iESOP;dKp`jxw(4cmr28NF5cW?$%lM zog>$EOdu;T*|3%p>>`~DPD5444s0DG7-eEAhK!bAvV(Op=8R|x3`8K!muSvRd6$@bzn zZ2O#RN|$;9=1J%A;y%ll9%**4;?%=Kz8nqTBG>=Bm!EhjkZJW#wS&0rpMHTD1k0CZ zC{?qGb6enID{|B^R9l;B#cZVIbDsrv>6&Mj$v10+d9kEilg1@E=YK=u!BcdtO${fX5b7~{rjDQ`u%3H{-k;FNomB1#(wzH_ptB7k9XeY&K!68ApS;1!@P!@gNyX%orXVi6i)C$Dm(cHE9#ZfL6?O0;_@sP(DuP||`Dq0Y zOVy94codJRn1@^B@Z$=eP_aNxe^Nd_BVVUwZ$Q4@Et{uQ?7?6JPpfza&nkFM!Dj^` z-Q9~FyW8p!nBEd|diCyZz0*jVddwfymn{okHwsK`P1&B+YqncSt21sk*|y^up5@p{ zfzw(Xw?|JVT+8n1c8y-M-*GqUou*+Y^=>2PIqoLi$S%;EQl8Uqxn>u|DyD5vT$g}Y zCouou1hpISlu03#eX=7Et+_JUZ}jw-ZbK;cDuHnc!`raJNF)f3Q(7)H`V2j8*gbli zCjoQ)l-#~?{Q#ZDL1Ol+}ib7iWx({wM8;H6Y2X2jbK*OLFk z!3uAKMRKylhMcwq2(!eFkGZDdnXP8hYf4xG3us?MP)oa=T)gi@tzuBoL z;;9~s{4Q}~8%>X!s4vPLm3rpoUOxTJJQvQNm^5Q4*YY;C#Wt9|CXq&|*=Hx^S#iC^ zN=mV+k+9A;H_3kjlM3HY8NKyQiOlw!_nEt}^sY>|&x)CP+bBSdi>ST2&FZlYFXfWt zB?a&fN#vx=zIg(Y8g6{`fkRDLdNPC?Qk%@;4h8zaTMq{8feIbhWp*2>xJL)tz~eIb za9ryO-woShPJ$%O-!IE@@#t0L`S3znN$XmA;3V&34_PTb zv*#QPvtvq9Xxhu|Zbx7aWtQ~0PzIe-P9|AX<3?|1mr;}1WyX+d<_R>{mKId(m{%oC z*FV3E@yuoz6ohovo0LP(ZF5p?%v@&q5o%P}X^?I%aLR#(41!~lNCik6HLS!cffGwI z<|l$8QA)w*G<+UkkOID_VHwWR@Fjd%!$!nq^A!zW#n%Lmvm8AP z5I3vju5xz3cqlM_lp`tlp@tvf#~OZum*oC_s^DiDevX$F{6fPo@hc56bSU_>h7H)u zP}=M`Uea@o#0rxR*_E7Fg`r7!nUCQ~ur-Xxy}W`~{rG2KmiD}91kr017))|)a9J%m!0-0=IkfJ(MR=mq}{lk*}(j5F3s2RTRx>xVN z{q?8sShj5B;hiHlZ5erDaAfe_^~2j99NPZC@NL%(?|eYR@9~;I+wk`7uRQlC=Z@U^ z(B3`Ug88rBxn=0i`-gYz*t>h{(B@r3+jo!LaqZqcdxmbleeZKShp%~L?$G9ez0ce- zbmQjXt-IE)T|1Y*;fHn(-Myosp+UpzQuGP?<54;yYZeX7Sgha=8vZB`^iTM+z>)jb z4%yAABR5<>d>0`NoT1?__^XD$$yI-s%|Gy(Jj1wxe`@#_USc(&H`FQkw}$`VzXH?3 z!YdZkT%#P7CzsQ?s`FAa#w=W4atn+wtOs%h!v##ow1QPlZR<~FaMH(&DFrJT>P{Lv zoE0vSWl~j8d@;V%t{Wq+mWmQod+``*b8hH|<3m$Wl{Di%mrY|u{z8O|KyCg?#|_V( zXiqD39$8;#H7`rCzB|{jyW*ysk-(&QM8C!2)DHl;ikfa&8zf7=OkEr|lF7#W(yTjW z$7JcPuVxW##aKNO#hIm01mmN^ap5*t+!_g4uC5PN`!!$@MF+)qp&kNlCYaP2^d+(6$lr@!&mI)|Y-xQ?{&9r2hC`DyH7~RE@-h)m z>az0Em)mrkbC)(PS=!2g&{A?1=~Fz%zxU91GK`GA&758YZJs%W_zOp*>rTk!#Gv9Y zH@bK?o18B)2t$psP+3^&D3ir%olJcnmO9)@c;W)GsCzTAnu9DudKSM0Vg%M4l;!OI zPLRQ;;tl+d9|Kt9p~7QG5IBr=dr(+qOkTjuS6{@`-zu`sev`D5?-TM(V@%sRugJ_p zx?o5{t@JEU*0mWI&v${+?1c8VZ*jtH@M@KexmH4k)m%z0_AP{F+hckw`IUn`=4@Fk z2wb%Pj1?9ZjO3+Ev^2abe!nnndSZPM62sJxM?uEicnKiZc9vuQwj!ProDh+-5)1~% z$QwoMI$M8dop`bvB)9Mr3uCuuy5umgaLFp|H9UT7V1ynOP(rJjy-pEA6J?@GLoX;{ zX0G(H>^^6sskitSFXl@l{H(-->&^XBM1*0q#c?*K5(3(C+csT4drFlrtz zmXkHX!p6eLm^U(Np)9ZRryuysK;_tL^N%%@yx54x+bpJgMN|tMU%*eX{Rqq$dmi4- zPl`?aELqMEnk;%5nwIci6`xD_ER*-NaBLi(=km8aiSzh^cd5b`E1+hE3298^t4V1b#z!=b!#V$mG$ubvDP@qF8!(QojtMvsQJl;V zwF@vEr{Xv?Vm20{9*Zy^XR(#E=y?d6LxdT6*7!1c%M8&bxT`Xb%^bv(jsYCmGG`D+ zbwsB|r#_CO)0j4Zw>^dFWmq#uqAB;$OyCnFHG<_hmaIxXrUX(#Z4n%eb-0i`T*P;h zt6=0^>|M-}GOXv1H(a)ov+MnX1ZHJX?8Xd|aZDP=?%`o0jhSg2SAb+D<%0Sn)LYGy z7|(M!iYGA*YcPXjHM~ma(9O!Cn?c>9(a8}bi>{Nnc=Zj@-GfS0P|v(U)O19TkIovv z2`v@Rpk~F~@;PlG%A!CHzA2lwmX&u{aVidMRh|qXbt;Mz@64x?~V_Jl8qVxoOl# z8`97RF|UILc48VQ2{C|^)0jVq1)OtA^wcy?3tpYhUK(el(U`_UxsSjOXV6gqn_MSo zi!P?Zquuq<>iX$~w!fFaGnNET{D&Cx zj|`JtI8lQ7S>Sr^Udsyuaxghau61EZq@_Q=vfC#|C-l=URZP{ZUg+DhQ}uIZJ0L~L zr1Urj8!8;WIh9l&n3MP61S~tUoc#W zyEP`88))HbPH>_JY6UBv4Ou+ELknMK@f9izS5MI8426F0a@Uq^)89M_woLTC*F9pm z)G2hyaI9pCE&UP=gp%A!aE(W`Eoo~Dt68k!k-6)77VqF|B5FSpSbwq}{{XXN_`=k&1kT9_p!}%e$W>|jr`UC7l;|lN5cPdBUErx`l zC9M-AC2$^Z(0+=}FGMmk%q8h9k~r;*_L1p*uwSCrZ_{d&K}wfs&2|)U8COVR#DaI} z!)J_tLW+LC!t}35yhQTxK2kTIV#>7jEJxQr>XN|F_j w2K(21unW<>^Yp$*+S5=}LZKhEY+!Tb;@5JmqIzzG!vH=qd()1;$H6Dg8WBwSFB*JEoP+iUIGhFmR04#1%hYmqc* zMo;>0=4&q3?;ij!c#053cvM*QZDl!oGnFVDpJVF^@~tyXkvp#CWZfs7B&E8qI@7Z2 zX#Yp!&TbQHTT`A>%3erYCzRQmO+&9GpAX`Ly$dyo?VXl;&FVe*@*^hV2BT$L^1uq~ q-%EK&$loLSrz$K*nJR7y`bbOB-CRLo621b|RN(>BkuVE$g82=`R!AHG literal 0 HcmV?d00001 diff --git a/ff-admin/target/classes/com/ff/file/service/impl/LocalSysFileServiceImpl.class b/ff-admin/target/classes/com/ff/file/service/impl/LocalSysFileServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..3d43addcd02d86b6e70c8247d712fac184b41f6d GIT binary patch literal 2299 zcmb7G*-{);82%13&_mOaFbRo-7_+bpYbTLJ6A&dBl*mA2Sd4Ky)0}A#J+{ADSBl7)z3Y{uO@j(h7Hen366pS~b6(6N=y9pEcSivVLOe(me;!{ki zXhK#+Go}^HsJM&I6wERtY}aH+Pr06{`*vYyMW1p_Q+UG+4I`Fg1*3E()3d;k9Cw!l zL-Um7i0QDH7v3Dt+q6Q$2DcZuXUTbGF&QjdKEu^1!!7ECf?lv}q5HyHvkakI#ga{S zNGiACPtZ;--k79yGOUIr+vQ7ggJCff`&RNS$1HffDArwXRbLl*y%^eoRpMTtXLm+Y zX1Hg^XrB8*H(XEXOKy={jy|@+AIu7$PLr9G^yw}SmL-H0zQ%Q%JEoosq@|txX);LI zISDd!98NJKiPl)7`IW- zoEv(Eh)Fy9ALI^7m<(;Rp%Yj|v0(WYg>1}m+<;35DPpzh_5b)x%%5A3lEd^N(9EHn++@ZM}T7{ql$Ha=HJz?-dvt zmOvh6Dp?pMgxCp(9!+milI%u^0v9LWpp4Vt?oo2@b%xC3SA-ELC}=RTtii&(guB9U z`KZ~hU{!;SBEzLxqLX{;gWy&JF64F-0&R)lQt&Co?^@61%HfNf=nR zAD5>jJ{F&si_`&PE}|lQ4Zl(#N6z4yzFe&KrFN+@D1K-d!Y7Zq2+{vbP;MqlVZd-F za}a;kN*u_;_KWk?hWFDJ6Q)oA;*QZ(!*Wdm^r-V5zPnL1kdc{vwGx%j-VRRnDLl{h z79>^W)@dToxm!Z3c zqAER=gp=N#-hWR`a3gTN4TeTi7++lsoz?orZSMONAg@!UADik zjKp*q$(zZxWV(J}6Ag84^zp>+XelGz zzljr1aq`c|?hvlgy`G4?>V-~Oc|1{lPD?(<*1j=GSU<=5h|oFg+c6)b|LZ%XiT@3 gaq0;)NgS&p?i4B1X{`>I$vg-EeJIfX9Unvg0_TK;Z2$lO literal 0 HcmV?d00001 diff --git a/ff-admin/target/classes/com/ff/member/controller/MemberController.class b/ff-admin/target/classes/com/ff/member/controller/MemberController.class new file mode 100644 index 0000000000000000000000000000000000000000..7e74eea57db0f3bb7bed597d0b000344babf2312 GIT binary patch literal 3950 zcmb7H*>V#{6um9U64(O<2SW&(4Fs>ySpb7gh&KUBWTV)|fjHYpYTIL^88O}C1w!%# zdB{VmQhY>;RHaO1seC}bBjGbrIXxq5^H{cDx~G?W@40)=-~avo7ZF{h?^>yY9=6g^ zdUO!OXKl1VpX=op3HmZYU$s)4zCJ*vp0oNerw{Y`OX#mf{k5cr$2==cTk=ISryO^Kn-u~+<|${*az!3&6{5^j5^Xz&MeHEuBF%I&6rxYAby}hhn!<8*C`Z)%L6SYDjSd(D_Bx7 zn(S?$$~#5Vvda`BeOsqlQwpAQT)|7`lHk7NNmH3Ad(qMO1G_OgvqexgWIa1ZN75_i zs>wZN6?hs5KzqDir;XBmqOD&>`BQ)Yx)w0e62MTX0hwpvdgqpP8k)pj@Xv3PPlCkhX+1o+Y2?(FWMi_L5s*hE|Rbe*J{oJl*r6_urQHpKt= z^ToeE{KUw}dJ?H3<25&+OFa27bAM)z(X~B0GJ}|@dNRScT$orA zN~Zy%>w(>Q!L*ln+JVPI@~4~;V=Lx5eCri-3Ph}YB{izVj4m`Y*Aq{;8`@ee{F#-1 zj=-(2O&L?yASK+oB6WT5`kHEatI_~t)XW3q#J=lAn7-Z3^nx6%RXjC4o7|s=W&~^^ z)wq-20N|L&Tgb4c>8!8#!X9KM$L5mz$?J?)6Af`!6rELs-cavCP_?RV++z$xtvrhO z(QV|6nkG#k*w33}6@$9i~!jwPsIP?2nd94aw7S8nS& zRW(MZ>KlJuztX&)pt=NQ=Jk&+Uw{9zK`u#y6nO@%(waf*v|-RwdS=i!`s+D;%c!rO zX_HROsJ|AX-(hR6kE88Y4aex9RHmykXu$}JdLiLY7L*kUC+Ae)L)~&2@!gVmTaPwS z<8-?(zc_}V9WL{1b;DMxhgY72^~-)$I8?YVz7ybwlea&K1YcbLz; z&IIEdDbz8Tz*jOPO@p}Nb&-IOO-RpwJ|K8&Y42xOVBNhIdc#61cgxN|quRw0DU?Cw z=vKj~r#BU1Rm^dA&|)RA~a2Zm!O zV*{5v4sKGb);ECI0Scm<)JDTF(g-xX<-@!h@TtJ;qCqGT*hT}6fTGg}90gq~l;hx} zp&zfDU4)F_>>ZqGC3>(^R^nZH4;SB;_&>TP=sFG2jfzq?@ih!EQD3PE%n=Z`_m?f* z7NJctw3%ytmh^FJ>9|_K-41;|0J{bg-mWp>hcpTjLx;ndh9E)0Xq>cMZPab@4{7;_ z8|7zqkRP~L%Rg7uezHOPB(x_VM?&Mcg9W3zJ40v>g|M(62=^Kwr0ApV5I&~#PF6S) v3Sn^v2val-jT&O$eglLIeS%9tV9!*oF$P=_n)SyypGODQ53ruET>tccrN$e3 literal 0 HcmV?d00001 diff --git a/ff-admin/target/classes/com/ff/member/domain/Member.class b/ff-admin/target/classes/com/ff/member/domain/Member.class new file mode 100644 index 0000000000000000000000000000000000000000..02775b815188bc69ec2320c642eb8964fb8b89cc GIT binary patch literal 4564 zcmb_g?Qnp#wb?MqUc}RM}U)RB6u}a5W*S~JOb@TPh|97d6n`0NaAG?%3t?nsp1`7lA@e+nF$TXoY$COT61)`DY3c9YLWGEStWu4 z3%xO4V%~P&?fHD7O~)rU>T*xSf2%TCqExJ{d}Sy)98O?21;-*u6UkU4QAS-YW7|Oc zDh8(+3$>wGdc&X~6oIiHHw8mcG#Conf}tcDOu~C^$t^QSkq13FbJi<1_6Oqx1TU8)tm$4atAyVM4GNVcbj!Qi-3OTF8+x3P$tjR6eW7{aiP zj|lmgkcWkQ62lsH-o>4bB97VEj{_``jVI;iAP(6W6Y{8#aUqWhnFT}Lv2lc`+_aAV zlv>0%jB^a!8f=39r1X8 z6Sj}j&BT59F#0*TALLyOd->18`8;b!`3U(gUPt-=P#t*!SkKLhk5a)JZ&rMq3f6tI z;uBP`7d9(C#c7_zr|}u83VeJYf%385g?9QHVsDezu#YssD~Q&lSx5z)=T)S}&^w3= zG!}w7c!UyL0q|LTj(3_g7iqh(-fq0RqcNMZgR#+W{6I%zHggB#M7!~W9gVpOIvAVn z#)BP=xp_JmTkXc99gPp;NMKxGdZjvvq2X1;e@iZ$?yPUUT_J*WOVy;sq)HQbyptb& ztA13AYIvfvA7iV2R7Y!=?CdA8RX=J2Xqf8k$K0wPwO=$G?d-?esvotzG&w?5o?|*| z(akE|9v->^L%%xwXC&W(5x+Y8CnTpvhSresZ^?8W9U&>`qkln{qrZoq71*PWz6QIA zNEZx3(uIU$2qy6!aw|wXhLZ?^G6j>MOu=$Y0a*dabgU4lyO1QPyO45{0!js-q>~DP zvV|^!vIX1e5|AB$$b~>Xg)~7ug^ZIHP$mGSolFy?U*-Dap+iA+>1CCdR+rw!=W(1_ z>%}@w@SuqCnEX3VQWob}`x~Ajr{geIF-^{3&3}V0kV~M9*KmrQi5gzUX>$CEf^&G9 zToP}>!xzb=u*M1Y47o1cp#LwCv+)le&0i*$#y_zWUm=&lvy68Vy{2^=858dN*luEm zf0p(>?p18^e_|OoCv33ueKuuzZ!(QnBf1wX1UrJfl_+tTT>Z;|%7wJ_EnPJh>Q)_H&fD_Bf~J zOE^nT=Mgv0;z|pgW)qajCD7n3Tp(v+89PuRXGs~gJ+MEZKxY{>jiuw)%Ma*m<31*W zUKmY46Qf5(0W1-MZ6MpF0oaU!H}D-4fr+)rWW%bnE-*}XGTgAeqnhT-H(#MtSK&qG zT!#6ncd?D5|DIg$8n#Pwtzk#*Ud5+*$vKMWCf}aBPx0Nt?^JwN_+5(c5q>wx8t!i& zcj_om?+2%XKG66+`&GQ4(V0im-z(YWF*CXPKJu^b21j>cZt3Jdy~BU@J&02Y~!_uk+si< ZT!$$hL!GW-Y}Gxy%5OLPu|Zx8{|nD-d`yW4!1ME>29mVNCR(AzAdWM^D4Joo{Al(Bba zeJmvCsWLrP)#>Vf|9E`^aEYTP4w^V*=%&(_ZZ?s@R3^7CV~>Fk?1gw1+!x`T+fg_l z4Q)3H_-w`lP2*k^2o-W88ZDXFD$TUXI?d3u$TQ{hLO>=hN6kZ#<%wi?7_9BMtiD>y zz9#dI3R9VsV=|on;Xfut9(y8_W=0y(qny5;Ca2zNPNcJzi77*W@U#*sQBSJbn^rfj z8|5J-c=6lb$rAOCMI2Wh??oWL{n}2HC$79xJ_T%)R!Eu%q9**wfgBrE$MNQueg6 F{|SF~#*zR4 literal 0 HcmV?d00001 diff --git a/ff-admin/target/classes/com/ff/member/service/IMemberService.class b/ff-admin/target/classes/com/ff/member/service/IMemberService.class new file mode 100644 index 0000000000000000000000000000000000000000..e59ae93c0fddefa29426ffe8d7c1678552d25e39 GIT binary patch literal 693 zcma)4yH3ME5S$AkCLutA0|?PjP$UhfNOVC+P=F#CC|puq>`Qc!eMWvn;@2qn06q$_ zK8J@LDNv1WZ)R3IyYC;bZvZZEWZ}TVAwwsTf%MXQ8BSz;^D_1sc;A_eh2VkEGwwus zHX1ly6!Phmhla-eC=^QbLNuzFI4Vhv$vVxTXpyBV;JJWIny#8@k!G=Ec<8U~SXE!H zWnYnbTj@l`%P|>F|L`A^B762lDvKEzx<2Lf^~`fh7<&Dum83}7sZts2)kukWQqI0; zb?tdkrYXVUZ;hMA>K}_ZE<4_dP=5Qh+$f7Zd8+~n*d7<%Tp2HvC(rYRGn|!IMv3L0 zyv(Hmf6n7^GNn`8r;v3 Jl(td!J^>qM$ZY@s literal 0 HcmV?d00001 diff --git a/ff-admin/target/classes/com/ff/member/service/impl/MemberServiceImpl.class b/ff-admin/target/classes/com/ff/member/service/impl/MemberServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..fe3f952c8b6acb5d6e3713f9a9c851987430097b GIT binary patch literal 2180 zcmai!TT|0O6vzJ?kV+dwD&k#1QCmP3yrLioC|WI`RCsa5nY3N%Vw-f5tqkAE2c2=e zJ@^6qP>yGlP|_PbBR{=OyCh_wU~?JG3Mh~z!SY( z)Uzc$Th`*K7SFU;(c*awFJj2V@RGr-h)Q0#t5&rtT!w4ef>Yt!+dSCj6@Q{wJKuQaX<3BuxyWSTLtB~d)%rU z@Wq;PcBLzdgzcG=wp8;BU8(dIL-(>%6b$`YX^XX*_VTSor!ge6PQfZ~S+3OUaI;%| zkaYZH(*-=?ev$>jWu;mUuaOJ3GPFa7p7can6jX4-rM*m%fv2)N)+dXXExW|Cj$N8f zH&KgD#gcZ&BZwi%>}0c56Fe(D<-;38+{j7?keZTZt_^fpf?P0MI>L+IoGjUvs<{-S zwbY@?&Bx3gsy$C$n9`?E@0x>_Cd)3V ze-5<#qkuL;7*4fjix3wY(;7IjSSUDDxeU`$o1D_MdSs6Kf;7|_$%yA6f;yw|*ymLL zb%R7Hx{BwVnp+SnQdjg);9sONCv^ofq}q0qr-UmUwO189G?_JV8bc-qkc{D#iHo>o zVi+SaWKFDMErxXyukpsj4cs)bp=T*QOJmH$Elir=m@;t(Qw$T01xjf@q=hIa2hFmc z-=SV&7;R6;G+dKmq*1NSV?&7yb@G-cxNZxNKc%YL)H8;7NvJhvSMSifkP6HCpm7iE zgY5B!Ze!^4gj#k5nZKp?tZgyTOQf|n{bJTy7@?=PA9Qj03>|VBPtnudL*pQgy);rb zNS>h;r;*WkZ0rZvSDF|&OHwO?OwW-t0|lJN1zItkJ(AjZfwT=86Jy_CjQ>KHfiJX- zB8Gj$P@onf$N-mdg&@?aLY_hI;)pMxVv#^EgH6i&i?N)-Tnep$@a^$y84{CB@^kOe-;3jgh6% zZrfe49LrgDy#?;ASti%$MA~%oY&&cz2*Sp2C+;9Y2HcaVyo6IN+u!*8{*Da6d z0GlWnLg0F?%x<`b-8#>fsexIh_BH^b<1kO2)2Jyqu%uD*l$(QziL~YLxne%cy+s3b zHR?*creQA`o~7Qy&1Si3fq$~3GVcP*^;nG$rd&sQu5EJ<>Y8m!NR2XOk!m02+`M5q zwbEk)C2;?y>3WSJ zV>b&WgU7br9j_s`lb&;c9jzN@!Ofy)Nrc!mxe%=2@q#NP%Xl1-UUfa|4u^2dnqe0a zi2n0J99=a;hI@G{*&n)mv||0Ja&iBFMk96Asf@^4POdtmE^;|*6beW`rHBPFit>$u z>mgW+N#E)XKap%M*{YNUb_stf>98@+MFEM-#~SvAO0`xm6jKSLLePK$B#?@eMu%!t zsXaK(wODGy4tS>47plrg(~!>jb5!$U$Q|* zwM?Z`6LT<=g_6;tW4q=pjDnyPnD6@qsU||B-ft~p2F<}P)vW!NRt?gK{{s@r|N65B zKR>7WF!0LarPMrdS#X8jE$M=9;|p%lGx-HeW&eQ}wEm-t(2FKry_STe zk~Nc~{*bIMdb?KaNu7$crqjAoyFnLq+DEU&Xj7*439GMgsfKs> zA#o;5d*$k22-m5kx?{h)x?rYkeBX?z;nE(oHGdpvG~4ii2@0n|>l3+xFBMN(ujO;0D90VQm?FNZN0{ z$N~JTON2{r;$IIg&|7p6Zy1SC8u5kmSevldGq^>O!3Wed^oW`xG&?xFMJ>PLpotV% zr+=xBnyH@>l=MM+1Hlj!5OkQ{26zIhd+8kjzY9sFI@syMjuB@-=Ak29ZCeyq_68KYAVGAD+UYnP zcLJ84^l6R+IAxl>bkuhluzkW2Nc8xGn;;hl!f_xe>U+T@IO~Is;Oqp>lo9>dIf?TT zL8s_6r!#c6WYl{!S~hA7Pvi7HE-Ry^utu;Z218G`M`(+5<>rX*<{)OHK5wNRSIfK; zbdEj%TuFQA!t>i`OweRm`xH$BBBs(Kg$Io;&_$psD&u(5uy!gYkEjDFzD1oCCUIZ; zB(;HbC4)LcHZS3Dsfxo4)O<*nLl2|?tIX|B?v{PDy=^9eV_+E@RKeL2J_$$p#>kP3r~x9zY5?W6_@@80^}EJ literal 0 HcmV?d00001 diff --git a/ff-admin/target/classes/com/ff/monitor/SysOperlogController.class b/ff-admin/target/classes/com/ff/monitor/SysOperlogController.class new file mode 100644 index 0000000000000000000000000000000000000000..110037d9621645fb506fef4de56b5eb3f4853a91 GIT binary patch literal 3209 zcmb7GYjYD-7=AZR6Pm`hL@riQN((d%v_}*uwzbepfN0u=wp0*ro6TvuxY-l;oRn6_ zpWr7yFyr{u?>gg@K}Y@W?@)e*<8yX5Z32tL$;_VHdwJe_{`}{c--+lV-A~Z~y`Q3f zD)!*B)Jw~>qK~B{-AdAGiW0PTh%V@LT|eH|j~jaTf!^Io(%mF|Xi%T1bFV0>Yuwwm zEp8AiTB61_H(A+~oXK6Oc#X;6l@-=@<(32&E~`wVQZp~M5*;}wWa%-F82W)14fj%^qe zUl0|*>o3|aUvAXO+*>!H&7e$CSf;aKdbU1?mvOaaL;abiF*N~M!eb$RM^qPtt32U2 z+=H&TV@qYwQnpFoYJ5f1Oxta;!dKH{ZDf}4IIEjg&V1#IrZNlerhwRF=v;%&wsC}B zeO9nR1I7F1w#gdGc32UhAmv!QfxGplkyoCgo#{-;EM!ha#zk_g;n@lyu`Dhnt9!gI zq+%tHBQjgUv%lnE?%pu`Q+Q>?S@sd2zAIWgS_^r#th5 z&ZVnZIKqm;i)j8w&`z|;YAG9?lW>@_l`e?% zlW)KI>$mTpJpAGBKOW*(Zb;OOlVrIponWbJC!A*F)CbofZGJ7vbYsYk}tSFER5#<(^&fI--2T^Z0x=#FRD^yVS zho2DvqZaeU{CfU{Mg=&uQIj1TwaAfu{J^Xf`$`u9uzYRMaC>_!nYs-s?zQ#F%N^?~ znQE)q>~zpA2h9{#Wjpjz_d+p0w+w%66;YDtTCEh% z>%>}#nWi#XX{r!U(mRbo$vz{9WSI5KbnTeCGa;3*uI7}yl*4Q$XB62Nq03HcB z{aRjdOev>z*X<3e-tUwC)YS+&>FZA+ZD|y1O8>?1rDrOBIfl-d-}PIuy$ib-r{>4Cx+F~ zx4B1T{De)6Ucpxr6Aj`=lnw~!ReB94gHF)vpwi4WtX)`-=JqI-`6Vc{TQ$WZ^O_LyiMRu z8!?I-hW9rmU7)u(y^a6Tp;4FUGQTY5{8uYkw~EbZ?CID6QSx8neqj zZmk`p`?&jQil!khTKh~>`@1x|ul*`rgNUR~k2!1%ng@iyzcV;#AM|M?kLe}!mp$q` rK$7yc&r%OvZONd%5KT0O#V8DU2)YhMF}mSH&tP{G=K|CRK6>w80k>^| literal 0 HcmV?d00001 diff --git a/ff-admin/target/classes/com/ff/quartz/controller/SysJobController.class b/ff-admin/target/classes/com/ff/quartz/controller/SysJobController.class new file mode 100644 index 0000000000000000000000000000000000000000..a2d331d919414443b7906539808daa9f8e1186fd GIT binary patch literal 6794 zcmb_gd3+T075`2WvYX97bOo$c1X0WdPOS(wsFfUQXn>eN6lhB)n;}`)?5s1h3Bg)R zy%p59DuQ_6Nv%+zHUvTFX(Ekd-F_cru8mLUbVx2Q$>p%D z9g)kYMf5X4d{$mQ7r^HO_=1AaTC=^?uzI2qL&5n?5wlxcvqrl-hK76=du&PkhhVU{&!$&6|Z>mx>NIbZ4g6(^E8F+4N#XV%MzOc#0dYYhK#2Ou@zD z2D6#0$)Fj~(l7=(4Mz$=!8|YbT1=03YE33l&rw0Cnpn72Ur&6KF)4xxq*r6dNPT4V z2~Pg3U7s|pK1o_oyTLVZqk@^)9jaNEPUIL?R;!vf{+M;AE8TDCXQAFfFY8XaYvhW# zkS;5j*y`w!bxdojn}vjQ3Ad#N@NxiOR4_e%2I!8&U);E)wc+HzY%!QU+o?4>`WRP{ z(Gg`q9;fz2z};$jbN#|)4JXqCnv*`-sF5y`!(h}-l3lwvZuBmaJXGWl(yt*dOw{}< z1jS0mX^9rL|mfvs7ke%J6 z)i*RXNYdtyn|SpG`=601w~`daZE`%+Y9_6Sab;9G!IaUb+XZsOdx-81LscNYMLu1lZT!zb4d|58=E2Pm4BmFDir-4!e}~_z_yb;7@kjiLKps7^d+7cHBS8LHKEENK|AN1& z_?xKwUDkSJZ3F%xJozU<^E6}|*R!EJ9vs}iZ}`aVL)#yF{m@1g|H8i&RA%#!;O3hs z6;x%@fRmz6yq4o58IjWFm?)ESYD8>}bQv8Rg+j8Vxd| zZ;tMpbGV-DA1dl%x@|9ziLcZfKO`3%;TDg3>KipxFYp}-UYBsKXX3Bzlfi`XXX-F} zvdJ^*2kfLfZ?hBob(glUWnRZS7oEx^N*`)i&#B$E`9n*=`7G)??{O+VfUde94LEVT`U`{T9FB5=ARG7n47q0Y3=HUmX@V0t6P_~ zC^*e8ok|N2pd2u!TSO|vlHRVUV|aC0%A_o35y#!+m)b%XLwAhYzC1v)a!QyT!xG52 z-3jWtk-TtBnbp~qDjIXt?3jK-*u;4o&byoxX|9SeC?Jpt6Bj&J=>MJ+7wVM(WGf z-pV4bNED~@{w}UI*;tGv@~{eujir2Q#x?vXer@Ac6L_B?KFxN0T5=G@E5d>O2-Xyx zQB*xAT+)w_#Ot{jrUsa_QYLIFQ#PHON$hhyJ0ot+Knq&A7j3%^7f@r0>u@3ULRg07 zv?Q)ir7zyMMcl*t*2ZrVL^)SdL0pULD7eDLN~|*QZoCKYrFk!?)qHv%bP7vQb-Wkw zURIULbZG(lp-P(lnAN*}%kC5%@w*J|h|t`q6n6MhXkZOhRG~wsxL{L7K^LNQn)@ry zF%>kb%&qRn!~sm&hI6Y9qHM)}oDx2@A7L(^##?wYFa4O(kEwgObb9!V0lal<9@#Uq zWhcCZvsM&_r?svq3ZLCNfa&@4X5`d6NAzYMPw(7py?r?EIGfDM79PO)`9d!DNwO3w z`cat%sY*bq&eTE;CNaxPNtJ6*MJmlBVcKvl;#h%uunNzR0WV`UUM22t5VHTkP^O_% znMEXokS?&w+%&L!TI<%$I(`eHxT<>o{MnU=@vWF>b5%n90 z&W%LuTR@Zf}(a%Z~7PC@>oy1n&OX?Q5WGy1; zx<~iM^*NkQ_r|`_l-)4myh)ql{Ipb`yr=+|owXGqR_5GiQBoDYSb7r$yw)F*u7;=B zte^HdJZ;3`X(@+G5hh~qr?k`>wcf;3r6E8BrP@w9fDeog;3j;~>$GlCyiV^Osq+dT zzGphU=kgvpu{T4HtZu&%A7VyFw*lX|bMvU&-a_W3b9-CHwN8dsKtjs(4i}#=pYG)Q JT_fUm{|~(nsU-ja literal 0 HcmV?d00001 diff --git a/ff-admin/target/classes/com/ff/quartz/controller/SysJobLogController.class b/ff-admin/target/classes/com/ff/quartz/controller/SysJobLogController.class new file mode 100644 index 0000000000000000000000000000000000000000..34531df3e0b8cd5b345ba9e5e97db4785f62aa17 GIT binary patch literal 3630 zcma)8TT>KA6h6HyESC|KcukC=QCSe_MDY?JL~bg$;0BOr%x!jQU~qS4o$lpgDo=UK zAE3&&JS2}PQxjw&3%58$FzHDZd<8E=Ye1VS^m9t^FVhLiKhArDt zBa9l7J&TOur?&oW^b^OBE+ zPC#7Kvn7!5mfPPf|p#HSP@ER2cv7g6L`+FS9r=n1Vp4&kb0wQ<|cey z%;}tH_RH1OQaNKPBH*aK>3dQX?v`e+jel2?@jaun)g>%#>QbeITUE=h)o;0}R!ap* zbLWb@vksoGCm;DaTR~f=!7U}QC~Ak^5&{GEHrZFMZ9cyH>$5l8J5d4AG%=Z)T$lvJ zx{aI=$UaeVuu)-Dg3`up4ppAfg=C#38r31%IG&muodtP35Y#&F6y2=2W$CCs9#Ovg zb?MxzSq(O>`2CdVEL7Q5yODRTu)q?)N12XCjBlFr? z=*Ad&U4<~++!S61Y4klt-PL;bd@vwmB_b!QroCr`ZgPw+*U@j^YK#Wzi0-sO%fB8J zlS=Q52)xK1eK=f(#&f2WL%LbC`31`>?~G>ZZWuLfc_@_f^GZL2Jn2;|jBV*s1{ORc zBdSC2466+T6qkf7dOaI~AHIGsvj&dqt*3{Uykz!WqQRid9F8bfQ^-f<=u!-aC#NC^ zj;hveUIzQZ=?tEoop{DFis{6_cm%5^j7NhJiG$S%tT;x7v9b3BvEML>(YwJR!h!cN zH~a&1lHSJ(c|)ghN?*=nY`}P=cZXuVzf;4-mlTiDOmE)~H9p6W22WVKcj!FD=>m07 zwqG3s4Wi4`Mpr=604%)f!5r}A zlwo#JA6TCsUL*KJ?KY)#s7B>I{beh;-5C68#{p!A3eu z4AM}BaY)nOu1R=F9dP>&9jqW}^$fpHEwt#N@q@QLAfkr+GKLu+!)yq{JqSueQH(zG PSnI@W4(s_c%7y;`Z71Zr literal 0 HcmV?d00001 diff --git a/ff-admin/target/classes/com/ff/quartz/domain/SysJob.class b/ff-admin/target/classes/com/ff/quartz/domain/SysJob.class new file mode 100644 index 0000000000000000000000000000000000000000..4f4f69980148396b457071478a09a17dab79da45 GIT binary patch literal 4835 zcmb7I`(G5-6+c&m9hN~6ABlMwH8u)9miR~;6{{fXT0qOgXwt?GyCV+n&TM984cIo( zsMVMdjE&JGCK2BnwdNrbNVLyi`ggEE`g4D7`#m!Q4#SWpd_H^cIrp4z*J9!cOYb@*$GzD_Z$1vCdF)3Z9y}K?;IX_@7mBuw+GK3 z%iTINbo0tUF91wQn1)`{o-tL6qm3vIzIk=H`|aWGYs2^N=f3Hhi^!)nYma8C+l`c# z=m0-_yE}LM)X=T>hfZIHyu?(MByMNFYTBv^V}iC;RDRcgcKG(CCC^q4efCza^UL9@ zS8`qNy2h6*uXNdg-h+cTyS>E~l>@z=nmexnCoTT!4Kca9XbcywVJNk>jdR3 zD%*iOuQrmn$*HxPuGVMMEvnh1AaMkh)*1=qq=L)@?=4QY_i8xi$&rhGC99bBfmqT= zE1Di_?69^PEx23>Hvo!rv~*FK?^eAmm8?ZP`mOdR~f-wyQl4PEaO^z`?eYt#;? zFqN0q^gO2wK`QM`uE*Z-W`}!@4nH{d+{%I88*cI;YGZ4YOK41eM%}2mplABy;$h~< z6uFV{N}$Ny;&D?Ui;pRSd7(w%2Mz?{--1?zDt>qRL9P#F!*Ox}t*WT-A)1Qg#~wHh zE>s5!>?vLd6j{Ip`mdnH6RNpKFJHCFcl0zI9XzN6hu5p^+%L6c6S|-;{j#=}ifvSE zzQp22TS@GzQ!-vwFLl#du~5wI=~S!@Qp?c&EpjXPO@^6PY|f{QVnY?ZV|oYvme$oR zO(y4V*|IvFUTvW~*pIrg9Rw{txKzxc^3{1UBl7Wuki$`@t_vX>p(WdJ^8sbjXk^WV zx=G`LEpp3m8NUfKHBytHXZ#J{DGt0QvBtz+HJMGRILzYb1s;nEnc}oT#*4a2ru9r! z^H9UXX4(*;FJ=0Q?nbCbrhC*YQyojT(*{8mhS?fZG77As0Mlt$b)KXZv6ifsN~&h8 z$#b~M}NG z(28xf3X%uRM_ryTU#36POVG$>&>b9&zc?B$?`r&&H402Mt(f~{`Wu@)!b*>OfeY(z zg65A6tErAOz$!efHF$sRjtKo-&_cgn@V)gthiDCcO-@xS=H78L(}1N}=w~(QjE&bQ zv^Bga=!vmTI~mU<;@KFfj+%Bg0U1Ai3&NU=+mD^yUcD^)!8hD!cW^3})HT;O#dp`n z>uYv5HtnjdL6+41I3p;t8ozhjTH4fvz2?VS;g(sTWHPFbw`ix|px0A`*$+R% zOKAAYZMoV@MP%+M=XN2MHhXF4N?p#Ca-lakDfsXXLqE}I9zGqH;mIka$0$Y>B^^VqUUL~O6%z7;84__yvUIYmRCW5LLV>K2my+JykHXqXb9s4 zTOdFS@dPE9Js-BxFD$Bs6fI-Cw4SBgAVn`3Fa0G;8)!NtXlNLlf$w=}3(Q63_ehkN z=G~>qpF3gLfiVgp(JY#b0KEW8c2#L7?E)vb+jwSTnAuEz`B#*G2gD>|0|n0FTHogU z(apc2UwfO^L7NXMC|`V+@`J~3pnQaukDujgc^25ZdryL!9pyQA{Eid^9oZ7%2w(CX z82$~MQ7meq1S}=vq|%-^wer$l(x5Y+Ce5HxEs!C4g4$?b7^s3Es5*eEp8%AbT!Ndo zXUh*N5(L!{0!mOi+>uDokr&{|&IufGlUa}+8eJ*q$jc#)1fpwkLG2$8$_{|?^aQ;c4yrH+$^fX$ z1fbj|BKTEDDsx?LL+Wrr&OkvH_EPi%RJcPG-4Tp2&#BKTn2E9|^jFd8I(%4XcvW`5 z(G{gmGvsFXTl{`!(eE+g^8q8D=1?0Gvc3Y(2PnZx# z2BHG)D}f~ zIK#-mAd1$?TdOn;FPV&OLX}z2|)PoOAE~``?3q zh-ed?3Db+Dgs72{EK)4eEL0W)ECyK|W1+Da3efQoWoS4|HKYe=O&AXio{R)(Jx@*q zsf|Z7NSk=Hg0z`OJ4jo3%m%50$I&2l@%SNc9t+TTfKCdkw^UP8GQFy4X@=et-6=@y z5mdXw&@Efh?Or95RjUBcKOrbMWF%w8U^I=bu_0wtku!=uD8~$auwBrKLs{L{hSgrp z(vlf51#PhZDI6mvfiz z2?`)!cizxY5-)C>T0WxmXlg2V;acvCOEWiaIe5EGBRc{=j%8-*GZ-<|^ikuuno!I^ z)fTk$@vU<+SAU)P;g9Jb&*yGV%>4e#qx*LRg%NI_YFWzQEXt#Y*QU?>DX1D5v9ov; zY5MaUkFQ;vxiC3>`V10bs!AFO8&yqPH6vpPzNoEp`sPo$`}fyv=*<0m`|;iD$f=4K z9pP+5^#KE3a(|!2ih}nLyqk6c*(;_tYik*Kr(&zfPSCQA5yx8Hq3N34C1^oYb1(9? z!$@OKT};!}?(A?A@CuEEYMjU->Pb0m3@e&0$H%Qb z`2r(i4HD%{xY`X(%_aGF>s@1&E?L~^X(zwzKi*;+|Gbz!V^p-?xs7a#r z)GARMi&t4}VzHUURu&!9DNz@73TiXVL0K75QpZ#o2Xz={Hh;7?%E_#jNvo!uaAR+G z<^lRhqL1km2m3^#U9?-GPwBKoduXpj-7F5VNU-Q-afJFLdY8rfv=tuu=yrX{adJa6KY0wdOzrsMG~!Pbrj@jsULrv+V^%@0 z;Exu;yczQvj4k-DwP+m-Xq)*483we{e8UD9&|dQm8(~1p%{ROT1KQ9v)MISH69nHv zuUqs6boA%^ZS63iXY>4MTZ~Jv2;C034Ko>|z*yCCkHqc#vh9%7`GMDsFi;Z}HvyHbvddT_CIAP%Uf!qKetj;r!DMssb&CU*@cG!!w#w1HtFU z2V{X4WScKYjQ06~EbxNt0?6(%AWqE%pIsl2N-xM>Uy%L&AeCN_0{}T#2E^$xK?i(6 zs=OdQz90wvL8`nUM*;Fq84#zZ1z%)78L9Sy^!tLu{Xwd|AZdW8Wk8%WB=|D*0SS0P zG+&S&e~^F|LYJ`*V(O$P027Am_?}@O8wO4nAx?AYm`ad0&wC{6WHAkc$AhR0f3aLk7Xe)dl&D zDxnb_o}!w*mOCWfquPdrEt6C?N%akjpfs?u7|Ie>mO@#^%5o^ru(ATmN>-kQ@*FGA zLs=@1G%-wR}tMvCz8?*bQ_6faq#vfS#G)`Ysfrjz!s z$3InHG2(jK9T+3boLUB+aKgaj!8bTVDEmRIqHjY9C!4+K5^4k9LZUKzXW}uTX+LE) zFUd2t`jbj%*z1TTS1TE0B?()0>yc3Gg=yrf8(;I9n)8L;$;m`TXR~1mr>i55&EI1A z8JGK5SaaVW@d@n^2syqkz{;~A@{G3`<*>up!tNXw7#C3jIF_+z;yx-SR#7vtjt1v) Im!`tO7m(G*xBvhE literal 0 HcmV?d00001 diff --git a/ff-admin/target/classes/com/ff/quartz/mapper/SysJobMapper.class b/ff-admin/target/classes/com/ff/quartz/mapper/SysJobMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..42518b0754a133716375e59c1168d9d405f759c0 GIT binary patch literal 648 zcmb7CO;5r=6r6`hEduhTUiDTlZcMykO!Q!ase0(q)6y~tEE|cs{c=1#Q zk#OcI*9^|=iF}nJ&w@}C4FiJd1b!s5JW+(l|8-w&eCwLU8;kL7!jRCl)(mj*=Wx63 z()R6q=xN*9SSTZ3*m2~u(@i;Wa2^MjDGsGn=vienzZ8aq)=E`M=v&Y0>dbuRNv%dW z*%Bhlnn9GRq}Upv?!QiCFg}D!s)7!slNMJXjw>TFWoWmZ9rxq-a}H<{P54=^^+)Y!s-#x^<{y9IJbPb>7l0hEHaTmS$7 literal 0 HcmV?d00001 diff --git a/ff-admin/target/classes/com/ff/quartz/service/ISysJobLogService.class b/ff-admin/target/classes/com/ff/quartz/service/ISysJobLogService.class new file mode 100644 index 0000000000000000000000000000000000000000..41db0d03ca4140e144b3fcaf6cf8d43784931b3f GIT binary patch literal 590 zcmb7?%}&BV6otduCqWo?if5;K;$i!I03;RieV;)=Yd8`#LWO=dK@`xtLDHQz^4z zB_cDIIu*e(uVv$rKa&e7%0efini&&1fsRvIl$j#j|N94*n;fs$Vh#0r=|vXRk|Z*X zg>TZB(KfI%s*Iv~5yHu4)Ca;r#32=`9;%#k!q9!JQ~2iXG2~AvVc`BH?1hPv=?6#C z9kEY0Fl8318=Y{9$KGe)fyx#-RA<$$gwyp6^ZHQyk~7R#ICqm7Uvry4Xz&XF+ATs8 iE$+9tYuMhwHo)II=-S%Dj;*`cvvnVR)^Z+p;_w~wA*ks9 literal 0 HcmV?d00001 diff --git a/ff-admin/target/classes/com/ff/quartz/service/ISysJobService.class b/ff-admin/target/classes/com/ff/quartz/service/ISysJobService.class new file mode 100644 index 0000000000000000000000000000000000000000..e15e204c3191c39a9e4c97b488614d15e25d5b9a GIT binary patch literal 872 zcmb7?xlRKy5QcwqWJw73eN!M28r;xv(Rj={s-yG*OSEW{(Y%KwnDfG=)yp5iZu4Ht*Z*+Qa*Caekuw{ED z5=H(@l|E5~&Zx{G>Q@N0H<3J432kYj+}>s=&8>>$X67iv+E*WGe0IsdY8gg9{6DGI z>FF>mX;XWDE+NsyK9QzlB*Xe!=c=%h%Xfo$U03<3u-6@Bj)9?v-X}2FM`odq;(m&H zkfS)j06^b73X~tDe0E=?%urWmxGOV)(Qj2_U7B%BeA7&JG&!OuVv43s|B#!(Eb%bR IwP@#G0dG6sdjJ3c literal 0 HcmV?d00001 diff --git a/ff-admin/target/classes/com/ff/quartz/service/impl/SysJobLogServiceImpl.class b/ff-admin/target/classes/com/ff/quartz/service/impl/SysJobLogServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..b5ab374649c6654236a027a1700cffcdfec4b440 GIT binary patch literal 1739 zcmb7ET~pIQ6g?Y03T+e$h~gJ02rVcph=77RpyN!Ppfi>!4?d;swl1bgO;VWpn|#n2 zXB>R+2l%5L?Y~}e&Bgw+8!^N1>bS&+-xN9y_)Zw zN>>yKc6e9X(tpY@kV@wm2A?}c!7ye>TfDAS^1?kd=`@B3!zq|n&UB?(N1KEGdr8Ny zwQ2B#dm;;h%SzR1D#?bs8QP?C$30<*f**=Bq~|lNr`m9ePQ{dV6JaN99GfR5uldsA zDo61T%gHd;FPUL9E6cX&*Id$b_}_=^_B-HdyR7|srWnWySX-uD=7wXJNyhn}cj#mo z31zAL@lbR#orIXhVputb`TjzvugM~n+ZSPy;zeznO1*1`PG_j1mQxPCCp$h9nRXn8 z$y7I#Arhe2Ckhsg;a{@xtW$Ff;-yq0HPaaKmeE*MwPHwhooLS&u5kQ%Rq!ZfN5?pl zI&@r!;jxa(xT50*ZtB>-mLd#Z&*#KfX42vKr0W-Kt zP}hR!>-0vAA=?dfuoHBp2k0#32!v4yZbx7*B8Gaza7e>ZQ)N7$wMlfgS`hUHO+BJX zmB&I4dczt%w`tyQ0ZTN%61aoKfF4a<53pD#*g+4lbflH0Hv-!Zz=62ZdWI2(cBMHQ WjiUfB>}fnAr(q?KaJMli_kce-{)wpo literal 0 HcmV?d00001 diff --git a/ff-admin/target/classes/com/ff/quartz/service/impl/SysJobServiceImpl.class b/ff-admin/target/classes/com/ff/quartz/service/impl/SysJobServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..84e130c60fb254f1c495dca5e4a0cec52a530d36 GIT binary patch literal 5723 zcmcgvdvqLS75~k?CcBxYkTxl48`_#u(mc9aptMO_nzkvXBxz~VmWPUy%{1M1v%AdB z_63M2qM{&(FHj3sps1*A#Xtayh))z0@vR*7c=+F==XlT~t-t%t>|{1s68OiHlbLV6 zx!=9_cOSny`}~!e4mUFkx4C}VYHvpL6f(z$Fw!)kS? zkhjy>kv+CKY8}kk`;$YKnJpyum?U*|f7>L%4bQE)9`QxnWDg?A~MxECS@xhw|1{M0 z=2B*6muaWv+1rdbd((7y#Ux7w%RZ1!S;_QhKI7RNaJPE6L!%L~Nt5(eL*t~=!?{s2 zo%PO9Sf^BPx z_?nJKH6*$ZrL4TljE=AC_=bkXO7)>&4z}kC&L$?$v5P5jYgWO^SSg2rc0ErvPiubp zBxk81K9C;CnoiMX?EBx^={Et@cW>k2o?#7iPenFkW=E2}x$H>i@@f6m5M@&2q?eM3 zgBq&xX0c!qIwLiM<2{t7qRZ`EF)t-H;lzL=)z3IY?A$??nAW4?n>tQt=&0Boj?M01 zZ?J=cc^RD8Hl^^Y?OY}^#58Zou|w(t2K_Wk>}{)19CabYhnY#oUDx<)2^+nd+k9<6 zg&R0FQA`Dg@6Vm`TE}%7jMQER+G4#qMM}jA-Xd%lvoi^4%Lj+2Z;I?HC3I_A2Vr*bzE zweH$yG$pWd`fLXx?!OrGig>=U9c`ohX}bQRVL3E z4CIP-%G#0^s;YM>ErT4F4W~Fpw8pHVQiaXy8vMYG^Bm&$^jr2#`4@ntj{QK9Z$|rIj`Gl;xAzS10`` zK;oF#=wUKVPDqZGKnVOg^}Afdg~3o*C6Z6FH0=(i5Z%xzxI z28v|W!`za*0_UcI(u>PIQ;{wK*va85%$Bk(l0j)#_5UijzovZcOgl=11FA+Wp%|Gb zK0-g-^rzZ=?~RFar~N_E9?a((m-bShbxRAQC!4kGO&POL5C)BI@7g)g&6!wodxl=| z6w*zBLE>3jnq{*Uu2D~4qEUM6u?uGpSs0Vt8vhM zh+lU!li*jt$cSaD@@lVybW%)8Lrwy)utF8fobf7HPrFkFOZXAr0u8MQ@sFI(^$Pwf ziSeG~JtWjWX|IOQ91*-;Oo=4#8t>7T$Dy56M=s%26aWjbidVxGz@=EtCk<xxQL7+s-d@a95D@jZR5~2+>7(LsM0t$;{77r{sa=o&%P=KBM^i0 zX%a*eC!RUP)6Tz3h-EcB6ekwbWIL+RfljVy(sO4HmSHW{(XI8|6<6Jz%edOWof?E* z$9x@KIyU|Xjo8G!7~S5CZa-36xTnc*Z{sd`t; zbA<<#dm4I_^j0e6u;jIpQe&#pEpMQ-5B*f4$$0bve~R}gjjU=N!>m4DYWiDGVfGl# z8N<1r*R>(6iqu7ps*O+^BR*#wb3>?$Jj#<{1?GI{T<@T+0VFVpx!B1_@4^MRib=jk z`E#*r$p^X00~uvyiDx06Y{Qk*66V=@Y8qrtH&8FLaRwLZ*r|gxEs>89#bybC^l%^1Wr!~Oe?`YH9uM6^yi4xdCvqnl zV}HymWvo_O#LL)uA?yyO%x#n-RB;1A-N=C7#6G>5ZF5TiP`jV5c0XOse!7~xbk$?t zt@N@Ad%Q#}be-O1Ad3on9Z7qH8>crnb7s%8sZ&Ylx16<=zo%X^4%XVfU>O z?fBVOr1#w_tXJ{4lli%ejCMDgaVKl!9tEd`HM4~3rSD^un5#fY{E|MzB;JGTSV0@O zI}4#RsM7IXO?!=ro~h_eKP|_ILbz;YcpVcnzyB1Z;M&Kq;9eLl+*-KqIO^Rdb9dvi z+qiDw1W-ZoFYcY8yG z6w#qe?KSA*SQ;X2*GAU4&keD0To6V8> z+j*CgZ7SupPr8i*i`2iq@u-w-8}mMf3mYeD)OGdG9JGI7ef|~a;cs;H)j(}dbv4fM zEC~ql#BAksScN?f?R6}Xh^qik?>B#NQGtxYhj~{WEalkW-X>)iQDw$&2UT{nOHaan zvX*#H5QfWvf2WdvaLD|V-u;W80k4rX{;hDhBP&P{LLVAUCsj#_`4+Ft45mg3$sJkM zf@qnlpIjLx4GxM_A^xx7J;ZyIUNuW(178MOM0wzT8ASc0M{$51&5ukRRPu+^5R`9; T!+icB{}Wu_!A$&ML&N_7pz9b_ literal 0 HcmV?d00001 diff --git a/ff-admin/target/classes/com/ff/quartz/task/RyTask.class b/ff-admin/target/classes/com/ff/quartz/task/RyTask.class new file mode 100644 index 0000000000000000000000000000000000000000..c1c251b071cd104b5c55ca519a420cc8e9c71d58 GIT binary patch literal 2381 zcmb7GU31iA7(HosH_L8-b_<2_B`Vg^0`UV>D7MlTq_Qp8E!71P(`{Npv&oWV3oFA7 z&N#!!j5i`9<2dR#a-)u*mR3N$_Qos!fh~H)y)%BCH`%WY^}?OmB=7T_Jm)+g@4Nf+ z-{1cLU?)lmM9{Yk{TPU2zl;M3yoiGd4B{mjhZ2y{7e`v$hs0$#fx|eG#LE~-B7@N+ zj$%w)UXk%?63xhpcs}Y_9LHt6CLy-hunez9LSx6)F$s}=dqS76GHqD;a4|owJEPjT zNlPki=QMLna}2RA8zbH+!PTsnw{8hdPHCuUdPc$2 zk7$mT=L;t~(xU^@u^s)2DQ&TVx@T zBUKl$OhL!EgqAu-g^3=MO6xp6A*c==>FiY3|f}%^qZRN>dbX@AiU@qraGh*w)iN%*5c@{ zZO-Tu1DdC0?4pws=#^nKajoIzmI{>y_lBWC;JtNaDl7CY=T!HMsn)2vdl-6mIKuyW zcX`Isa??!6A2%5%WV|jR5hQZJ5M!AP#%zZeCkbsMMawht`k3Jw9FKjLWqX=u*cP+y zOxwK4SXO>zwNv$iv>x}NUnw#SUsemh^VEf!kTdqy*h3?Fm+DORusYh|2N@CHb8 za`Dpj-#@v$@Y%J6cP}o!Kfn0RmHT(DZC?2D>b);M|84H(y&Ja|K6>Z;h5L6dFU-BQ z@b!CjhCiPfptc@l8#K?R_`1w9C3YvzlgTc6)fqQz^$1(& zF=t)NvsD|*jN_WCt3s_?K2eT}XSQ(CcJdkn>|SCs9)EC@x7L}e=SEPAFt-F*43lSC zB+&{5-QroXeF>5WBbHl5^>NP*NF=Q4co0a$uKN5YxQ|_bAFBf;OUoO%+IH)=c>rq z4Oqu(%r`b+J)e~TfDPElm4r=rh*$CQ+r-6qZ@-C#RAc-uBH6~SOg6GDlZ|fAWMgfS zOjd4-X66u`MXVM*K^7o|$I#+4^aN4L42*}(6f9)5;}JaSqua5C_(tE>j>r9E+R=fn zh!WX}uCk^PVnpu)WwS_h@jHv;5;|I$%Nk!tYw%`O$2x5Db#NG~1^b1V zDC76eK}mPbW4VNRtdKCYZ5}Hne1Hx_{(iWLT%N$mTGOeb9>;L>J ziV^Wky@`J}D3`1COmzbj*@UNA;%*k9hxDQao%D902|L)Y2vKYC1Tmr*y=Acx;&);f zi|`DsB9Q>~EKz~)Ir?_fw*n1+p-ILb8Qp&}u}18rwE@qQ4M-Bz%kK*=_TecS5?nO% Kf6$Y$W&Z+%{)T!0 literal 0 HcmV?d00001 diff --git a/ff-admin/target/classes/com/ff/quartz/util/AbstractQuartzJob.class b/ff-admin/target/classes/com/ff/quartz/util/AbstractQuartzJob.class new file mode 100644 index 0000000000000000000000000000000000000000..5150ef9a697a4e0bfc8075b37099d579fe56e828 GIT binary patch literal 3818 zcmbtX`F9&v75>JSJo0E9+e+i$EUkl^c!?cl>w@iuW^r1(cH&x2pcDvWX)G&|HSWyF zP0E%O0UK^5()$;TiCZ>N$79<1DqbdJ0okc-Sh{J&Utg+efQnv zyZ7Dq^wKM{F96t%e`@H$xQdj93XF$w7)Mm3LzvKzfu&&*k7>9YwhWF8u8M3mzf&PR z9>!4|lgSe*-l?G;;~MV8yJUE`4DV6#UJVVxuE24jP6+j+Q127!{X(6T;R7;!P=*hQ zqNjv9}VGS^8L81d_u)DA$(HEPigoxKBM6@J}c8RA$(57 z=QVr*Ukqa#zNF&I8oq+FD!wZIG45wod`&@R+Da;j3|MwD>ZHfEAC3-K$)ss_D+s&e zwrL~=thkX@uyWwAF=a&4MkW~@DK1d1I+jXi3^!|=3fh*I>halGHnkI+N(Sw7AosxN;8F0r_j)DyXacd$v zHWqy>YuN4+QP0B8QOC87xcjij>$gT}Of`?1@vKXA&8=Rr`3+p{^;S|=X1A4b&7*F& zc%x8qMM*HdN8{$COCiw}_XQO+y_PCQ=^S%tM8Vnxt|qJrBbAB9yk%;wiMdAn$e=Ol zMaa5jxhc>Jh8-1Or@B#d%o3#Uf6Xv%X-{Gd8e^_$D>(4~sag^x(H}Bx+p-58ufU4c z6LalUCdr7a9hXTPNlh@Ex`h=Y%N{hWM*+G#&t>3Ig4%+1HZ#bQQ2Kc!dHkp#VfneG z{!mXmoi8^nW@YWTxi=-n)v%~oHi@S?c44=I)wi&!;u|{7;hQYNyws@Sm{HaS!^*hP zSbW?}WYZ?A%45*A+L4{HhYk%5?;q+N9_j0isrZ(T=kUCWZ|nFDzN_OP-lQWT!<+Gl zg5^cj3U#2P2lpvx{MX#vji=AveCpiGXHVU@^5l)_>87U6rvF^wxj(Ptd$^!u2i~Y) znWv+0^mJUrC9(Q_9Y2s5Z@)#1L{>)*mvu~IM#rpBb3$Da>W4zTfFJ3&D#MTQqK=>7 zr#gOy7uhh1zWW*9l})7+rmf=|e$Iq9-8?>bnNa?ek9` z!;JYH6@S$6C;VB*U+`B2cb0Eky1S_On~uNZA8Z)KkV{%5V=eOcj~+JTF0&#Hx7dSN z;pL1%Q!3=0IJ}Aok&wQ{a!H!*plK(~1UnA=PORA*lNd zX;$UJg?^^dLP4g?P+mluV%S&ofNf<7L)hPvpVe}$FEeEw;Vs83(%o9FmveM-cvH;x z&E@%c3g_F4Rn*2@YtrwnVzM}k%tu<>!Yhp;zA!K2erC(tQm|5GOir4ago4ge_~xT3 z0nTUTPdf2i)7oE(>%!%bYxyi*e?Ag}rsEh%VqERV>1J6wcPuWi!m*I@@+-f<+BsbGQo%y7|0aC6^SR*_zxz*3BRrn3I zUxsqQ6Y1qBLcnV5<*54tcmNM_rl1e~R3w|PBfuZfJBNx#E~9d=W8(}0d@feypiU#y zzOf^R>W*uu_9%^`l0*0$8und8O=MZ;3~DPuZYQ}HsCp$fVG9jbLY&xyFvs->VFOoM zu@-Guhjz4}gKL{9*@>;B?qd{tNQtxUbZ9FgcnAa3Lf7(c3pI#+v=O5Gehe{$hq+#Z z%KxH8#c-dBSOgBZYRH=o$m7D-uAHE)YVMk)_8e}ziu$gAN3NJd18uGB3N{7_=UcEkz&0Qhd2<5Ql95k+OD_*hsHL!*o*O46n43 zL&I(L=Z=QEI@%QCo`zY0mIWv8_>Tpe63H!r=yG9K3Us8Myxb_~cBHpy?YN9|r3<#@ zZdsnAzQbVDf9I40M$&d6XYTEpAIg^Je=^IyM~ zVD*nLE57;C@=9{0V#}h>mZaI9@h$uPx>XG1(L;ewcHAI%r6O(0Qq0CLZWsuEYWb4I zqDqm#P`cn{&x}!?)I|~`NJ-BW%APHsIm+f(&9)h(-#`aC4ctecz`%ut6zYLMf8baH zX$Br*jK%I`)hTEM;HX7w0EixZVzRaM$RXnAoAs}^;e7f{dnu;=L?j5H*Y|K~5aiHX}q+!E+5)nKMf9Rlc8z zRV^pZTBfH@p>3bw(lJ_(pdY4B(YCEP9K-k#lN^k&dw%5`1ympdGo#Rec$*0 z-gms&R9lwv+489yu;J|bryjbb16NANMpbs&OU9sR-_pZ=aUycgxvl6x<_~-W$OYNxUzD`=dzU0R<06 z@Q`E~iedpCR#1rGXcUX^h=NC>xDcOJa7=D}Yz#h!$K~*O1$hNu5U5yYWDIMCK(L{4 zvp{H7wnrBj*J)(*uKYl^p4+H(r%8!*W>Z>vvz9aDyGsmN{e~$}*O|%=Bzk)jSLL;w zwI`9cjC5jcw!0&fn(Fr^uj%e}IDu;`gN!+4i%8;N2C1ym(1Ewy8vHfVcP!54YR z3cf@`*6d2@gO-uamUPVY_AlL_ZIS`~an!B-VL zq2Ox@jtf*KjlPU#<#Y5&=POY?I$(LM)rPrQOB+3_(wb>Hj-KS#;6iD9%bM6|{9z;0qwf-!G-7dCd<7$8 zr-H8wEOX&_%15_-q(xGQz{FvQ7y)@gnloH#YncGg@TJ4~&O*DlIhxGob1D5|!>(gx zb!na~Eh<*vBBq{-Z{V9Mbo8p|lS4lY6)E&6_?C)q<2x$WV5^Gn;(M%+rJ`gzUd8wE z0|s}A?C4kULlr;5j}`nx#ZU1hlUv2l@N*Tvz%NzgV5)cuPpfz%u2t|W70=+;47YhI zeuLj~(xBpZcvi*lwr%bKW_IX3vWThp8+uvDN_Ma6*K$eys=S^_@q|P@|LRoy9sf}AoV5F&_*WTD zC;C8e;(2LWxK~S?eEARlD=@yKpgo&S+m&5(s`wvHNRAf-#+Eobvzb1s zT`gBmmML4E&9nVT`v1#hc4REQPtU11g%=sGDt8N21VoUX=1k2=U}`x_St}|U<^?{J zt7NHHr3Ge`s9o7)KGpA(ARoun5=T-`<#UF$+qXKiwAztQ>wQ{!Wh$kcrjMm=BulO@ zKcHtUA5&9_saWM@BTi|unK*sW#~rh|ZEziyp3|%>tD7vCPV+AI&4~?-qgC43uH(8j zQ@7i`nJ@=sS4|}C$0qiERwIS-WE~ecQw{f$R_V>=oa$Yy5%vYZEwz4Qigj-?m8{lT zfpdD#Dz;5VV#-FdpkYL1YxN5#ddatm6{~in8+{DyO&R^_4r@qpEi zbeRLn^;M-|c4e)ud^*jN?C&8(q3nwx)7Zn@8!n+SKaX zTt=5p8E59Z83ByMcAb$#XI64=9+;)Yd5Q_IhZzRM*S$_%bKVMV+{QoO z-a@~eGJpCHu53YG(JInhI_n)we;dhpnQT{f5n=qc6j=TE$|* znz2(}5!SOejf&9cFSnmCG$VSZ$42yu!iH#ySFF?38rhhr=S)@1=~84olj&~TlBOG8 z^_^VI;+u!#PMk7Ty+?*3aj~6$y?9G(RmQUuo$jP`DDot2qmEr8uL7tI(SpU^jF#BWAq!^`v^@KE8+5<}?NBz* zH4=0Pf%s$_pGv8(!xgv^ug4ppaV>yu1_bZKl+(udHKa(1)$!P*0w#yP)&FU^`V{u8svIo@+jf~Fk0@4HOZys{iuqy*t30@?rkezo@7sW z?AO$UW3MXU{C#Njm?*v|yMXzUe}Tt;Dft(^9RCH9f04&O)stGlV!3poyRB{ zB0cP6_gcg_AK|_A%V!rMn$F;Z~*Wmzvo4XTx`AK#IKc8;I zN!%nR!V**XGnWkb74-c=JdN!<>o8{Xi(?1UGWEnXHxeqv1WJ>UP$Pm2_zcf&7G6M> z`5yE_-=SjCVEaH!2+0szcw3<+8{^N)y_Xg;wr)UPcajL6F6^Z?2>)^YF`1ncc;ydQzTU5lSj>I>07{1_q2i!9wz}-Vb z@1==H2;zRs!vh5PAOSw)0~htcE%LxM6I|W~7x#g4ii+ft;QWx5Ign<$klw_t*O4WF GH@^fUShNxV literal 0 HcmV?d00001 diff --git a/ff-admin/target/classes/com/ff/quartz/util/QuartzDisallowConcurrentExecution.class b/ff-admin/target/classes/com/ff/quartz/util/QuartzDisallowConcurrentExecution.class new file mode 100644 index 0000000000000000000000000000000000000000..6e19caf2c9a52d79950321a314e21ecad549b791 GIT binary patch literal 861 zcmbVKO>Yx16r7ijE)9W}0)+yFR6;04h`m%?f)G_H2o#W@GCKuf6CvF_??Zxj4mHAI`;Y}L9 zEccI0uF}+f*m5>0vP@gQJ<$mP&h`ZJBUh!o;9P%fhYkQLDccJ4v!YcC}S7eEPY=SMfP8{>@8+E7z zE3XRc%~%giZfM}9wa%+jRPfj2vm9%qiMa^Z+qi*_VB>#m7u-CCwmHmwrV?L`Lqi4U zL*sF(?0$UY0G&OCO!!lK=-%pG{&+##l*x1L58Q~1?o5N%2UtU$?=pNfNEnf8#4KhM z#^&uWkk4iL6xUD&7BSDYT>;R-X=V-PXDAZLPgtolHt&2z?GL%dGH{X5?=-HN@)H@8(^je-Fwy%nUA(@k& zIIY(T!oT2!Dn&+e%H`EO_oczDU`$tJz_6NgRm~}toZCA0^@CH_vg(|L=VMjKHiSzN zGEM%DP zs>@(!8?Lx99S0U>37@OF?}`Iy_AvQ-uFWfc#}kO7$HH6!^H^Y5`PW7mmOJqF3W4^y ztJ^m*jG8N)D)-7xyEz)VLou!9$h%Y5;*x#>Lqdk&MCghtQboG!>}z=}Axdw=d=W4+ z6IqLpL!Ob3uRno3hUs3iCJhXtk8GkzfQ^1aF~S2RVu}wb6D1$tct+%_*rqfvO4PAX eAk`$b1c*+;$(HC4hKW5A3e!F)I!5OR#yxkR>;xq^vEw63upx=DJKH|eiai|;*;;?Lv`0z1&+=ncV%I=(Gc+883@UV}~C*;^C<=7)q z{6{@_%!5yP@M*c_XJqqP*?dmH=RNp>2VeB!OL*LePJG#euSl+6_26sr{dF(Cfp5yM zZ^`D{K70q?mG=3b58uZReE1=LBuSo7@M8r(5pefJj6^h37 z;mn>%JvpvT#yH{+B_djEhn9@WzBTAf&qPxKD?*XPp5V@%!K*S_GJQ=jla9uM;mC|W zm5J#WvyemI?sa%8ogQDHH;xppNc z2d4xU*cKT~1U#JDo=jwBrE>~~vRG0z3PPa_A=aO+5avSZwn$Rf(t6ID92YpZ*)DHx zD%pKfk4SWRQx+(a0=1=i5Qx;v)XqXlwN1Mm47?=Ts;9MRY#t{HXpU3%nn*Gc&xyAs z6OB#j+&Ez0xc@{7E>!3i=|F)c^NB6*kcbM{BVzw-E-D)5%UcR43Vx>G=L&wI;Fk)1 zrQk{C4guf5zKA}Xjwa$M1-}+Jb4H6##dN!vL($aEXi^_d#G(=6YvSanoiG19a}-0* zzKvxsD(Z;PAKtw)(X<|lrWi|$>}bkCnDM1X<5wqk(+o*MPoR93(WXu7!`dE3mn)LU z7=buQ7bhln6{B`!a+e-SbF->RU5k$v78*&)7fxi75q(?K$V536jLfn|B45RJoX;3v zOOvYj4W6P=Rs0rD3#=@Wn(}FAV4oggvP#4SI$w}(Yc!?BVu`(lY+_rscz)pJVYbR* zIH{%dV1)imYw>hGE0UQpz$92T-WR@bqCeCZ4o?jC4GpOH9eyvHKdAVlROL@9{*1pU z_^XP);qNMjF{0uh_@|10$?1Qq_z(W8;z~@Y_#ghS;u#!Q@vNMCQpI!h3-)2ZB7`a& zqD;k0a489eQxz`ZCbduqW?LqcD6n8oWU9g=yg4aH$3{j6#>NK+!iw;zqFkuNu_`J= zr7EgKr6LxnqFVSBQKO25cv=;UM6D_oQxvg874@P)6-)7yDwc^eRS}S1%f$*hZXKVq z`E;n_EYYZnm9kkS8U>o{X4G@R5oGuW$F zM2p80>A<8O$fWeCKr|kRP|rXvBN;1GifB?rvsg_)i5AM!tcq6A#*a0sXcub~5md!m zu}-D16tz>Fqlj}=v0iLY#YWM^6Gau>qDK*%RM9K7J5OpBC;_b^3^TnKU}Q!D4PF?s z^58<7k8`<9z-USZ3R=L}uU-Y$M1EWb=qT3JX!g zeVXkjdj6nt>#Q4MjD(`RVr7KY%qwnfc26$WLd~uMf5p_C!zPG6FHkK zvguYhk(r>aqro^W|Mj6&I3k%P1$UQ=lg~dMz*29M7&u;EDcx(Mwq-=PB89ki}cJvgn{p!(qnpB z=ZHW|MIV*AFjK+y(gzrYra zOP?>Zn=ub$Te(|(!N``0OU@r09|#SG$0x$$v|i2SCmMsLbH`%SF$vzDHh z+=~RTvniU8RfH=w8;de+y~uOb&daizK%-qdGgqW$rTK$l<7K4`g~73f_ZWdyb|aQB zem*10@U!Z?8pc5Z8|HD#!h;0Xy+~F{b`ootsH!fk%hO6>%qv)hG`#^>X?85<4_Mpy z3mW)yn2ATD+#IO;w$-f@LlV7 zv}941g|nyr06c!zLAdVTmrAW#&BNl8RCfCbIHR{E3>p8_rzYR#g0n2o>7**1ro_B!Vr7G|+1 zi`p(1#~06GNte5|&OL{^E;eTv6!lp&)VZ@*n#HomaAucM=Q@S}OTOh?vf`2!lg%-l z<-h?f$afoQKa=OmIjlN>%9c7;opKCKWyW~(VXV%A=5roERen*cgFjIMPQ!Uyuz=s^ zz=id6;0E?KVg-88icRRiX7uqtgsn8~c0{@2Y69d&I`%d?@Gd&N2W=PeFSCRiNLNi2{?M949-a|eTo+ght zc}NJIg|g=;hDSj{!7PEK;3@@41^k&Mtsny|uIIc&xdVIo!>U)_nJr({P;DpYj?gG= zLyq3IEZXm5e~iysJ{^3P@@eI>k`r$i{X4*?s zR8;tu38&L(7|Y3dX{wi#s~L(<&}1&I9%=D!oI_Wr)!#jbo=pwTdl-?2v1tyy546a! z^UBVi!{*`kEc&w8l0|=)v(9M}9DrYbZYAv+dSuH&!qofzC)_dKi_>Rtc< literal 0 HcmV?d00001 diff --git a/ff-admin/target/classes/com/ff/system/SysConfigController.class b/ff-admin/target/classes/com/ff/system/SysConfigController.class new file mode 100644 index 0000000000000000000000000000000000000000..6ac39c2d0d6f48ba794065a068cfa3d5a455f257 GIT binary patch literal 5332 zcmbVPYkM4Z6+g4NY_gdo?b@bP&^8pBG-*0sdcmYra-)sirfY6e>TP!Szsa<_Gs|4k zEXYMv1f^27AR?k5C@RDh>&8+aeedTmMPK<1eEgl6+1=UgBrLqx`QOhuzjNPz{_p+2 z6VYM18KZsV#OQ8XZpY_R2dz+%mybs2u_%2jMy>RC8$H3}lYICTAAXx>PxI_MJo|2x zz89lyHZq50p{I zHZEzV$bf9?aZT6k6B0G`A6Ss6dECfAy6%Lgi)kmH66Tx=ZW6^4Mq14+sHVnif3w+M z(!hRS8H*32B0VtJrjg4D6P%iJnq^Cr=r7+6BF`9kRnwKq%aH>$x6+0wl!Ce_6qoaa zYO7Ov)?oQPy-IX%%>!SO+sI0^Epb6zRu#wAa!LXcfksa)wql`-?^xa4;|=jR0g}U^ z7O_OyF*O^;NT-EmDFss$49ixMrhrYB3{!hl;Bm{cnscD@yC1NuLrbca6lPxQ@AEJX zdw_>on|%i)IvmRBl1M2jP0s|)ep1+H)ItG1!aNku9IaxdV3@E=vfl-};yPhY*vgV^ z7nD=@u+L&+Mpy-Sn;26?5(xjTkUZiDv&cX?l*h_c9*1k!X0xQqS<4n?OG+g-lrspa?ZIsTt_>^v6z#VaDp5wbk@Rc!Hm#d$%$V__J|Zr>18o*(<}{4f#mR zxWy)zPZqpgw~U0p3(GO8OsSK*#_S=YjNKkw1T_h8eiAhFstYHtI5J-7MO)mlA{{99dyJb8vIXaE@M5!eZn>8FWEgsZ3>D^H&%LppJpdaEYx>@HD zZg-1gvf2-XH!a~$U6-kX?(iWcm%gDbri@Tb|9y^gDW6qFrvM5y%%~ zj+V;^6Y9S8(%QxwuX)7!Wcoe*L8d>_JCL?-haQ)mv9@R4AADc%6^`N;g=zyiD&C zLcZ4r?c)tGu|xww#kf5f6z*G48AIb*HK;`GmaUq05>1*!2ZIlN4x2W&C@L1bJME`z zZpt`DYZB`wRzVuSt()WI&kdrV{y?biN=Rsgww61BWn(<2TGj}6H631Ib^8#B&Ulv^ zX`AZA2&ABLO#<~ARg4w6>MYsw6`{3ogt|64s4mN1rhf$i)vI-q)7;1>8A7Usios}kF8odQX zK~Ag>NL*{P4G#c%VquyFqO$`p=i#op`>w-6GhqtV7Gvloc7{m-yU7|_W7Bux#sN+N zplxuoB~f4hRIOp%hzl$6EYf@d71FZQGO$k4HB2Hjh%a9zx|0s#D|;7c zhz?;T;mK!kiy!APHeuX3P@>4db!r;CLCq05GjOm(Eo(Sva*1`hm-?s~e7nJ!iSG3t z`b0s3K1-hi@ounI=<^_a7`K?Uw{rwLjA9qYqu4!W(S7siAC>$EZ*4>@bJz?amFC}urr49af>EsQqY5RvJC1J zO@X`z>PwiNrUWiCsBw%DjNJpiraK~3BAL}3wAuZx+{_(UD{^Ko3Ngz1)p^sVtoa~tA=~1p6fY!*ynoL2Rz~9?T)~( z`vz{(wsY&WJsvO7Ck9Kj14Dc#J|*fY(XO>Y_~IQU+FjPtCt1`xtIp_IdWJfIZU}-M zfk13&Ph%4mjZOFtc^+p?Bn`Q$+k>g^eP6A!;MZU{a=~+(%r4$Mtt&;v3UfK>pa2tDGu1-rG0wN;VQ{y$i8xH$j- literal 0 HcmV?d00001 diff --git a/ff-admin/target/classes/com/ff/system/SysDatasourceController.class b/ff-admin/target/classes/com/ff/system/SysDatasourceController.class new file mode 100644 index 0000000000000000000000000000000000000000..4775d770712bbd4848bd22aa6ca998c228669090 GIT binary patch literal 4188 zcmbtXTXWM!6h3P^HY9?8Nw~DMTnfYq0Z|HsCP2vzaO)%{2`LnMk?l>QU`s~33JH|< zwJ)9NOJDlZ$G&ywOeaj~On*RsNct~2{Z>+9%aMsQec9Ds&N<(??$O`>zW$4dF44E` zl&1Ubw4WaA#_(AOJ)}o!`FV=INYR(=l%%hAk)h^-IxMQglKSH6YhHaVs9`ZhW{Q>= zb%|9mW=KQWu2bYQ+*vk@oYBQx(XQz8^LoJ$T*n>BE4uJc_3TUp%@Cs_)2=1W3ZFBD zSt#>i%d({*P1_QTuI6lKK^IlWv=-(aqr#us&SSm64NK_rMp4?%s%~r&=)6~3O%5#Qes&%lLkc%e7_iX4B zs1nj()V8E!m&@FNv_#nyl2JahK~Zmkl3g)OOAk>G^@eU1ZHMbsV}a`)0%hB*HE)CS z9>}hlno*c802V2M(Z1Z0v25tBG|PGp0Kx8HSl!j?hRQ7?ckb2(XaMhyin9n$f+m?;83s;=EDa83jL*%(rF*7~B%)!!ToDC`? z_w+Kl6e;Z~FX#o+D%D5CZ7wH_Y8Bz5AY;_B0ECco6QdI$QECr%vrT<`rO3G;}cS_&zb83N0l}?PV_zuy_hP9yQY=lKPpS(N_ zvT1n9SU~`|WtBHEv$UB{HDZ*A?QHkN<<6=yU7P;gEWKcKGF5cB7R^2r^M29tctcC;Bm7=mn6|yw4smkbBePyjJm9w! z5jhgs$8^5&qT7EAZx|N`N@ltn2s&>)i9%Yr0)hsF`tm5g~ zEZGCAH)*U=!u2{D