From 245d318152efce1e3751c732af770f8a09967659 Mon Sep 17 00:00:00 2001 From: enoch Date: Tue, 6 Apr 2021 10:32:48 +0800 Subject: [PATCH] init --- .gitignore | 4 + build.gradle | 103 +++++ settings.gradle | 3 + sliyun-app/build.gradle | 2 + sliyun-app/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 + sliyun-app/settings.gradle | 1 + .../aopcloud/beam/app/BeamAppApplication.java | 25 ++ .../com/aopcloud/beam/app/CodeGenerator.java | 118 ++++++ .../app/Interceptor/ApiSignInterceptor.java | 55 +++ .../app/Interceptor/AuthorityInterceptor.java | 54 +++ .../app/Interceptor/LogcatInterceptor.java | 56 +++ .../app/Interceptor/UserLoginInterceptor.java | 98 +++++ .../beam/app/annotion/LoginRequired.java | 16 + .../beam/app/annotion/Permission.java | 24 ++ .../api/ad/controller/AdItemController.java | 41 ++ .../ad/controller/AdPositionController.java | 41 ++ .../aopcloud/beam/app/api/ad/entity/Ad.java | 52 +++ .../beam/app/api/ad/entity/AdEntity.java | 53 +++ .../beam/app/api/ad/entity/AdItem.java | 177 +++++++++ .../beam/app/api/ad/entity/AdPosition.java | 95 +++++ .../aopcloud/beam/app/api/ad/entity/Item.java | 175 +++++++++ .../beam/app/api/ad/mapper/AdItemMapper.java | 16 + .../beam/app/api/ad/mapper/AdMapper.java | 16 + .../app/api/ad/mapper/AdPositionMapper.java | 16 + .../beam/app/api/ad/mapper/ItemMapper.java | 16 + .../app/api/ad/service/IAdItemService.java | 16 + .../api/ad/service/IAdPositionService.java | 16 + .../beam/app/api/ad/service/IAdService.java | 16 + .../beam/app/api/ad/service/IItemService.java | 16 + .../ad/service/impl/AdItemServiceImpl.java | 55 +++ .../service/impl/AdPositionServiceImpl.java | 20 + .../api/ad/service/impl/AdServiceImpl.java | 20 + .../api/ad/service/impl/ItemServiceImpl.java | 56 +++ .../app/api/app/controller/AppController.java | 41 ++ .../app/controller/HomeCoinController.java | 20 + .../app/controller/HomeNoticeController.java | 20 + .../beam/app/api/app/entity/Banner.java | 52 +++ .../beam/app/api/app/entity/HomeBean.java | 17 + .../beam/app/api/app/entity/HomeCoin.java | 147 +++++++ .../beam/app/api/app/entity/HomeCoinBean.java | 102 +++++ .../beam/app/api/app/entity/HomeNotice.java | 167 ++++++++ .../beam/app/api/app/entity/NoticeBean.java | 58 +++ .../app/api/app/mapper/HomeCoinMapper.java | 16 + .../app/api/app/mapper/HomeNoticeMapper.java | 16 + .../beam/app/api/app/service/IAppService.java | 4 + .../app/api/app/service/IHomeCoinService.java | 16 + .../api/app/service/IHomeNoticeService.java | 16 + .../api/app/service/impl/AppServiceImpl.java | 45 +++ .../app/service/impl/HomeCoinServiceImpl.java | 20 + .../service/impl/HomeNoticeServiceImpl.java | 34 ++ .../api/coin/controller/CoinController.java | 86 ++++ .../controller/CoinPackageController.java | 46 +++ .../controller/CoinPackageUnitController.java | 20 + .../beam/app/api/coin/entity/Coin.java | 192 +++++++++ .../beam/app/api/coin/entity/CoinAction.java | 56 +++ .../beam/app/api/coin/entity/CoinPackage.java | 175 +++++++++ .../app/api/coin/entity/CoinPackageUnit.java | 94 +++++ .../beam/app/api/coin/mapper/CoinMapper.java | 16 + .../api/coin/mapper/CoinPackageMapper.java | 16 + .../coin/mapper/CoinPackageUnitMapper.java | 16 + .../api/coin/service/ICoinPackageService.java | 16 + .../coin/service/ICoinPackageUnitService.java | 16 + .../app/api/coin/service/ICoinService.java | 16 + .../service/impl/CoinPackageServiceImpl.java | 46 +++ .../impl/CoinPackageUnitServiceImpl.java | 20 + .../coin/service/impl/CoinServiceImpl.java | 70 ++++ .../api/img/controller/BeamImgController.java | 20 + .../beam/app/api/img/entity/BeamImg.java | 61 +++ .../app/api/img/mapper/BeamImgMapper.java | 16 + .../app/api/img/service/IBeamImgService.java | 16 + .../img/service/impl/BeamImgServiceImpl.java | 20 + .../MemberCoinAddressController.java | 50 +++ .../MemberCoinRecordController.java | 38 ++ .../member/controller/MemberController.java | 80 ++++ .../controller/MemberLevelController.java | 19 + .../controller/MemberLoginLogController.java | 19 + .../MemberStatisticsInfoController.java | 19 + .../app/api/member/entity/AddCoinAddress.java | 14 + .../beam/app/api/member/entity/Member.java | 278 +++++++++++++ .../api/member/entity/MemberActionBean.java | 65 +++ .../api/member/entity/MemberCoinAddress.java | 165 ++++++++ .../api/member/entity/MemberCoinRecord.java | 217 ++++++++++ .../app/api/member/entity/MemberLevel.java | 161 ++++++++ .../app/api/member/entity/MemberLoginLog.java | 119 ++++++ .../member/entity/MemberStatisticsInfo.java | 142 +++++++ .../mapper/MemberCoinAddressMapper.java | 34 ++ .../member/mapper/MemberCoinRecordMapper.java | 26 ++ .../api/member/mapper/MemberLevelMapper.java | 16 + .../member/mapper/MemberLoginLogMapper.java | 16 + .../app/api/member/mapper/MemberMapper.java | 16 + .../mapper/MemberStatisticsInfoMapper.java | 16 + .../service/IMemberCoinAddressService.java | 16 + .../service/IMemberCoinRecordService.java | 16 + .../member/service/IMemberLevelService.java | 16 + .../service/IMemberLoginLogService.java | 16 + .../api/member/service/IMemberService.java | 16 + .../service/IMemberStatisticsInfoService.java | 16 + .../impl/MemberCoinAddressServiceImpl.java | 70 ++++ .../impl/MemberCoinRecordServiceImpl.java | 35 ++ .../service/impl/MemberLevelServiceImpl.java | 20 + .../impl/MemberLoginLogServiceImpl.java | 20 + .../service/impl/MemberServiceImpl.java | 195 +++++++++ .../impl/MemberStatisticsInfoServiceImpl.java | 20 + .../beam/app/api/notify/NotifyController.java | 69 ++++ .../api/order/controller/OrderController.java | 64 +++ .../OrderOperateHistoryController.java | 19 + .../controller/OrderPayRecordsController.java | 20 + .../beam/app/api/order/entity/BlockBean.java | 78 ++++ .../beam/app/api/order/entity/Order.java | 369 +++++++++++++++++ .../api/order/entity/OrderCreateEntity.java | 10 + .../app/api/order/entity/OrderDetailBean.java | 66 ++++ .../api/order/entity/OrderOperateHistory.java | 118 ++++++ .../app/api/order/entity/OrderPayRecords.java | 220 +++++++++++ .../app/api/order/entity/PayOrderInfo.java | 6 + .../app/api/order/mapper/OrderMapper.java | 16 + .../mapper/OrderOperateHistoryMapper.java | 16 + .../order/mapper/OrderPayRecordsMapper.java | 16 + .../service/IOrderOperateHistoryService.java | 16 + .../service/IOrderPayRecordsService.java | 16 + .../app/api/order/service/IOrderService.java | 16 + .../impl/OrderOperateHistoryServiceImpl.java | 20 + .../impl/OrderPayRecordsServiceImpl.java | 20 + .../order/service/impl/OrderServiceImpl.java | 370 ++++++++++++++++++ .../user/controller/BeamUserController.java | 74 ++++ .../beam/app/api/user/entity/BeamUser.java | 257 ++++++++++++ .../beam/app/api/user/entity/HBean.java | 102 +++++ .../app/api/user/entity/UpdateUserEntity.java | 114 ++++++ .../app/api/user/entity/UserActionBean.java | 39 ++ .../app/api/user/entity/UserPasswordBean.java | 25 ++ .../app/api/user/mapper/BeamUserMapper.java | 18 + .../api/user/service/IBeamUserService.java | 19 + .../service/impl/BeamUserServiceImpl.java | 156 ++++++++ .../aopcloud/beam/app/common/AccessLog.java | 186 +++++++++ .../aopcloud/beam/app/common/Constants.java | 5 + .../aopcloud/beam/app/common/OSSConfig.java | 58 +++ .../aopcloud/beam/app/common/PageBean.java | 22 ++ .../aopcloud/beam/app/common/PayConfig.java | 41 ++ .../beam/app/common/RequestContext.java | 24 ++ .../beam/app/configurer/AppContextHolder.java | 32 ++ .../beam/app/configurer/CorsFilter.java | 44 +++ .../configurer/GlobalExceptionHandler.java | 69 ++++ .../app/configurer/InterceptionConfig.java | 69 ++++ .../LocalDateTimeSerializerConfig.java | 49 +++ .../configurer/LocalDateTimeToTsConfig.java | 63 +++ .../beam/app/configurer/RequestHandler.java | 31 ++ .../beam/app/configurer/ResponseHandler.java | 76 ++++ .../aopcloud/beam/app/core/AppException.java | 54 +++ .../com/aopcloud/beam/app/core/Result.java | 47 +++ .../aopcloud/beam/app/core/ResultCode.java | 23 ++ .../beam/app/core/ResultGenerator.java | 39 ++ .../beam/app/delay/DelayQueueManager.java | 113 ++++++ .../aopcloud/beam/app/delay/DelayTask.java | 69 ++++ .../beam/app/dotwallet/BSVTransaction.java | 166 ++++++++ .../beam/app/dotwallet/DotApiConstants.java | 11 + .../beam/app/dotwallet/DotWalletClient.java | 252 ++++++++++++ .../beam/app/dotwallet/DotWalletManager.java | 89 +++++ .../app/dotwallet/entity/DotBaseResponse.java | 55 +++ .../beam/app/dotwallet/entity/PKIRequest.java | 45 +++ .../beam/app/dotwallet/entity/Vin.java | 32 ++ .../beam/app/dotwallet/entity/Vout.java | 32 ++ .../entity/response/BaseResponse.java | 48 +++ .../BroadcastTransactionResponse.java | 14 + .../response/BuildTransactionResponse.java | 24 ++ .../response/GetMerkleProofResponse.java | 23 ++ .../response/data/BuildTransactionData.java | 49 +++ .../entity/response/data/MerkleProofData.java | 56 +++ .../response/data/MerkleProofTarget.java | 171 ++++++++ .../entity/response/data/SignParam.java | 50 +++ .../beam/app/dotwallet/util/HttpUtil.java | 217 ++++++++++ .../beam/app/dotwallet/util/Util.java | 38 ++ .../aopcloud/beam/app/http/OkHttpUtils.java | 160 ++++++++ .../beam/app/http/builder/GetBuilder.java | 73 ++++ .../beam/app/http/builder/HasParamsable.java | 11 + .../beam/app/http/builder/HeadBuilder.java | 17 + .../http/builder/OkHttpRequestBuilder.java | 55 +++ .../app/http/builder/OtherRequestBuilder.java | 40 ++ .../app/http/builder/PostFileBuilder.java | 37 ++ .../app/http/builder/PostFormBuilder.java | 87 ++++ .../app/http/builder/PostStringBuilder.java | 35 ++ .../beam/app/http/callback/BCallback.java | 82 ++++ .../app/http/callback/GenericsCallback.java | 30 ++ .../http/callback/IGenericsSerializator.java | 8 + .../app/http/callback/StringCallback.java | 17 + .../app/http/request/CountingRequestBody.java | 87 ++++ .../beam/app/http/request/GetRequest.java | 31 ++ .../beam/app/http/request/OkHttpRequest.java | 93 +++++ .../beam/app/http/request/OtherRequest.java | 73 ++++ .../app/http/request/PostFileRequest.java | 68 ++++ .../app/http/request/PostFormRequest.java | 97 +++++ .../app/http/request/PostStringRequest.java | 51 +++ .../beam/app/http/request/RequestCall.java | 123 ++++++ .../beam/app/http/utils/Exceptions.java | 14 + .../com/aopcloud/beam/app/http/utils/L.java | 19 + .../app/scheduled/CoinMetadataScheduled.java | 229 +++++++++++ .../app/scheduled/CoinPriceScheduled.java | 88 +++++ .../app/scheduled/entity/BCHMetadata.java | 156 ++++++++ .../app/scheduled/entity/BSVMetadata.java | 165 ++++++++ .../app/scheduled/entity/BTCMetadata.java | 332 ++++++++++++++++ .../scheduled/entity/CoinCurrentPrice.java | 302 ++++++++++++++ .../aopcloud/beam/app/util/AliyunOSSUtil.java | 113 ++++++ .../com/aopcloud/beam/app/util/IdUtil.java | 54 +++ .../com/aopcloud/beam/app/util/IoUtil.java | 33 ++ .../com/aopcloud/beam/app/util/MD5Util.java | 53 +++ .../aopcloud/beam/app/util/OrderIdUtil.java | 21 + .../com/aopcloud/beam/app/util/RSAUtils.java | 209 ++++++++++ .../com/aopcloud/beam/app/util/RegUtil.java | 282 +++++++++++++ .../main/resources/application-dev.properties | 11 + .../resources/application-prod.properties | 1 + .../resources/application-test.properties | 1 + .../src/main/resources/application.properties | 45 +++ sliyun-app/src/main/resources/banner.txt | 26 ++ .../beam/app/BeamAppApplicationTests.java | 13 + 213 files changed, 13545 insertions(+) create mode 100644 .gitignore create mode 100644 build.gradle create mode 100644 settings.gradle create mode 100644 sliyun-app/build.gradle create mode 100644 sliyun-app/gradle/wrapper/gradle-wrapper.jar create mode 100644 sliyun-app/gradle/wrapper/gradle-wrapper.properties create mode 100644 sliyun-app/settings.gradle create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/BeamAppApplication.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/CodeGenerator.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/Interceptor/ApiSignInterceptor.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/Interceptor/AuthorityInterceptor.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/Interceptor/LogcatInterceptor.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/Interceptor/UserLoginInterceptor.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/annotion/LoginRequired.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/annotion/Permission.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/controller/AdItemController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/controller/AdPositionController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/Ad.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/AdEntity.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/AdItem.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/AdPosition.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/Item.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/mapper/AdItemMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/mapper/AdMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/mapper/AdPositionMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/mapper/ItemMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/IAdItemService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/IAdPositionService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/IAdService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/IItemService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/impl/AdItemServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/impl/AdPositionServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/impl/AdServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/impl/ItemServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/controller/AppController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/controller/HomeCoinController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/controller/HomeNoticeController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/Banner.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/HomeBean.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/HomeCoin.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/HomeCoinBean.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/HomeNotice.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/NoticeBean.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/mapper/HomeCoinMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/mapper/HomeNoticeMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/IAppService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/IHomeCoinService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/IHomeNoticeService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/impl/AppServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/impl/HomeCoinServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/impl/HomeNoticeServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/controller/CoinController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/controller/CoinPackageController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/controller/CoinPackageUnitController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/entity/Coin.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/entity/CoinAction.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/entity/CoinPackage.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/entity/CoinPackageUnit.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/mapper/CoinMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/mapper/CoinPackageMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/mapper/CoinPackageUnitMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/ICoinPackageService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/ICoinPackageUnitService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/ICoinService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/impl/CoinPackageServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/impl/CoinPackageUnitServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/impl/CoinServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/controller/BeamImgController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/entity/BeamImg.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/mapper/BeamImgMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/service/IBeamImgService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/service/impl/BeamImgServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberCoinAddressController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberCoinRecordController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberLevelController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberLoginLogController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberStatisticsInfoController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/AddCoinAddress.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/Member.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberActionBean.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberCoinAddress.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberCoinRecord.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberLevel.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberLoginLog.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberStatisticsInfo.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberCoinAddressMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberCoinRecordMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberLevelMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberLoginLogMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberStatisticsInfoMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberCoinAddressService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberCoinRecordService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberLevelService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberLoginLogService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberStatisticsInfoService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberCoinAddressServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberCoinRecordServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberLevelServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberLoginLogServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberStatisticsInfoServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/notify/NotifyController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/controller/OrderController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/controller/OrderOperateHistoryController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/controller/OrderPayRecordsController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/BlockBean.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/Order.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/OrderCreateEntity.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/OrderDetailBean.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/OrderOperateHistory.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/OrderPayRecords.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/PayOrderInfo.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/mapper/OrderMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/mapper/OrderOperateHistoryMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/mapper/OrderPayRecordsMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/IOrderOperateHistoryService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/IOrderPayRecordsService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/IOrderService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/impl/OrderOperateHistoryServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/impl/OrderPayRecordsServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/impl/OrderServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/controller/BeamUserController.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/BeamUser.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/HBean.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/UpdateUserEntity.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/UserActionBean.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/UserPasswordBean.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/mapper/BeamUserMapper.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/service/IBeamUserService.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/service/impl/BeamUserServiceImpl.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/common/AccessLog.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/common/Constants.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/common/OSSConfig.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/common/PageBean.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/common/PayConfig.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/common/RequestContext.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/AppContextHolder.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/CorsFilter.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/GlobalExceptionHandler.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/InterceptionConfig.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/LocalDateTimeSerializerConfig.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/LocalDateTimeToTsConfig.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/RequestHandler.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/ResponseHandler.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/core/AppException.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/core/Result.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/core/ResultCode.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/core/ResultGenerator.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/delay/DelayQueueManager.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/delay/DelayTask.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/BSVTransaction.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/DotApiConstants.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/DotWalletClient.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/DotWalletManager.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/DotBaseResponse.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/PKIRequest.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/Vin.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/Vout.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/BaseResponse.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/BroadcastTransactionResponse.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/BuildTransactionResponse.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/GetMerkleProofResponse.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/data/BuildTransactionData.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/data/MerkleProofData.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/data/MerkleProofTarget.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/data/SignParam.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/util/HttpUtil.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/util/Util.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/OkHttpUtils.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/GetBuilder.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/HasParamsable.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/HeadBuilder.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/OkHttpRequestBuilder.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/OtherRequestBuilder.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/PostFileBuilder.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/PostFormBuilder.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/PostStringBuilder.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/callback/BCallback.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/callback/GenericsCallback.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/callback/IGenericsSerializator.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/callback/StringCallback.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/CountingRequestBody.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/GetRequest.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/OkHttpRequest.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/OtherRequest.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/PostFileRequest.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/PostFormRequest.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/PostStringRequest.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/RequestCall.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/utils/Exceptions.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/http/utils/L.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/CoinMetadataScheduled.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/CoinPriceScheduled.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/entity/BCHMetadata.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/entity/BSVMetadata.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/entity/BTCMetadata.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/entity/CoinCurrentPrice.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/util/AliyunOSSUtil.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/util/IdUtil.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/util/IoUtil.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/util/MD5Util.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/util/OrderIdUtil.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/util/RSAUtils.java create mode 100644 sliyun-app/src/main/java/com/aopcloud/beam/app/util/RegUtil.java create mode 100644 sliyun-app/src/main/resources/application-dev.properties create mode 100644 sliyun-app/src/main/resources/application-prod.properties create mode 100644 sliyun-app/src/main/resources/application-test.properties create mode 100644 sliyun-app/src/main/resources/application.properties create mode 100644 sliyun-app/src/main/resources/banner.txt create mode 100644 sliyun-app/src/test/java/com/aopcloud/beam/app/BeamAppApplicationTests.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5c18320 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/.gradle +/.idea +/build +/sliyun-app/build diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..68fec9e --- /dev/null +++ b/build.gradle @@ -0,0 +1,103 @@ +//声明gradle脚本自身需要使用的资源,优先执行 +buildscript { + ext { + springBootVersion = '2.2.4.RELEASE' + } + repositories { + maven { url 'https://maven.aliyun.com/nexus/content/groups/public' } + maven { url 'https://maven.aliyun.com/repository/spring/' } + jcenter() + mavenCentral() + } + dependencies { + classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}" + } + // java编译的时候缺省状态下会因为中文字符而失败 + +} + + //allprojects 所有项目共享的配置 +allprojects { + apply plugin: 'groovy' + apply plugin: 'java' + apply plugin: 'idea' + apply plugin: 'java-library' + version = '1.0' + sourceCompatibility = 8 + targetCompatibility = 8 +} +// subprojects : 所有子模块共享的配置 +subprojects { + apply plugin: 'java' + apply plugin: 'org.springframework.boot' //使用springboot插件 + apply plugin: 'io.spring.dependency-management' //版本管理插件 + // java编译的时候缺省状态下会因为中文字符而失败 + [compileJava, compileTestJava, javadoc]*.options*.encoding = 'UTF-8' + // 配置所有子模块的依赖仓库地址 + repositories { + maven { url 'https://maven.aliyun.com/repository/jcenter' } + maven { url 'https://maven.aliyun.com/nexus/content/groups/public' } + maven { url 'https://maven.aliyun.com/repository/spring/' } + maven { url 'https://maven.aliyun.com/repository/google' } + maven { url 'https://oss.sonatype.org/content/repositories/' } + maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } + jcenter() + mavenCentral() + } + //所有子模块共有依赖 + dependencies { + implementation fileTree(dir: 'libs', includes: ['*.jar']) + + implementation 'org.codehaus.groovy:groovy-all:2.3.11' + + + implementation 'org.springframework.boot:spring-boot-starter-web' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + + + compile 'org.springframework.boot:spring-boot-devtools:2.1.14.RELEASE' + + //jdbc + implementation 'org.springframework.boot:spring-boot-starter-jdbc' + //alibaba druid + implementation 'com.alibaba:druid-spring-boot-starter:1.2.4' + //jdbc 驱动 + implementation 'mysql:mysql-connector-java:8.0.22' + //mail + implementation 'org.springframework.boot:spring-boot-starter-mail' + //Jwt + implementation 'com.auth0:java-jwt:3.12.0' + //fastjson + implementation 'com.alibaba:fastjson:1.2.47' + //okhttp + implementation 'com.squareup.okhttp3:okhttp:4.9.0' + //freemarker + implementation 'org.springframework.boot:spring-boot-starter-freemarker' + //mybatis-plus + implementation 'com.baomidou:mybatis-plus-boot-starter:3.4.2' + //mybatis-plus-generator + implementation 'com.baomidou:mybatis-plus-generator:3.3.2' + //lombok + implementation 'org.projectlombok:lombok:1.18.12' + // commons + implementation 'commons-lang:commons-lang:2.6' + //aop log + implementation 'org.springframework.boot:spring-boot-starter-aop:2.4.2' + // OSS + implementation 'com.aliyun.oss:aliyun-sdk-oss:3.10.2' + + implementation 'com.squareup.okhttp3:okhttp:3.10.0' + + implementation 'org.bitcoinj:bitcoinj-core:0.14.7' + compile 'org.apache.httpcomponents:httpclient:4.5.6' + compile 'org.apache.httpcomponents:httpcore:4.4.14' + } +} + + +// +//// jar 包名称自定义 +//bootJar { +//// archiveBaseName = 'aaa' //不需要带后缀(默认形式,会自带版本号:aaa-0.0.1-SNAPSHOT.jar ) +// archiveFileName = 'coin.jar' //需要加后缀 +//} diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..ae52dc4 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,3 @@ +rootProject.name = 'sliyun-app' +include ':sliyun-app' + diff --git a/sliyun-app/build.gradle b/sliyun-app/build.gradle new file mode 100644 index 0000000..571b417 --- /dev/null +++ b/sliyun-app/build.gradle @@ -0,0 +1,2 @@ +dependencies { +} \ No newline at end of file diff --git a/sliyun-app/gradle/wrapper/gradle-wrapper.jar b/sliyun-app/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f GIT binary patch literal 59203 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

K7UpUK$>l@ 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 E2O(~oYXATM literal 0 HcmV?d00001 diff --git a/sliyun-app/gradle/wrapper/gradle-wrapper.properties b/sliyun-app/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..4d9ca16 --- /dev/null +++ b/sliyun-app/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/sliyun-app/settings.gradle b/sliyun-app/settings.gradle new file mode 100644 index 0000000..57d638b --- /dev/null +++ b/sliyun-app/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'beam-app' diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/BeamAppApplication.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/BeamAppApplication.java new file mode 100644 index 0000000..b4bd441 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/BeamAppApplication.java @@ -0,0 +1,25 @@ +package com.aopcloud.beam.app; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; + +@SpringBootApplication +@MapperScan(basePackages = "com.aopcloud.beam.app.api.*") +public class BeamAppApplication { + + public static void main(String[] args) { + SpringApplication.run(BeamAppApplication.class, args); + } +// @Bean +// public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() { +// +// PropertySourcesPlaceholderConfigurer c = new PropertySourcesPlaceholderConfigurer(); +// +// c.setIgnoreUnresolvablePlaceholders(true); +// +// return c; +// } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/CodeGenerator.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/CodeGenerator.java new file mode 100644 index 0000000..77eb56e --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/CodeGenerator.java @@ -0,0 +1,118 @@ +package com.aopcloud.beam.app; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException; +import com.baomidou.mybatisplus.core.metadata.TableInfo; +import com.baomidou.mybatisplus.core.toolkit.StringPool; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.generator.AutoGenerator; +import com.baomidou.mybatisplus.generator.InjectionConfig; +import com.baomidou.mybatisplus.generator.config.*; +import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder; +import com.baomidou.mybatisplus.generator.config.rules.FileType; +import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; +import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +public class CodeGenerator { + + + private static String pack = "com.aopcloud.beam.app"; + private static String parent = pack+".api"; + + private static String moduleName = "beam-app"; + private static String projectPath = System.getProperty("user.dir") + "/" + moduleName; + + /** + *

+ * 读取控制台内容 + *

+ */ + public static String scanner(String tip) { + + Scanner scanner = new Scanner(System.in); + StringBuilder help = new StringBuilder(); + help.append("请输入" + tip + ":"); + System.out.println(help.toString()); + if (scanner.hasNext()) { + String ipt = scanner.next(); + if (StringUtils.isNotBlank(ipt)) { + return ipt; + } + } + throw new MybatisPlusException("请输入正确的" + tip + "!"); + } + + public static void main(String[] args) { + // 代码生成器 + AutoGenerator mpg = new AutoGenerator(); + + // 全局配置 + GlobalConfig gc = new GlobalConfig(); +// String projectPath = System.getProperty("user.dir"); + gc.setOutputDir(projectPath + "/src/main/java/"); +// gc.setOutputDir(projectPath); + gc.setAuthor("Enoch"); + gc.setOpen(false); + gc.setIdType(IdType.AUTO); + // gc.setSwagger2(true); 实体属性 Swagger2 注解 + mpg.setGlobalConfig(gc); + + // 数据源配置 + DataSourceConfig dsc = new DataSourceConfig(); + dsc.setUrl("jdbc:mysql://rm-wz99smt6zjv8tt10x1250109m.mysql.rds.aliyuncs.com:3306/sliyun?characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false"); + // dsc.setSchemaName("public"); + dsc.setDriverName("com.mysql.cj.jdbc.Driver"); + dsc.setUsername("live_solution"); + dsc.setPassword("Nf46KD8MCTN3jWKZ"); + mpg.setDataSource(dsc); + + // 包配置 + PackageConfig pc = new PackageConfig(); + pc.setModuleName(scanner("模块名")); + pc.setParent(parent); + mpg.setPackageInfo(pc); + + // 自定义配置 + InjectionConfig cfg = new InjectionConfig() { + @Override + public void initMap() { + // to do nothing + } + }; + + + // 配置模板 + TemplateConfig templateConfig = new TemplateConfig(); + + // 配置自定义输出模板 + //指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别 + // templateConfig.setEntity("templates/entity2.java"); + // templateConfig.setService(); + // templateConfig.setController(); + + templateConfig.setXml(null); + mpg.setTemplate(templateConfig); + + // 策略配置 + StrategyConfig strategy = new StrategyConfig(); + strategy.setNaming(NamingStrategy.underline_to_camel); + strategy.setColumnNaming(NamingStrategy.underline_to_camel); +// strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!"); + strategy.setEntityLombokModel(false); + strategy.setRestControllerStyle(true); + // 公共父类 +// strategy.setSuperControllerClass("你自己的父类控制器,没有就不用设置!"); + // 写于父类中的公共字段 +// strategy.setSuperEntityColumns("id"); + strategy.setInclude(scanner("表名,多个英文逗号分割").split(",")); + strategy.setControllerMappingHyphenStyle(true); + strategy.setTablePrefix("sys_","sly_"); + mpg.setStrategy(strategy); + mpg.setTemplateEngine(new FreemarkerTemplateEngine()); + mpg.execute(); + } +} \ No newline at end of file diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/Interceptor/ApiSignInterceptor.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/Interceptor/ApiSignInterceptor.java new file mode 100644 index 0000000..25f077a --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/Interceptor/ApiSignInterceptor.java @@ -0,0 +1,55 @@ +package com.aopcloud.beam.app.Interceptor; + +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + +@Component +public class ApiSignInterceptor implements HandlerInterceptor { + + /** + * 请求前 + * + * @param request + * @param response + * @param handler controllerHandler 对象 + * @return + * @throws Exception + */ + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + return false; + } + + /** + * 请求后 , 无抛出异常时 + * + * @param request + * @param response + * @param handler + * @param modelAndView + * @throws Exception + */ + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { + + } + /** + * 请求后,无论是否抛出异常 , 均执行 + * 注意: controlleradvice的执行是在该方法之前的.对exception进行处理过. 该方法接收不到该异常 + * 会拦截所有的controller,包括spring提供的controller , 如baseerrorcontroller 异常处理handler + * @param request + * @param response + * @param handler + * @param ex + * @throws Exception + */ + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/Interceptor/AuthorityInterceptor.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/Interceptor/AuthorityInterceptor.java new file mode 100644 index 0000000..1fc65f7 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/Interceptor/AuthorityInterceptor.java @@ -0,0 +1,54 @@ +package com.aopcloud.beam.app.Interceptor; + +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@Component +public class AuthorityInterceptor implements HandlerInterceptor { + + /** + * 请求前 + * + * @param request + * @param response + * @param handler controllerHandler 对象 + * @return + * @throws Exception + */ + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + return false; + } + + /** + * 请求后 , 无抛出异常时 + * + * @param request + * @param response + * @param handler + * @param modelAndView + * @throws Exception + */ + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { + + } + /** + * 请求后,无论是否抛出异常 , 均执行 + * 注意: controlleradvice的执行是在该方法之前的.对exception进行处理过. 该方法接收不到该异常 + * 会拦截所有的controller,包括spring提供的controller , 如baseerrorcontroller 异常处理handler + * @param request + * @param response + * @param handler + * @param ex + * @throws Exception + */ + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/Interceptor/LogcatInterceptor.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/Interceptor/LogcatInterceptor.java new file mode 100644 index 0000000..c6dede5 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/Interceptor/LogcatInterceptor.java @@ -0,0 +1,56 @@ +package com.aopcloud.beam.app.Interceptor; + +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + +@Component +public class LogcatInterceptor implements HandlerInterceptor { + + + /** + * 请求前 + * + * @param request + * @param response + * @param handler controllerHandler 对象 + * @return + * @throws Exception + */ + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + return false; + } + + /** + * 请求后 , 无抛出异常时 + * + * @param request + * @param response + * @param handler + * @param modelAndView + * @throws Exception + */ + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { + + } + /** + * 请求后,无论是否抛出异常 , 均执行 + * 注意: controlleradvice的执行是在该方法之前的.对exception进行处理过. 该方法接收不到该异常 + * 会拦截所有的controller,包括spring提供的controller , 如baseerrorcontroller 异常处理handler + * @param request + * @param response + * @param handler + * @param ex + * @throws Exception + */ + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/Interceptor/UserLoginInterceptor.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/Interceptor/UserLoginInterceptor.java new file mode 100644 index 0000000..ee688ce --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/Interceptor/UserLoginInterceptor.java @@ -0,0 +1,98 @@ +package com.aopcloud.beam.app.Interceptor; + +import com.alibaba.fastjson.JSON; +import com.aopcloud.beam.app.api.member.entity.Member; +import com.aopcloud.beam.app.api.member.service.impl.MemberServiceImpl; +import com.aopcloud.beam.app.annotion.LoginRequired; +import com.aopcloud.beam.app.core.AppException;; +import com.aopcloud.beam.app.core.Result; +import com.aopcloud.beam.app.core.ResultGenerator; +import org.apache.commons.lang.StringUtils; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; +import java.lang.reflect.Method; + + +@Component +public class UserLoginInterceptor implements HandlerInterceptor { + + @Resource + private MemberServiceImpl userService; + public static UserLoginInterceptor articlesReceiver; //关键2 + + @PostConstruct //关键3 + public void init() { + articlesReceiver = this; + } + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + String token = ""; + if (StringUtils.isBlank(token)) { + // 2.从headers中获取 + token = request.getHeader("token"); + } + if (StringUtils.isBlank(token)) { + // 3.从请求参数获取 + token = request.getParameter("token"); + } + if (!(handler instanceof HandlerMethod)) { + return true; + } + HandlerMethod handlerMethod = (HandlerMethod) handler; + Method method = handlerMethod.getMethod(); + if (method.isAnnotationPresent(LoginRequired.class)) { + if (!StringUtils.isEmpty(token)) { + Member user = articlesReceiver.userService.getMemberByToken(token); + if (user == null || !user.getToken().equals(token)) { + throw new AppException("token 无效"); + } else { + return true; + } + } + throw new AppException("token 无效"); + } + return true; + } + + + private void result(HttpServletResponse response, Result result) { + response.setCharacterEncoding("UTF-8"); + response.setContentType("application/json; charset=utf-8"); + response.setStatus(200); + PrintWriter out = null; + try { + out = response.getWriter(); + out.append(JSON.toJSONString(result)); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (out != null) + out.close(); + } + } + + private String getTokenFromCookie(HttpServletRequest request) { + String token = null; + Cookie[] cookies = request.getCookies(); + int len = null == cookies ? 0 : cookies.length; + if (len > 0) { + for (Cookie cookie : cookies) { + if (cookie.getName().equals("token")) { + token = cookie.getValue(); + break; + } + } + } + return token; + } +} \ No newline at end of file diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/annotion/LoginRequired.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/annotion/LoginRequired.java new file mode 100644 index 0000000..27ee90b --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/annotion/LoginRequired.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.annotion; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface LoginRequired { + /** + * 是否需要登录 + */ + boolean required() default true; + +} \ No newline at end of file diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/annotion/Permission.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/annotion/Permission.java new file mode 100644 index 0000000..bfd43ef --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/annotion/Permission.java @@ -0,0 +1,24 @@ +package com.aopcloud.beam.app.annotion; + + +import java.lang.annotation.*; + +/** + * 权限注解 用于检查权限 规定访问权限 + * + * @example @Permission({role1,role2}) + * @example @Permission + */ +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +public @interface Permission { + + /** + *

角色英文名称

+ *

使用注解时加上这个值表示限制只有某个角色的才可以访问对应的资源

+ *

常用在某些资源限制只有超级管理员角色才可访问

+ */ + String[] value() default {}; +} + diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/controller/AdItemController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/controller/AdItemController.java new file mode 100644 index 0000000..bc5251c --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/controller/AdItemController.java @@ -0,0 +1,41 @@ +package com.aopcloud.beam.app.api.ad.controller; + + +import com.aopcloud.beam.app.api.ad.entity.AdEntity; +import com.aopcloud.beam.app.api.ad.service.impl.AdItemServiceImpl; +import com.aopcloud.beam.app.core.Result; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + +/** + *

+ * 广告表 前端控制器 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@RestController +@RequestMapping("/ad") +public class AdItemController { + @Resource + private AdItemServiceImpl itemService; + + + @PostMapping("/create") + public Result create(@RequestBody AdEntity entity) { + return itemService.create(entity); + } + + @GetMapping("/list") + public Result list() { + return itemService.getAll(); + } + + + @PostMapping("/delete") + public Result delete(int id) { + return itemService.delete(id); + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/controller/AdPositionController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/controller/AdPositionController.java new file mode 100644 index 0000000..91c2881 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/controller/AdPositionController.java @@ -0,0 +1,41 @@ +package com.aopcloud.beam.app.api.ad.controller; + + +import com.aopcloud.beam.app.api.ad.entity.AdEntity; +import com.aopcloud.beam.app.api.ad.service.impl.AdItemServiceImpl; +import com.aopcloud.beam.app.core.Result; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + +/** + *

+ * 广告位表 前端控制器 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@RestController +@RequestMapping("/ad/position") +public class AdPositionController { + @Resource + private AdItemServiceImpl itemService; + + + @PostMapping("/create") + public Result create(@RequestBody AdEntity entity) { + return itemService.create(entity); + } + + @GetMapping("/list") + public Result list() { + return itemService.getAll(); + } + + + @PostMapping("/delete") + public Result delete(int id) { + return itemService.delete(id); + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/Ad.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/Ad.java new file mode 100644 index 0000000..c380b7e --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/Ad.java @@ -0,0 +1,52 @@ +package com.aopcloud.beam.app.api.ad.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * Banner表格 + *

+ * + * @author Enoch + * @since 2021-02-21 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class Ad implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + /** + * banner 名称,广告位名称 + */ + private String name; + + /** + * banner 描述 + */ + private String description; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/AdEntity.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/AdEntity.java new file mode 100644 index 0000000..000c054 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/AdEntity.java @@ -0,0 +1,53 @@ +package com.aopcloud.beam.app.api.ad.entity; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; + + +@JsonIgnoreProperties(ignoreUnknown = true) +public class AdEntity { + + + @Min(value = 1,message = "广告位ID不能为空") + public int adId; + @NotBlank(message = "广告位事件类型不能为空") + public String eventType; + @NotBlank(message = "广告位事件不能为空") + public String event; + @NotBlank(message = "广告位封面不能为空") + public String img; + + public int getAdId() { + return adId; + } + + public void setAdId(int adId) { + this.adId = adId; + } + + public String getEventType() { + return eventType; + } + + public void setEventType(String eventType) { + this.eventType = eventType; + } + + public String getEvent() { + return event; + } + + public void setEvent(String event) { + this.event = event; + } + + public String getImg() { + return img; + } + + public void setImg(String img) { + this.img = img; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/AdItem.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/AdItem.java new file mode 100644 index 0000000..47ea11e --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/AdItem.java @@ -0,0 +1,177 @@ +package com.aopcloud.beam.app.api.ad.entity; + +import com.aopcloud.beam.app.util.AliyunOSSUtil; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + *

+ * 广告表 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@TableName("sly_ad_item") +public class AdItem implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + /** + * 广告位ID id + */ + private Integer adId; + + /** + * imgage id + */ + @JsonIgnore + private String imgOssFile; + + /** + * 广告事件 + */ + private String actionEvent; + + /** + * 广告事件类型 + */ + private String actionType; + + /** + * 创建时间 + */ + + private LocalDateTime createTime; + + /** + * 更新时间 + */ + @JsonIgnore + private LocalDateTime updateTime; + + + @TableField(exist = false) + private String imgUrl; + + @TableField(exist = false) + private String adPosition = "App 首页Banner"; + + @TableField(exist = false) + private String eventName = "链接跳转"; + + @TableField(exist = false) + private String time ; + + + public void setTime(String time) { + this.time = time; + } + + public String getTime() { + DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + return dtf2.format(createTime); + } + + + + public String getImgUrl() { + return AliyunOSSUtil.getInstance().getFileUrl(imgOssFile); + } + + public void setImgUrl(String imgUrl) { + this.imgUrl = imgUrl; + } + + public String getAdPosition() { + return adPosition; + } + + public void setAdPosition(String adPosition) { + this.adPosition = adPosition; + } + + public String getEventName() { + return eventName; + } + + public void setEventName(String eventName) { + this.eventName = eventName; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + public Integer getAdId() { + return adId; + } + + public void setAdId(Integer adId) { + this.adId = adId; + } + public String getImgOssFile() { + return imgOssFile; + } + + public void setImgOssFile(String imgOssFile) { + this.imgOssFile = imgOssFile; + } + public String getActionEvent() { + return actionEvent; + } + + public void setActionEvent(String actionEvent) { + this.actionEvent = actionEvent; + } + public String getActionType() { + return actionType; + } + + public void setActionType(String actionType) { + this.actionType = actionType; + } + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + + @Override + public String toString() { + return "AdItem{" + + "id=" + id + + ", adId=" + adId + + ", imgOssFile=" + imgOssFile + + ", actionEvent=" + actionEvent + + ", actionType=" + actionType + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + "}"; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/AdPosition.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/AdPosition.java new file mode 100644 index 0000000..aa90560 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/AdPosition.java @@ -0,0 +1,95 @@ +package com.aopcloud.beam.app.api.ad.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 广告位表 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@TableName("sly_ad_position") +public class AdPosition implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + /** + * 广告位名称 + */ + private String name; + + /** + * 广告位名称 + */ + private String description; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + + @Override + public String toString() { + return "AdPosition{" + + "id=" + id + + ", name=" + name + + ", description=" + description + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + "}"; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/Item.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/Item.java new file mode 100644 index 0000000..ae526ff --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/entity/Item.java @@ -0,0 +1,175 @@ +package com.aopcloud.beam.app.api.ad.entity; + +import com.aopcloud.beam.app.util.AliyunOSSUtil; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + *

+ * Banner item 表格 + *

+ * + * @author Enoch + * @since 2021-02-21 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("ad_item") +public class Item implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + /** + * banner id + */ + private Integer adId; + + /** + * image + */ + @JsonIgnore + private String ossFileName; + + /** + * event + */ + private String actionEvent; + + /** + * 类型 + */ + private String actionType; + + /** + * 创建时间 + */ + @JsonIgnore + private LocalDateTime createTime; + + /** + * 更新时间 + */ + @JsonIgnore + private LocalDateTime updateTime; + + @TableField(exist = false) + private String imgUrl; + + @TableField(exist = false) + private String adPosition = "App 首页Banner"; + + @TableField(exist = false) + private String eventName = "链接跳转"; + + @TableField(exist = false) + private String time ; + + + public void setTime(String time) { + this.time = time; + } + + public String getTime() { + DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + return dtf2.format(createTime); + } + + public static long getSerialVersionUID() { + return serialVersionUID; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getAdId() { + return adId; + } + + public void setAdId(Integer adId) { + this.adId = adId; + } + + public String getOssFileName() { + return ossFileName; + } + + public void setOssFileName(String ossFileName) { + this.ossFileName = ossFileName; + } + + public String getActionEvent() { + return actionEvent; + } + + public void setActionEvent(String actionEvent) { + this.actionEvent = actionEvent; + } + + public String getActionType() { + return actionType; + } + + public void setActionType(String actionType) { + this.actionType = actionType; + } + + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + + public String getImgUrl() { + return AliyunOSSUtil.getInstance().getFileUrl(ossFileName); + } + + public void setImgUrl(String imgUrl) { + this.imgUrl = imgUrl; + } + + public String getAdPosition() { + return adPosition; + } + + public void setAdPosition(String adPosition) { + this.adPosition = adPosition; + } + + public String getEventName() { + return eventName; + } + + public void setEventName(String eventName) { + this.eventName = eventName; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/mapper/AdItemMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/mapper/AdItemMapper.java new file mode 100644 index 0000000..0928b73 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/mapper/AdItemMapper.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.ad.mapper; + +import com.aopcloud.beam.app.api.ad.entity.AdItem; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 广告表 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface AdItemMapper extends BaseMapper { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/mapper/AdMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/mapper/AdMapper.java new file mode 100644 index 0000000..49c6e24 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/mapper/AdMapper.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.ad.mapper; + +import com.aopcloud.beam.app.api.ad.entity.Ad; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * Banner表格 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-02-21 + */ +public interface AdMapper extends BaseMapper { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/mapper/AdPositionMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/mapper/AdPositionMapper.java new file mode 100644 index 0000000..8088e23 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/mapper/AdPositionMapper.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.ad.mapper; + +import com.aopcloud.beam.app.api.ad.entity.AdPosition; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 广告位表 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface AdPositionMapper extends BaseMapper { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/mapper/ItemMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/mapper/ItemMapper.java new file mode 100644 index 0000000..c196975 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/mapper/ItemMapper.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.ad.mapper; + +import com.aopcloud.beam.app.api.ad.entity.Item; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * Banner item 表格 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-02-21 + */ +public interface ItemMapper extends BaseMapper { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/IAdItemService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/IAdItemService.java new file mode 100644 index 0000000..ebe5393 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/IAdItemService.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.ad.service; + +import com.aopcloud.beam.app.api.ad.entity.AdItem; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 广告表 服务类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface IAdItemService extends IService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/IAdPositionService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/IAdPositionService.java new file mode 100644 index 0000000..141760f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/IAdPositionService.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.ad.service; + +import com.aopcloud.beam.app.api.ad.entity.AdPosition; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 广告位表 服务类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface IAdPositionService extends IService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/IAdService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/IAdService.java new file mode 100644 index 0000000..f79d12e --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/IAdService.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.ad.service; + +import com.aopcloud.beam.app.api.ad.entity.Ad; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * Banner表格 服务类 + *

+ * + * @author Enoch + * @since 2021-02-21 + */ +public interface IAdService extends IService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/IItemService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/IItemService.java new file mode 100644 index 0000000..b81c710 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/IItemService.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.ad.service; + +import com.aopcloud.beam.app.api.ad.entity.Item; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * Banner item 表格 服务类 + *

+ * + * @author Enoch + * @since 2021-02-21 + */ +public interface IItemService extends IService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/impl/AdItemServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/impl/AdItemServiceImpl.java new file mode 100644 index 0000000..1c33198 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/impl/AdItemServiceImpl.java @@ -0,0 +1,55 @@ +package com.aopcloud.beam.app.api.ad.service.impl; + +import com.aopcloud.beam.app.api.ad.entity.AdEntity; +import com.aopcloud.beam.app.api.ad.entity.AdItem; +import com.aopcloud.beam.app.api.ad.mapper.AdItemMapper; +import com.aopcloud.beam.app.api.ad.service.IAdItemService; +import com.aopcloud.beam.app.core.Result; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import com.aopcloud.beam.app.core.Result; +import com.aopcloud.beam.app.core.ResultGenerator; +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * 广告表 服务实现类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@Service +public class AdItemServiceImpl extends ServiceImpl implements IAdItemService { + public Result create(AdEntity adEntity) { + AdItem item = new AdItem(); + item.setAdId(adEntity.adId); + item.setActionType(adEntity.eventType); + item.setActionEvent(adEntity.event); + item.setImgOssFile(adEntity.getImg()); + item.setCreateTime(LocalDateTime.now()); + item.setUpdateTime(LocalDateTime.now()); + save(item); + return ResultGenerator.genSuccessResult(item); + } + + public Result delete(int id) { + removeById(id); + return ResultGenerator.genSuccessResult(); + } + + public Result getAll() { + return ResultGenerator.genSuccessResult(list()); + } + + public List getById(int id) { + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("ad_id",id); + return list(queryWrapper); + } + + +} + diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/impl/AdPositionServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/impl/AdPositionServiceImpl.java new file mode 100644 index 0000000..f2397f0 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/impl/AdPositionServiceImpl.java @@ -0,0 +1,20 @@ +package com.aopcloud.beam.app.api.ad.service.impl; + +import com.aopcloud.beam.app.api.ad.entity.AdPosition; +import com.aopcloud.beam.app.api.ad.mapper.AdPositionMapper; +import com.aopcloud.beam.app.api.ad.service.IAdPositionService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 广告位表 服务实现类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@Service +public class AdPositionServiceImpl extends ServiceImpl implements IAdPositionService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/impl/AdServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/impl/AdServiceImpl.java new file mode 100644 index 0000000..4a5551c --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/impl/AdServiceImpl.java @@ -0,0 +1,20 @@ +package com.aopcloud.beam.app.api.ad.service.impl; + +import com.aopcloud.beam.app.api.ad.entity.Ad; +import com.aopcloud.beam.app.api.ad.mapper.AdMapper; +import com.aopcloud.beam.app.api.ad.service.IAdService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * Banner表格 服务实现类 + *

+ * + * @author Enoch + * @since 2021-02-21 + */ +@Service +public class AdServiceImpl extends ServiceImpl implements IAdService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/impl/ItemServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/impl/ItemServiceImpl.java new file mode 100644 index 0000000..3ce7e15 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/ad/service/impl/ItemServiceImpl.java @@ -0,0 +1,56 @@ +package com.aopcloud.beam.app.api.ad.service.impl; + +import com.aopcloud.beam.app.api.ad.entity.AdEntity; +import com.aopcloud.beam.app.api.ad.entity.AdItem; +import com.aopcloud.beam.app.api.ad.entity.Item; +import com.aopcloud.beam.app.api.ad.mapper.ItemMapper; +import com.aopcloud.beam.app.api.ad.service.IItemService; +import com.aopcloud.beam.app.core.Result; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import com.aopcloud.beam.app.core.Result; +import com.aopcloud.beam.app.core.ResultGenerator; +import java.time.LocalDateTime; +import java.util.List; + +/** + *

+ * Banner item 表格 服务实现类 + *

+ * + * @author Enoch + * @since 2021-02-21 + */ +@Service +public class ItemServiceImpl extends ServiceImpl implements IItemService { + + public Result create(AdEntity adEntity) { + System.out.println(adEntity.img); + Item item = new Item(); + item.setAdId(adEntity.adId); + item.setActionType(adEntity.eventType); + item.setActionEvent(adEntity.event); + item.setOssFileName(adEntity.getImg()); + item.setCreateTime(LocalDateTime.now()); + item.setUpdateTime(LocalDateTime.now()); + save(item); + return ResultGenerator.genSuccessResult(item); + } + + public Result delete(int id) { + removeById(id); + return ResultGenerator.genSuccessResult(); + } + + public Result getAll() { + return ResultGenerator.genSuccessResult(list()); + } + + + public AdItemServiceImpl adItemService; + public List getAdList(int i) { + QueryWrapper queryWrapper= new QueryWrapper().eq("ad_id",i); + return adItemService.list(queryWrapper); + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/controller/AppController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/controller/AppController.java new file mode 100644 index 0000000..f8b1ed4 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/controller/AppController.java @@ -0,0 +1,41 @@ +package com.aopcloud.beam.app.api.app.controller; + + +import com.aopcloud.beam.app.api.app.service.impl.AppServiceImpl; +import com.aopcloud.beam.app.core.Result; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + *

+ * Banner表格 前端控制器 + *

+ * + * @author Enoch + * @since 2021-01-29 + */ +@RestController +@RequestMapping("/app/") +public class AppController { + + + @Resource + private AppServiceImpl service; + + + @GetMapping("/home") + public Result getList(){ + return service.getHome(); + } + + + + + + + + +} \ No newline at end of file diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/controller/HomeCoinController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/controller/HomeCoinController.java new file mode 100644 index 0000000..3f0fe07 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/controller/HomeCoinController.java @@ -0,0 +1,20 @@ +package com.aopcloud.beam.app.api.app.controller; + + +import org.springframework.web.bind.annotation.RequestMapping; + +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 首页货币 前端控制器 + *

+ * + * @author Enoch + * @since 2021-03-05 + */ +@RestController +@RequestMapping("/app/home") +public class HomeCoinController { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/controller/HomeNoticeController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/controller/HomeNoticeController.java new file mode 100644 index 0000000..5792729 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/controller/HomeNoticeController.java @@ -0,0 +1,20 @@ +package com.aopcloud.beam.app.api.app.controller; + + +import org.springframework.web.bind.annotation.RequestMapping; + +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 首页广播 前端控制器 + *

+ * + * @author Enoch + * @since 2021-03-05 + */ +@RestController +@RequestMapping("/app/home-notice") +public class HomeNoticeController { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/Banner.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/Banner.java new file mode 100644 index 0000000..2567a1f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/Banner.java @@ -0,0 +1,52 @@ +package com.aopcloud.beam.app.api.app.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * Banner表格 + *

+ * + * @author Enoch + * @since 2021-01-29 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class Banner implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + /** + * banner 名称,广告位名称 + */ + private String name; + + /** + * banner 描述 + */ + private String description; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/HomeBean.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/HomeBean.java new file mode 100644 index 0000000..04f05a6 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/HomeBean.java @@ -0,0 +1,17 @@ +package com.aopcloud.beam.app.api.app.entity; + + + +import java.util.List; +import java.util.Map; + +public class HomeBean { + + public List banner; + public List notice; + public List coin; + + + public HomeBean() { + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/HomeCoin.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/HomeCoin.java new file mode 100644 index 0000000..bd68f21 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/HomeCoin.java @@ -0,0 +1,147 @@ +package com.aopcloud.beam.app.api.app.entity; + +import java.math.BigDecimal; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.time.LocalDateTime; +import java.io.Serializable; + +/** + *

+ * 首页货币 + *

+ * + * @author Enoch + * @since 2021-03-05 + */ +@TableName("sly_home_coin") +public class HomeCoin implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + /** + * 货币ID + */ + private Integer coinId; + + /** + * icon + */ + private String imgOssFile; + + /** + * 加载 + */ + private BigDecimal price; + + /** + * 奖励 + */ + private String reward; + + /** + * 平均出块时间 + */ + private Integer averageTime; + + /** + * 上一次出块时间 + */ + private LocalDateTime lastTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + public Integer getCoinId() { + return coinId; + } + + public void setCoinId(Integer coinId) { + this.coinId = coinId; + } + public String getImgOssFile() { + return imgOssFile; + } + + public void setImgOssFile(String imgOssFile) { + this.imgOssFile = imgOssFile; + } + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + public String getReward() { + return reward; + } + + public void setReward(String reward) { + this.reward = reward; + } + public Integer getAverageTime() { + return averageTime; + } + + public void setAverageTime(Integer averageTime) { + this.averageTime = averageTime; + } + public LocalDateTime getLastTime() { + return lastTime; + } + + public void setLastTime(LocalDateTime lastTime) { + this.lastTime = lastTime; + } + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + + @Override + public String toString() { + return "HomeCoin{" + + "id=" + id + + ", coinId=" + coinId + + ", imgOssFile=" + imgOssFile + + ", price=" + price + + ", reward=" + reward + + ", averageTime=" + averageTime + + ", lastTime=" + lastTime + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + "}"; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/HomeCoinBean.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/HomeCoinBean.java new file mode 100644 index 0000000..acef7dd --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/HomeCoinBean.java @@ -0,0 +1,102 @@ +package com.aopcloud.beam.app.api.app.entity; + + + +public class HomeCoinBean { + private int id; + private int coinType; + private String coinEnName;//英文名称 + private String coinCnName;//中午名称 + private String coinIcon;//icon + private String average ;// 平均 + private String lastTime;//上一次出块时间 + private double amount;//金额 + private double reward;//奖励 + public HomeCoinBean(){ + + } + + public HomeCoinBean(int id, int coinType, String coinEnName, String coinCnName, String coinIcon, String average, String lastTime, double amount, double reward) { + this.id = id; + this.coinType = coinType; + this.coinEnName = coinEnName; + this.coinCnName = coinCnName; + this.coinIcon = coinIcon; + this.average = average; + this.lastTime = lastTime; + this.amount = amount; + this.reward = reward; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getCoinType() { + return coinType; + } + + public void setCoinType(int coinType) { + this.coinType = coinType; + } + + public String getCoinEnName() { + return coinEnName; + } + + public void setCoinEnName(String coinEnName) { + this.coinEnName = coinEnName; + } + + public String getCoinCnName() { + return coinCnName; + } + + public void setCoinCnName(String coinCnName) { + this.coinCnName = coinCnName; + } + + public String getCoinIcon() { + return coinIcon; + } + + public void setCoinIcon(String coinIcon) { + this.coinIcon = coinIcon; + } + + public String getAverage() { + return average; + } + + public void setAverage(String average) { + this.average = average; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public double getAmount() { + return amount; + } + + public void setAmount(double amount) { + this.amount = amount; + } + + public double getReward() { + return reward; + } + + public void setReward(double reward) { + this.reward = reward; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/HomeNotice.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/HomeNotice.java new file mode 100644 index 0000000..e0d83f0 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/HomeNotice.java @@ -0,0 +1,167 @@ +package com.aopcloud.beam.app.api.app.entity; + +import java.math.BigDecimal; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; + +import java.time.LocalDateTime; +import java.io.Serializable; + +/** + *

+ * 首页广播 + *

+ * + * @author Enoch + * @since 2021-03-05 + */ +@TableName("sly_home_notice") +public class HomeNotice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + /** + * 入库唯一编号 + */ + private String noticeSn; + + + /** + * 货币ID + */ + private Integer coinId; + + private String coinName; + + /** + * 收益 + */ + private BigDecimal profit; + + /** + * 广播方、发布方 + */ + private String noticeSource; + + private String remarks; + + + /** + * 广播时间、通知时间 + */ + private long noticeTimestamp; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getCoinId() { + return coinId; + } + + public void setCoinId(Integer coinId) { + this.coinId = coinId; + } + + public BigDecimal getProfit() { + return profit; + } + + public void setProfit(BigDecimal profit) { + this.profit = profit; + } + + public String getNoticeSource() { + return noticeSource; + } + + public void setNoticeSource(String noticeSource) { + this.noticeSource = noticeSource; + } + + public LocalDateTime getCreateTime() { + return createTime; + } + + public long getNoticeTimestamp() { + return noticeTimestamp; + } + + public void setNoticeTimestamp(long noticeTimestamp) { + this.noticeTimestamp = noticeTimestamp; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + + public String getCoinName() { + return coinName; + } + + public void setCoinName(String coinName) { + this.coinName = coinName; + } + + public String getRemarks() { + return remarks; + } + + public void setRemarks(String remarks) { + this.remarks = remarks; + } + + public String getNoticeSn() { + return noticeSn; + } + + public void setNoticeSn(String noticeSn) { + this.noticeSn = noticeSn; + } + + @Override + public String toString() { + return "HomeNotice{" + + "id=" + id + + ", noticeSn='" + noticeSn + '\'' + + ", coinId=" + coinId + + ", coinName='" + coinName + '\'' + + ", profit=" + profit + + ", noticeSource='" + noticeSource + '\'' + + ", remarks='" + remarks + '\'' + + ", noticeTimestamp=" + noticeTimestamp + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + '}'; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/NoticeBean.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/NoticeBean.java new file mode 100644 index 0000000..f336235 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/entity/NoticeBean.java @@ -0,0 +1,58 @@ +package com.aopcloud.beam.app.api.app.entity; + +public class NoticeBean { + private int id; + private String name; + private String url; + private long time = System.currentTimeMillis() / 1000; + private double coin; + private String coinName; + + public double getCoin() { + return coin; + } + + public void setCoin(double coin) { + this.coin = coin; + } + + public String getCoinName() { + return coinName; + } + + public void setCoinName(String coinName) { + this.coinName = coinName; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/mapper/HomeCoinMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/mapper/HomeCoinMapper.java new file mode 100644 index 0000000..8432c50 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/mapper/HomeCoinMapper.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.app.mapper; + +import com.aopcloud.beam.app.api.app.entity.HomeCoin; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 首页货币 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-03-05 + */ +public interface HomeCoinMapper extends BaseMapper { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/mapper/HomeNoticeMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/mapper/HomeNoticeMapper.java new file mode 100644 index 0000000..9c9c1ab --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/mapper/HomeNoticeMapper.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.app.mapper; + +import com.aopcloud.beam.app.api.app.entity.HomeNotice; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 首页广播 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-03-05 + */ +public interface HomeNoticeMapper extends BaseMapper { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/IAppService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/IAppService.java new file mode 100644 index 0000000..325b0cc --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/IAppService.java @@ -0,0 +1,4 @@ +package com.aopcloud.beam.app.api.app.service; + +public interface IAppService { +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/IHomeCoinService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/IHomeCoinService.java new file mode 100644 index 0000000..34207b4 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/IHomeCoinService.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.app.service; + +import com.aopcloud.beam.app.api.app.entity.HomeCoin; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 首页货币 服务类 + *

+ * + * @author Enoch + * @since 2021-03-05 + */ +public interface IHomeCoinService extends IService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/IHomeNoticeService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/IHomeNoticeService.java new file mode 100644 index 0000000..66516a3 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/IHomeNoticeService.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.app.service; + +import com.aopcloud.beam.app.api.app.entity.HomeNotice; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 首页广播 服务类 + *

+ * + * @author Enoch + * @since 2021-03-05 + */ +public interface IHomeNoticeService extends IService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/impl/AppServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/impl/AppServiceImpl.java new file mode 100644 index 0000000..48d90a0 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/impl/AppServiceImpl.java @@ -0,0 +1,45 @@ +package com.aopcloud.beam.app.api.app.service.impl; + +import com.aopcloud.beam.app.api.ad.entity.AdItem; +import com.aopcloud.beam.app.api.ad.service.impl.AdItemServiceImpl; +import com.aopcloud.beam.app.api.ad.service.impl.ItemServiceImpl; +import com.aopcloud.beam.app.api.app.entity.HomeCoinBean; +import com.aopcloud.beam.app.api.app.entity.HomeBean; +import com.aopcloud.beam.app.api.app.entity.HomeNotice; +import com.aopcloud.beam.app.api.app.entity.NoticeBean; +import com.aopcloud.beam.app.api.app.mapper.HomeNoticeMapper; +import com.aopcloud.beam.app.api.app.service.IAppService; +import com.aopcloud.beam.app.api.coin.service.impl.CoinServiceImpl; +import com.aopcloud.beam.app.util.AliyunOSSUtil; +import com.aopcloud.beam.app.core.Result; +import com.aopcloud.beam.app.core.ResultGenerator; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; + +@Service +public class AppServiceImpl implements IAppService { + + + @Resource + private AdItemServiceImpl itemService; + @Resource + private HomeNoticeServiceImpl homeNoticeService; + + @Resource + private CoinServiceImpl coinService; + + public Result getHome() { + HomeBean homeBean = new HomeBean(); + List list = itemService.getById(1); + homeBean.banner = list; + homeBean.notice = homeNoticeService.getList(); + homeBean.coin = coinService.list(); + return ResultGenerator.genSuccessResult(homeBean); + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/impl/HomeCoinServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/impl/HomeCoinServiceImpl.java new file mode 100644 index 0000000..7c6a36e --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/impl/HomeCoinServiceImpl.java @@ -0,0 +1,20 @@ +package com.aopcloud.beam.app.api.app.service.impl; + +import com.aopcloud.beam.app.api.app.entity.HomeCoin; +import com.aopcloud.beam.app.api.app.mapper.HomeCoinMapper; +import com.aopcloud.beam.app.api.app.service.IHomeCoinService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 首页货币 服务实现类 + *

+ * + * @author Enoch + * @since 2021-03-05 + */ +@Service +public class HomeCoinServiceImpl extends ServiceImpl implements IHomeCoinService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/impl/HomeNoticeServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/impl/HomeNoticeServiceImpl.java new file mode 100644 index 0000000..4b0cd16 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/app/service/impl/HomeNoticeServiceImpl.java @@ -0,0 +1,34 @@ +package com.aopcloud.beam.app.api.app.service.impl; + +import com.aopcloud.beam.app.api.app.entity.HomeNotice; +import com.aopcloud.beam.app.api.app.mapper.HomeNoticeMapper; +import com.aopcloud.beam.app.api.app.service.IHomeNoticeService; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + *

+ * 首页广播 服务实现类 + *

+ * + * @author Enoch + * @since 2021-03-05 + */ +@Service +public class HomeNoticeServiceImpl extends ServiceImpl implements IHomeNoticeService { + + + public List getList() { + QueryWrapper notice = new QueryWrapper(); + notice.orderByDesc("create_time"); + notice.last("limit 0,10"); + return baseMapper.selectList(notice); + } + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/controller/CoinController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/controller/CoinController.java new file mode 100644 index 0000000..a145f2f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/controller/CoinController.java @@ -0,0 +1,86 @@ +package com.aopcloud.beam.app.api.coin.controller; + + +import com.aopcloud.beam.app.api.coin.entity.CoinAction; +import com.aopcloud.beam.app.api.coin.service.impl.CoinServiceImpl; +import com.aopcloud.beam.app.core.Result; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + + +/** + *

+ * 货币类型表 前端控制器 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@RestController +@RequestMapping("/coin") +public class CoinController { + @Resource + private CoinServiceImpl mCoinServiceImpl; + + @PostMapping("/create") + public Result create(@RequestBody @Valid CoinAction action) { +// if (icon != null) { +// try { +// //当前项目下路径 +// String realPath = System.getProperty("user.dir") + new String("/beam-system/src/main/resources/" + UPLOAD_PATH_PREFIX); +// System.out.println("-----------上传文件保存的路径【" + realPath + "】-----------"); +// //存放上传文件的文件夹 +// File folder = new File(realPath); +// System.out.println("-----------存放上传文件的文件夹【" + folder.getAbsolutePath() + "】-----------"); +// System.out.println("-----------输出文件夹绝对路径 -- 这里的绝对路径是相当于当前项目的路径而不是“容器”路径【" + folder.getAbsolutePath() + "】-----------"); +// if (!folder.isDirectory()) { +// //递归生成文件夹 +// folder.mkdirs(); +// } +// //获取原始的名字 方法是得到原来的文件名在客户机的文件系统名称 +// String oldName = icon.getOriginalFilename(); +// System.out.println("-----------文件原始的名字【" + oldName + "】-----------"); +// //新命名=随机UUID+原始文件的后缀名 +// String newName = "img_coin_" + System.currentTimeMillis() + oldName.substring(oldName.lastIndexOf(".")); +// System.out.println("-----------文件要保存后的新名字【" + newName + "】-----------"); +// File newFile = new File(folder.getAbsolutePath().replace("\\", "/") + File.separator + newName); +// System.out.println("-----------getAbsolutePath【" + newFile.getAbsolutePath() + "】-----------"); +// //将图片保存到static文件夹里 +// icon.transferTo(newFile); +// System.out.println("-----------getAbsolutePath【" + newFile.exists() + "/" + newFile.isFile() + "】-----------"); +// String filePath = "/images/" + newName; +// System.out.println("icon:" + filePath); +// BeamImg img = new BeamImg(); +//// img.setUrl(filePath); +//// img.setDescription("coin create icon"); +//// img.setImgMd5(""); +//// img.setCreateBy("coin create icon"); +//// img.setCreateTime(LocalDateTime.now()); +//// img.setUpdateTime(LocalDateTime.now()); +// mImgService.save(img); +// return mCoinServiceImpl.create(img.getId(), name, description); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } + return mCoinServiceImpl.create(action); + } + + @PostMapping("/edit") + public Result editCoin(@RequestBody CoinAction action) { + return mCoinServiceImpl.edit(action); + } + + @PostMapping("/delete") + public Result deleteCoin(@RequestBody CoinAction action) { + return mCoinServiceImpl.delete(action.getId()); + } + + @GetMapping("/list") + public Result list(@RequestParam(defaultValue = "1") int pageNo, + @RequestParam(defaultValue = "20") int pageSize) { + return mCoinServiceImpl.getList(pageNo, pageSize); + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/controller/CoinPackageController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/controller/CoinPackageController.java new file mode 100644 index 0000000..f8f5ece --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/controller/CoinPackageController.java @@ -0,0 +1,46 @@ +package com.aopcloud.beam.app.api.coin.controller; + + +import com.aopcloud.beam.app.api.coin.entity.CoinPackage; +import com.aopcloud.beam.app.api.coin.service.impl.CoinPackageServiceImpl; +import com.aopcloud.beam.app.core.Result; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + *

+ * 算力包 前端控制器 + *

+ * + * @author Enoch + * @since 2021-03-01 + */ +@RestController +@RequestMapping("/coin/package") +public class CoinPackageController { + @Resource + private CoinPackageServiceImpl mCoinServiceImpl; + + @PostMapping("/create") + public Result create(@RequestBody @Valid CoinPackage entity) { + return mCoinServiceImpl.create(entity); + } + + @PostMapping("/edit") + public Result edit(@RequestBody CoinPackage entity) { + return mCoinServiceImpl.edit(entity); + } + + @PostMapping("/delete") + public Result delete(@RequestBody int id) { + return mCoinServiceImpl.delete(id); + } + + + @GetMapping("/list") + public Result list(@RequestParam(required = false ,defaultValue = "0") int coinId) { + return mCoinServiceImpl.getList(coinId); + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/controller/CoinPackageUnitController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/controller/CoinPackageUnitController.java new file mode 100644 index 0000000..374b98c --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/controller/CoinPackageUnitController.java @@ -0,0 +1,20 @@ +package com.aopcloud.beam.app.api.coin.controller; + + +import org.springframework.web.bind.annotation.RequestMapping; + +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 算力包单位 前端控制器 + *

+ * + * @author Enoch + * @since 2021-03-01 + */ +@RestController +@RequestMapping("/coin/package/unit") +public class CoinPackageUnitController { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/entity/Coin.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/entity/Coin.java new file mode 100644 index 0000000..0399d64 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/entity/Coin.java @@ -0,0 +1,192 @@ +package com.aopcloud.beam.app.api.coin.entity; + +import com.aopcloud.beam.app.util.AliyunOSSUtil; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + *

+ * 货币类型表 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@TableName("sly_coin") +public class Coin implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + /** + * 英文名称 + */ + private String enName; + + /** + * 中文名称 + */ + private String cnName; + + /** + * img name + */ + @JsonIgnore + private String imgOssFile; + + /** + * 奖励 + */ + private BigDecimal reward; + + /** + * 平均出块时间 + */ + private Integer averageDuration; + + + /** + *最新币价 + */ + private BigDecimal currentPrice; + + /** + *最新出块时间戳 + */ + private Long latestTime; + + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + + + @TableField(exist = false) + public String icon ; + + + + public String getIcon() { + return AliyunOSSUtil.getInstance().getFileUrl(imgOssFile); + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + public String getEnName() { + return enName; + } + + public void setEnName(String enName) { + this.enName = enName; + } + public String getCnName() { + return cnName; + } + + public void setCnName(String cnName) { + this.cnName = cnName; + } + public String getImgOssFile() { + return imgOssFile; + } + + public void setImgOssFile(String imgOssFile) { + this.imgOssFile = imgOssFile; + } + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + + public static long getSerialVersionUID() { + return serialVersionUID; + } + + public BigDecimal getCurrentPrice() { + return currentPrice; + } + + public void setCurrentPrice(BigDecimal currentPrice) { + this.currentPrice = currentPrice; + } + + public Long getLatestTime() { + return latestTime; + } + + public void setLatestTime(Long latestTime) { + this.latestTime = latestTime; + } + + public BigDecimal getReward() { + return reward; + } + + public void setReward(BigDecimal reward) { + this.reward = reward; + } + + public Integer getAverageDuration() { + return averageDuration; + } + + public void setAverageDuration(Integer averageDuration) { + this.averageDuration = averageDuration; + } + + @Override + public String toString() { + return "Coin{" + + "id=" + id + + ", enName='" + enName + '\'' + + ", cnName='" + cnName + '\'' + + ", imgOssFile='" + imgOssFile + '\'' + + ", reward='" + reward + '\'' + + ", averageDuration=" + averageDuration + + ", currentPrice=" + currentPrice + + ", latestTime=" + latestTime + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + ", icon='" + icon + '\'' + + '}'; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/entity/CoinAction.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/entity/CoinAction.java new file mode 100644 index 0000000..b9ac102 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/entity/CoinAction.java @@ -0,0 +1,56 @@ +package com.aopcloud.beam.app.api.coin.entity; + +import javax.validation.constraints.NotBlank; + + +public class CoinAction { + + private int id; + @NotBlank(message = "货币名称不能为空") + private String cnName; + @NotBlank(message = "货币简写不能为空") + private String enName; + @NotBlank(message = "货币Icon不能为空") + private String imgOssFile; + private String description; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getEnName() { + return enName; + } + + public void setEnName(String enName) { + this.enName = enName; + } + + public String getCnName() { + return cnName; + } + + public void setCnName(String cnName) { + this.cnName = cnName; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getImgOssFile() { + return imgOssFile; + } + + public void setImgOssFile(String imgOssFile) { + this.imgOssFile = imgOssFile; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/entity/CoinPackage.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/entity/CoinPackage.java new file mode 100644 index 0000000..b2f95cb --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/entity/CoinPackage.java @@ -0,0 +1,175 @@ +package com.aopcloud.beam.app.api.coin.entity; + +import java.math.BigDecimal; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; + +import javax.validation.constraints.*; +import java.time.LocalDateTime; +import java.io.Serializable; + +/** + *

+ * 算力包 + *

+ * + * @author Enoch + * @since 2021-03-01 + */ +@TableName("sly_coin_package") +public class CoinPackage implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + +// /** +// * 货币ID +// */ +// @NotNull(message="货币ID不能为空!") +// private Long coinId; +// + /** + * 单位时间 + */ + @NotNull(message="算力包单位时间必须大于等于1分钟!") + private Integer duration; + + /** + * 包名称 + */ + @NotBlank(message = "算力包名称不能为空") + private String title; + + /** + * 单价 + */ + @DecimalMin(value = "1", message = "算力包单价必须大0") + @NotNull(message = "算力包单价必须大0") + private BigDecimal price; + + /** + * 算力包 单位数量 + */ + @NotNull(message = "算力包单位数量不能为空") + private Integer number; + + /** + * 算力包单位ID + */ + @NotNull(message = "算力包名单位ID不能为空") + private Long packageUnitId; + + /** + * 算力包单位名称 + */ + @NotBlank(message = "算力包单位名称不能为空") + private String packageUnitName; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + public static long getSerialVersionUID() { + return serialVersionUID; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public Integer getNumber() { + return number; + } + + public void setNumber(Integer number) { + this.number = number; + } + + public Long getPackageUnitId() { + return packageUnitId; + } + + public void setPackageUnitId(Long packageUnitId) { + this.packageUnitId = packageUnitId; + } + + public String getPackageUnitName() { + return packageUnitName; + } + + public void setPackageUnitName(String packageUnitName) { + this.packageUnitName = packageUnitName; + } + + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + + public Integer getDuration() { + return duration; + } + + public void setDuration(Integer duration) { + this.duration = duration; + } + + @Override + public String toString() { + return "CoinPackage{" + + "id=" + id + + ", duration=" + duration + + ", title='" + title + '\'' + + ", price=" + price + + ", number=" + number + + ", packageUnitId=" + packageUnitId + + ", packageUnitName='" + packageUnitName + '\'' + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + '}'; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/entity/CoinPackageUnit.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/entity/CoinPackageUnit.java new file mode 100644 index 0000000..f70655f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/entity/CoinPackageUnit.java @@ -0,0 +1,94 @@ +package com.aopcloud.beam.app.api.coin.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.time.LocalDateTime; +import java.io.Serializable; + +/** + *

+ * 算力包单位 + *

+ * + * @author Enoch + * @since 2021-03-01 + */ +@TableName("sly_coin_package_unit") +public class CoinPackageUnit implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 单位名称 + */ + private String name; + + /** + * 备注 + */ + private String desc; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + + @Override + public String toString() { + return "CoinPackageUnit{" + + "id=" + id + + ", name=" + name + + ", desc=" + desc + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + "}"; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/mapper/CoinMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/mapper/CoinMapper.java new file mode 100644 index 0000000..abd6c85 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/mapper/CoinMapper.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.coin.mapper; + +import com.aopcloud.beam.app.api.coin.entity.Coin; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 货币类型表 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface CoinMapper extends BaseMapper { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/mapper/CoinPackageMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/mapper/CoinPackageMapper.java new file mode 100644 index 0000000..5c9acb5 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/mapper/CoinPackageMapper.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.coin.mapper; + +import com.aopcloud.beam.app.api.coin.entity.CoinPackage; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 算力包 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-03-01 + */ +public interface CoinPackageMapper extends BaseMapper { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/mapper/CoinPackageUnitMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/mapper/CoinPackageUnitMapper.java new file mode 100644 index 0000000..42a630f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/mapper/CoinPackageUnitMapper.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.coin.mapper; + +import com.aopcloud.beam.app.api.coin.entity.CoinPackageUnit; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 算力包单位 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-03-01 + */ +public interface CoinPackageUnitMapper extends BaseMapper { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/ICoinPackageService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/ICoinPackageService.java new file mode 100644 index 0000000..5ebb162 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/ICoinPackageService.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.coin.service; + +import com.aopcloud.beam.app.api.coin.entity.CoinPackage; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 算力包 服务类 + *

+ * + * @author Enoch + * @since 2021-03-01 + */ +public interface ICoinPackageService extends IService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/ICoinPackageUnitService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/ICoinPackageUnitService.java new file mode 100644 index 0000000..ae52dde --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/ICoinPackageUnitService.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.coin.service; + +import com.aopcloud.beam.app.api.coin.entity.CoinPackageUnit; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 算力包单位 服务类 + *

+ * + * @author Enoch + * @since 2021-03-01 + */ +public interface ICoinPackageUnitService extends IService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/ICoinService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/ICoinService.java new file mode 100644 index 0000000..7f260fd --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/ICoinService.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.coin.service; + +import com.aopcloud.beam.app.api.coin.entity.Coin; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 货币类型表 服务类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface ICoinService extends IService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/impl/CoinPackageServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/impl/CoinPackageServiceImpl.java new file mode 100644 index 0000000..972c88f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/impl/CoinPackageServiceImpl.java @@ -0,0 +1,46 @@ +package com.aopcloud.beam.app.api.coin.service.impl; + +import com.alibaba.fastjson.JSON; +import com.aopcloud.beam.app.api.coin.entity.CoinPackage; +import com.aopcloud.beam.app.api.coin.mapper.CoinPackageMapper; +import com.aopcloud.beam.app.api.coin.service.ICoinPackageService; +import com.aopcloud.beam.app.core.Result; +import com.aopcloud.beam.app.core.ResultGenerator; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 算力包 服务实现类 + *

+ * + * @author Enoch + * @since 2021-03-01 + */ +@Service +public class CoinPackageServiceImpl extends ServiceImpl implements ICoinPackageService { + + public Result create(CoinPackage entity) { + System.out.println("create:"+JSON.toJSONString(entity)); + save(entity); + return ResultGenerator.genSuccessResult(entity.getId()); + } + + public Result edit(CoinPackage entity) { + System.out.println("edit:"+JSON.toJSONString(entity)); + updateById(entity); + return ResultGenerator.genSuccessResult(entity); + + } + + public Result delete(int id) { + removeById(id); + return ResultGenerator.genSuccessResult(); + + } + + public Result getList(int coinId) { + return ResultGenerator.genSuccessResult(list()); + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/impl/CoinPackageUnitServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/impl/CoinPackageUnitServiceImpl.java new file mode 100644 index 0000000..5739c28 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/impl/CoinPackageUnitServiceImpl.java @@ -0,0 +1,20 @@ +package com.aopcloud.beam.app.api.coin.service.impl; + +import com.aopcloud.beam.app.api.coin.entity.CoinPackageUnit; +import com.aopcloud.beam.app.api.coin.mapper.CoinPackageUnitMapper; +import com.aopcloud.beam.app.api.coin.service.ICoinPackageUnitService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 算力包单位 服务实现类 + *

+ * + * @author Enoch + * @since 2021-03-01 + */ +@Service +public class CoinPackageUnitServiceImpl extends ServiceImpl implements ICoinPackageUnitService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/impl/CoinServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/impl/CoinServiceImpl.java new file mode 100644 index 0000000..8d8df5d --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/coin/service/impl/CoinServiceImpl.java @@ -0,0 +1,70 @@ +package com.aopcloud.beam.app.api.coin.service.impl; + +import com.aopcloud.beam.app.api.coin.entity.Coin; +import com.aopcloud.beam.app.api.coin.entity.CoinAction; +import com.aopcloud.beam.app.api.coin.mapper.CoinMapper; +import com.aopcloud.beam.app.api.coin.service.ICoinService; +import com.aopcloud.beam.app.core.Result; +import com.aopcloud.beam.app.core.ResultGenerator; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; + +/** + *

+ * 货币类型表 服务实现类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@Service +public class CoinServiceImpl extends ServiceImpl implements ICoinService { + + + public Result add(CoinAction coinAction) { + Coin coin = new Coin(); + BeanUtils.copyProperties(coinAction, coin); + baseMapper.insert(coin); + return ResultGenerator.genSuccessResult(); + } + + public Result edit(CoinAction coinAction) { + Coin mCoin = baseMapper.selectOne(new QueryWrapper().ge("id", coinAction.getId())); + if (mCoin == null) { + return ResultGenerator.genFailResult("货币类型不存在"); + } + BeanUtils.copyProperties(coinAction, mCoin); + baseMapper.update(mCoin, new UpdateWrapper<>()); + return ResultGenerator.genSuccessResult(); + } + + public Result delete(int deleteId) { + baseMapper.deleteById(deleteId); + return ResultGenerator.genSuccessResult("删除成功"); + } + + public Result getList(Integer pageIndex, Integer size) { + Page page = new Page<>(pageIndex, size); + Page userMyPage = page(page); + return ResultGenerator.genSuccessResult(userMyPage.getRecords()); + } + + public Result create(CoinAction action) { + Coin coin = new Coin(); + coin.setImgOssFile("" + action.getImgOssFile()); + coin.setCnName(action.getCnName()); + coin.setEnName(action.getEnName()); + coin.setCreateTime(LocalDateTime.now()); + coin.setUpdateTime(LocalDateTime.now()); + baseMapper.insert(coin); + return ResultGenerator.genSuccessResult(); + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/controller/BeamImgController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/controller/BeamImgController.java new file mode 100644 index 0000000..e335337 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/controller/BeamImgController.java @@ -0,0 +1,20 @@ +package com.aopcloud.beam.app.api.img.controller; + + +import org.springframework.web.bind.annotation.RequestMapping; + +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * img 表格 前端控制器 + *

+ * + * @author Enoch + * @since 2021-01-30 + */ +@RestController +@RequestMapping("/img/beam-img") +public class BeamImgController { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/entity/BeamImg.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/entity/BeamImg.java new file mode 100644 index 0000000..3d6bb5f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/entity/BeamImg.java @@ -0,0 +1,61 @@ +package com.aopcloud.beam.app.api.img.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.time.LocalDateTime; +import java.io.Serializable; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * img 表格 + *

+ * + * @author Enoch + * @since 2021-01-30 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class BeamImg implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + /** + * url + */ + private String url; + + /** + * url 描述 + */ + private String description; + + /** + * file_md5 + */ + private String imgMd5; + + /** + * 创建人 + */ + private String createBy; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/mapper/BeamImgMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/mapper/BeamImgMapper.java new file mode 100644 index 0000000..998300f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/mapper/BeamImgMapper.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.img.mapper; + +import com.aopcloud.beam.app.api.img.entity.BeamImg; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * img 表格 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-01-30 + */ +public interface BeamImgMapper extends BaseMapper { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/service/IBeamImgService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/service/IBeamImgService.java new file mode 100644 index 0000000..900050b --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/service/IBeamImgService.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.img.service; + +import com.aopcloud.beam.app.api.img.entity.BeamImg; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * img 表格 服务类 + *

+ * + * @author Enoch + * @since 2021-01-30 + */ +public interface IBeamImgService extends IService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/service/impl/BeamImgServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/service/impl/BeamImgServiceImpl.java new file mode 100644 index 0000000..a061cfe --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/img/service/impl/BeamImgServiceImpl.java @@ -0,0 +1,20 @@ +package com.aopcloud.beam.app.api.img.service.impl; + +import com.aopcloud.beam.app.api.img.entity.BeamImg; +import com.aopcloud.beam.app.api.img.mapper.BeamImgMapper; +import com.aopcloud.beam.app.api.img.service.IBeamImgService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * img 表格 服务实现类 + *

+ * + * @author Enoch + * @since 2021-01-30 + */ +@Service +public class BeamImgServiceImpl extends ServiceImpl implements IBeamImgService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberCoinAddressController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberCoinAddressController.java new file mode 100644 index 0000000..f6051f9 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberCoinAddressController.java @@ -0,0 +1,50 @@ +package com.aopcloud.beam.app.api.member.controller; + + +import com.aopcloud.beam.app.api.member.entity.AddCoinAddress; +import com.aopcloud.beam.app.api.member.entity.Member; +import com.aopcloud.beam.app.api.member.service.impl.MemberCoinAddressServiceImpl; +import com.aopcloud.beam.app.core.Result; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.HashMap; + +/** + *

+ * 会员货币地址表 前端控制器 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@RestController +@RequestMapping("/member/address") +public class MemberCoinAddressController { + + + + @Resource + private MemberCoinAddressServiceImpl service; + + @PostMapping("/create") + public Result create(@RequestBody HashMap params){ + return service.create(params); + } + + + @PostMapping("/delete") + public Result delete(@RequestBody HashMap params) { + return service.delete((Integer) params.get("id")); + } + + @GetMapping("/list") + public Result getList(@RequestHeader(required = false) String token,@RequestParam(required = false,defaultValue = "0") int coinId) { + return service.getList(token,coinId); + } + + + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberCoinRecordController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberCoinRecordController.java new file mode 100644 index 0000000..852f6c6 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberCoinRecordController.java @@ -0,0 +1,38 @@ +package com.aopcloud.beam.app.api.member.controller; + + +import com.aopcloud.beam.app.api.member.service.impl.MemberCoinAddressServiceImpl; +import com.aopcloud.beam.app.api.member.service.impl.MemberCoinRecordServiceImpl; +import com.aopcloud.beam.app.core.Result; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + *

+ * 会员挖矿记录表 前端控制器 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@RestController +@RequestMapping("/member/profit") +public class MemberCoinRecordController { + + @Resource + private MemberCoinRecordServiceImpl recordService; + + @GetMapping("/list") + public Result getList(@RequestHeader String token) { + + return recordService.getList(token); + } + + + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberController.java new file mode 100644 index 0000000..4fc235c --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberController.java @@ -0,0 +1,80 @@ +package com.aopcloud.beam.app.api.member.controller; + + +import com.alibaba.fastjson.JSON; +import com.aopcloud.beam.app.api.member.entity.Member; +import com.aopcloud.beam.app.api.member.entity.MemberActionBean; +import com.aopcloud.beam.app.api.member.service.impl.MemberServiceImpl; +import com.aopcloud.beam.app.api.user.entity.UpdateUserEntity; +import com.aopcloud.beam.app.api.user.entity.UserActionBean; +import com.aopcloud.beam.app.annotion.LoginRequired; +import com.aopcloud.beam.app.core.Result; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import java.util.Map; + +/** + *

+ * 会员表 前端控制器 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@RestController +@RequestMapping("/member") +public class MemberController { + @Resource + MemberServiceImpl beamUserService; + + + @PostMapping("/register") + public Result register(@RequestBody @Valid MemberActionBean register) { + return beamUserService.register(register); + } + + @PostMapping("/login") + public Result login(@RequestBody MemberActionBean register) { + return beamUserService.login(register); + } + + @PostMapping("/logout") + public Result logout(@RequestHeader @NotBlank String token) { + return beamUserService.logout(token); + } + + @LoginRequired + @PostMapping("/edit") + public Result edit(@RequestHeader @NotBlank String token, @RequestBody @Valid UpdateUserEntity user) { + return beamUserService.edit(token, user); + } + + @LoginRequired + @GetMapping("/info") + public Result getInfo(@RequestHeader @NotBlank String token) { + return beamUserService.getInfo(token); + } + + @PostMapping("/forgePassword") + public Result getPassword(@RequestBody @Valid MemberActionBean actionBean) { + return beamUserService.getPassword(actionBean); + } + + @LoginRequired + @PostMapping("/updatePassword") + public Result updatePassword(@RequestBody Map actionBean, @RequestHeader String token) { + System.out.println(JSON.toJSONString(actionBean)); + return beamUserService.updatePassword(token, actionBean); + } + + + @GetMapping("/history") + public Result history(@RequestHeader @NotBlank String token) { + return beamUserService.history(token); + } + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberLevelController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberLevelController.java new file mode 100644 index 0000000..168dd8f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberLevelController.java @@ -0,0 +1,19 @@ +package com.aopcloud.beam.app.api.member.controller; + + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 会员等级表 前端控制器 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@RestController +@RequestMapping("/member/level") +public class MemberLevelController { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberLoginLogController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberLoginLogController.java new file mode 100644 index 0000000..d135e10 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberLoginLogController.java @@ -0,0 +1,19 @@ +package com.aopcloud.beam.app.api.member.controller; + + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 会员登录记录 前端控制器 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@RestController +@RequestMapping("/member/login/log") +public class MemberLoginLogController { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberStatisticsInfoController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberStatisticsInfoController.java new file mode 100644 index 0000000..6f84857 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/controller/MemberStatisticsInfoController.java @@ -0,0 +1,19 @@ +package com.aopcloud.beam.app.api.member.controller; + + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 会员统计信息 前端控制器 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@RestController +@RequestMapping("/member/statistics/info") +public class MemberStatisticsInfoController { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/AddCoinAddress.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/AddCoinAddress.java new file mode 100644 index 0000000..46abc73 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/AddCoinAddress.java @@ -0,0 +1,14 @@ +package com.aopcloud.beam.app.api.member.entity; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + +public class AddCoinAddress { + + @NotBlank(message = "手机号不能为空") + private String phone; + @Size(max = 20, min = 6 ,message = "密码长度最低为6位") + private String password; + private String code=""; + private String name; +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/Member.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/Member.java new file mode 100644 index 0000000..c2414e4 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/Member.java @@ -0,0 +1,278 @@ +package com.aopcloud.beam.app.api.member.entity; + +import com.aopcloud.beam.app.util.AliyunOSSUtil; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import java.io.Serializable; +import java.time.LocalDate; +import java.time.LocalDateTime; + +/** + *

+ * 会员表 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@TableName("sly_member") +public class Member implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + private String memberSn; + + private Long memberLevelId; + + /** + * 用户名 + */ + private String username; + + /** + * 密码 + */ + private String password; + + /** + * 昵称 + */ + private String nickname; + + /** + * 头像 + */ + @JsonIgnore + private String avatarOssFile; + + /** + * 手机号码 + */ + private String phone; + + /** + * 帐号启用状态:0->禁用;1->启用; 2->删除 + */ + private Integer status; + + /** + * 性别:0->未知;1->男;2->女 + */ + private Integer gender; + + /** + * 生日 + */ + private LocalDate birthday; + + /** + * 所做城市 + */ + private String city; + + /** + * 个性签名 + */ + private String personalizedSignature; + + /** + * 用户来源 + */ + private Integer sourceType; + + /** + * 注册时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * Token + */ + private String token; + + + @TableField(exist = false) + private String avatar; + + + public String getAvatar() { + return AliyunOSSUtil.getInstance().getFileUrl(avatarOssFile); + } + + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public static long getSerialVersionUID() { + return serialVersionUID; + } + + public String getMemberSn() { + return memberSn; + } + + public void setMemberSn(String memberSn) { + this.memberSn = memberSn; + } + + public Long getMemberLevelId() { + return memberLevelId; + } + + public void setMemberLevelId(Long memberLevelId) { + this.memberLevelId = memberLevelId; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public String getAvatarOssFile() { + return avatarOssFile; + } + + public void setAvatarOssFile(String avatarOssFile) { + this.avatarOssFile = avatarOssFile; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public Integer getGender() { + return gender; + } + + public void setGender(Integer gender) { + this.gender = gender; + } + + public LocalDate getBirthday() { + return birthday; + } + + public void setBirthday(LocalDate birthday) { + this.birthday = birthday; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getPersonalizedSignature() { + return personalizedSignature; + } + + public void setPersonalizedSignature(String personalizedSignature) { + this.personalizedSignature = personalizedSignature; + } + + public Integer getSourceType() { + return sourceType; + } + + public void setSourceType(Integer sourceType) { + this.sourceType = sourceType; + } + + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + @Override + public String toString() { + return "Member{" + + "id=" + id + + ", memberSn='" + memberSn + '\'' + + ", memberLevelId=" + memberLevelId + + ", username='" + username + '\'' + + ", password='" + password + '\'' + + ", nickname='" + nickname + '\'' + + ", avatarOssFile='" + avatarOssFile + '\'' + + ", phone='" + phone + '\'' + + ", status=" + status + + ", gender=" + gender + + ", birthday=" + birthday + + ", city='" + city + '\'' + + ", personalizedSignature='" + personalizedSignature + '\'' + + ", sourceType=" + sourceType + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + ", token='" + token + '\'' + + ", avatar='" + avatar + '\'' + + '}'; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberActionBean.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberActionBean.java new file mode 100644 index 0000000..45c8d0f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberActionBean.java @@ -0,0 +1,65 @@ +package com.aopcloud.beam.app.api.member.entity; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + +public class MemberActionBean { + + @NotBlank(message = "手机号不能为空") + private String phone; + private String lodPassword; + @NotBlank(message = "密码不能为空") + private String password; + private String code=""; + private String name; + private String ossFile; + + public String getLodPassword() { + return lodPassword; + } + + public void setLodPassword(String lodPassword) { + this.lodPassword = lodPassword; + } + + public String getOssFile() { + return ossFile; + } + + public void setOssFile(String ossFile) { + this.ossFile = ossFile; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} + diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberCoinAddress.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberCoinAddress.java new file mode 100644 index 0000000..e13b3a5 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberCoinAddress.java @@ -0,0 +1,165 @@ +package com.aopcloud.beam.app.api.member.entity; + +import com.aopcloud.beam.app.util.AliyunOSSUtil; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 会员货币地址表 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@TableName("sly_member_coin_address") +public class MemberCoinAddress implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 货币ID + */ + private Integer coinId; + + /** + * 用户ID + */ + private Integer memberId; + + /** + * 钱包地址 + */ + private String address; + + /** + * coin 描述 + */ + private String description; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + + /** + * 英文名称 + */ + @TableField(exist = false) + private String enName; + + /** + * 中文名称 + */ + @TableField(exist = false) + private String cnName; + + /** + * img name + */ + @JsonIgnore + @TableField(exist = false) + private String imgOssFile; + + @TableField(exist = false) + public String icon ; + + public String getEnName() { + return enName; + } + + public void setEnName(String enName) { + this.enName = enName; + } + + public String getCnName() { + return cnName; + } + + public void setCnName(String cnName) { + this.cnName = cnName; + } + + public String getIcon() { + return AliyunOSSUtil.getInstance().getFileUrl(imgOssFile); + } + + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + public Integer getCoinId() { + return coinId; + } + + public void setCoinId(Integer coinId) { + this.coinId = coinId; + } + public Integer getMemberId() { + return memberId; + } + + public void setMemberId(Integer memberId) { + this.memberId = memberId; + } + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + + @Override + public String toString() { + return "MemberCoinAddress{" + + "id=" + id + + ", coinId=" + coinId + + ", memberId=" + memberId + + ", address=" + address + + ", description=" + description + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + "}"; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberCoinRecord.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberCoinRecord.java new file mode 100644 index 0000000..ecd9d82 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberCoinRecord.java @@ -0,0 +1,217 @@ +package com.aopcloud.beam.app.api.member.entity; + +import com.aopcloud.beam.app.util.AliyunOSSUtil; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + *

+ * 会员挖矿记录表 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@TableName("sly_member_coin_record") +public class MemberCoinRecord implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 货币ID + */ + private Integer coinId; + + /** + * 用户ID + */ + private Long memberId; + + /** + * 钱包地址 + */ + private String address; + + /** + * 收益 + */ + private BigDecimal profit; + + /** + * 记录编号 + */ + private String recordSn; + + /** + * 订单编号 + */ + private String orderSn; + + /** + * 备注 + */ + private String remarks; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + + /** + * 英文名称 + */ + @TableField(exist = false) + private String enName; + + /** + * 中文名称 + */ + @TableField(exist = false) + private String cnName; + + /** + * img name + */ + @JsonIgnore + @TableField(exist = false) + private String imgOssFile; + + @TableField(exist = false) + public String icon ; + + + public String getEnName() { + return enName; + } + + public void setEnName(String enName) { + this.enName = enName; + } + + public String getCnName() { + return cnName; + } + + public void setCnName(String cnName) { + this.cnName = cnName; + } + + public String getImgOssFile() { + return imgOssFile; + } + + public void setImgOssFile(String imgOssFile) { + this.imgOssFile = imgOssFile; + } + + public String getIcon() { + return AliyunOSSUtil.getInstance().getFileUrl(imgOssFile); + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + public Integer getCoinId() { + return coinId; + } + + public void setCoinId(Integer coinId) { + this.coinId = coinId; + } + public Long getMemberId() { + return memberId; + } + + public void setMemberId(Long memberId) { + this.memberId = memberId; + } + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + public BigDecimal getProfit() { + return profit; + } + + public void setProfit(BigDecimal profit) { + this.profit = profit; + } + public String getRecordSn() { + return recordSn; + } + + public void setRecordSn(String recordSn) { + this.recordSn = recordSn; + } + public String getOrderSn() { + return orderSn; + } + + public void setOrderSn(String orderSn) { + this.orderSn = orderSn; + } + public String getRemarks() { + return remarks; + } + + public void setRemarks(String remarks) { + this.remarks = remarks; + } + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + + @Override + public String toString() { + return "MemberCoinRecord{" + + "id=" + id + + ", coinId=" + coinId + + ", memberId=" + memberId + + ", address=" + address + + ", profit=" + profit + + ", recordSn=" + recordSn + + ", orderSn=" + orderSn + + ", remarks=" + remarks + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + "}"; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberLevel.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberLevel.java new file mode 100644 index 0000000..ddf1fec --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberLevel.java @@ -0,0 +1,161 @@ +package com.aopcloud.beam.app.api.member.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 会员等级表 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@TableName("sly_member_level") +public class MemberLevel implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + private String name; + + private Integer growthPoint; + + /** + * 是否为默认等级:0->不是;1->是 + */ + private Integer defaultStatus; + + /** + * 是否有签到特权 + */ + private Integer priviledgeSignIn; + + /** + * 是否有专享活动特权 + */ + private Integer priviledgePromotion; + + /** + * 是否有会员价格特权 + */ + private Integer priviledgeMemberPrice; + + /** + * 是否有生日特权 + */ + private Integer priviledgeBirthday; + + private String note; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + public Integer getGrowthPoint() { + return growthPoint; + } + + public void setGrowthPoint(Integer growthPoint) { + this.growthPoint = growthPoint; + } + public Integer getDefaultStatus() { + return defaultStatus; + } + + public void setDefaultStatus(Integer defaultStatus) { + this.defaultStatus = defaultStatus; + } + public Integer getPriviledgeSignIn() { + return priviledgeSignIn; + } + + public void setPriviledgeSignIn(Integer priviledgeSignIn) { + this.priviledgeSignIn = priviledgeSignIn; + } + public Integer getPriviledgePromotion() { + return priviledgePromotion; + } + + public void setPriviledgePromotion(Integer priviledgePromotion) { + this.priviledgePromotion = priviledgePromotion; + } + public Integer getPriviledgeMemberPrice() { + return priviledgeMemberPrice; + } + + public void setPriviledgeMemberPrice(Integer priviledgeMemberPrice) { + this.priviledgeMemberPrice = priviledgeMemberPrice; + } + public Integer getPriviledgeBirthday() { + return priviledgeBirthday; + } + + public void setPriviledgeBirthday(Integer priviledgeBirthday) { + this.priviledgeBirthday = priviledgeBirthday; + } + public String getNote() { + return note; + } + + public void setNote(String note) { + this.note = note; + } + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + + @Override + public String toString() { + return "MemberLevel{" + + "id=" + id + + ", name=" + name + + ", growthPoint=" + growthPoint + + ", defaultStatus=" + defaultStatus + + ", priviledgeSignIn=" + priviledgeSignIn + + ", priviledgePromotion=" + priviledgePromotion + + ", priviledgeMemberPrice=" + priviledgeMemberPrice + + ", priviledgeBirthday=" + priviledgeBirthday + + ", note=" + note + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + "}"; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberLoginLog.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberLoginLog.java new file mode 100644 index 0000000..bd075bd --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberLoginLog.java @@ -0,0 +1,119 @@ +package com.aopcloud.beam.app.api.member.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 会员登录记录 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@TableName("sly_member_login_log") +public class MemberLoginLog implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + private Long memberId; + + private String ip; + + private String city; + + /** + * 登录类型:0->PC;1->android;2->ios;3->小程序 + */ + private Integer loginType; + + private String province; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + public Long getMemberId() { + return memberId; + } + + public void setMemberId(Long memberId) { + this.memberId = memberId; + } + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + public Integer getLoginType() { + return loginType; + } + + public void setLoginType(Integer loginType) { + this.loginType = loginType; + } + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + + @Override + public String toString() { + return "MemberLoginLog{" + + "id=" + id + + ", memberId=" + memberId + + ", ip=" + ip + + ", city=" + city + + ", loginType=" + loginType + + ", province=" + province + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + "}"; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberStatisticsInfo.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberStatisticsInfo.java new file mode 100644 index 0000000..ea04d67 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/entity/MemberStatisticsInfo.java @@ -0,0 +1,142 @@ +package com.aopcloud.beam.app.api.member.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + *

+ * 会员统计信息 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@TableName("sly_member_statistics_info") +public class MemberStatisticsInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + private Long memberId; + + /** + * 累计消费金额 + */ + private BigDecimal consumeAmount; + + /** + * 订单数量 + */ + private Integer orderCount; + + /** + * 登录次数 + */ + private Integer loginCount; + + /** + * 钱包地址数量 + */ + private Integer coinAddressCount; + + /** + * 最后一次下订单时间 + */ + private LocalDateTime recentOrderTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + public Long getMemberId() { + return memberId; + } + + public void setMemberId(Long memberId) { + this.memberId = memberId; + } + public BigDecimal getConsumeAmount() { + return consumeAmount; + } + + public void setConsumeAmount(BigDecimal consumeAmount) { + this.consumeAmount = consumeAmount; + } + public Integer getOrderCount() { + return orderCount; + } + + public void setOrderCount(Integer orderCount) { + this.orderCount = orderCount; + } + public Integer getLoginCount() { + return loginCount; + } + + public void setLoginCount(Integer loginCount) { + this.loginCount = loginCount; + } + public Integer getCoinAddressCount() { + return coinAddressCount; + } + + public void setCoinAddressCount(Integer coinAddressCount) { + this.coinAddressCount = coinAddressCount; + } + public LocalDateTime getRecentOrderTime() { + return recentOrderTime; + } + + public void setRecentOrderTime(LocalDateTime recentOrderTime) { + this.recentOrderTime = recentOrderTime; + } + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + + @Override + public String toString() { + return "MemberStatisticsInfo{" + + "id=" + id + + ", memberId=" + memberId + + ", consumeAmount=" + consumeAmount + + ", orderCount=" + orderCount + + ", loginCount=" + loginCount + + ", coinAddressCount=" + coinAddressCount + + ", recentOrderTime=" + recentOrderTime + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + "}"; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberCoinAddressMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberCoinAddressMapper.java new file mode 100644 index 0000000..1b9e30c --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberCoinAddressMapper.java @@ -0,0 +1,34 @@ +package com.aopcloud.beam.app.api.member.mapper; + +import com.aopcloud.beam.app.api.member.entity.MemberCoinAddress; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + *

+ * 会员货币地址表 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface MemberCoinAddressMapper extends BaseMapper { + + + /** + * @return + */ + @Select("SELECT distinct sly_member_coin_address.*,sly_coin.`cn_name` AS cnName ,sly_coin.`en_name` AS enName ,sly_coin.`img_oss_file` AS imgOssFile FROM sly_member_coin_address,sly_member, sly_coin WHERE sly_member_coin_address.coin_id=sly_coin.id AND sly_member_coin_address.member_id= #{memberId} ") + List getAddressList(@Param("memberId")long memberId); + + /** + * @return + */ + @Select("SELECT distinct sly_member_coin_address.*,sly_coin.`cn_name` AS cnName ,sly_coin.`en_name` AS enName ,sly_coin.`img_oss_file` AS imgOssFile FROM sly_member_coin_address,sly_member, sly_coin WHERE sly_member_coin_address.coin_id= #{coinId} AND sly_coin.id= #{coinId} AND sly_member_coin_address.member_id= #{memberId} ") + List getAddressListByCoinId(@Param("memberId")long memberId, @Param("coinId")long coinId); + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberCoinRecordMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberCoinRecordMapper.java new file mode 100644 index 0000000..5e3d49f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberCoinRecordMapper.java @@ -0,0 +1,26 @@ +package com.aopcloud.beam.app.api.member.mapper; + +import com.aopcloud.beam.app.api.member.entity.MemberCoinAddress; +import com.aopcloud.beam.app.api.member.entity.MemberCoinRecord; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + *

+ * 会员挖矿记录表 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface MemberCoinRecordMapper extends BaseMapper { + + + /** + * @return + */ + @Select("SELECT distinct sly_member_coin_record.*,sly_coin.`cn_name` AS cnName ,sly_coin.`en_name` AS enName ,sly_coin.`img_oss_file` AS imgOssFile FROM sly_member_coin_record,sly_member, sly_coin WHERE sly_member_coin_record.coin_id=sly_coin.id AND sly_member_coin_record.member_id= ${memberId} ") + List getList(long memberId); +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberLevelMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberLevelMapper.java new file mode 100644 index 0000000..4c1f58d --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberLevelMapper.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.member.mapper; + +import com.aopcloud.beam.app.api.member.entity.MemberLevel; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 会员等级表 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface MemberLevelMapper extends BaseMapper { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberLoginLogMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberLoginLogMapper.java new file mode 100644 index 0000000..ec20a8e --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberLoginLogMapper.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.member.mapper; + +import com.aopcloud.beam.app.api.member.entity.MemberLoginLog; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 会员登录记录 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface MemberLoginLogMapper extends BaseMapper { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberMapper.java new file mode 100644 index 0000000..7232224 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberMapper.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.member.mapper; + +import com.aopcloud.beam.app.api.member.entity.Member; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 会员表 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface MemberMapper extends BaseMapper { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberStatisticsInfoMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberStatisticsInfoMapper.java new file mode 100644 index 0000000..d84b00d --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/mapper/MemberStatisticsInfoMapper.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.member.mapper; + +import com.aopcloud.beam.app.api.member.entity.MemberStatisticsInfo; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 会员统计信息 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface MemberStatisticsInfoMapper extends BaseMapper { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberCoinAddressService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberCoinAddressService.java new file mode 100644 index 0000000..6eee01f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberCoinAddressService.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.member.service; + +import com.aopcloud.beam.app.api.member.entity.MemberCoinAddress; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 会员货币地址表 服务类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface IMemberCoinAddressService extends IService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberCoinRecordService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberCoinRecordService.java new file mode 100644 index 0000000..21bb5b3 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberCoinRecordService.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.member.service; + +import com.aopcloud.beam.app.api.member.entity.MemberCoinRecord; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 会员挖矿记录表 服务类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface IMemberCoinRecordService extends IService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberLevelService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberLevelService.java new file mode 100644 index 0000000..121d2aa --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberLevelService.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.member.service; + +import com.aopcloud.beam.app.api.member.entity.MemberLevel; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 会员等级表 服务类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface IMemberLevelService extends IService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberLoginLogService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberLoginLogService.java new file mode 100644 index 0000000..4a37146 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberLoginLogService.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.member.service; + +import com.aopcloud.beam.app.api.member.entity.MemberLoginLog; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 会员登录记录 服务类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface IMemberLoginLogService extends IService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberService.java new file mode 100644 index 0000000..20513f7 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberService.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.member.service; + +import com.aopcloud.beam.app.api.member.entity.Member; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 会员表 服务类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface IMemberService extends IService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberStatisticsInfoService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberStatisticsInfoService.java new file mode 100644 index 0000000..dd8b40e --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/IMemberStatisticsInfoService.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.member.service; + +import com.aopcloud.beam.app.api.member.entity.MemberStatisticsInfo; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 会员统计信息 服务类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface IMemberStatisticsInfoService extends IService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberCoinAddressServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberCoinAddressServiceImpl.java new file mode 100644 index 0000000..4ff7135 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberCoinAddressServiceImpl.java @@ -0,0 +1,70 @@ +package com.aopcloud.beam.app.api.member.service.impl; + +import com.aopcloud.beam.app.api.member.entity.AddCoinAddress; +import com.aopcloud.beam.app.api.member.entity.Member; +import com.aopcloud.beam.app.api.member.entity.MemberCoinAddress; +import com.aopcloud.beam.app.api.member.mapper.MemberCoinAddressMapper; +import com.aopcloud.beam.app.api.member.service.IMemberCoinAddressService; +import com.aopcloud.beam.app.core.AppException;; +import com.aopcloud.beam.app.core.ResultGenerator; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.apache.commons.lang.StringUtils; +import org.springframework.stereotype.Service; +import com.aopcloud.beam.app.core.Result; +import com.aopcloud.beam.app.core.ResultGenerator; +import javax.annotation.Resource; +import java.util.Map; + +/** + *

+ * 会员货币地址表 服务实现类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@Service +public class MemberCoinAddressServiceImpl extends ServiceImpl implements IMemberCoinAddressService { + + + @Resource + private MemberServiceImpl memberService; + + public Result getList(String token,int coinId) { + Member member = memberService.getMemberByToken(token); + if (coinId>0){ + return ResultGenerator.genSuccessResult(baseMapper.getAddressListByCoinId(member.getId(),coinId)); + }else { + return ResultGenerator.genSuccessResult(baseMapper.getAddressList(member.getId())); + } + } + + + public Result delete(Integer id) { + removeById(id); + return ResultGenerator.genSuccessResult(); + + } + + public Result create(Map params) { + String token = (String) params.get("token"); + Integer coinId = (Integer) params.get("coinId"); + Integer memberId = (Integer) params.get("memberId"); + if (StringUtils.isEmpty(token)) { + throw new AppException("地址不能为空"); + } + if (coinId < 1) { + throw new AppException("货币类型不能为空"); + } + if (memberId < 1) { + throw new AppException("地址不能为空"); + } + MemberCoinAddress address = new MemberCoinAddress(); + address.setAddress(token); + address.setCoinId(coinId); + address.setMemberId(memberId); + address.setDescription(""); + save(address); + return ResultGenerator.genSuccessResult(); + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberCoinRecordServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberCoinRecordServiceImpl.java new file mode 100644 index 0000000..0bd849c --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberCoinRecordServiceImpl.java @@ -0,0 +1,35 @@ +package com.aopcloud.beam.app.api.member.service.impl; + +import com.aopcloud.beam.app.api.member.entity.Member; +import com.aopcloud.beam.app.api.member.entity.MemberCoinRecord; +import com.aopcloud.beam.app.api.member.mapper.MemberCoinRecordMapper; +import com.aopcloud.beam.app.api.member.service.IMemberCoinRecordService; +import com.aopcloud.beam.app.core.Result; +import com.aopcloud.beam.app.core.ResultGenerator; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; + +/** + *

+ * 会员挖矿记录表 服务实现类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@Service +public class MemberCoinRecordServiceImpl extends ServiceImpl implements IMemberCoinRecordService { + + + @Resource + private MemberServiceImpl memberService; + + public Result getList(String token) { + Member member = memberService.getMemberByToken(token); + return ResultGenerator.genSuccessResult(baseMapper.getList(member.getId())); + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberLevelServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberLevelServiceImpl.java new file mode 100644 index 0000000..ae97780 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberLevelServiceImpl.java @@ -0,0 +1,20 @@ +package com.aopcloud.beam.app.api.member.service.impl; + +import com.aopcloud.beam.app.api.member.entity.MemberLevel; +import com.aopcloud.beam.app.api.member.mapper.MemberLevelMapper; +import com.aopcloud.beam.app.api.member.service.IMemberLevelService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 会员等级表 服务实现类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@Service +public class MemberLevelServiceImpl extends ServiceImpl implements IMemberLevelService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberLoginLogServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberLoginLogServiceImpl.java new file mode 100644 index 0000000..6cce582 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberLoginLogServiceImpl.java @@ -0,0 +1,20 @@ +package com.aopcloud.beam.app.api.member.service.impl; + +import com.aopcloud.beam.app.api.member.entity.MemberLoginLog; +import com.aopcloud.beam.app.api.member.mapper.MemberLoginLogMapper; +import com.aopcloud.beam.app.api.member.service.IMemberLoginLogService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 会员登录记录 服务实现类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@Service +public class MemberLoginLogServiceImpl extends ServiceImpl implements IMemberLoginLogService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberServiceImpl.java new file mode 100644 index 0000000..7e01b25 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberServiceImpl.java @@ -0,0 +1,195 @@ +package com.aopcloud.beam.app.api.member.service.impl; + +import com.alibaba.fastjson.JSON; +import com.aopcloud.beam.app.api.member.entity.Member; +import com.aopcloud.beam.app.api.member.entity.MemberActionBean; +import com.aopcloud.beam.app.api.member.mapper.MemberMapper; +import com.aopcloud.beam.app.api.member.service.IMemberService; +import com.aopcloud.beam.app.api.user.entity.BeamUser; +import com.aopcloud.beam.app.api.user.entity.HBean; +import com.aopcloud.beam.app.api.user.entity.UpdateUserEntity; +import com.aopcloud.beam.app.api.user.entity.UserActionBean; +import com.aopcloud.beam.app.common.Constants; +import com.aopcloud.beam.app.core.AppException;; +import com.aopcloud.beam.app.core.Result; +import com.aopcloud.beam.app.core.ResultCode; +import com.aopcloud.beam.app.core.ResultGenerator; +import com.aopcloud.beam.app.util.IdUtil; +import com.aopcloud.beam.app.util.RegUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.*; + +/** + *

+ * 会员表 服务实现类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@Service +public class MemberServiceImpl extends ServiceImpl implements IMemberService { + public Result register(MemberActionBean userRegister) { + if (!RegUtil.checkMobile(userRegister.getPhone())) { + throw new AppException("手机号不正确"); + } + System.out.println("phone:" + userRegister.getPhone()); + Member user = baseMapper.selectOne(new QueryWrapper().eq("phone", userRegister.getPhone())); + if (user != null) { + System.out.println("phone:" + user.getUsername() + "/" + user.getPhone()); + throw new AppException("手机号已经注册"); + } + + Member member = new Member(); + member.setMemberSn("" + IdUtil.create()); + member.setNickname(StringUtils.isEmpty(userRegister.getName()) ? IdUtil.genNickname() : userRegister.getName() + ""); + member.setUsername(StringUtils.isEmpty(userRegister.getName()) ? IdUtil.genNickname() : userRegister.getName() + ""); + + if (StringUtils.isEmpty(userRegister.getOssFile())) { + member.setAvatarOssFile(Constants.IMG_DEFAULT_USER_AVATAR); + } else { + member.setAvatarOssFile(userRegister.getOssFile()); + } + member.setPhone(userRegister.getPhone()); + + member.setPassword(userRegister.getPassword()); + member.setCreateTime(LocalDateTime.now()); + member.setUpdateTime(LocalDateTime.now()); + member.setSourceType(1); + int id = baseMapper.insert(member); + return ResultGenerator.genSuccessResult(id); + } + + public Result login(MemberActionBean userRegister) { + + String token = null;//JwtUtil.createToken(user.getId() + "_" + user.getPhone()); + token = UUID.randomUUID().toString().replace("-", ""); + Member user = baseMapper.selectOne(new QueryWrapper().eq("phone", userRegister.getPhone())); + if (user == null) { + throw new AppException(-1, "用户不存在!", "用户不存在"); + } + if (!userRegister.getPassword().equals(user.getPassword())) { + throw new AppException(-1, "密码不正确!", "密码不正确"); + } + user.setToken(token); + baseMapper.updateById(user); + return ResultGenerator.genSuccessResult(user); + } + + public Result logout(String token) { + Member user = baseMapper.selectOne(new QueryWrapper().eq("token", token)); + if (user != null) { + user.setToken(""); + baseMapper.updateById(user); + } + return ResultGenerator.genSuccessResult("退出成功"); + } + + public Result edit(String token, UpdateUserEntity updateUser) { + Member user = baseMapper.selectOne(new QueryWrapper().eq("token", token)); + if (user == null) { + return ResultGenerator.genFailResult("用户不存在"); + } + BeanUtils.copyProperties(updateUser, user); + baseMapper.updateById(user); + return ResultGenerator.genSuccessResult(); + } + + public Result getInfo(String token) { + Member user = baseMapper.selectOne(new QueryWrapper().eq("token", token)); + if (user == null) { + throw new AppException("用户不存在"); + } + return ResultGenerator.genSuccessResult(user); + } + + public Result getPassword(MemberActionBean updateUser) { + Member user = baseMapper.selectOne(new QueryWrapper().eq("phone", updateUser.getPhone())); + if (user == null) { + throw new AppException(-1, "用户不存在!", "用户不存在"); + } + user.setPassword(updateUser.getPassword()); + baseMapper.updateById(user); + return ResultGenerator.genSuccessResult(user); + } + + public Result updatePassword(String token, Map updateUser) { + Member user = baseMapper.selectOne(new QueryWrapper().eq("token",token)); + if (user == null) { + throw new AppException("用户不存在"); + } + if (StringUtils.isEmpty(updateUser.get("oldPassword"))||StringUtils.isEmpty(updateUser.get("password"))) { + throw new AppException("请输入旧密码或新密码"); + } + if (!user.getPassword().equals(updateUser.get("oldPassword"))) { + throw new AppException("旧密码不正确"); + } + user.setPassword(updateUser.get("password")); + baseMapper.updateById(user); + return ResultGenerator.genSuccessResult(user); + } + + public Result getList(Integer pageIndex, Integer size) { + System.out.println(pageIndex + "/" + size); + Page page = new Page<>(pageIndex, size); + Page userMyPage = baseMapper.selectPage(page, new QueryWrapper<>()); + System.out.println("" + JSON.toJSONString(userMyPage)); + Map map = new HashMap(); + map.put("totalCount", userMyPage.getTotal()); + map.put("totalPage", userMyPage.getPages()); + map.put("pageNo", userMyPage.getCurrent()); + map.put("pageSize", size); + map.put("data", userMyPage.getRecords()); + return ResultGenerator.genSuccessResult(map); + } + + + public Result updateStatus(Map params) { + Member user = baseMapper.selectOne(new QueryWrapper().eq("id", params.get("id"))); + if (user == null) { + throw new AppException("用户不存在"); + } + user.setStatus((Integer) params.get("status")); + baseMapper.updateById(user); + return ResultGenerator.genSuccessResult(); + } + + + public Result history(String token) { + Member user = baseMapper.selectOne(new QueryWrapper().eq("token", token)); + if (user == null) { + throw new AppException(-1, "用户不存在!", "用户不存在"); + } + String url = "http://oss.mxzhe.cn/img/img_coin_1612004588012.png"; + List list = new ArrayList<>(); + //String coinName, String coinN, String coinIcon, String type, String createTime, String orderNo, String id, int sum, String tag) { + HBean hBean = new HBean("比特币", "BTC", url, 1, "2021-02-13 19:00", "8qwoiqwndonqwkdqkd", "123", 8980670.01f, "区块奖励"); + list.add(hBean); + hBean = new HBean("比特现金", "BCH", url, 2, "2021-02-14 19:00", "8qwoiqwndonqwkdqkd", "1212e1", 24520.01f, "区块奖励"); + list.add(hBean); + hBean = new HBean("莱特币", "LTC", url, 1, "2021-02-13 19:00", "8qwoiqwndonqwkdqkd", "asdasd123123asdasda", 892340.01f, "区块奖励"); + list.add(hBean); + return ResultGenerator.genSuccessResult(list); + } + + + public Member getMemberByToken(String token) { + System.out.println("getMemberByToken:"+token); + if (StringUtils.isEmpty(token)){ + throw new AppException(ResultCode.LOGIN_INVALID.code(),"登录已过期"); + } + Member user = baseMapper.selectOne(new QueryWrapper().eq("token", token)); + if (user == null) { + throw new AppException(ResultCode.LOGIN_INVALID.code(),"登录已过期"); + } + return user; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberStatisticsInfoServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberStatisticsInfoServiceImpl.java new file mode 100644 index 0000000..5401601 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/member/service/impl/MemberStatisticsInfoServiceImpl.java @@ -0,0 +1,20 @@ +package com.aopcloud.beam.app.api.member.service.impl; + +import com.aopcloud.beam.app.api.member.entity.MemberStatisticsInfo; +import com.aopcloud.beam.app.api.member.mapper.MemberStatisticsInfoMapper; +import com.aopcloud.beam.app.api.member.service.IMemberStatisticsInfoService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 会员统计信息 服务实现类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@Service +public class MemberStatisticsInfoServiceImpl extends ServiceImpl implements IMemberStatisticsInfoService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/notify/NotifyController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/notify/NotifyController.java new file mode 100644 index 0000000..8be9d6a --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/notify/NotifyController.java @@ -0,0 +1,69 @@ +package com.aopcloud.beam.app.api.notify; + + +import com.alibaba.fastjson.JSON; +import com.aopcloud.beam.app.api.order.entity.Order; +import com.aopcloud.beam.app.api.order.entity.OrderPayRecords; +import com.aopcloud.beam.app.api.order.service.impl.OrderPayRecordsServiceImpl; +import com.aopcloud.beam.app.api.order.service.impl.OrderServiceImpl; +import com.aopcloud.beam.app.delay.DelayQueueManager; +import com.aopcloud.beam.app.delay.DelayTask; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.apache.commons.lang.StringUtils; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.HashMap; +import java.util.Map; + +@RestController +@RequestMapping("/notify") +public class NotifyController { + + @Resource + public OrderPayRecordsServiceImpl payRecordsService; + + @Resource + public OrderServiceImpl orderService; + + + @PostMapping("/pay/yx") + public String notifyByPay(@RequestParam Map params) { + System.out.println("支付回调:" + JSON.toJSONString(params)); + + String prepayid = params.get("id").toString(); + + if (StringUtils.isEmpty(prepayid)) { + return "success"; + } + OrderPayRecords orderPayRecords = payRecordsService.getOne(new QueryWrapper() + .eq("prepayid", prepayid)); + if (orderPayRecords != null) { + LocalDateTime localDateTime = LocalDateTime.now(); + orderPayRecords.setPaymentTime(localDateTime); + orderPayRecords.setStatus(1); + Order order = orderService.getById(orderPayRecords.getOrderId()); + System.out.println("支付回调 order:" + JSON.toJSONString(order)); + + if (order != null) { + order.setStatus(1); + order.setPaymentTime(localDateTime); + } + orderService.updateById(order); + Long second = order.getLeaseEndTime().toEpochSecond(ZoneOffset.of("+8")); + //任务等待时间 15s + long expire = second - System.currentTimeMillis() / 1000; + DelayTask task = new DelayTask(Math.toIntExact(order.getId()), order, expire); + DelayQueueManager.getQueueManager().put(task); + } + return "success"; + } + + @PostMapping("/block/produce") + public String notifyByBlock(@RequestParam Map params) { + System.out.println("支付回调:" + JSON.toJSONString(params)); + return "success"; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/controller/OrderController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/controller/OrderController.java new file mode 100644 index 0000000..507a448 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/controller/OrderController.java @@ -0,0 +1,64 @@ +package com.aopcloud.beam.app.api.order.controller; + + +import com.aopcloud.beam.app.api.order.entity.OrderCreateEntity; +import com.aopcloud.beam.app.api.order.service.impl.OrderServiceImpl; +import com.aopcloud.beam.app.annotion.LoginRequired; +import com.aopcloud.beam.app.core.Result; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.Map; + +/** + *

+ * 订单表 前端控制器 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@RestController +@RequestMapping("/order") +public class OrderController { + + + @Resource + public OrderServiceImpl orderService; + + + @GetMapping("/basicInfo") + public Result getBasicInfo(){ + return orderService.getBasicInfo(); + } + + @LoginRequired + @PostMapping("/create") + public Result create(@RequestHeader String token,@RequestBody OrderCreateEntity object){ + return orderService.create(token,object); + } + + @LoginRequired + @PostMapping("/payInfo") + public Result pay(@RequestHeader String token, @RequestBody Map params){ + return orderService.pay(token,params.get("orderSn"),params.get("payChannel")); + } + + + @LoginRequired + @GetMapping("/list") + public Result list(@RequestHeader String token){ + return orderService.list(token); + } + + @LoginRequired + @GetMapping("/payState") + public Result getPayState(@RequestParam String orderSn){ + return orderService.getPayState(orderSn); + } + @LoginRequired + @GetMapping("/detail") + public Result getOrderDetail(@RequestParam String orderSn){ + return orderService.getOrderDetail(orderSn); + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/controller/OrderOperateHistoryController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/controller/OrderOperateHistoryController.java new file mode 100644 index 0000000..d760f3b --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/controller/OrderOperateHistoryController.java @@ -0,0 +1,19 @@ +package com.aopcloud.beam.app.api.order.controller; + + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 订单操作历史记录 前端控制器 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@RestController +@RequestMapping("/order/operate/history") +public class OrderOperateHistoryController { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/controller/OrderPayRecordsController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/controller/OrderPayRecordsController.java new file mode 100644 index 0000000..4a50799 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/controller/OrderPayRecordsController.java @@ -0,0 +1,20 @@ +package com.aopcloud.beam.app.api.order.controller; + + +import org.springframework.web.bind.annotation.RequestMapping; + +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 订单支付记录 前端控制器 + *

+ * + * @author Enoch + * @since 2021-03-06 + */ +@RestController +@RequestMapping("/order/order-pay-records") +public class OrderPayRecordsController { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/BlockBean.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/BlockBean.java new file mode 100644 index 0000000..4c32151 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/BlockBean.java @@ -0,0 +1,78 @@ +package com.aopcloud.beam.app.api.order.entity; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class BlockBean { + + /** + * puid : 145 + * worker_full_name : h555.cpu + * height : 24492 + * hash : 5f9ac746b83bb33c6ff2ba79715057a9b8b6d5df0763d33a51eee2ded306d8ff + * rewards : 0 + * created_at : 1591828601 + */ + + @JsonProperty("puid") + private Integer puid; + @JsonProperty("worker_full_name") + private String workerFullName; + @JsonProperty("height") + private Integer height; + @JsonProperty("hash") + private String hash; + @JsonProperty("rewards") + private int rewards; + @JsonProperty("created_at") + private long createdAt; + + public Integer getPuid() { + return puid; + } + + public void setPuid(Integer puid) { + this.puid = puid; + } + + public String getWorkerFullName() { + return workerFullName; + } + + public void setWorkerFullName(String workerFullName) { + this.workerFullName = workerFullName; + } + + public Integer getHeight() { + return height; + } + + public void setHeight(Integer height) { + this.height = height; + } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + + public Integer getRewards() { + return rewards; + } + + public void setRewards(Integer rewards) { + this.rewards = rewards; + } + + public long getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(long createdAt) { + this.createdAt = createdAt; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/Order.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/Order.java new file mode 100644 index 0000000..dfa8a30 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/Order.java @@ -0,0 +1,369 @@ +package com.aopcloud.beam.app.api.order.entity; + +import com.aopcloud.beam.app.util.AliyunOSSUtil; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.apache.ibatis.type.Alias; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + *

+ * 订单表 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@TableName("sly_order") +public class Order implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 订单id + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + private Integer memberId; + + + /** + * 订单编号 + */ + private String orderSn; + + /** + * 用户帐号 + */ + private String memberSn; + + /** + * 订单总金额 + */ + private BigDecimal totalAmount; + + /** + * 应付金额(实际支付金额) + */ + private BigDecimal payAmount; + + /** + * 管理员后台调整订单使用的折扣金额 + */ + @JsonIgnore + private BigDecimal discountAmount; + + /** + * 支付方式:0->未支付;1->支付宝;2->微信 + */ + private Integer payType; + + /** + * 订单来源:0->PC订单;1->app订单; 2> web 订单 + */ + private Integer sourceType; + + /** + * 订单状态:0->待付款;1->待进行;2->进行中;3->已完成;4->已关闭;5->无效订单 + */ + private Integer status; + + /** + * 订单类型:0->正常订单; + */ + private Integer orderType; + + /** + * 货币ID + */ + private Integer coinId; + + /** + * 钱包地址 + */ + private Long coinAddressId; + + /** + * 钱包地址 + */ + private String coinAddress; + + /** + * 订单图片 + */ + @JsonIgnore + private String ossImg; + + /** + * 购买时长 + */ + private long duration; + + /** + * 规格包 + */ + private Integer sukId; + + /** + * 租赁状态(0 待进行 1 进行中 2 已完成 ) + */ + private String leaseStatus; + + /** + * 租用开始时间 + */ + private LocalDateTime leaseStartTime; + + /** + * 租用结束时间 + */ + private LocalDateTime leaseEndTime; + + /** + * 支付时间 + */ + private LocalDateTime paymentTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + + @TableField(exist = false) + public String icon ; + + + public String getIcon() { + return AliyunOSSUtil.getInstance().getFileUrl(ossImg); + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Integer getMemberId() { + return memberId; + } + + public void setMemberId(Integer memberId) { + this.memberId = memberId; + } + + public String getOrderSn() { + return orderSn; + } + + public void setOrderSn(String orderSn) { + this.orderSn = orderSn; + } + + + public String getMemberSn() { + return memberSn; + } + + public void setMemberSn(String memberSn) { + this.memberSn = memberSn; + } + + public BigDecimal getTotalAmount() { + return totalAmount; + } + + public void setTotalAmount(BigDecimal totalAmount) { + this.totalAmount = totalAmount; + } + + public BigDecimal getPayAmount() { + return payAmount; + } + + public void setPayAmount(BigDecimal payAmount) { + this.payAmount = payAmount; + } + + public BigDecimal getDiscountAmount() { + return discountAmount; + } + + public void setDiscountAmount(BigDecimal discountAmount) { + this.discountAmount = discountAmount; + } + + public Integer getPayType() { + return payType; + } + + public void setPayType(Integer payType) { + this.payType = payType; + } + + public Integer getSourceType() { + return sourceType; + } + + public void setSourceType(Integer sourceType) { + this.sourceType = sourceType; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public Integer getOrderType() { + return orderType; + } + + public void setOrderType(Integer orderType) { + this.orderType = orderType; + } + + public Integer getCoinId() { + return coinId; + } + + public void setCoinId(Integer coinId) { + this.coinId = coinId; + } + + public Long getCoinAddressId() { + return coinAddressId; + } + + public void setCoinAddressId(Long coinAddressId) { + this.coinAddressId = coinAddressId; + } + + public String getCoinAddress() { + return coinAddress; + } + + public void setCoinAddress(String coinAddress) { + this.coinAddress = coinAddress; + } + + public String getOssImg() { + return ossImg; + } + + public void setOssImg(String ossImg) { + this.ossImg = ossImg; + } + + public long getDuration() { + return duration; + } + + public void setDuration(long duration) { + this.duration = duration; + } + + public Integer getSukId() { + return sukId; + } + + public void setSukId(Integer suk) { + this.sukId = suk; + } + + public String getLeaseStatus() { + return leaseStatus; + } + + public void setLeaseStatus(String leaseStatus) { + this.leaseStatus = leaseStatus; + } + + public LocalDateTime getLeaseStartTime() { + return leaseStartTime; + } + + public void setLeaseStartTime(LocalDateTime leaseStartTime) { + this.leaseStartTime = leaseStartTime; + } + + public LocalDateTime getLeaseEndTime() { + return leaseEndTime; + } + + public void setLeaseEndTime(LocalDateTime leaseEndTime) { + this.leaseEndTime = leaseEndTime; + } + + public LocalDateTime getPaymentTime() { + return paymentTime; + } + + public void setPaymentTime(LocalDateTime paymentTime) { + this.paymentTime = paymentTime; + } + + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + + @Override + public String toString() { + return "Order{" + + "id=" + id + + ", memberId=" + memberId + + ", orderSn=" + orderSn + + ", memberSn=" + memberSn + + ", totalAmount=" + totalAmount + + ", payAmount=" + payAmount + + ", discountAmount=" + discountAmount + + ", payType=" + payType + + ", sourceType=" + sourceType + + ", status=" + status + + ", orderType=" + orderType + + ", coinId=" + coinId + + ", coinAddress=" + coinAddressId + + ", ossImg=" + ossImg + + ", duration=" + duration + + ", sukId=" + sukId + + ", leaseStatus=" + leaseStatus + + ", leaseStartTime=" + leaseStartTime + + ", leaseEndTime=" + leaseEndTime + + ", paymentTime=" + paymentTime + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + "}"; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/OrderCreateEntity.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/OrderCreateEntity.java new file mode 100644 index 0000000..42ee7a2 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/OrderCreateEntity.java @@ -0,0 +1,10 @@ +package com.aopcloud.beam.app.api.order.entity; + +public class OrderCreateEntity { + public int coinId; + public int skuId; + public long startTime; + public long endTime; + public String coinAddress; + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/OrderDetailBean.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/OrderDetailBean.java new file mode 100644 index 0000000..5a3605c --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/OrderDetailBean.java @@ -0,0 +1,66 @@ +package com.aopcloud.beam.app.api.order.entity; + + +import com.aopcloud.beam.app.api.coin.entity.CoinPackage; +import org.spongycastle.util.Pack; + +import java.util.List; + +public class OrderDetailBean extends Order { + + private List hash; + private List blockList; + private double totalProfit; + private String enName; + private String cnName; + private CoinPackage coinPackage; + + public CoinPackage getCoinPackage() { + return coinPackage; + } + + public void setCoinPackage(CoinPackage coinPackage) { + this.coinPackage = coinPackage; + } + + public List getHash() { + return hash; + } + + public void setHash(List hash) { + this.hash = hash; + } + + public List getBlockList() { + return blockList; + } + + public void setBlockList(List blockList) { + this.blockList = blockList; + } + + public double getTotalProfit() { + return totalProfit; + } + + public void setTotalProfit(double totalProfit) { + this.totalProfit = totalProfit; + } + + + public String getEnName() { + return enName; + } + + public void setEnName(String enName) { + this.enName = enName; + } + + public String getCnName() { + return cnName; + } + + public void setCnName(String cnName) { + this.cnName = cnName; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/OrderOperateHistory.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/OrderOperateHistory.java new file mode 100644 index 0000000..1914dde --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/OrderOperateHistory.java @@ -0,0 +1,118 @@ +package com.aopcloud.beam.app.api.order.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 订单操作历史记录 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@TableName("sly_order_operate_history") +public class OrderOperateHistory implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 订单id + */ + private Long orderId; + + /** + * 操作人:用户;系统;后台管理员 + */ + private String operateMan; + + /** + * 订单状态:0->待付款;1->待进行;2->进行中;3->已完成;4->已关闭;5->无效订单 + */ + private Integer orderStatus; + + /** + * 备注 + */ + private String note; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 操作时间 + */ + private LocalDateTime updateTime; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + public Long getOrderId() { + return orderId; + } + + public void setOrderId(Long orderId) { + this.orderId = orderId; + } + public String getOperateMan() { + return operateMan; + } + + public void setOperateMan(String operateMan) { + this.operateMan = operateMan; + } + public Integer getOrderStatus() { + return orderStatus; + } + + public void setOrderStatus(Integer orderStatus) { + this.orderStatus = orderStatus; + } + public String getNote() { + return note; + } + + public void setNote(String note) { + this.note = note; + } + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + + @Override + public String toString() { + return "OrderOperateHistory{" + + "id=" + id + + ", orderId=" + orderId + + ", operateMan=" + operateMan + + ", orderStatus=" + orderStatus + + ", note=" + note + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + "}"; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/OrderPayRecords.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/OrderPayRecords.java new file mode 100644 index 0000000..2e4d433 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/OrderPayRecords.java @@ -0,0 +1,220 @@ +package com.aopcloud.beam.app.api.order.entity; + +import java.math.BigDecimal; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.time.LocalDateTime; +import java.io.Serializable; + +/** + *

+ * 订单支付记录 + *

+ * + * @author Enoch + * @since 2021-03-06 + */ +@TableName("sly_order_pay_records") +public class OrderPayRecords implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 预支付订单号 + */ + private String prepayid; + + /** + * 订单id + */ + private Long orderId; + + /** + * 订单号 + */ + private String orderSn; + + private Integer status; + + /** + * 支付方式:0->未支付;1->支付宝;2->微信 + */ + private Integer paymentChannel; + + /** + * 支付标题 + */ + private String paymentSubject; + + /** + * 应付金额(实际支付金额) + */ + private BigDecimal paymentAmount; + + /** + * 扩展字段 + */ + private String extendsParam; + + /** + * 交易开始时间 + */ + private LocalDateTime prepayStartTime; + + /** + * 交易结束时间 + */ + private LocalDateTime prepayExpire; + + /** + * 交易备注 + */ + private String remarks; + + /** + * 支付时间 + */ + private LocalDateTime paymentTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 操作时间 + */ + private LocalDateTime updateTime; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + public String getPrepayid() { + return prepayid; + } + + public void setPrepayid(String prepayid) { + this.prepayid = prepayid; + } + public Long getOrderId() { + return orderId; + } + + public void setOrderId(Long orderId) { + this.orderId = orderId; + } + public String getOrderSn() { + return orderSn; + } + + public void setOrderSn(String orderSn) { + this.orderSn = orderSn; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public Integer getPaymentChannel() { + return paymentChannel; + } + + public void setPaymentChannel(Integer paymentChannel) { + this.paymentChannel = paymentChannel; + } + public String getPaymentSubject() { + return paymentSubject; + } + + public void setPaymentSubject(String paymentSubject) { + this.paymentSubject = paymentSubject; + } + public BigDecimal getPaymentAmount() { + return paymentAmount; + } + + public void setPaymentAmount(BigDecimal paymentAmount) { + this.paymentAmount = paymentAmount; + } + public String getExtendsParam() { + return extendsParam; + } + + public void setExtendsParam(String extendsParam) { + this.extendsParam = extendsParam; + } + public LocalDateTime getPrepayStartTime() { + return prepayStartTime; + } + + public void setPrepayStartTime(LocalDateTime prepayStartTime) { + this.prepayStartTime = prepayStartTime; + } + public LocalDateTime getPrepayExpire() { + return prepayExpire; + } + + public void setPrepayExpire(LocalDateTime prepayExpire) { + this.prepayExpire = prepayExpire; + } + public String getRemarks() { + return remarks; + } + + public void setRemarks(String remarks) { + this.remarks = remarks; + } + public LocalDateTime getPaymentTime() { + return paymentTime; + } + + public void setPaymentTime(LocalDateTime paymentTime) { + this.paymentTime = paymentTime; + } + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + + @Override + public String toString() { + return "OrderPayRecords{" + + "id=" + id + + ", prepayid=" + prepayid + + ", orderId=" + orderId + + ", orderSn=" + orderSn + + ", paymentChannel=" + paymentChannel + + ", paymentSubject=" + paymentSubject + + ", paymentAmount=" + paymentAmount + + ", extendsParam=" + extendsParam + + ", prepayStartTime=" + prepayStartTime + + ", prepayExpire=" + prepayExpire + + ", remarks=" + remarks + + ", paymentTime=" + paymentTime + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + "}"; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/PayOrderInfo.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/PayOrderInfo.java new file mode 100644 index 0000000..7a96de6 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/entity/PayOrderInfo.java @@ -0,0 +1,6 @@ +package com.aopcloud.beam.app.api.order.entity; + + +public class PayOrderInfo { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/mapper/OrderMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/mapper/OrderMapper.java new file mode 100644 index 0000000..df84efd --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/mapper/OrderMapper.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.order.mapper; + +import com.aopcloud.beam.app.api.order.entity.Order; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 订单表 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface OrderMapper extends BaseMapper { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/mapper/OrderOperateHistoryMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/mapper/OrderOperateHistoryMapper.java new file mode 100644 index 0000000..9ee8436 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/mapper/OrderOperateHistoryMapper.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.order.mapper; + +import com.aopcloud.beam.app.api.order.entity.OrderOperateHistory; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 订单操作历史记录 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface OrderOperateHistoryMapper extends BaseMapper { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/mapper/OrderPayRecordsMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/mapper/OrderPayRecordsMapper.java new file mode 100644 index 0000000..cb5f7ca --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/mapper/OrderPayRecordsMapper.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.order.mapper; + +import com.aopcloud.beam.app.api.order.entity.OrderPayRecords; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 订单支付记录 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-03-06 + */ +public interface OrderPayRecordsMapper extends BaseMapper { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/IOrderOperateHistoryService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/IOrderOperateHistoryService.java new file mode 100644 index 0000000..5365b44 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/IOrderOperateHistoryService.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.order.service; + +import com.aopcloud.beam.app.api.order.entity.OrderOperateHistory; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 订单操作历史记录 服务类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface IOrderOperateHistoryService extends IService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/IOrderPayRecordsService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/IOrderPayRecordsService.java new file mode 100644 index 0000000..dbfda1b --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/IOrderPayRecordsService.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.order.service; + +import com.aopcloud.beam.app.api.order.entity.OrderPayRecords; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 订单支付记录 服务类 + *

+ * + * @author Enoch + * @since 2021-03-06 + */ +public interface IOrderPayRecordsService extends IService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/IOrderService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/IOrderService.java new file mode 100644 index 0000000..c7eddc2 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/IOrderService.java @@ -0,0 +1,16 @@ +package com.aopcloud.beam.app.api.order.service; + +import com.aopcloud.beam.app.api.order.entity.Order; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 订单表 服务类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +public interface IOrderService extends IService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/impl/OrderOperateHistoryServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/impl/OrderOperateHistoryServiceImpl.java new file mode 100644 index 0000000..4267b56 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/impl/OrderOperateHistoryServiceImpl.java @@ -0,0 +1,20 @@ +package com.aopcloud.beam.app.api.order.service.impl; + +import com.aopcloud.beam.app.api.order.entity.OrderOperateHistory; +import com.aopcloud.beam.app.api.order.mapper.OrderOperateHistoryMapper; +import com.aopcloud.beam.app.api.order.service.IOrderOperateHistoryService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 订单操作历史记录 服务实现类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@Service +public class OrderOperateHistoryServiceImpl extends ServiceImpl implements IOrderOperateHistoryService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/impl/OrderPayRecordsServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/impl/OrderPayRecordsServiceImpl.java new file mode 100644 index 0000000..77b16e3 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/impl/OrderPayRecordsServiceImpl.java @@ -0,0 +1,20 @@ +package com.aopcloud.beam.app.api.order.service.impl; + +import com.aopcloud.beam.app.api.order.entity.OrderPayRecords; +import com.aopcloud.beam.app.api.order.mapper.OrderPayRecordsMapper; +import com.aopcloud.beam.app.api.order.service.IOrderPayRecordsService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 订单支付记录 服务实现类 + *

+ * + * @author Enoch + * @since 2021-03-06 + */ +@Service +public class OrderPayRecordsServiceImpl extends ServiceImpl implements IOrderPayRecordsService { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/impl/OrderServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/impl/OrderServiceImpl.java new file mode 100644 index 0000000..7444647 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/order/service/impl/OrderServiceImpl.java @@ -0,0 +1,370 @@ +package com.aopcloud.beam.app.api.order.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.aopcloud.beam.app.api.app.entity.HomeNotice; +import com.aopcloud.beam.app.api.coin.entity.Coin; +import com.aopcloud.beam.app.api.coin.entity.CoinPackage; +import com.aopcloud.beam.app.api.coin.service.impl.CoinPackageServiceImpl; +import com.aopcloud.beam.app.api.coin.service.impl.CoinServiceImpl; +import com.aopcloud.beam.app.api.member.entity.Member; +import com.aopcloud.beam.app.api.member.entity.MemberCoinAddress; +import com.aopcloud.beam.app.api.member.service.impl.MemberCoinAddressServiceImpl; +import com.aopcloud.beam.app.api.member.service.impl.MemberCoinRecordServiceImpl; +import com.aopcloud.beam.app.api.member.service.impl.MemberServiceImpl; +import com.aopcloud.beam.app.api.order.entity.*; +import com.aopcloud.beam.app.api.order.mapper.OrderMapper; +import com.aopcloud.beam.app.api.order.service.IOrderService; +import com.aopcloud.beam.app.common.PayConfig; +import com.aopcloud.beam.app.dotwallet.DotWalletManager; +import com.aopcloud.beam.app.util.OrderIdUtil; +import com.aopcloud.beam.app.core.AppException;; +import com.aopcloud.beam.app.core.Result; +import com.aopcloud.beam.app.core.ResultGenerator; +import com.aopcloud.beam.app.http.OkHttpUtils; +import com.aopcloud.beam.app.util.MD5Util; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import okhttp3.*; +import org.apache.commons.lang.math.RandomUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.math.BigDecimal; +import java.net.URLEncoder; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.*; + +/** + *

+ * 订单表 服务实现类 + *

+ * + * @author Enoch + * @since 2021-02-24 + */ +@Service +public class OrderServiceImpl extends ServiceImpl implements IOrderService { + + + @Resource + public MemberServiceImpl memberService; + @Resource + public CoinServiceImpl coinService; + @Resource + public MemberCoinAddressServiceImpl coinAddressService; + @Resource + public CoinPackageServiceImpl coinPackageService; + @Resource + public OrderPayRecordsServiceImpl payRecordsService; + @Resource + public MemberCoinRecordServiceImpl coinRecordService; + + + public Result create(String token, OrderCreateEntity createEntity) { +// System.out.println("create order:"+JSON.toJSONString(createEntity)); + Member member = memberService.getMemberByToken(token); + Order order = new Order(); + order.setOrderSn(OrderIdUtil.createOrderSn(member.getMemberSn())); + order.setMemberId(member.getId()); + order.setMemberSn(member.getMemberSn()); + order.setSourceType(2); + order.setStatus(0); + order.setOrderType(0); + + + Coin coin = coinService.getById(createEntity.coinId); + if (coin == null) { + throw new AppException("货币不存在"); + } + + CoinPackage coinPackage = coinPackageService.getById(createEntity.skuId); + if (coinPackage == null) { + throw new AppException("算力包不存在"); + } + + QueryWrapper condition = new QueryWrapper(); + condition.orderByDesc("lease_end_time") + .last("limit 1"); + Order lastOrder= baseMapper.selectOne(condition); + + if (lastOrder != null&&lastOrder.getLeaseEndTime().toEpochSecond(ZoneOffset.of("+8"))>createEntity.startTime) { + throw new AppException("开始时间应大于:"+lastOrder.getLeaseEndTime()); + } + + MemberCoinAddress memberCoinAddress = coinAddressService.getOne( + new QueryWrapper() + .eq("address", createEntity.coinAddress) + .eq("coin_id", createEntity.coinId) + .eq("member_id", member.getId()) + ); + if (memberCoinAddress == null) { + memberCoinAddress = new MemberCoinAddress(); + memberCoinAddress.setAddress(createEntity.coinAddress); + memberCoinAddress.setCoinId(createEntity.coinId); + memberCoinAddress.setMemberId(member.getId()); + memberCoinAddress.setDescription(""); + coinAddressService.save(memberCoinAddress); + } + + order.setCoinId(createEntity.coinId); + order.setCoinAddress(memberCoinAddress.getAddress()); + order.setCoinAddressId(memberCoinAddress.getId()); + order.setOssImg(coin.getImgOssFile()); + + LocalDateTime leaseStartTime = LocalDateTime.ofEpochSecond(createEntity.startTime, 0, ZoneOffset.ofHours(8)); + LocalDateTime leaseEndTime = LocalDateTime.ofEpochSecond(createEntity.endTime, 0, ZoneOffset.ofHours(8)); + + order.setSukId(createEntity.skuId); + order.setLeaseStartTime(leaseStartTime); + order.setLeaseEndTime(leaseEndTime); + order.setDuration(createEntity.endTime - createEntity.startTime); + + long s = createEntity.endTime - createEntity.startTime; + long price = s * coinPackage.getPrice().longValue(); + + order.setTotalAmount(BigDecimal.valueOf(price)); + order.setPayAmount(BigDecimal.valueOf(price)); + order.setPayAmount(BigDecimal.valueOf(0.01)); + order.setDiscountAmount(BigDecimal.valueOf(0)); + + save(order); + return ResultGenerator.genSuccessResult(order); + } + + + String payInfo; + + public Result pay(String token, String orderSn, String payChannel) { + Member member = memberService.getMemberByToken(token); + + Order order = getOne(new QueryWrapper().eq("order_sn", orderSn)); + if (order == null) { + throw new AppException("订单不存在"); + } + + if (order.getStatus() != 0) { + throw new AppException("订单已经支付"); + } + + + long timestamp = System.currentTimeMillis() / 1000; + String appId = PayConfig.PAY_APP_ID; + String payKey = PayConfig.PAY_KEY; + String subject = "算力租赁"; + String price = "" + order.getPayAmount(); + String notifyUrl = PayConfig.PAY_NOTIFY_URL; + String extendsParam = "算力租赁"; + Map map = new HashMap<>(); + map.put("appid", appId); + map.put("timestamp", "" + timestamp); + map.put("subject", subject); + map.put("orderid", orderSn); + map.put("price", price); + map.put("notifyurl", notifyUrl); + map.put("channel", "" + payChannel); + map.put("extends_param", extendsParam); + + String s = appId + timestamp + orderSn + payChannel + subject + price + notifyUrl + extendsParam + payKey; + System.out.println("计算签名值 s:" + s); + String sign = MD5Util.encrypt(s); + System.out.println("sign:" + MD5Util.encrypt(s)); + map.put("sign", sign); + map.put("user_id", member.getMemberSn()); + map.put("front_url", ""); + System.out.println("JSON:" + JSON.toJSONString(map)); + + String query = urlEncodeUTF8(map); + String url = PayConfig.PAY_ORDER_CREATE_URL + "?" + query; + System.out.println("url:" + url); + Response response = null; + try { + response = OkHttpUtils + .post() + .url(PayConfig.PAY_ORDER_CREATE_URL) + .params(map) + .build().execute(); + String p = response.body().string(); + System.out.println("-------:" + p); + JSONObject jsonObject = JSON.parseObject(p); + if (jsonObject.get("code").equals("error")) { + throw new AppException(jsonObject.get("msg").toString()); + } + JSONObject data = JSON.parseObject(jsonObject.get("data").toString()); + + + OrderPayRecords payRecords = new OrderPayRecords(); + payRecords.setPrepayid(data.get("id").toString()); + payRecords.setOrderId(order.getId()); + payRecords.setOrderSn(order.getOrderSn()); + payRecords.setPaymentChannel(Integer.valueOf(payChannel)); + payRecords.setPaymentSubject(subject); + payRecords.setPaymentAmount(order.getPayAmount()); + payRecords.setExtendsParam(extendsParam); + payRecordsService.save(payRecords); + System.out.println("payInfo:" + jsonObject.get("data")); + return ResultGenerator.genSuccessResult(jsonObject.get("data")); + } catch (IOException e) { + e.printStackTrace(); + throw new AppException("获取支付内容失败"); + } + } + + + public Result queryOrderPayStatus(String orderSn) { + + Order order = getOne(new QueryWrapper().eq("order_sn", orderSn)); + OrderPayRecords payRecords = payRecordsService.getOne(new QueryWrapper() + .eq("order_sn", orderSn).orderByDesc(true, "create_time").last("limit 1")); + if (order == null) { + throw new AppException("订单不存在"); + } + long timestamp = System.currentTimeMillis() / 1000; + String appId = PayConfig.PAY_APP_ID; + String payKey = PayConfig.PAY_KEY; + String id = payRecords.getPrepayid(); + Map map = new HashMap<>(); + map.put("appid", appId); + map.put("timestamp", "" + timestamp); + map.put("id", id); + String s = appId + timestamp + id + payKey; + System.out.println("计算签名值 s:" + s); + String sign = MD5Util.encrypt(s); + map.put("sign", sign); + + Response response = null; + try { + response = OkHttpUtils + .post() + .url(PayConfig.PAY_ORDER_QUERY_URL) + .params(map) + .build().execute(); + payInfo = response.body().string(); + + System.out.println("-------:" + payInfo); + JSONObject jsonObject = JSON.parseObject(payInfo); + if (jsonObject.get("code").equals("error")) { + throw new AppException(jsonObject.get("msg").toString()); + } + JSONObject data = JSON.parseObject(jsonObject.get("data").toString()); + + System.out.println("payInfo:" + payInfo); + return ResultGenerator.genSuccessResult(data); + } catch (IOException e) { + e.printStackTrace(); + throw new AppException("获取支付内容失败"); + } + } + + + static String urlEncodeUTF8(String s) { + try { + return URLEncoder.encode(s, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new UnsupportedOperationException(e); + } + } + + static String urlEncodeUTF8(Map map) { + StringBuilder sb = new StringBuilder(); + for (Map.Entry entry : map.entrySet()) { + if (sb.length() > 0) { + sb.append("&"); + } + sb.append(String.format("%s=%s", + urlEncodeUTF8(entry.getKey().toString()), + urlEncodeUTF8(entry.getValue().toString()) + )); + } + return sb.toString(); + } + + public Result list(String token) { + return ResultGenerator.genSuccessResult(list()); + } + + public Result getPayState(String orderSn) { + Order order = getOne(new QueryWrapper().eq("order_sn", orderSn)); + if (order == null) { + throw new AppException("订单不存在"); + } + return queryOrderPayStatus(orderSn); + } + + public Result getOrderDetail(String orderSn) { + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("order_sn", orderSn); + Order order = getOne(new QueryWrapper() + .eq("order_sn", orderSn) + ); + if (order == null) { + throw new AppException("订单不存在"); + } + List hash = new ArrayList<>(); + for (int i = 0; i < 3; i++) { + Map map = new HashMap(); + map.put("time", "12:" + (i + 1) + "0"); + map.put("hash", RandomUtils.nextInt(3) * 100); + hash.add(map); + } + Coin coin = coinService.getById(order.getCoinId()); + CoinPackage coinPackage = coinPackageService.getById(order.getSukId()); + + long startTime = order.getLeaseStartTime().toEpochSecond(ZoneOffset.of("+8")); + long endTime = order.getLeaseStartTime().toEpochSecond(ZoneOffset.of("+8")); + List blockList = DotWalletManager.getInstance().getBlockList(startTime, endTime); + + if (blockList.isEmpty() || blockList.size() == 0) { + BlockBean blockBean = new BlockBean(); + blockBean.setPuid(0); + blockBean.setWorkerFullName("123"); + blockBean.setHeight(RandomUtils.nextInt()); + blockBean.setHash(""+RandomUtils.nextInt()); + blockBean.setRewards(RandomUtils.nextInt()); + blockBean.setCreatedAt(System.currentTimeMillis() / 1000); + blockList.add(blockBean); + } + System.out.println("coin:" + JSON.toJSONString(coin)); + OrderDetailBean orderDetailBean = new OrderDetailBean(); + BeanUtils.copyProperties(order, orderDetailBean); + BeanUtils.copyProperties(coin, orderDetailBean); + orderDetailBean.setHash(hash); + orderDetailBean.setBlockList(blockList); + orderDetailBean.setCoinPackage(coinPackage); + + + int rewards = 0; + for (int i = 0; i < blockList.size(); i++) { + rewards = rewards + blockList.get(i).getRewards(); + } + orderDetailBean.setTotalProfit(rewards); + + return ResultGenerator.genSuccessResult(orderDetailBean); + } + + public Result getBasicInfo() { + QueryWrapper condition = new QueryWrapper(); + condition.orderByDesc("lease_end_time") + .last("limit 1"); + Order order = baseMapper.selectOne(condition); + + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + Map map = new HashMap(); + if (order!=null){ + map.put("startTime",order.getLeaseEndTime()); + }else { + map.put("startTime",dateFormat.format(new Date())); + } + map.put("coinList",coinService.list()); + map.put("skuList",coinPackageService.list()); + return ResultGenerator.genSuccessResult(map); + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/controller/BeamUserController.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/controller/BeamUserController.java new file mode 100644 index 0000000..703406d --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/controller/BeamUserController.java @@ -0,0 +1,74 @@ +package com.aopcloud.beam.app.api.user.controller; + + +import com.alibaba.fastjson.JSON; +import com.aopcloud.beam.app.api.user.entity.UpdateUserEntity; +import com.aopcloud.beam.app.api.user.entity.UserActionBean; +import com.aopcloud.beam.app.api.user.service.impl.BeamUserServiceImpl; +import com.aopcloud.beam.app.core.Result; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; + +/** + *

+ * 用户表 前端控制器 + *

+ * + * @author Enoch + * @since 2021-01-28 + */ +@RestController +@RequestMapping("/v1/user") +public class BeamUserController { + + @Autowired + BeamUserServiceImpl beamUserService; + + @PostMapping("/register") + public Result register(@RequestBody @Valid UserActionBean register) { + return beamUserService.register(register); + } + + @PostMapping("/login") + public Result login(@RequestBody UserActionBean register) { + return beamUserService.login(register); + } + + @PostMapping("/logout") + public Result logout(@RequestHeader @NotBlank String token) { + return beamUserService.logout(token); + } + + @PostMapping("/edit") + public Result edit(@RequestHeader @NotBlank String token, @RequestBody @Valid UpdateUserEntity user) { + return beamUserService.edit(token, user); + } + + @GetMapping("/info") + public Result getInfo(@RequestHeader @NotBlank String token) { + return beamUserService.getInfo(token); + } + + @PostMapping("/forgePassword") + public Result getPassword(@RequestBody @Valid UserActionBean actionBean) { + return beamUserService.getPassword(actionBean); + } + + @PostMapping("/updatePassword") + public Result updatePassword(@RequestBody @Valid UserActionBean actionBean) { + System.out.println(JSON.toJSONString(actionBean)); + return beamUserService.updatePassword( actionBean); + } + + + @GetMapping("/history") + public Result history(@RequestHeader @NotBlank String token) { + return beamUserService.history(token); + } + + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/BeamUser.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/BeamUser.java new file mode 100644 index 0000000..f87028f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/BeamUser.java @@ -0,0 +1,257 @@ +package com.aopcloud.beam.app.api.user.entity; + +import java.time.LocalDateTime; +import java.io.Serializable; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 用户表 + *

+ * + * @author Enoch + * @since 2021-01-28 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class BeamUser implements Serializable { + + private static final long serialVersionUID = 1L; + /** + * 主键id + */ + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + /** + * 头像 + */ + private String avatar; + + /** + * 账号 + */ + private String account; + + /** + * 密码 + */ + private String password; + + /** + * md5密码盐 + */ + @JsonIgnore + private String salt; + + /** + * 名字 + */ + private String name; + + /** + * 生日 + */ + private LocalDateTime birthday; + + /** + * 性别(1:男 2:女) + */ + private String sex; + + /** + * 电子邮件 + */ + private String mail; + + /** + * 电话 + */ + private String phone; + + /** + * 状态(1:启用 2:冻结 3:删除) + */ + @JsonIgnore + private String status; + + /** + * 创建人 + */ + @JsonIgnore + private String createdBy; + + /** + * 创建时间 + */ + @JsonIgnore + private LocalDateTime createdTime; + + /** + * 更新人 + */ + @JsonIgnore + private String updateBy; + + /** + * 更新时间 + */ + @JsonIgnore + private LocalDateTime updateTime; + + /** + * Token + */ + private String token; + + /** + * 保留字段 + */ + @JsonIgnore + private Integer version; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public static long getSerialVersionUID() { + return serialVersionUID; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getSalt() { + return salt; + } + + public void setSalt(String salt) { + this.salt = salt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public LocalDateTime getBirthday() { + return birthday; + } + + public void setBirthday(LocalDateTime birthday) { + this.birthday = birthday; + } + + public String getSex() { + return sex; + } + + public void setSex(String sex) { + this.sex = sex; + } + + public String getMail() { + return mail; + } + + public void setMail(String mail) { + this.mail = mail; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + + public LocalDateTime getCreatedTime() { + return createdTime; + } + + public void setCreatedTime(LocalDateTime createdTime) { + this.createdTime = createdTime; + } + + public String getUpdateBy() { + return updateBy; + } + + public void setUpdateBy(String updateBy) { + this.updateBy = updateBy; + } + + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/HBean.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/HBean.java new file mode 100644 index 0000000..89bdfeb --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/HBean.java @@ -0,0 +1,102 @@ +package com.aopcloud.beam.app.api.user.entity; + +public class HBean { + + private String cnName; + private String enName; + private String coinIcon; + private int type; + private String createTime; + private String orderNo; + private String id; + private float sum; + private String tag; + + public HBean() { + } + + public HBean(String coinName, String coinN, String coinIcon, int type, String createTime, String orderNo, String id, float sum, String tag) { + + this.cnName = coinName; + this.enName = coinN; + this.coinIcon = coinIcon; + this.type = type; + this.createTime = createTime; + this.orderNo = orderNo; + this.id = id; + this.sum = sum; + this.tag = tag; + } + + public String getCnName() { + return cnName; + } + + public void setCnName(String cnName) { + this.cnName = cnName; + } + + public String getEnName() { + return enName; + } + + public void setEnName(String enName) { + this.enName = enName; + } + + public String getCoinIcon() { + return coinIcon; + } + + public void setCoinIcon(String coinIcon) { + this.coinIcon = coinIcon; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getOrderNo() { + return orderNo; + } + + public void setOrderNo(String orderNo) { + this.orderNo = orderNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public float getSum() { + return sum; + } + + public void setSum(float sum) { + this.sum = sum; + } + + public String getTag() { + return tag; + } + + public void setTag(String tag) { + this.tag = tag; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/UpdateUserEntity.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/UpdateUserEntity.java new file mode 100644 index 0000000..3358ca9 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/UpdateUserEntity.java @@ -0,0 +1,114 @@ +package com.aopcloud.beam.app.api.user.entity; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +import java.time.LocalDateTime; + +public class UpdateUserEntity { + + /** + * 头像 + */ + private String avatar; + + /** + * 账号 + */ + private String account; + + /** + * 密码 + */ + private String password; + + + /** + * 名字 + */ + private String name; + + /** + * 生日 + */ + private LocalDateTime birthday; + + /** + * 性别(1:男 2:女) + */ + private String sex; + + /** + * 电子邮件 + */ + private String mail; + + /** + * 电话 + */ + private String phone; + + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public LocalDateTime getBirthday() { + return birthday; + } + + public void setBirthday(LocalDateTime birthday) { + this.birthday = birthday; + } + + public String getSex() { + return sex; + } + + public void setSex(String sex) { + this.sex = sex; + } + + public String getMail() { + return mail; + } + + public void setMail(String mail) { + this.mail = mail; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/UserActionBean.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/UserActionBean.java new file mode 100644 index 0000000..ba46175 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/UserActionBean.java @@ -0,0 +1,39 @@ +package com.aopcloud.beam.app.api.user.entity; + + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; + +@Valid +public class UserActionBean { + + + @NotBlank(message = "手机号不能为空") + private String phone; + private String password; + private String code; + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/UserPasswordBean.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/UserPasswordBean.java new file mode 100644 index 0000000..e3dc37f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/entity/UserPasswordBean.java @@ -0,0 +1,25 @@ +package com.aopcloud.beam.app.api.user.entity; + +import javax.validation.Valid; +import javax.validation.constraints.Size; + +@Valid +public class UserPasswordBean { + + /** + * 密码 + */ + @Size(min = 6, max = 25) + private String password; + + + + + public void setPassword(String password) { + this.password = password; + } + + public String getPassword() { + return password; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/mapper/BeamUserMapper.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/mapper/BeamUserMapper.java new file mode 100644 index 0000000..b6f8074 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/mapper/BeamUserMapper.java @@ -0,0 +1,18 @@ +package com.aopcloud.beam.app.api.user.mapper; + +import com.aopcloud.beam.app.api.user.entity.BeamUser; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 用户表 Mapper 接口 + *

+ * + * @author Enoch + * @since 2021-01-28 + */ +@Mapper +public interface BeamUserMapper extends BaseMapper { + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/service/IBeamUserService.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/service/IBeamUserService.java new file mode 100644 index 0000000..2992cb0 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/service/IBeamUserService.java @@ -0,0 +1,19 @@ +package com.aopcloud.beam.app.api.user.service; + +import com.aopcloud.beam.app.api.user.entity.BeamUser; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.io.Serializable; + +/** + *

+ * 用户表 服务类 + *

+ * + * @author Enoch + * @since 2021-01-28 + */ +public interface IBeamUserService extends IService { + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/service/impl/BeamUserServiceImpl.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/service/impl/BeamUserServiceImpl.java new file mode 100644 index 0000000..2cb3731 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/api/user/service/impl/BeamUserServiceImpl.java @@ -0,0 +1,156 @@ +package com.aopcloud.beam.app.api.user.service.impl; + +import com.alibaba.fastjson.JSON; +import com.aopcloud.beam.app.api.user.entity.BeamUser; +import com.aopcloud.beam.app.api.user.entity.HBean; +import com.aopcloud.beam.app.api.user.entity.UpdateUserEntity; +import com.aopcloud.beam.app.api.user.entity.UserActionBean; +import com.aopcloud.beam.app.api.user.mapper.BeamUserMapper; +import com.aopcloud.beam.app.api.user.service.IBeamUserService; +import com.aopcloud.beam.app.common.Constants; +import com.aopcloud.beam.app.util.RSAUtils; +import com.aopcloud.beam.app.core.AppException;; +import com.aopcloud.beam.app.core.Result; +import com.aopcloud.beam.app.core.ResultGenerator; +import com.aopcloud.beam.app.util.IdUtil; +import com.aopcloud.beam.app.util.RegUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + *

+ * 用户表 服务实现类 + *

+ * + * @author Enoch + * @since 2021-01-28 + */ +@Service +public class BeamUserServiceImpl extends ServiceImpl implements IBeamUserService { + + + public Result register(UserActionBean userRegister) { + if (!RegUtil.checkMobile(userRegister.getPhone())) { + throw new AppException(-1, "手机号不正确!", "手机号不正确"); + } + List user = baseMapper.selectList(new QueryWrapper().ge("phone", userRegister.getPhone())); + if (!user.isEmpty() && user.size() > 0) { + throw new AppException(1001, "用户已存在!", "用户已存在"); + } + + BeamUser beamUser = new BeamUser(); + beamUser.setAccount("" + IdUtil.create()); + beamUser.setName("会员" + IdUtil.create() + ""); + beamUser.setAvatar(Constants.IMG_DEFAULT_USER_AVATAR); + beamUser.setPhone(userRegister.getPhone()); + beamUser.setSalt(userRegister.getPhone()); + beamUser.setPassword(userRegister.getPassword()); + beamUser.setCreatedTime(LocalDateTime.now()); + beamUser.setCreatedBy(userRegister.getPhone()); + beamUser.setUpdateTime(LocalDateTime.now()); + beamUser.setUpdateBy(userRegister.getPhone()); + int id = baseMapper.insert(beamUser); + return ResultGenerator.genSuccessResult(id); + } + + + public Result login(UserActionBean userRegister) { + + String token = null;//JwtUtil.createToken(user.getId() + "_" + user.getPhone()); + token = UUID.randomUUID().toString().replace("-", ""); + BeamUser user = baseMapper.selectOne(new QueryWrapper().ge("phone", userRegister.getPhone())); + if (user == null) { + throw new AppException(-1, "用户不存在!", "用户不存在"); + } + if (!userRegister.getPassword().equals("sunaliyun_" + userRegister.getPassword())) { + } +// throw new AppException(-1, "密码不正确!", "密码不正确"); +// } + String password = null; + + +// password = new String(RSAUtils.decryptByPrivateKey(userRegister.getPassword().getBytes(StandardCharsets.UTF_8),RSAUtils.PRIVATE_KEY.getBytes(StandardCharsets.UTF_8))); +// System.out.println("password:"+password); +// if (!password.equals("sunaliyun_"+userRegister.getPassword())) { +// throw new AppException(-1, "密码不正确!", "密码不正确"); +// } + user.setToken(token); + System.out.println("-------:" + JSON.toJSONString(user)); + baseMapper.update(user, new UpdateWrapper<>()); + return ResultGenerator.genSuccessResult(user); + } + + public Result logout(String token) { + BeamUser user = baseMapper.selectOne(new QueryWrapper().ge("token", token)); + if (user == null) { + throw new AppException(-1, "用户不存在!", "用户不存在"); + } + user.setToken(""); + baseMapper.update(user, new UpdateWrapper<>()); + return ResultGenerator.genSuccessResult("退出成功"); + } + + public Result edit(String token, UpdateUserEntity updateUser) { + BeamUser user = baseMapper.selectOne(new QueryWrapper().ge("token", token)); + if (user == null) { + throw new AppException(-1, "用户不存在!", "用户不存在"); + } + BeanUtils.copyProperties(updateUser, user); + baseMapper.update(user, new UpdateWrapper<>()); + return ResultGenerator.genSuccessResult(); + } + + public Result getInfo(String token) { + BeamUser user = baseMapper.selectOne(new QueryWrapper().ge("token", token)); + if (user == null) { + throw new AppException(-1, "用户不存在!", "用户不存在"); + } + return ResultGenerator.genSuccessResult(user); + } + + public Result getPassword(UserActionBean updateUser) { + BeamUser user = baseMapper.selectOne(new QueryWrapper().ge("phone", updateUser.getPhone())); + if (user == null) { + throw new AppException(-1, "用户不存在!", "用户不存在"); + } + user.setPassword(updateUser.getPassword()); + baseMapper.update(user, new UpdateWrapper<>()); + return ResultGenerator.genSuccessResult(user); + } + + public Result updatePassword(UserActionBean updateUser) { + BeamUser user = baseMapper.selectOne(new QueryWrapper().ge("phone", updateUser.getPhone())); + if (user == null) { + throw new AppException(-1, "用户不存在!", "用户不存在"); + } + user.setPassword(updateUser.getPassword()); + baseMapper.update(user, new UpdateWrapper<>()); + return ResultGenerator.genSuccessResult("修改成功"); + } + + public Result history(String token) { + BeamUser user = baseMapper.selectOne(new QueryWrapper().ge("token", token)); + if (user == null) { + throw new AppException(-1, "用户不存在!", "用户不存在"); + } + String url = "http://oss.mxzhe.cn/img/img_coin_1612004588012.png"; + List list = new ArrayList<>(); + //String coinName, String coinN, String coinIcon, String type, String createTime, String orderNo, String id, int sum, String tag) { + HBean hBean = new HBean("比特币", "BTC", url, 1, "2021-02-13 19:00", "8qwoiqwndonqwkdqkd", "123", 8980670.01f, "区块奖励"); + list.add(hBean); + hBean = new HBean("比特现金", "BCH", url, 2, "2021-02-14 19:00", "8qwoiqwndonqwkdqkd", "1212e1", 24520.01f, "区块奖励"); + list.add(hBean); + hBean = new HBean("莱特币", "LTC", url, 1, "2021-02-13 19:00", "8qwoiqwndonqwkdqkd", "asdasd123123asdasda", 892340.01f, "区块奖励"); + list.add(hBean); + return ResultGenerator.genSuccessResult(list); + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/common/AccessLog.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/common/AccessLog.java new file mode 100644 index 0000000..4922184 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/common/AccessLog.java @@ -0,0 +1,186 @@ +package com.aopcloud.beam.app.common; + +import java.util.Date; + +public class AccessLog { + + private Long id; + + /** + * 接口名 + */ + private String api; + + /** + * 接口方法 + */ + private String apiMethod; + + /** + * 接口入参 + */ + private String apiArgs; + + /** + * 请求耗时(毫秒单位) + */ + private Integer apiTimeConsuming; + + /** + * 接口返回code + */ + private Integer returnCode; + + /** + * 接口返回信息 + */ + private String returnMessage; + + /** + * 接口返回时间 + */ + private Date returnTime; + + /** + * HTTP STARTS CODE + */ + private String returnHttpCode; + + /** + * 访问时间 + */ + private Date reqTime; + + /** + * 请求客户端IP + */ + private String reqClientIp; + + /** + * 访问的操作系统 + */ + private String reqOs; + + /** + * 设备型号 + */ + private String reqDevice; + + /** + * 请求时的userAgent + */ + private String reqUa; + + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getApi() { + return api; + } + + public void setApi(String api) { + this.api = api; + } + + public String getApiMethod() { + return apiMethod; + } + + public void setApiMethod(String apiMethod) { + this.apiMethod = apiMethod; + } + + public String getApiArgs() { + return apiArgs; + } + + public void setApiArgs(String apiArgs) { + this.apiArgs = apiArgs; + } + + public Integer getApiTimeConsuming() { + return apiTimeConsuming; + } + + public void setApiTimeConsuming(Integer apiTimeConsuming) { + this.apiTimeConsuming = apiTimeConsuming; + } + + public Integer getReturnCode() { + return returnCode; + } + + public void setReturnCode(Integer returnCode) { + this.returnCode = returnCode; + } + + public String getReturnMessage() { + return returnMessage; + } + + public void setReturnMessage(String returnMessage) { + this.returnMessage = returnMessage; + } + + public Date getReturnTime() { + return returnTime; + } + + public void setReturnTime(Date returnTime) { + this.returnTime = returnTime; + } + + public String getReturnHttpCode() { + return returnHttpCode; + } + + public void setReturnHttpCode(String returnHttpCode) { + this.returnHttpCode = returnHttpCode; + } + + public Date getReqTime() { + return reqTime; + } + + public void setReqTime(Date reqTime) { + this.reqTime = reqTime; + } + + public String getReqClientIp() { + return reqClientIp; + } + + public void setReqClientIp(String reqClientIp) { + this.reqClientIp = reqClientIp; + } + + public String getReqOs() { + return reqOs; + } + + public void setReqOs(String reqOs) { + this.reqOs = reqOs; + } + + public String getReqDevice() { + return reqDevice; + } + + public void setReqDevice(String reqDevice) { + this.reqDevice = reqDevice; + } + + public String getReqUa() { + return reqUa; + } + + public void setReqUa(String reqUa) { + this.reqUa = reqUa; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/common/Constants.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/common/Constants.java new file mode 100644 index 0000000..3984fbb --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/common/Constants.java @@ -0,0 +1,5 @@ +package com.aopcloud.beam.app.common; + +public class Constants { + public static String IMG_DEFAULT_USER_AVATAR =""; +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/common/OSSConfig.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/common/OSSConfig.java new file mode 100644 index 0000000..dc6ef7f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/common/OSSConfig.java @@ -0,0 +1,58 @@ +package com.aopcloud.beam.app.common; + + +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; + +@Component +public class OSSConfig implements InitializingBean { + @Value("${oss.file.endpoint}") + private String oss_file_endpoint; + + @Value("${oss.file.keyid}") + private String oss_file_keyid; + + @Value("${oss.file.keysecret}") + private String oss_file_keysecret; + + @Value("${oss.file.filehost}") + private String oss_file_filehost; + + @Value("${oss.file.bucketname}") + private String oss_file_bucketname; + public static String OSS_END_POINT; + public static String OSS_ACCESS_KEY_ID; + public static String OSS_ACCESS_KEY_SECRET; + public static String OSS_BUCKET_NAME; + public static String OSS_FILE_HOST; + + public static String OSS_DOMAIN="http://oss.mxzhe.cn/"; + + + public static String OSS_IMG_PATH="img/"; + + + + + + + private String accessKeyId; + private String accessKeySecret; + private String securityToken; + private String expiration; + private String bucketName; + private String endpoint; + + + + @Override + public void afterPropertiesSet() throws Exception { + OSS_END_POINT=oss_file_endpoint; + OSS_ACCESS_KEY_ID=oss_file_keyid; + OSS_ACCESS_KEY_SECRET=oss_file_keysecret; + OSS_BUCKET_NAME=oss_file_bucketname; + OSS_FILE_HOST=oss_file_filehost; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/common/PageBean.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/common/PageBean.java new file mode 100644 index 0000000..c5a3c95 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/common/PageBean.java @@ -0,0 +1,22 @@ +package com.aopcloud.beam.app.common; + +public class PageBean { + private int page =1; + private int size=20; + + public int getPage() { + return page; + } + + public void setPage(int page) { + this.page = page; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/common/PayConfig.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/common/PayConfig.java new file mode 100644 index 0000000..88a5ec4 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/common/PayConfig.java @@ -0,0 +1,41 @@ +package com.aopcloud.beam.app.common; + + +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class PayConfig implements InitializingBean { + @Value("${xy.pay.appid}") + private String appId; + + @Value("${xy.pay.key}") + private String key; + + @Value("${xy.pay.notify-url}") + private String notifyUrl; + + @Value("${xy.pay.order.create-url}") + private String orderCreateUrl; + @Value("${xy.pay.order.query-url}") + private String orderQueryUrl; + + + public static String PAY_APP_ID; + public static String PAY_KEY; + public static String PAY_NOTIFY_URL; + + public static String PAY_ORDER_CREATE_URL; + public static String PAY_ORDER_QUERY_URL; + + + @Override + public void afterPropertiesSet() throws Exception { + PAY_APP_ID = appId; + PAY_KEY = key; + PAY_NOTIFY_URL = notifyUrl; + PAY_ORDER_CREATE_URL = orderCreateUrl; + PAY_ORDER_QUERY_URL = orderQueryUrl; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/common/RequestContext.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/common/RequestContext.java new file mode 100644 index 0000000..25aa52f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/common/RequestContext.java @@ -0,0 +1,24 @@ +package com.aopcloud.beam.app.common; + +public class RequestContext { + + private final static ThreadLocal CURRENT_TOKEN; + + static { + CURRENT_TOKEN = new ThreadLocal<>(); + CURRENT_TOKEN.set(String.valueOf(System.currentTimeMillis())); + } + + + public static void setCurrentToken(String currentToken){ + CURRENT_TOKEN.set(currentToken); + } + + public static String getToken() { + return CURRENT_TOKEN.get(); + } + + public static void clear(){ + CURRENT_TOKEN.remove(); + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/AppContextHolder.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/AppContextHolder.java new file mode 100644 index 0000000..c609ead --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/AppContextHolder.java @@ -0,0 +1,32 @@ +package com.aopcloud.beam.app.configurer; + + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +@Component +public class AppContextHolder implements ApplicationContextAware { + + private static ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext context) throws BeansException { + AppContextHolder.applicationContext = context; + } + + public static ApplicationContext getContext() { + return applicationContext; + } + + @SuppressWarnings("unchecked") + public static T getBean(String name) throws BeansException { + return (T)applicationContext.getBean(name); + } + + public static T getBean(Class clz) throws BeansException { + return (T)applicationContext.getBean(clz); + } + +} \ No newline at end of file diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/CorsFilter.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/CorsFilter.java new file mode 100644 index 0000000..2c4e6e5 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/CorsFilter.java @@ -0,0 +1,44 @@ +package com.aopcloud.beam.app.configurer; + + +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; + +import javax.servlet.*; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@WebFilter(filterName = "CorsFilter ") +@Order(Ordered.HIGHEST_PRECEDENCE)//控制过滤器的级别最高 +@Configuration +public class CorsFilter implements Filter { + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { + HttpServletResponse response = (HttpServletResponse) res; + response.setHeader("Access-Control-Allow-Origin","*"); + response.setHeader("Access-Control-Allow-Credentials", "true"); + response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT, OPTIONS"); + response.setHeader("Access-Control-Max-Age", "180000"); +// response.setHeader("Access-Control-Allow-Headers", "Origin,X-Requested-With,Content-Type,Accept,Access-Token"); + response.setHeader("Access-Control-Allow-Headers", "*"); + response.setHeader("Content-Security-Policy", "upgrade-insecure-requests"); + + if ("OPTIONS".equalsIgnoreCase(((HttpServletRequest) req).getMethod())) { + response.setStatus(HttpServletResponse.SC_OK); + } else { + chain.doFilter(req, res); + } + } + + @Override + public void destroy() { + + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/GlobalExceptionHandler.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/GlobalExceptionHandler.java new file mode 100644 index 0000000..e2c594d --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/GlobalExceptionHandler.java @@ -0,0 +1,69 @@ +package com.aopcloud.beam.app.configurer; + +import com.alibaba.fastjson.JSON; +import com.aopcloud.beam.app.core.AppException;; +import com.aopcloud.beam.app.core.Result; +import com.aopcloud.beam.app.core.ResultCode; +import com.aopcloud.beam.app.core.ResultGenerator; +import org.springframework.http.HttpStatus; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.NoHandlerFoundException; + +import java.util.List; + + +/** + * 全局异常 + */ +@ControllerAdvice +public class GlobalExceptionHandler { +// @InitBinder +// public void initBinder(WebDataBinder binder) { +// // 方法1,注册converter +// GenericConversionService genericConversionService = (GenericConversionService) binder.getConversionService(); +// if (genericConversionService != null) { +// genericConversionService.addConverter(new DateConverter()); +// } +// +// // 方法2,定义单格式的日期转换,可以通过替换格式,定义多个dateEditor,代码不够简洁 +// DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); +// CustomDateEditor dateEditor = new CustomDateEditor(df, true); +// binder.registerCustomEditor(Date.class, dateEditor); +// +// +// // 方法3,同样注册converter +// binder.registerCustomEditor(Date.class, new PropertyEditorSupport() { +// @Override +// public void setAsText(String text) throws IllegalArgumentException { +// setValue(new DateConverter().convert(text)); +// } +// }); +// +// } + + @ResponseBody + @ExceptionHandler(value = NoHandlerFoundException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + public Result exceptionHandler(NoHandlerFoundException e) { + e.printStackTrace(); + return ResultGenerator.genFailResult(ResultCode.NOT_FOUND,e.getRequestURL()+"接口不存在"); + } + + + @ExceptionHandler + @ResponseBody + @ResponseStatus(code=HttpStatus.BAD_REQUEST) + public Result exceptionHandler(MethodArgumentNotValidException e) { + List bindingResult = e.getBindingResult().getFieldErrors(); + System.out.println(JSON.toJSONString(bindingResult.get(0))); + return ResultGenerator.genFailResult(bindingResult.get(0).getDefaultMessage()); + } + @ExceptionHandler + @ResponseBody + @ResponseStatus(code=HttpStatus.BAD_REQUEST) + public Result exceptionHandler(AppException e) { + return ResultGenerator.genFailResult(e.getCode(),e.getMessage()); + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/InterceptionConfig.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/InterceptionConfig.java new file mode 100644 index 0000000..bb1b589 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/InterceptionConfig.java @@ -0,0 +1,69 @@ +package com.aopcloud.beam.app.configurer; + +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.stereotype.Component; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.util.List; + + +@Component +public class InterceptionConfig implements WebMvcConfigurer { + + + + //使用阿里 FastJson 作为JSON MessageConverter + @Override + public void configureMessageConverters(List> converters) { + } + + + //解决跨域问题 + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**")// 允许跨域访问的路径 + .allowedOrigins("*")// 允许跨域访问的源 + .allowedMethods("*") + .allowedHeaders("*")// 允许头部设置 + .maxAge(180000) + .allowCredentials(true) + ;//是否发送cookie + } + +// // //本地资源 + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + + } + + //添加拦截器 + @Override + public void addInterceptors(InterceptorRegistry registry) { + //登录 +// registry.addInterceptor(loginInterceptor); +// //日志 +// registry.addInterceptor(logcatInterceptor); +// //接口签名 +// registry.addInterceptor(signInterceptor); + // +// InterceptorRegistration authority = registry.addInterceptor(authorityInterceptor); + +// authority.addPathPatterns("system/**"); +// authority.excludePathPatterns("system/login"); + + } + + // + @Override + public void addArgumentResolvers(List resolvers) { + + } + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/LocalDateTimeSerializerConfig.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/LocalDateTimeSerializerConfig.java new file mode 100644 index 0000000..c6890f4 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/LocalDateTimeSerializerConfig.java @@ -0,0 +1,49 @@ +package com.aopcloud.beam.app.configurer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; + +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +@Configuration +public class LocalDateTimeSerializerConfig { + + @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}") + private String pattern; + + // 方案三 + @Bean + @Primary + public ObjectMapper serializingObjectMapper() { + ObjectMapper objectMapper = new ObjectMapper(); + JavaTimeModule javaTimeModule = new JavaTimeModule(); + javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer()); + javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer()); + objectMapper.registerModule(javaTimeModule); + return objectMapper; + } + + public class LocalDateTimeSerializer extends JsonSerializer { + @Override + public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) + throws IOException { + gen.writeString(value.format(DateTimeFormatter.ofPattern(pattern))); + } + } + + public class LocalDateTimeDeserializer extends JsonDeserializer { + @Override + public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext) + throws IOException { + return LocalDateTime.parse(p.getValueAsString(), DateTimeFormatter.ofPattern(pattern)); + } + } +} \ No newline at end of file diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/LocalDateTimeToTsConfig.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/LocalDateTimeToTsConfig.java new file mode 100644 index 0000000..f9dd88b --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/LocalDateTimeToTsConfig.java @@ -0,0 +1,63 @@ +package com.aopcloud.beam.app.configurer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; + +import java.io.IOException; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; + +//@Configuration +public class LocalDateTimeToTsConfig { + /** + * 序列化LocalDateTime + * + * @return + */ + @Bean + @Primary + public ObjectMapper serializingObjectMapper() { + ObjectMapper objectMapper = new ObjectMapper(); + JavaTimeModule javaTimeModule = new JavaTimeModule(); + javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer()); + javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer()); + objectMapper.registerModule(javaTimeModule); + return objectMapper; + } + + /** + * 序列化实现 + */ + public static class LocalDateTimeSerializer extends JsonSerializer { + @Override + public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) + throws IOException { + if (value != null) { + long timestamp = value.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); + gen.writeNumber(timestamp); + } + } + } + + /** + * 反序列化实现 + */ + public static class LocalDateTimeDeserializer extends JsonDeserializer { + @Override + public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext) + throws IOException { + long timestamp = p.getValueAsLong(); + if (timestamp > 0) { + return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault()); + } else { + return null; + } + } + } +} \ No newline at end of file diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/RequestHandler.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/RequestHandler.java new file mode 100644 index 0000000..7b5f1ec --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/RequestHandler.java @@ -0,0 +1,31 @@ +package com.aopcloud.beam.app.configurer; + +import org.springframework.core.MethodParameter; +import org.springframework.http.HttpInputMessage; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice; + +import java.io.IOException; +import java.lang.reflect.Type; + +public class RequestHandler implements RequestBodyAdvice { + @Override + public boolean supports(MethodParameter methodParameter, Type targetType, Class> converterType) { + return false; + } + + @Override + public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class> converterType) throws IOException { + return null; + } + + @Override + public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class> converterType) { + return null; + } + + @Override + public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class> converterType) { + return null; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/ResponseHandler.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/ResponseHandler.java new file mode 100644 index 0000000..587b8bb --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/configurer/ResponseHandler.java @@ -0,0 +1,76 @@ +package com.aopcloud.beam.app.configurer; + +import com.alibaba.fastjson.JSON; +import com.aopcloud.beam.app.common.AccessLog; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.MethodParameter; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.server.ServerHttpRequest; +import org.springframework.http.server.ServerHttpResponse; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + + +@ControllerAdvice +public class ResponseHandler implements ResponseBodyAdvice { + + private final Logger log = LoggerFactory.getLogger(this.getClass()); + + @Override + public boolean supports(MethodParameter returnType, Class> converterType) { + return true; + } + + + @Override + public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { + AccessLog accessLog = new AccessLog(); + + + //获得所有头信息的name + HttpHeaders header = request.getHeaders(); + //输出所有的头信息的名字 + Map headers = new HashMap(); + for (String key : header.keySet()) { + headers.put(key, header.get(key)); + } + + Map param = new HashMap(); + Map params = new HashMap(); + params.put("header", headers); + params.put("query", request.getURI().getQuery()); + params.put("params", request.getURI().getScheme()); + //当前时间 + long currentTime = System.currentTimeMillis(); + //请求开始时间 +// long time = Long.valueOf(request.getAttribute(LOGGER_SEND_TIME).toString()); + + + accessLog.setApi(request.getURI().getPath()); + accessLog.setApiArgs(JSON.toJSONString(params)); + accessLog.setApiMethod(request.getMethod().name()); + //请求时间 + accessLog.setReqTime(new Date()); + // + accessLog.setReqClientIp(""); + //设置请求时间差 + accessLog.setApiTimeConsuming((int) (currentTime - 1)); + //设置返回时间 + accessLog.setReturnTime(new Date(currentTime)); + + + log.info("Method:{} ", request.getMethod().name()); + log.info("接口:{} 入参:{} 返回:{}", request.getURI().getPath(),"",""); +// log.info("接口:{} 入参:{} 返回:{}", request.getURI().getPath(), JSON.toJSON(params), JSON.toJSON(body)); + return body; + } + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/core/AppException.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/core/AppException.java new file mode 100644 index 0000000..d1703a8 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/core/AppException.java @@ -0,0 +1,54 @@ +package com.aopcloud.beam.app.core; + +public class AppException extends RuntimeException{ + + private int code; //异常状态码 + private String message; //异常信息 + private String descinfo; //描述 + public AppException(String message){ + this.message = message; + } + /** + * @param code 状态 + * @param message 信息 + */ + public AppException(int code, String message) { + this.code = code; + this.message = message; + } + /** + * @param code 状态 + * @param message 信息 + * @param descinfo 错误,描述! + */ + public AppException(int code, String message,String descinfo) { + this.code = code; + this.message = message; + this.descinfo = descinfo; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + @Override + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getDescinfo() { + return descinfo; + } + + public void setDescinfo(String descinfo) { + this.descinfo = descinfo; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/core/Result.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/core/Result.java new file mode 100644 index 0000000..8729eca --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/core/Result.java @@ -0,0 +1,47 @@ +package com.aopcloud.beam.app.core; + +public class Result { + private int code; + private String message; + private long timestamp; + private T data; + + public Result setCode(ResultCode resultCode) { + this.code = resultCode.code(); + return this; + } + public Result setCode(int resultCode) { + this.code = resultCode; + return this; + } + + public int getCode() { + return code; + } + + public String getMessage() { + return message; + } + + public long getTimestamp() { + return timestamp; + } + + public Result setMessage(String message) { + this.message = message; + this.timestamp = System.currentTimeMillis(); + return this; + } + + public T getData() { + return data; + } + + + public Result setData(T data) { + this.data = data; + this.timestamp = System.currentTimeMillis(); + return this; + } + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/core/ResultCode.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/core/ResultCode.java new file mode 100644 index 0000000..9b8aefd --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/core/ResultCode.java @@ -0,0 +1,23 @@ +package com.aopcloud.beam.app.core; + +/** + * 响应码枚举,参考HTTP状态码的语义 + */ +public enum ResultCode { + SUCCESS(200),//成功 + FAIL(400),//失败 + UNAUTHORIZED(401),//未认证(签名错误) + NOT_FOUND(404),//接口不存在 + INTERNAL_SERVER_ERROR(500),//服务器内部错误 + LOGIN_INVALID(10001);//服务器内部错误 + + private final int code; + + ResultCode(int code) { + this.code = code; + } + + public int code() { + return code; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/core/ResultGenerator.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/core/ResultGenerator.java new file mode 100644 index 0000000..f66079e --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/core/ResultGenerator.java @@ -0,0 +1,39 @@ +package com.aopcloud.beam.app.core; + +public class ResultGenerator { + private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS"; + + private String format = "json"; + + public static Result genSuccessResult() { + return new Result() + .setCode(ResultCode.SUCCESS) + .setMessage(DEFAULT_SUCCESS_MESSAGE); + } + + public static Result genSuccessResult(T data) { + return new Result() + .setCode(ResultCode.SUCCESS) + .setMessage(DEFAULT_SUCCESS_MESSAGE) + .setData(data); + } + + public static Result genFailResult(String message) { + return new Result() + .setCode(ResultCode.FAIL) + .setMessage(message); + } + + public static Result genFailResult(ResultCode code, String message) { + return new Result() + .setCode(code) + .setMessage(message); + } + + public static Result genFailResult(int code, String message) { + return new Result() + .setCode(code) + .setMessage(message); + } +} + diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/delay/DelayQueueManager.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/delay/DelayQueueManager.java new file mode 100644 index 0000000..ef3c93f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/delay/DelayQueueManager.java @@ -0,0 +1,113 @@ +package com.aopcloud.beam.app.delay; + +import com.aopcloud.beam.app.api.order.entity.Order; +import com.aopcloud.beam.app.api.order.service.impl.OrderServiceImpl; +import com.aopcloud.beam.app.configurer.AppContextHolder; +import com.aopcloud.beam.app.dotwallet.DotWalletManager; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.DelayQueue; +import java.util.concurrent.Executors; + +@Component +public class DelayQueueManager implements CommandLineRunner, InitializingBean { + private final Logger logger = LoggerFactory.getLogger(DelayQueueManager.class); + private DelayQueue delayQueue = new DelayQueue<>(); + + /** + * 加入到延时队列中 + * + * @param task + */ + public void put(DelayTask task) { + logger.info("加入延时任务:{}", task); + delayQueue.put(task); + logger.info("延时任务SIZE:{}", delayQueue.size()); + } + + + /** + * 取消延时任务 + * + * @param task + * @return + */ + public boolean remove(DelayTask task) { + logger.info("取消延时任务:{}", task); + return delayQueue.remove(task); + } + + /** + * 取消延时任务 + * + * @param taskId + * @return + */ + public boolean remove(int taskId) { + return remove(new DelayTask((taskId), "", 0)); + } + + + @Override + public void run(String... args) { + logger.info("初始化延时队列"); + Executors.newSingleThreadExecutor().execute((this::executeThread)); + } + + /** + * 延时任务执行线程 + */ + private void executeThread() { + while (true) { + try { + DelayTask task = delayQueue.take(); + processTask(task); + } catch (InterruptedException e) { + e.printStackTrace(); + logger.error("执行延时任务ERROR:{}", e.getMessage()); + } + } + } + + /** + * 内部执行延时任务 + * + * @param task + */ + private void processTask(DelayTask task) { + logger.info("执行延时任务:{}", task); + //根据task中的data自定义数据来处理相关逻辑,例 if (task.getData() instanceof XXX) {} + orderService = AppContextHolder.getBean(OrderServiceImpl.class); + Order order = (Order) task.getData(); + if (order.getLeaseStatus().equals("0")) { + boolean s = DotWalletManager.getInstance().startSolo(order.getCoinAddress()); + order.setLeaseStatus(s ? "1" : "0"); + } else if (order.getLeaseStatus().equals("1")) { + boolean s = DotWalletManager.getInstance().stopSolo(order.getCoinAddress()); + order.setLeaseStatus(s ? "2" : "1"); + } + orderService.saveOrUpdate(order); + System.out.println("task order:" + orderService.getById(order.getId())); + } + + + private OrderServiceImpl orderService; + private static DelayQueueManager queueManager; + + public static DelayQueueManager getQueueManager() { + return queueManager; + } + + @Override + public void afterPropertiesSet() throws Exception { + queueManager = this; + } +} \ No newline at end of file diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/delay/DelayTask.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/delay/DelayTask.java new file mode 100644 index 0000000..1bf866d --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/delay/DelayTask.java @@ -0,0 +1,69 @@ +package com.aopcloud.beam.app.delay; + + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.concurrent.Delayed; +import java.util.concurrent.TimeUnit; + +public class DelayTask implements Delayed { + final private T data; + final private long expire; + private int identifier; + + /** + * 构造延时任务 + * + * @param id id + * @param data 业务数据 + * @param expire 任务延时时间(ms) + */ + public DelayTask(int id, T data, long expire) { + super(); + this.identifier = id; + this.data = data; + this.expire = expire + System.currentTimeMillis(); + + } + + public T getData() { + return data; + } + + public long getExpire() { + return expire; + } + + public int getId() { + return identifier; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof DelayTask) { + return this.getId()==getId(); + } + return false; + } + + @Override + public String toString() { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return "{" + "data:" + data.toString() + "," + "expire:" + dateFormat.format(new Date(expire)) + "}"; + } + + @Override + public long getDelay(TimeUnit unit) { + // //下面用到unit.convert()方法,其实在这个小场景不需要用到,只是学习一下如何使用罢了 + long e= this.expire-System.currentTimeMillis(); + System.out.println("delay:"+e); + return unit.convert(e, TimeUnit.MILLISECONDS); + } + + @Override + public int compareTo(Delayed o) { + // //这里根据取消时间来比较,如果取消时间小的,就会优先被队列提取出来 + long delta = getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS); + return (int) delta; + } +} \ No newline at end of file diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/BSVTransaction.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/BSVTransaction.java new file mode 100644 index 0000000..84b7259 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/BSVTransaction.java @@ -0,0 +1,166 @@ +package com.aopcloud.beam.app.dotwallet; + +import com.aopcloud.beam.app.dotwallet.entity.response.data.SignParam; +import com.aopcloud.beam.app.dotwallet.util.Util; +import com.subgraph.orchid.encoders.Hex; +import org.bitcoinj.core.*; +import org.bitcoinj.crypto.ChildNumber; +import org.bitcoinj.crypto.DeterministicKey; +import org.bitcoinj.crypto.HDKeyDerivation; +import org.bitcoinj.script.Script; +import org.bitcoinj.script.ScriptBuilder; + +import java.util.ArrayList; +import java.util.List; + +public class BSVTransaction extends Transaction { + public static final byte ForkID = 0x40; + public BSVTransaction(NetworkParameters params, byte[] payloadBytes) throws ProtocolException { + super(params, payloadBytes); + } + + public BSVTransaction(NetworkParameters params, String rawTx) throws ProtocolException { + super(params, Hex.decode(rawTx)); + } + + private int appendVarInt(ArrayList byteArray, byte[] connectedScript) { + long len = connectedScript.length; + int scriptLen = 0; + if (len < 0xfd) { + scriptLen += appendBytes(byteArray, Util.byteToBytesLittle((byte) len)); + return scriptLen; + } + + if (len <= Short.MAX_VALUE) { + scriptLen += appendBytes(byteArray, Util.byteToBytesLittle((byte) 0xfd)); + scriptLen += appendBytes(byteArray, Util.shortToBytesLittle((short) len)); + return scriptLen; + } + + if (len <= Integer.MAX_VALUE) { + scriptLen += appendBytes(byteArray, Util.byteToBytesLittle((byte) 0xfe)); + scriptLen += appendBytes(byteArray, Util.intToBytesLittle((int) len)); + return scriptLen; + } + + scriptLen += appendBytes(byteArray, Util.byteToBytesLittle((byte) 0xff)); + scriptLen += appendBytes(byteArray, Util.longToBytesLittle(len)); + return scriptLen; + } + + private int appendBytes(ArrayList byteArray, byte[] newByte) { + byteArray.add(newByte); + return newByte.length; + } + + private byte[] getFinalBytes(ArrayList byteArray, int totalLen) { + byte[] finalBytes = new byte[totalLen]; + int off = 0; + for (byte[] tmpBytes : byteArray) { + System.arraycopy(tmpBytes, 0, finalBytes, off, tmpBytes.length); + off += tmpBytes.length; + } + return finalBytes; + } + + private Sha256Hash hashForSignature(int inputIndex, byte[] connectedScript, long value, byte sigHashType) { + ArrayList byteArray = new ArrayList<>(); + byte sigHashMask = 0x1f; + int totalLen = 0; + + if (inputIndex > getInputs().size() - 1) { + throw new RuntimeException("inputIndex out of range"); + } + + totalLen += appendBytes(byteArray, Util.intToBytesLittle((int) getVersion())); + + if ((sigHashType & SigHash.ANYONECANPAY.value) == 0) { + ArrayList byteArrayTmp = new ArrayList(); + int tmplen = 0; + for (TransactionInput tmpInput : getInputs()) { + tmplen += appendBytes(byteArrayTmp, tmpInput.getOutpoint().bitcoinSerialize()); + } + byte[] tmpBufferBytes = getFinalBytes(byteArrayTmp, tmplen); + Sha256Hash tmpHash = Sha256Hash.twiceOf(tmpBufferBytes); + totalLen += appendBytes(byteArray, tmpHash.getBytes()); + } else { + totalLen += appendBytes(byteArray, Sha256Hash.ZERO_HASH.getBytes()); + } + + if ((sigHashType & SigHash.ANYONECANPAY.value) == 0 && + (sigHashType & sigHashMask) != SigHash.SINGLE.value && + (sigHashType & sigHashMask) != SigHash.NONE.value) { + ArrayList byteArrayTmp = new ArrayList<>(); + int tmplen = 0; + for (TransactionInput tmpInput : getInputs()) { + tmplen += appendBytes(byteArrayTmp, Util.intToBytesLittle((int) tmpInput.getSequenceNumber())); + } + + byte[] tmpBufferBytes = getFinalBytes(byteArrayTmp, tmplen); + Sha256Hash tmpHash = Sha256Hash.twiceOf(tmpBufferBytes); + totalLen += appendBytes(byteArray, tmpHash.getBytes()); + } else { + totalLen += appendBytes(byteArray, Sha256Hash.ZERO_HASH.getBytes()); + } + + totalLen += appendBytes(byteArray, getInput(inputIndex).getOutpoint().bitcoinSerialize()); + totalLen += appendVarInt(byteArray, connectedScript); + totalLen += appendBytes(byteArray, connectedScript); + totalLen += appendBytes(byteArray, Util.longToBytesLittle(value)); + totalLen += appendBytes(byteArray, Util.intToBytesLittle((int) getInput(inputIndex).getSequenceNumber())); + + if ((sigHashType & SigHash.SINGLE.value) != SigHash.SINGLE.value && + (sigHashType & SigHash.NONE.value) != SigHash.NONE.value) { + ArrayList byteArrayTmp = new ArrayList(); + int tmplen = 0; + for (TransactionOutput tmpOutput : getOutputs()) { + tmplen += appendBytes(byteArrayTmp, tmpOutput.bitcoinSerialize()); + } + byte[] tmpBufferBytes = getFinalBytes(byteArrayTmp, tmplen); + Sha256Hash tmpHash = Sha256Hash.twiceOf(tmpBufferBytes); + totalLen += appendBytes(byteArray, tmpHash.getBytes()); + } else if ((sigHashType & sigHashMask) == SigHash.SINGLE.value && + inputIndex < getOutputs().size()) { + byte[] tmpBytes = getOutput(inputIndex).bitcoinSerialize(); + Sha256Hash tmpHash = Sha256Hash.twiceOf(tmpBytes); + totalLen += appendBytes(byteArray, tmpHash.getBytes()); + } else { + totalLen += appendBytes(byteArray, Sha256Hash.ZERO_HASH.getBytes()); + } + + totalLen += appendBytes(byteArray, Util.intToBytesLittle((int) getLockTime())); + totalLen += appendBytes(byteArray, Util.intToBytesLittle(sigHashType | ForkID)); + byte[] finalBytes = getFinalBytes(byteArray, totalLen); + return Sha256Hash.twiceOf(finalBytes); + } + + private Script createVinScript(int inputIndex, ECKey key, byte[] connectedScript, long value, SigHash hashType) { + byte trueSigHashByte = (byte) (hashType.byteValue() | ForkID); + Sha256Hash hash = this.hashForSignature(inputIndex, connectedScript, value, trueSigHashByte); + ECKey.ECDSASignature ecdsaSignature = key.sign(hash); + byte[] ecdsaSignatureByte = ecdsaSignature.encodeToDER(); + byte[] trueSignResult = new byte[ecdsaSignatureByte.length + 1]; + System.arraycopy(ecdsaSignatureByte, 0, trueSignResult, 0, ecdsaSignatureByte.length); + trueSignResult[trueSignResult.length - 1] = trueSigHashByte; + return new ScriptBuilder().data(trueSignResult).data(key.getPubKey()).build(); + } + + public String signBSVTransaction(DeterministicKey key, List signParams) throws Exception { + List inputs = this.getInputs(); + if (inputs.size() != signParams.size()) { + throw new Exception(String.format("transactionInputs size %d , but signParams size %d", inputs.size(), signParams.size())); + } + for (int i = 0; i < signParams.size(); i++) { + int changeStep = 0; + if (signParams.get(i).isChange()) { + changeStep = 1; + } + DeterministicKey step4 = HDKeyDerivation.deriveChildKey(key, new ChildNumber(changeStep, false)); + DeterministicKey privateKey = HDKeyDerivation.deriveChildKey(step4, new ChildNumber(signParams.get(i).getAddressIndex(), false)); + byte[] preScript = Hex.decode(signParams.get(i).getScriptHex().getBytes()); + Script inputScript = this.createVinScript(i, privateKey, preScript, signParams.get(i).getAmount(), SigHash.ALL); + this.getInput(i).setScriptSig(inputScript); + } + return new String(Hex.encode(this.bitcoinSerialize())); + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/DotApiConstants.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/DotApiConstants.java new file mode 100644 index 0000000..300ef7b --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/DotApiConstants.java @@ -0,0 +1,11 @@ +package com.aopcloud.beam.app.dotwallet; + +public interface DotApiConstants { + + + String getSubUserList = "/v1/mempool/getSubUserList"; + String setMiningType = "/v1/mempool/setMiningType"; + String getBlockList = "/v1/mempool/getBlockList"; + String getShareAccept = "/v1/mempool/getShareAccept"; + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/DotWalletClient.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/DotWalletClient.java new file mode 100644 index 0000000..577a571 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/DotWalletClient.java @@ -0,0 +1,252 @@ +package com.aopcloud.beam.app.dotwallet; + +import com.alibaba.fastjson.JSON; +import com.aopcloud.beam.app.dotwallet.entity.DotBaseResponse; +import com.aopcloud.beam.app.dotwallet.entity.PKIRequest; +import com.aopcloud.beam.app.dotwallet.entity.Vout; +import com.aopcloud.beam.app.dotwallet.entity.response.BaseResponse; +import com.aopcloud.beam.app.dotwallet.entity.response.BroadcastTransactionResponse; +import com.aopcloud.beam.app.dotwallet.entity.response.BuildTransactionResponse; +import com.aopcloud.beam.app.dotwallet.entity.response.GetMerkleProofResponse; +import com.aopcloud.beam.app.dotwallet.util.HttpUtil; +import com.aopcloud.beam.app.http.OkHttpUtils; +import okhttp3.MediaType; +import okhttp3.Response; +import org.bitcoinj.core.ECKey; +import org.bitcoinj.core.Sha256Hash; +import org.bitcoinj.crypto.ChildNumber; +import org.bitcoinj.crypto.DeterministicKey; +import org.bitcoinj.crypto.HDKeyDerivation; +import org.bitcoinj.crypto.MnemonicCode; +import org.bitcoinj.params.AbstractBitcoinNetParams; +import org.bitcoinj.params.MainNetParams; +import org.spongycastle.util.encoders.Hex; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +public class DotWalletClient { + private static final String DotWalletHost = "https://api.ddpurse.com"; + public static final AbstractBitcoinNetParams BSVNetParams = MainNetParams.get(); + private DeterministicKey masterKey; + + /** + * 打点HD钱包使用路径为:m/44'/0'/0' + * + * @param masterKey main HDKey + */ + private DotWalletClient(DeterministicKey masterKey) { + //path:m/44' + DeterministicKey step1 = HDKeyDerivation.deriveChildKey(masterKey, new ChildNumber(44, true)); + //path:m/44'/0' + DeterministicKey step2 = HDKeyDerivation.deriveChildKey(step1, new ChildNumber(0, true)); + //path:m/44'/0'/0' + DeterministicKey step3 = HDKeyDerivation.deriveChildKey(step2, new ChildNumber(0, true)); + this.masterKey = step3; + } + + /** + * @param mnemonicWords 助记词 + * @return + * @throws Exception + */ + public static DotWalletClient newInstance(List mnemonicWords) throws Exception { + if (mnemonicWords == null || mnemonicWords.size() == 0) { + throw new Exception("mnemonic words empty"); + } + byte[] seed = MnemonicCode.toSeed(mnemonicWords, ""); + return new DotWalletClient(HDKeyDerivation.createMasterPrivateKey(seed)); + } + + /** + * 注册xPub + * + * @param userIndex 该xpub与用户的关联,不可重复,不可为0,需要记住该数字 + * @param xPub 公钥 + * @return + * @throws Exception + */ + public BaseResponse registerXPub(Integer userIndex, String xPub) throws Exception { + Map params = new HashMap<>(); + params.put("appid", "test_bsv_coin_regular"); + params.put("user_index", userIndex); + params.put("xpub", xPub); + params.put("seed", xPub); + return doPKIRequest("/v1/bsv/register_xpub", params, BaseResponse.class); + } + + /** + * 构建未签名交易 + * + * @param userIndex 注册公钥时填写的userIndex + * @param vouts 交易输出 + * @param feeByte 交易手续费费率,最终以feesatoshi/feebyte计算,表示每字节多少聪,建议值`2` + * @param feeSatoshi 交易手续费费率,最终以feesatoshi/feebyte计算,表示每字节多少聪,建议值`2` + * @return + * @throws Exception + */ + public BuildTransactionResponse buildTransaction(Integer userIndex, List vouts, Integer feeByte, Integer feeSatoshi) throws Exception { + Map sender = new HashMap<>(); + sender.put("appid", "test_bsv_coin_regular"); + sender.put("user_index", userIndex); + Map params = new HashMap<>(); + params.put("sender", sender); + params.put("vouts", vouts); + params.put("feebyte", feeByte); + params.put("feesatoshi", feeSatoshi); + params.put("sign", false); + params.put("send", false); + return doPKIRequest("/v1/bsv/send_to_script", params, BuildTransactionResponse.class); + } + + /** + * 广播交易 + * + * @param rawtx 十六进制已签名的原始交易 + * @param unlimited 是否突破链式交易上线 + * @return + * @throws Exception + */ + public BroadcastTransactionResponse broadcastTransaction(String rawtx, Boolean unlimited) throws Exception { + Map params = new HashMap<>(); + params.put("rawtx", rawtx); + params.put("unlimit", unlimited); + return doPKIRequest("/v1/bsv/broadcast_transaction", params, BroadcastTransactionResponse.class); + } + + /** + * 获取默克尔证明 + * + * @param txid 交易txid + * @return + * @throws Exception + */ + public GetMerkleProofResponse getMerkleProof(String txid) throws Exception { + Map params = new HashMap<>(); + params.put("txid", txid); + return doPKIRequest("/v1/bsvchain/get_merkleproof", params, GetMerkleProofResponse.class); + } + + public GetMerkleProofResponse getSubUser() throws Exception { + Map params = new HashMap<>(); + return doPKIRequest(DotApiConstants.getSubUserList, params, GetMerkleProofResponse.class); + } + + + public DotBaseResponse getSubUserList() { + Map params = new HashMap<>(); + return doRequest(DotApiConstants.getSubUserList,params); + } + + + public DotBaseResponse startSolo(int puid, String address) { + Map params = new HashMap<>(); + params.put("puid", puid); + params.put("is_solo", 1); + params.put("address", address); + return doRequest(DotApiConstants.setMiningType,params); + } + + public DotBaseResponse stopSolo(int puid, String address) { + Map params = new HashMap<>(); + params.put("puid", puid); + params.put("is_solo", 0); + params.put("address", address); + return doRequest(DotApiConstants.setMiningType,params); + } + + + public DotBaseResponse getBlockList(long startTime, long endTime) { + Map params = new HashMap<>(); + params.put("start_time", startTime); + params.put("end_time", endTime); + return doRequest(DotApiConstants.getBlockList,params); + } + + + public DotBaseResponse getShareAccept(long startTime, long endTime) { + Map params = new HashMap<>(); + params.put("start_time", startTime); + params.put("end_time", endTime); + return doRequest(DotApiConstants.getShareAccept,params); + } + + + private DotBaseResponse doRequest(String requestURL, Map params) { + String payload = JSON.toJSONString(params); + //path:m/44'/0'/0'/0 + DeterministicKey step4 = HDKeyDerivation.deriveChildKey(this.masterKey, new ChildNumber(0, false)); + //path:m/44'/0'/0'/0/0 + DeterministicKey PKIKey = HDKeyDerivation.deriveChildKey(step4, new ChildNumber(0, false)); + Sha256Hash hashToSign = Sha256Hash.of(payload.getBytes()); + ECKey.ECDSASignature ecdsaSignature = PKIKey.sign(hashToSign); + PKIRequest request = new PKIRequest(); + request.setPayload(payload); + request.setSignature(Hex.toHexString(ecdsaSignature.encodeToDER())); + request.setPubkey(Hex.toHexString(PKIKey.getPubKey())); + String json = JSON.toJSONString(request); + System.out.println("doRequest json :"+json); + Response response = null; + try { + response = + OkHttpUtils + .postString() + .url(DotWalletHost+requestURL) + .content(json) + .mediaType(MediaType.parse("application/json; charset=utf-8")) + .build() + .execute(); + String re = response.body().string(); + System.out.println("response:" + re); + DotBaseResponse baseResponse = JSON.parseObject(re, DotBaseResponse.class); + return baseResponse; + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + private T + doPKIRequest(String requestURL, Map params, Class tClass) throws Exception { + String payload = JSON.toJSONString(params); + //path:m/44'/0'/0'/0 + DeterministicKey step4 = HDKeyDerivation.deriveChildKey(this.masterKey, new ChildNumber(0, false)); + //path:m/44'/0'/0'/0/0 + DeterministicKey PKIKey = HDKeyDerivation.deriveChildKey(step4, new ChildNumber(0, false)); + Sha256Hash hashToSign = Sha256Hash.of(payload.getBytes()); + ECKey.ECDSASignature ecdsaSignature = PKIKey.sign(hashToSign); + PKIRequest request = new PKIRequest(); + request.setPayload(payload); + request.setSignature(Hex.toHexString(ecdsaSignature.encodeToDER())); + request.setPubkey(Hex.toHexString(PKIKey.getPubKey())); + String json = JSON.toJSONString(request); + System.out.println("doPKIRequest json :"+json); + + String result = HttpUtil.httpPostWithJson(DotWalletHost+requestURL, json); + T response; + try { + if (result.equals("")) { + throw new RuntimeException("empty http result"); + } + response = JSON.parseObject(result, tClass); + return response; + } catch (Exception e) { + try { + response = tClass.newInstance(); + Field code = tClass.getSuperclass().getDeclaredField("code"); + code.setAccessible(true); + code.set(response, -1); + Field msg = tClass.getSuperclass().getDeclaredField("msg"); + msg.setAccessible(true); + msg.set(response, result); + return response; + } catch (Exception e1) { + throw new RuntimeException(e1); + } + } + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/DotWalletManager.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/DotWalletManager.java new file mode 100644 index 0000000..93c71bc --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/DotWalletManager.java @@ -0,0 +1,89 @@ +package com.aopcloud.beam.app.dotwallet; + +import com.alibaba.fastjson.JSON; +import com.aopcloud.beam.app.dotwallet.entity.DotBaseResponse; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class DotWalletManager { + + + public static void main(String[] args) { + long s = System.currentTimeMillis()/1000-86400 ; + long e= System.currentTimeMillis()/1000; + getInstance().getBlockList(s,e); + } + + private DotWalletClient client; + public static DotWalletManager dotWalletManager; + public String[] mnemonicWordArray = new String[]{"world", "ramp", "coil", "awesome", "loud", "warrior", "equip", "panic", "shield", "away", "desert", "find"}; + + public static DotWalletManager getInstance() { + if (dotWalletManager == null) { + dotWalletManager = new DotWalletManager(); + } + return dotWalletManager; + } + + + public DotWalletManager() { + //获取PKI接口能力 + //从打点钱包web版(www.ddpurse.com)导出BSV助记词 + List mnemonicWords = Arrays.asList(mnemonicWordArray); + System.out.println("BSV助记词:" + JSON.toJSONString(mnemonicWords)); + //初始化DotWalletClient + try { + //使用该助记词生成的私钥进行接口调用签名 + client = DotWalletClient.newInstance(mnemonicWords); + } catch (Exception e) { + e.printStackTrace(); + } + } + + + public void getSubUserList() { + try { +// GetMerkleProofResponse response= client.getSubUser(); +// System.out.println("response:"+response.toString()); +// DotBaseResponse broadcastTransactionResponse= client.getSubUserList(); +// System.out.println("getSubUserList:"+ JSON.toJSONString(broadcastTransactionResponse)); + Object startSolo = client.startSolo(7990, "123"); + System.out.println("startSolo:" + JSON.toJSONString(startSolo)); + +// DotBaseResponse startSolo= client.startSolo("1","add"); +// System.out.println("startSolo:"+startSolo.toString()); +// DotBaseResponse stopSolo= client.stopSolo("1","asd"); +// System.out.println("stopSolo:"+stopSolo.toString()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public boolean startSolo(String address) { + DotBaseResponse startSolo = client.startSolo(7990, address); + if (startSolo.getCode() == 0) { + return true; + } + return false; + } + + public boolean stopSolo(String address) { + DotBaseResponse startSolo = client.startSolo(7990, address); + if (startSolo.getCode() == 0) { + return true; + } + return false; + } + + + public List getBlockList(long startTime, long endTime) { + DotBaseResponse startSolo = client.getBlockList(startTime, endTime); + if (startSolo.getCode() == 0) { + return startSolo.getData(); + } + return new ArrayList(); + } + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/DotBaseResponse.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/DotBaseResponse.java new file mode 100644 index 0000000..c43d7e8 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/DotBaseResponse.java @@ -0,0 +1,55 @@ +package com.aopcloud.beam.app.dotwallet.entity; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + + +@JsonIgnoreProperties(ignoreUnknown = true) +public class DotBaseResponse { + + /** + * code : 0 + * msg : MSG_act_success + * data : [{"puid":5024,"user_name":"loan_system","is_solo":0,"address":"","created_at":1589446708}] + */ + + @JsonProperty("code") + private Integer code; + @JsonProperty("msg") + private String msg; + @JsonProperty("data") + private T t; + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public T getData() { + return t; + } + + public void setData(T data) { + this.t = data; + } + + @Override + public String toString() { + return "DotBaseResponse{" + + "code=" + code + + ", msg='" + msg + '\'' + + ", t=" + t + + '}'; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/PKIRequest.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/PKIRequest.java new file mode 100644 index 0000000..56cd140 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/PKIRequest.java @@ -0,0 +1,45 @@ +package com.aopcloud.beam.app.dotwallet.entity; + +import com.alibaba.fastjson.annotation.JSONField; + +public class PKIRequest { + @JSONField(name = "payload") + private String payload; + @JSONField(name = "signature") + private String signature; + @JSONField(name = "pubkey") + private String pubkey; + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + public String getSignature() { + return signature; + } + + public void setSignature(String signature) { + this.signature = signature; + } + + public String getPubkey() { + return pubkey; + } + + public void setPubkey(String pubkey) { + this.pubkey = pubkey; + } + + @Override + public String toString() { + return "PKIRequest{" + + "payload='" + payload + '\'' + + ", signature='" + signature + '\'' + + ", pubkey='" + pubkey + '\'' + + '}'; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/Vin.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/Vin.java new file mode 100644 index 0000000..edefaf5 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/Vin.java @@ -0,0 +1,32 @@ +package com.aopcloud.beam.app.dotwallet.entity; + + +import com.alibaba.fastjson.annotation.JSONField; + +public class Vin { + @JSONField(name = "txid") + private String txid; + @JSONField(name = "index") + private int index; + + public Vin(String txid, int index) { + this.txid = txid; + this.index = index; + } + + public String getTxid() { + return txid; + } + + public void setTxid(String txid) { + this.txid = txid; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/Vout.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/Vout.java new file mode 100644 index 0000000..f51100a --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/Vout.java @@ -0,0 +1,32 @@ +package com.aopcloud.beam.app.dotwallet.entity; + + +import com.alibaba.fastjson.annotation.JSONField; + +public class Vout { + @JSONField(name="amount") + private long amount; + @JSONField(name="hexscript") + private String hexScript; + + public long getAmount() { + return amount; + } + + public void setAmount(long amount) { + this.amount = amount; + } + + public String getHexScript() { + return hexScript; + } + + public void setHexScript(String hexScript) { + this.hexScript = hexScript; + } + + public Vout(long amount, String hexScript) { + this.amount = amount; + this.hexScript = hexScript; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/BaseResponse.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/BaseResponse.java new file mode 100644 index 0000000..2a408a9 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/BaseResponse.java @@ -0,0 +1,48 @@ +package com.aopcloud.beam.app.dotwallet.entity.response; + +import com.alibaba.fastjson.annotation.JSONField; + +/** + * 响应基类 + */ +public class BaseResponse { + public static final Integer SuccessCode = 0; + /** + * 状态码 + */ + @JSONField(name = "code") + private Integer code; + /** + * 信息 + */ + @JSONField(name = "msg") + private String msg; + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public boolean isSuccess() { + return this.code == SuccessCode; + } + + @Override + public String toString() { + return "BaseResponse{" + + "code=" + code + + ", msg='" + msg + '\'' + + '}'; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/BroadcastTransactionResponse.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/BroadcastTransactionResponse.java new file mode 100644 index 0000000..18315d2 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/BroadcastTransactionResponse.java @@ -0,0 +1,14 @@ +package com.aopcloud.beam.app.dotwallet.entity.response; + +public class BroadcastTransactionResponse extends BaseResponse { + //txid + private String data; + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/BuildTransactionResponse.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/BuildTransactionResponse.java new file mode 100644 index 0000000..20a179f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/BuildTransactionResponse.java @@ -0,0 +1,24 @@ +package com.aopcloud.beam.app.dotwallet.entity.response; + + +import com.aopcloud.beam.app.dotwallet.entity.response.data.BuildTransactionData; + +public class BuildTransactionResponse extends BaseResponse { + + private BuildTransactionData data; + + public BuildTransactionData getData() { + return data; + } + + public void setData(BuildTransactionData data) { + this.data = data; + } + + @Override + public String toString() { + return "BuildTransactionResponse{" + + "data=" + data + + '}'; + } +} \ No newline at end of file diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/GetMerkleProofResponse.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/GetMerkleProofResponse.java new file mode 100644 index 0000000..1e233a3 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/GetMerkleProofResponse.java @@ -0,0 +1,23 @@ +package com.aopcloud.beam.app.dotwallet.entity.response; + + +import com.aopcloud.beam.app.dotwallet.entity.response.data.MerkleProofData; + +public class GetMerkleProofResponse extends BaseResponse { + private MerkleProofData data; + + public MerkleProofData getData() { + return data; + } + + public void setData(MerkleProofData data) { + this.data = data; + } + + @Override + public String toString() { + return "GetMerkleProofResponse{" + + "data=" + data + + '}'; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/data/BuildTransactionData.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/data/BuildTransactionData.java new file mode 100644 index 0000000..1d9953e --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/data/BuildTransactionData.java @@ -0,0 +1,49 @@ +package com.aopcloud.beam.app.dotwallet.entity.response.data; + +import com.alibaba.fastjson.annotation.JSONField; + +import java.util.List; + +public class BuildTransactionData { + @JSONField(name = "txid") + private String txid; + @JSONField(name = "fee") + private long fee; + @JSONField(name = "rawtx") + private String rawtx; + @JSONField(name = "params") + private List params; + + public String getTxid() { + return txid; + } + + public void setTxid(String txid) { + this.txid = txid; + } + + public long getFee() { + return fee; + } + + public void setFee(long fee) { + this.fee = fee; + } + + public String getRawtx() { + return rawtx; + } + + public void setRawtx(String rawtx) { + this.rawtx = rawtx; + } + + public List getParams() { + return params; + } + + public void setParams(List params) { + this.params = params; + } +} + diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/data/MerkleProofData.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/data/MerkleProofData.java new file mode 100644 index 0000000..57dae2b --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/data/MerkleProofData.java @@ -0,0 +1,56 @@ +package com.aopcloud.beam.app.dotwallet.entity.response.data; + +import com.alibaba.fastjson.annotation.JSONField; + +public class MerkleProofData { + @JSONField(name = "flags") + private Integer flags; + @JSONField(name = "index") + private Integer index; + @JSONField(name = "txOrId") + private String TxOrId; + @JSONField(name = "target") + private MerkleProofTarget Target; + @JSONField(name = "nodes") + private String[] nodes; + + public Integer getFlags() { + return flags; + } + + public void setFlags(Integer flags) { + this.flags = flags; + } + + public Integer getIndex() { + return index; + } + + public void setIndex(Integer index) { + this.index = index; + } + + public String getTxOrId() { + return TxOrId; + } + + public void setTxOrId(String txOrId) { + TxOrId = txOrId; + } + + public MerkleProofTarget getTarget() { + return Target; + } + + public void setTarget(MerkleProofTarget target) { + Target = target; + } + + public String[] getNodes() { + return nodes; + } + + public void setNodes(String[] nodes) { + this.nodes = nodes; + } +} \ No newline at end of file diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/data/MerkleProofTarget.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/data/MerkleProofTarget.java new file mode 100644 index 0000000..aab903c --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/data/MerkleProofTarget.java @@ -0,0 +1,171 @@ +package com.aopcloud.beam.app.dotwallet.entity.response.data; + +import com.alibaba.fastjson.annotation.JSONField; + +// Hash string `json:"hash"` +// Confirmations int64 `json:"confirmations"` +// Height int64 `json:"height"` +// Version int64 `json:"version"` +// VersionHex string `json:"versionHex"` +// Merkleroot string `json:"merkleroot"` +// NumTx int64 `json:"num_tx"` +// Time int64 `json:"time"` +// Mediantime int64 `json:"mediantime"` +// Nonce int64 `json:"nonce"` +// Bits string `json:"bits"` +// Difficulty float64 `json:"difficulty"` +// Chainwork string `json:"chainwork"` +// Previousblockhash string `json:"previousblockhash"` +// Nextblockhash string `json:"nextblockhash"` +public class MerkleProofTarget { + @JSONField(name = "hash") + private String hash; + @JSONField(name = "confirmations") + private Integer confirmations; + @JSONField(name = "height") + private Integer height; + @JSONField(name = "version") + private Integer version; + @JSONField(name = "versionHex") + private String versionHex; + @JSONField(name = "merkleroot") + private String merkleRoot; + @JSONField(name = "num_tx") + private Integer numTx; + @JSONField(name = "time") + private Integer time; + @JSONField(name = "mediantime") + private Integer mediantime; + @JSONField(name = "nonce") + private Integer nonce; + @JSONField(name = "bits") + private String bits; + @JSONField(name = "difficulty") + private Float difficulty; + @JSONField(name = "chainwork") + private String chainWork; + @JSONField(name = "previousblockhash") + private String PreviousBlockHash; + @JSONField(name = "nextblockhash") + private String nextBlockHash; + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + + public Integer getConfirmations() { + return confirmations; + } + + public void setConfirmations(Integer confirmations) { + this.confirmations = confirmations; + } + + public Integer getHeight() { + return height; + } + + public void setHeight(Integer height) { + this.height = height; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public String getVersionHex() { + return versionHex; + } + + public void setVersionHex(String versionHex) { + this.versionHex = versionHex; + } + + public String getMerkleRoot() { + return merkleRoot; + } + + public void setMerkleRoot(String merkleRoot) { + this.merkleRoot = merkleRoot; + } + + public Integer getNumTx() { + return numTx; + } + + public void setNumTx(Integer numTx) { + this.numTx = numTx; + } + + public Integer getTime() { + return time; + } + + public void setTime(Integer time) { + this.time = time; + } + + public Integer getMediantime() { + return mediantime; + } + + public void setMediantime(Integer mediantime) { + this.mediantime = mediantime; + } + + public Integer getNonce() { + return nonce; + } + + public void setNonce(Integer nonce) { + this.nonce = nonce; + } + + public String getBits() { + return bits; + } + + public void setBits(String bits) { + this.bits = bits; + } + + public Float getDifficulty() { + return difficulty; + } + + public void setDifficulty(Float difficulty) { + this.difficulty = difficulty; + } + + public String getChainWork() { + return chainWork; + } + + public void setChainWork(String chainWork) { + this.chainWork = chainWork; + } + + public String getPreviousBlockHash() { + return PreviousBlockHash; + } + + public void setPreviousBlockHash(String previousBlockHash) { + PreviousBlockHash = previousBlockHash; + } + + public String getNextBlockHash() { + return nextBlockHash; + } + + public void setNextBlockHash(String nextBlockHash) { + this.nextBlockHash = nextBlockHash; + } +} \ No newline at end of file diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/data/SignParam.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/data/SignParam.java new file mode 100644 index 0000000..6a1f4c1 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/entity/response/data/SignParam.java @@ -0,0 +1,50 @@ +package com.aopcloud.beam.app.dotwallet.entity.response.data; + + +import com.alibaba.fastjson.annotation.JSONField; + +public class SignParam { + @JSONField(name = "address_index") + private int addressIndex; + + @JSONField(name = "is_change") + private boolean isChange; + + @JSONField(name = "script_hex") + private String scriptHex; + + @JSONField(name = "amount") + private long amount; + + public int getAddressIndex() { + return addressIndex; + } + + public void setAddressIndex(int addressIndex) { + this.addressIndex = addressIndex; + } + + public boolean isChange() { + return isChange; + } + + public void setChange(boolean change) { + isChange = change; + } + + public String getScriptHex() { + return scriptHex; + } + + public void setScriptHex(String scriptHex) { + this.scriptHex = scriptHex; + } + + public long getAmount() { + return amount; + } + + public void setAmount(long amount) { + this.amount = amount; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/util/HttpUtil.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/util/HttpUtil.java new file mode 100644 index 0000000..839d7ae --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/util/HttpUtil.java @@ -0,0 +1,217 @@ +package com.aopcloud.beam.app.dotwallet.util; + +import org.apache.http.HttpEntity; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.util.Map; + +/** + * Http操作工具类 + * + * @author + */ +public class HttpUtil { + /** + * 发送POST请求,参数为JSON格式 + * + * @param url 请求地址 + * @param json JSON格式参数 + * @return + */ + public static String httpPostWithJson(String url, String json) throws Exception{ + String returnValue = ""; + CloseableHttpClient httpClient = HttpClients.createDefault(); + try { + HttpPost httpPost = new HttpPost(url); + StringEntity requestEntity = new StringEntity(json, "utf-8"); + httpPost.setConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()); + httpPost.setHeader("Content-Type", "application/json"); + httpPost.setEntity(requestEntity); + CloseableHttpResponse resp = httpClient.execute(httpPost); + returnValue = EntityUtils.toString(resp.getEntity()); + } catch (Exception e) { + throw e; + } finally { + try { + httpClient.close(); + } catch (IOException e) { + throw e; + } + } + return returnValue; + } + + /** + * 发送POST请求,body参数为JSON格式,自定义添加header参数 + * + * @param url 请求地址 + * @param json JSON格式参数 + * @param paramHeadMap header参数 + * @return + */ + public static String httpPostWithJson(String url, String json, Map paramHeadMap) { + String returnValue = ""; + CloseableHttpClient httpClient = HttpClients.createDefault(); + try { + HttpPost httpPost = new HttpPost(url); + StringEntity requestEntity = new StringEntity(json, "utf-8"); + + httpPost.setConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()); + httpPost.setHeader("Content-Type", "application/json"); + for (Map.Entry entry : paramHeadMap.entrySet()) { + httpPost.setHeader(entry.getKey(), entry.getValue()); + } + httpPost.setEntity(requestEntity); + + CloseableHttpResponse resp = httpClient.execute(httpPost); + returnValue = EntityUtils.toString(resp.getEntity()); + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return returnValue; + } + + /** + * 发送普通get请求 + * + * @param url 地址 + * @return + */ + public static String httpGet(String url) { + CloseableHttpClient client = HttpClients.createDefault(); + HttpGet httpGet = new HttpGet(url); + CloseableHttpResponse response = null; + try { + response = client.execute(httpGet); + HttpEntity entity = response.getEntity(); + return EntityUtils.toString(entity, "UTF-8"); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (response != null) { + try { + response.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + try { + client.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + } + + /** + * 发送普通get请求 + * + * @param url 地址 + * @param paramMap 参数 + * @return + */ + public static String httpGet(String url, Map paramMap) { + if (paramMap != null && !paramMap.isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (Map.Entry entry : paramMap.entrySet()) { + sb.append(entry.getKey()); + sb.append("="); + sb.append(entry.getValue()); + sb.append("&"); + } + url = url + "?" + sb.toString(); + } + CloseableHttpClient client = HttpClients.createDefault(); + HttpGet httpGet = new HttpGet(url); + CloseableHttpResponse response = null; + try { + response = client.execute(httpGet); + HttpEntity entity = response.getEntity(); + return EntityUtils.toString(entity, "UTF-8"); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (response != null) { + try { + response.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + try { + client.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + } + + /** + * 发送普通get请求 + * + * @param url 地址 + * @param paramMap 参数 + * @param headerMap header + * @return + */ + public static String httpGet(String url, Map paramMap, Map headerMap) { + if (paramMap != null && !paramMap.isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (Map.Entry entry : paramMap.entrySet()) { + sb.append(entry.getKey()); + sb.append("="); + sb.append(entry.getValue()); + sb.append("&"); + } + url = url + "?" + sb.toString(); + } + CloseableHttpClient client = HttpClients.createDefault(); + HttpGet httpGet = new HttpGet(url); + httpGet.setConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()); + if (headerMap != null && !headerMap.isEmpty()) { + for (Map.Entry entry : headerMap.entrySet()) { + httpGet.setHeader(entry.getKey(), (String)entry.getValue()); + } + } + CloseableHttpResponse response = null; + try { + response = client.execute(httpGet); + HttpEntity entity = response.getEntity(); + return EntityUtils.toString(entity, "UTF-8"); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (response != null) { + try { + response.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + try { + client.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + } + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/util/Util.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/util/Util.java new file mode 100644 index 0000000..117c0e2 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/dotwallet/util/Util.java @@ -0,0 +1,38 @@ +package com.aopcloud.beam.app.dotwallet.util; + +public class Util { + public static byte[] longToBytesLittle(long n) { + byte[] b = new byte[8]; + b[0] = (byte) (n & 0xff); + b[1] = (byte) (n >> 8 & 0xff); + b[2] = (byte) (n >> 16 & 0xff); + b[3] = (byte) (n >> 24 & 0xff); + b[4] = (byte) (n >> 32 & 0xff); + b[5] = (byte) (n >> 40 & 0xff); + b[6] = (byte) (n >> 48 & 0xff); + b[7] = (byte) (n >> 56 & 0xff); + return b; + } + + public static byte[] intToBytesLittle(int n) { + byte[] b = new byte[4]; + b[0] = (byte) (n & 0xff); + b[1] = (byte) (n >> 8 & 0xff); + b[2] = (byte) (n >> 16 & 0xff); + b[3] = (byte) (n >> 24 & 0xff); + return b; + } + + public static byte[] shortToBytesLittle(short n) { + byte[] b = new byte[2]; + b[0] = (byte) (n & 0xff); + b[1] = (byte) (n >> 8 & 0xff); + return b; + } + + public static byte[] byteToBytesLittle(byte n) { + byte[] b = new byte[1]; + b[0] = (byte) (n & 0xff); + return b; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/OkHttpUtils.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/OkHttpUtils.java new file mode 100644 index 0000000..74f62b0 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/OkHttpUtils.java @@ -0,0 +1,160 @@ +package com.aopcloud.beam.app.http; + +import com.aopcloud.beam.app.http.builder.*; +import com.aopcloud.beam.app.http.callback.BCallback; +import com.aopcloud.beam.app.http.request.RequestCall; +import okhttp3.Call; +import okhttp3.OkHttpClient; +import okhttp3.Response; + +import java.io.IOException; + +/** + * Created by zhy on 15/8/17. + */ +public class OkHttpUtils { + public static final long DEFAULT_MILLISECONDS = 10_000L; + private volatile static OkHttpUtils mInstance; + private OkHttpClient mOkHttpClient; + + public OkHttpUtils(OkHttpClient okHttpClient) { + if (okHttpClient == null) { + mOkHttpClient = new OkHttpClient(); + } else { + mOkHttpClient = okHttpClient; + } + + } + + + public static OkHttpUtils initClient(OkHttpClient okHttpClient) { + if (mInstance == null) { + synchronized (OkHttpUtils.class) { + if (mInstance == null) { + mInstance = new OkHttpUtils(okHttpClient); + } + } + } + return mInstance; + } + + public static OkHttpUtils getInstance() { + return initClient(null); + } + + + public static void reset() { + if (mInstance != null) { + mInstance = null; + } + } + + + public OkHttpClient getOkHttpClient() { + return mOkHttpClient; + } + + public static GetBuilder get() { + return new GetBuilder(); + } + + public static PostStringBuilder postString() { + return new PostStringBuilder(); + } + + public static PostFileBuilder postFile() { + return new PostFileBuilder(); + } + + public static PostFormBuilder post() { + return new PostFormBuilder(); + } + + public static OtherRequestBuilder put() { + return new OtherRequestBuilder(METHOD.PUT); + } + + public static HeadBuilder head() { + return new HeadBuilder(); + } + + public static OtherRequestBuilder delete() { + return new OtherRequestBuilder(METHOD.DELETE); + } + + public static OtherRequestBuilder patch() { + return new OtherRequestBuilder(METHOD.PATCH); + } + + public void execute(final RequestCall requestCall, BCallback BCallback) { + if (BCallback == null) + BCallback = BCallback.sBCallbackDefault; + final com.aopcloud.beam.app.http.callback.BCallback finalBCallback = BCallback; + final int id = requestCall.getOkHttpRequest().getId(); + + requestCall.getCall().enqueue(new okhttp3.Callback() { + @Override + public void onFailure(Call call, final IOException e) { + sendFailResultCallback(call, e, finalBCallback, id); + } + + @Override + public void onResponse(final Call call, final Response response) { + try { + if (call.isCanceled()) { + sendFailResultCallback(call, new IOException("Canceled!"), finalBCallback, id); + return; + } + + if (!finalBCallback.validateReponse(response, id)) { + sendFailResultCallback(call, new IOException("request failed , reponse's code is : " + response.code()), finalBCallback, id); + return; + } + + Object o = finalBCallback.parseNetworkResponse(response, id); + sendSuccessResultCallback(o, finalBCallback, id); + } catch (Exception e) { + sendFailResultCallback(call, e, finalBCallback, id); + } finally { + if (response.body() != null) + response.body().close(); + } + + } + }); + } + + + public void sendFailResultCallback(final Call call, final Exception e, final BCallback BCallback, final int id) { + if (BCallback == null) return; + BCallback.onError(call, e, id); + BCallback.onAfter(id); + } + + public void sendSuccessResultCallback(final Object object, final BCallback BCallback, final int id) { + if (BCallback == null) return; + BCallback.onResponse(object, id); + BCallback.onAfter(id); + } + + public void cancelTag(Object tag) { + for (Call call : mOkHttpClient.dispatcher().queuedCalls()) { + if (tag.equals(call.request().tag())) { + call.cancel(); + } + } + for (Call call : mOkHttpClient.dispatcher().runningCalls()) { + if (tag.equals(call.request().tag())) { + call.cancel(); + } + } + } + + public static class METHOD { + public static final String HEAD = "HEAD"; + public static final String DELETE = "DELETE"; + public static final String PUT = "PUT"; + public static final String PATCH = "PATCH"; + } +} + diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/GetBuilder.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/GetBuilder.java new file mode 100644 index 0000000..48209cf --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/GetBuilder.java @@ -0,0 +1,73 @@ +package com.aopcloud.beam.app.http.builder; + + +import com.aopcloud.beam.app.http.request.GetRequest; +import com.aopcloud.beam.app.http.request.RequestCall; + +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +/** + * Created by zhy on 15/12/14. + */ +public class GetBuilder extends OkHttpRequestBuilder implements HasParamsable +{ + @Override + public RequestCall build() + { + if (params != null) + { + url = appendParams(url, params); + } + + return new GetRequest(url, tag, params, headers,id).build(); + } + + protected String appendParams(String url, Map params) + { + if (url == null || params == null || params.isEmpty()) + { + return url; + } + + StringBuffer builder =new StringBuffer(); + if (!url.contains("?")){ + builder.append(url+"?"); + }else { + builder.append(url); + + } + Set keys = params.keySet(); + Iterator iterator = keys.iterator(); + while (iterator.hasNext()) + { + String key = iterator.next(); + builder.append(key+"="+params.get(key)+"&"); + } + System.out.println("url:"+builder.toString()); + return builder.toString(); + } + + + @Override + public GetBuilder params(Map params) + { + this.params = params; + return this; + } + + @Override + public GetBuilder addParams(String key, String val) + { + if (this.params == null) + { + params = new LinkedHashMap<>(); + } + params.put(key, val); + return this; + } + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/HasParamsable.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/HasParamsable.java new file mode 100644 index 0000000..7572eb3 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/HasParamsable.java @@ -0,0 +1,11 @@ +package com.aopcloud.beam.app.http.builder; + +import java.util.Map; + +/** + * Created by zhy on 16/3/1. + */ +public interface HasParamsable { + OkHttpRequestBuilder params(Map params); + OkHttpRequestBuilder addParams(String key, String val); +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/HeadBuilder.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/HeadBuilder.java new file mode 100644 index 0000000..bbd587b --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/HeadBuilder.java @@ -0,0 +1,17 @@ +package com.aopcloud.beam.app.http.builder; + +import com.aopcloud.beam.app.http.OkHttpUtils; +import com.aopcloud.beam.app.http.request.OtherRequest; +import com.aopcloud.beam.app.http.request.RequestCall; + +/** + * Created by zhy on 16/3/2. + */ +public class HeadBuilder extends GetBuilder +{ + @Override + public RequestCall build() + { + return new OtherRequest(null, null, OkHttpUtils.METHOD.HEAD, url, tag, params, headers,id).build(); + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/OkHttpRequestBuilder.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/OkHttpRequestBuilder.java new file mode 100644 index 0000000..bc46e70 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/OkHttpRequestBuilder.java @@ -0,0 +1,55 @@ +package com.aopcloud.beam.app.http.builder; + +import com.aopcloud.beam.app.http.request.RequestCall; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Created by zhy on 15/12/14. + */ +public abstract class OkHttpRequestBuilder +{ + protected String url; + protected Object tag; + protected Map headers; + protected Map params; + protected int id; + + public T id(int id) + { + this.id = id; + return (T) this; + } + + public T url(String url) + { + this.url = url; + return (T) this; + } + + + public T tag(Object tag) + { + this.tag = tag; + return (T) this; + } + + public T headers(Map headers) + { + this.headers = headers; + return (T) this; + } + + public T addHeader(String key, String val) + { + if (this.headers == null) + { + headers = new LinkedHashMap<>(); + } + headers.put(key, val); + return (T) this; + } + + public abstract RequestCall build(); +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/OtherRequestBuilder.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/OtherRequestBuilder.java new file mode 100644 index 0000000..ef12e29 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/OtherRequestBuilder.java @@ -0,0 +1,40 @@ +package com.aopcloud.beam.app.http.builder; + +import com.aopcloud.beam.app.http.request.OtherRequest; +import com.aopcloud.beam.app.http.request.RequestCall; +import okhttp3.RequestBody; + +/** + * DELETE、PUT、PATCH等其他方法 + */ +public class OtherRequestBuilder extends OkHttpRequestBuilder +{ + private RequestBody requestBody; + private String method; + private String content; + + public OtherRequestBuilder(String method) + { + this.method = method; + } + + @Override + public RequestCall build() + { + return new OtherRequest(requestBody, content, method, url, tag, params, headers,id).build(); + } + + public OtherRequestBuilder requestBody(RequestBody requestBody) + { + this.requestBody = requestBody; + return this; + } + + public OtherRequestBuilder requestBody(String content) + { + this.content = content; + return this; + } + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/PostFileBuilder.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/PostFileBuilder.java new file mode 100644 index 0000000..c74a991 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/PostFileBuilder.java @@ -0,0 +1,37 @@ +package com.aopcloud.beam.app.http.builder; + +import com.aopcloud.beam.app.http.request.PostFileRequest; +import com.aopcloud.beam.app.http.request.RequestCall; +import okhttp3.MediaType; + +import java.io.File; + +/** + * Created by zhy on 15/12/14. + */ +public class PostFileBuilder extends OkHttpRequestBuilder +{ + private File file; + private MediaType mediaType; + + + public OkHttpRequestBuilder file(File file) + { + this.file = file; + return this; + } + + public OkHttpRequestBuilder mediaType(MediaType mediaType) + { + this.mediaType = mediaType; + return this; + } + + @Override + public RequestCall build() + { + return new PostFileRequest(url, tag, params, headers, file, mediaType,id).build(); + } + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/PostFormBuilder.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/PostFormBuilder.java new file mode 100644 index 0000000..bfcb18a --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/PostFormBuilder.java @@ -0,0 +1,87 @@ +package com.aopcloud.beam.app.http.builder; + +import com.aopcloud.beam.app.http.request.PostFormRequest; +import com.aopcloud.beam.app.http.request.RequestCall; + +import java.io.File; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by zhy on 15/12/14. + */ +public class PostFormBuilder extends OkHttpRequestBuilder implements HasParamsable +{ + private List files = new ArrayList<>(); + + @Override + public RequestCall build() + { + return new PostFormRequest(url, tag, params, headers, files,id).build(); + } + + public PostFormBuilder files(String key, Map files) + { + for (String filename : files.keySet()) + { + this.files.add(new FileInput(key, filename, files.get(filename))); + } + return this; + } + + public PostFormBuilder addFile(String name, String filename, File file) + { + files.add(new FileInput(name, filename, file)); + return this; + } + + public static class FileInput + { + public String key; + public String filename; + public File file; + + public FileInput(String name, String filename, File file) + { + this.key = name; + this.filename = filename; + this.file = file; + } + + @Override + public String toString() + { + return "FileInput{" + + "key='" + key + '\'' + + ", filename='" + filename + '\'' + + ", file=" + file + + '}'; + } + } + + + + @Override + public PostFormBuilder params(Map params) + { + this.params = params; + return this; + } + + @Override + public PostFormBuilder addParams(String key, String val) + { + if (this.params == null) + { + params = new LinkedHashMap<>(); + } + params.put(key, val); + return this; + } + + + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/PostStringBuilder.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/PostStringBuilder.java new file mode 100644 index 0000000..944993c --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/builder/PostStringBuilder.java @@ -0,0 +1,35 @@ +package com.aopcloud.beam.app.http.builder; + +import com.aopcloud.beam.app.http.request.PostStringRequest; +import com.aopcloud.beam.app.http.request.RequestCall; +import okhttp3.MediaType; + +/** + * Created by zhy on 15/12/14. + */ +public class PostStringBuilder extends OkHttpRequestBuilder +{ + private String content; + private MediaType mediaType; + + + public PostStringBuilder content(String content) + { + this.content = content; + return this; + } + + public PostStringBuilder mediaType(MediaType mediaType) + { + this.mediaType = mediaType; + return this; + } + + @Override + public RequestCall build() + { + return new PostStringRequest(url, tag, params, headers, content, mediaType,id).build(); + } + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/callback/BCallback.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/callback/BCallback.java new file mode 100644 index 0000000..eecd29f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/callback/BCallback.java @@ -0,0 +1,82 @@ +package com.aopcloud.beam.app.http.callback; + +import okhttp3.Call; +import okhttp3.Request; +import okhttp3.Response; + +public abstract class BCallback +{ + /** + * UI Thread + * + * @param request + */ + public void onBefore(Request request, int id) + { + } + + /** + * UI Thread + * + * @param + */ + public void onAfter(int id) + { + } + + /** + * UI Thread + * + * @param progress + */ + public void inProgress(float progress, long total , int id) + { + + } + + /** + * if you parse reponse code in parseNetworkResponse, you should make this method return true. + * + * @param response + * @return + */ + public boolean validateReponse(Response response, int id) + { + return response.isSuccessful(); + } + + /** + * Thread Pool Thread + * + * @param response + */ + public abstract T parseNetworkResponse(Response response, int id) throws Exception; + + public abstract void onError(Call call, Exception e, int id); + + public abstract void onResponse(T response, int id); + + + public static BCallback sBCallbackDefault = new BCallback() + { + + @Override + public Object parseNetworkResponse(Response response, int id) throws Exception + { + return null; + } + + @Override + public void onError(Call call, Exception e, int id) + { + + } + + @Override + public void onResponse(Object response, int id) + { + + } + }; + +} \ No newline at end of file diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/callback/GenericsCallback.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/callback/GenericsCallback.java new file mode 100644 index 0000000..b9c5863 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/callback/GenericsCallback.java @@ -0,0 +1,30 @@ +package com.aopcloud.beam.app.http.callback; + +import okhttp3.Response; + +import java.io.IOException; +import java.lang.reflect.ParameterizedType; + +/** + * Created by JimGong on 2016/6/23. + */ + +public abstract class GenericsCallback extends BCallback { + IGenericsSerializator mGenericsSerializator; + + public GenericsCallback(IGenericsSerializator serializator) { + mGenericsSerializator = serializator; + } + + @Override + public T parseNetworkResponse(Response response, int id) throws IOException { + String string = response.body().string(); + Class entityClass = (Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; + if (entityClass == String.class) { + return (T) string; + } + T bean = mGenericsSerializator.transform(string, entityClass); + return bean; + } + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/callback/IGenericsSerializator.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/callback/IGenericsSerializator.java new file mode 100644 index 0000000..6e2c899 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/callback/IGenericsSerializator.java @@ -0,0 +1,8 @@ +package com.aopcloud.beam.app.http.callback; + +/** + * Created by JimGong on 2016/6/23. + */ +public interface IGenericsSerializator { + T transform(String response, Class classOfT); +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/callback/StringCallback.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/callback/StringCallback.java new file mode 100644 index 0000000..e2eb81b --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/callback/StringCallback.java @@ -0,0 +1,17 @@ +package com.aopcloud.beam.app.http.callback; + +import okhttp3.Response; + +import java.io.IOException; + +/** + * Created by zhy on 15/12/14. + */ +public abstract class StringCallback extends BCallback +{ + @Override + public String parseNetworkResponse(Response response, int id) throws IOException + { + return response.body().string(); + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/CountingRequestBody.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/CountingRequestBody.java new file mode 100644 index 0000000..286c81d --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/CountingRequestBody.java @@ -0,0 +1,87 @@ +package com.aopcloud.beam.app.http.request; + +import okhttp3.MediaType; +import okhttp3.RequestBody; +import okio.*; + +import java.io.IOException; + +/** + * Decorates an OkHttp request body to count the number of bytes written when writing it. Can + * decorate any request body, but is most useful for tracking the upload progress of large + * multipart requests. + * + * @author Leo Nikkilä + */ +public class CountingRequestBody extends RequestBody +{ + + protected RequestBody delegate; + protected Listener listener; + + protected CountingSink countingSink; + + public CountingRequestBody(RequestBody delegate, Listener listener) + { + this.delegate = delegate; + this.listener = listener; + } + + @Override + public MediaType contentType() + { + return delegate.contentType(); + } + + @Override + public long contentLength() + { + try + { + return delegate.contentLength(); + } catch (IOException e) + { + e.printStackTrace(); + } + return -1; + } + + @Override + public void writeTo(BufferedSink sink) throws IOException + { + + countingSink = new CountingSink(sink); + BufferedSink bufferedSink = Okio.buffer(countingSink); + + delegate.writeTo(bufferedSink); + + bufferedSink.flush(); + } + + protected final class CountingSink extends ForwardingSink + { + + private long bytesWritten = 0; + + public CountingSink(Sink delegate) + { + super(delegate); + } + + @Override + public void write(Buffer source, long byteCount) throws IOException + { + super.write(source, byteCount); + + bytesWritten += byteCount; + listener.onRequestProgress(bytesWritten, contentLength()); + } + + } + + public static interface Listener + { + public void onRequestProgress(long bytesWritten, long contentLength); + } + +} \ No newline at end of file diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/GetRequest.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/GetRequest.java new file mode 100644 index 0000000..90302cf --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/GetRequest.java @@ -0,0 +1,31 @@ +package com.aopcloud.beam.app.http.request; + +import okhttp3.Request; +import okhttp3.RequestBody; + +import java.util.Map; + +/** + * Created by zhy on 15/12/14. + */ +public class GetRequest extends OkHttpRequest +{ + public GetRequest(String url, Object tag, Map params, Map headers,int id) + { + super(url, tag, params, headers,id); + } + + @Override + protected RequestBody buildRequestBody() + { + return null; + } + + @Override + protected Request buildRequest(RequestBody requestBody) + { + return builder.get().build(); + } + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/OkHttpRequest.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/OkHttpRequest.java new file mode 100644 index 0000000..fa5249c --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/OkHttpRequest.java @@ -0,0 +1,93 @@ +package com.aopcloud.beam.app.http.request; + +import com.aopcloud.beam.app.http.callback.BCallback; +import com.aopcloud.beam.app.http.utils.Exceptions; +import okhttp3.Headers; +import okhttp3.Request; +import okhttp3.RequestBody; + +import java.util.Map; + +/** + * Created by zhy on 15/11/6. + */ +public abstract class OkHttpRequest +{ + protected String url; + protected Object tag; + protected Map params; + protected Map headers; + protected int id; + + protected Request.Builder builder = new Request.Builder(); + + protected OkHttpRequest(String url, Object tag, + Map params, Map headers,int id) + { + this.url = url; + this.tag = tag; + this.params = params; + this.headers = headers; + this.id = id ; + + if (url == null) + { + Exceptions.illegalArgument("url can not be null."); + } + + initBuilder(); + } + + + + /** + * 初始化一些基本参数 url , tag , headers + */ + private void initBuilder() + { + builder.url(url).tag(tag); + appendHeaders(); + } + + protected abstract RequestBody buildRequestBody(); + + protected RequestBody wrapRequestBody(RequestBody requestBody, final BCallback BCallback) + { + return requestBody; + } + + protected abstract Request buildRequest(RequestBody requestBody); + + public RequestCall build() + { + return new RequestCall(this); + } + + + public Request generateRequest(BCallback BCallback) + { + RequestBody requestBody = buildRequestBody(); + RequestBody wrappedRequestBody = wrapRequestBody(requestBody, BCallback); + Request request = buildRequest(wrappedRequestBody); + return request; + } + + + protected void appendHeaders() + { + Headers.Builder headerBuilder = new Headers.Builder(); + if (headers == null || headers.isEmpty()) return; + + for (String key : headers.keySet()) + { + headerBuilder.add(key, headers.get(key)); + } + builder.headers(headerBuilder.build()); + } + + public int getId() + { + return id ; + } + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/OtherRequest.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/OtherRequest.java new file mode 100644 index 0000000..b49ca7e --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/OtherRequest.java @@ -0,0 +1,73 @@ +package com.aopcloud.beam.app.http.request; + + +import com.aopcloud.beam.app.http.OkHttpUtils; +import com.aopcloud.beam.app.http.utils.Exceptions; +import okhttp3.MediaType; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.internal.http.HttpMethod; +import org.apache.commons.lang.StringUtils; + +import java.util.Map; + +/** + * Created by zhy on 16/2/23. + */ +public class OtherRequest extends OkHttpRequest +{ + private static MediaType MEDIA_TYPE_PLAIN = MediaType.parse("text/plain;charset=utf-8"); + + private RequestBody requestBody; + private String method; + private String content; + + public OtherRequest(RequestBody requestBody, String content, String method, String url, Object tag, Map params, Map headers,int id) + { + super(url, tag, params, headers,id); + this.requestBody = requestBody; + this.method = method; + this.content = content; + + } + + @Override + protected RequestBody buildRequestBody() + { + if (requestBody == null && StringUtils.isEmpty(content) && HttpMethod.requiresRequestBody(method)) + { + Exceptions.illegalArgument("requestBody and content can not be null in method:" + method); + } + + if (requestBody == null && !StringUtils.isEmpty(content)) + { + requestBody = RequestBody.create(MEDIA_TYPE_PLAIN, content); + } + + return requestBody; + } + + @Override + protected Request buildRequest(RequestBody requestBody) + { + if (method.equals(OkHttpUtils.METHOD.PUT)) + { + builder.put(requestBody); + } else if (method.equals(OkHttpUtils.METHOD.DELETE)) + { + if (requestBody == null) + builder.delete(); + else + builder.delete(requestBody); + } else if (method.equals(OkHttpUtils.METHOD.HEAD)) + { + builder.head(); + } else if (method.equals(OkHttpUtils.METHOD.PATCH)) + { + builder.patch(requestBody); + } + + return builder.build(); + } + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/PostFileRequest.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/PostFileRequest.java new file mode 100644 index 0000000..e6b37ab --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/PostFileRequest.java @@ -0,0 +1,68 @@ +package com.aopcloud.beam.app.http.request; + +import com.aopcloud.beam.app.http.callback.BCallback; +import com.aopcloud.beam.app.http.utils.Exceptions; +import okhttp3.MediaType; +import okhttp3.Request; +import okhttp3.RequestBody; + +import java.io.File; +import java.util.Map; + +/** + * Created by zhy on 15/12/14. + */ +public class PostFileRequest extends OkHttpRequest +{ + private static MediaType MEDIA_TYPE_STREAM = MediaType.parse("application/octet-stream"); + + private File file; + private MediaType mediaType; + + public PostFileRequest(String url, Object tag, Map params, Map headers, File file, MediaType mediaType,int id) + { + super(url, tag, params, headers,id); + this.file = file; + this.mediaType = mediaType; + + if (this.file == null) + { + Exceptions.illegalArgument("the file can not be null !"); + } + if (this.mediaType == null) + { + this.mediaType = MEDIA_TYPE_STREAM; + } + } + + @Override + protected RequestBody buildRequestBody() + { + return RequestBody.create(mediaType, file); + } + + @Override + protected RequestBody wrapRequestBody(RequestBody requestBody, final BCallback BCallback) + { + if (BCallback == null) return requestBody; + CountingRequestBody countingRequestBody = new CountingRequestBody(requestBody, new CountingRequestBody.Listener() + { + @Override + public void onRequestProgress(final long bytesWritten, final long contentLength) + { + BCallback.inProgress(bytesWritten * 1.0f / contentLength,contentLength,id); + + } + }); + return countingRequestBody; + } + + @Override + protected Request buildRequest(RequestBody requestBody) + { + return builder.post(requestBody).build(); + } + + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/PostFormRequest.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/PostFormRequest.java new file mode 100644 index 0000000..d97119f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/PostFormRequest.java @@ -0,0 +1,97 @@ +package com.aopcloud.beam.app.http.request; + +import com.aopcloud.beam.app.http.builder.PostFormBuilder; +import com.aopcloud.beam.app.http.callback.BCallback; +import okhttp3.*; + +import java.io.UnsupportedEncodingException; +import java.net.FileNameMap; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.util.List; +import java.util.Map; + +/** + * Created by zhy on 15/12/14. + */ +public class PostFormRequest extends OkHttpRequest { + private List files; + + public PostFormRequest(String url, Object tag, Map params, Map headers, List files, int id) { + super(url, tag, params, headers, id); + this.files = files; + } + + @Override + protected RequestBody buildRequestBody() { + if (files == null || files.isEmpty()) { + FormBody.Builder builder = new FormBody.Builder(); + addParams(builder); + FormBody formBody = builder.build(); + return formBody; + } else { + MultipartBody.Builder builder = new MultipartBody.Builder() + .setType(MultipartBody.FORM); + addParams(builder); + + for (int i = 0; i < files.size(); i++) { + PostFormBuilder.FileInput fileInput = files.get(i); + RequestBody fileBody = RequestBody.create(MediaType.parse(guessMimeType(fileInput.filename)), fileInput.file); + builder.addFormDataPart(fileInput.key, fileInput.filename, fileBody); + } + return builder.build(); + } + } + + @Override + protected RequestBody wrapRequestBody(RequestBody requestBody, final BCallback BCallback) { + if (BCallback == null) return requestBody; + CountingRequestBody countingRequestBody = new CountingRequestBody(requestBody, new CountingRequestBody.Listener() { + @Override + public void onRequestProgress(final long bytesWritten, final long contentLength) { + + BCallback.inProgress(bytesWritten * 1.0f / contentLength, contentLength, id); + + + } + }); + return countingRequestBody; + } + + @Override + protected Request buildRequest(RequestBody requestBody) { + return builder.post(requestBody).build(); + } + + private String guessMimeType(String path) { + FileNameMap fileNameMap = URLConnection.getFileNameMap(); + String contentTypeFor = null; + try { + contentTypeFor = fileNameMap.getContentTypeFor(URLEncoder.encode(path, "UTF-8")); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + if (contentTypeFor == null) { + contentTypeFor = "application/octet-stream"; + } + return contentTypeFor; + } + + private void addParams(MultipartBody.Builder builder) { + if (params != null && !params.isEmpty()) { + for (String key : params.keySet()) { + builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + key + "\""), + RequestBody.create(null, params.get(key))); + } + } + } + + private void addParams(FormBody.Builder builder) { + if (params != null) { + for (String key : params.keySet()) { + builder.add(key, params.get(key)); + } + } + } + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/PostStringRequest.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/PostStringRequest.java new file mode 100644 index 0000000..9639168 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/PostStringRequest.java @@ -0,0 +1,51 @@ +package com.aopcloud.beam.app.http.request; + +import com.aopcloud.beam.app.http.utils.Exceptions; +import okhttp3.MediaType; +import okhttp3.Request; +import okhttp3.RequestBody; + +import java.util.Map; + +/** + * Created by zhy on 15/12/14. + */ +public class PostStringRequest extends OkHttpRequest +{ + private static MediaType MEDIA_TYPE_PLAIN = MediaType.parse("text/plain;charset=utf-8"); + + private String content; + private MediaType mediaType; + + + public PostStringRequest(String url, Object tag, Map params, Map headers, String content, MediaType mediaType,int id) + { + super(url, tag, params, headers,id); + this.content = content; + this.mediaType = mediaType; + + if (this.content == null) + { + Exceptions.illegalArgument("the content can not be null !"); + } + if (this.mediaType == null) + { + this.mediaType = MEDIA_TYPE_PLAIN; + } + + } + + @Override + protected RequestBody buildRequestBody() + { + return RequestBody.create(mediaType, content); + } + + @Override + protected Request buildRequest( RequestBody requestBody) + { + return builder.post(requestBody).build(); + } + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/RequestCall.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/RequestCall.java new file mode 100644 index 0000000..32799ca --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/request/RequestCall.java @@ -0,0 +1,123 @@ +package com.aopcloud.beam.app.http.request; + +import com.aopcloud.beam.app.http.OkHttpUtils; +import com.aopcloud.beam.app.http.callback.BCallback; +import okhttp3.Call; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +/** + * Created by zhy on 15/12/15. + * 对OkHttpRequest的封装,对外提供更多的接口:cancel(),readTimeOut()... + */ +public class RequestCall +{ + private OkHttpRequest okHttpRequest; + private Request request; + private Call call; + + private long readTimeOut; + private long writeTimeOut; + private long connTimeOut; + + private OkHttpClient clone; + + public RequestCall(OkHttpRequest request) + { + this.okHttpRequest = request; + } + + public RequestCall readTimeOut(long readTimeOut) + { + this.readTimeOut = readTimeOut; + return this; + } + + public RequestCall writeTimeOut(long writeTimeOut) + { + this.writeTimeOut = writeTimeOut; + return this; + } + + public RequestCall connTimeOut(long connTimeOut) + { + this.connTimeOut = connTimeOut; + return this; + } + + public Call buildCall(BCallback BCallback) + { + request = generateRequest(BCallback); + + if (readTimeOut > 0 || writeTimeOut > 0 || connTimeOut > 0) + { + readTimeOut = readTimeOut > 0 ? readTimeOut : OkHttpUtils.DEFAULT_MILLISECONDS; + writeTimeOut = writeTimeOut > 0 ? writeTimeOut : OkHttpUtils.DEFAULT_MILLISECONDS; + connTimeOut = connTimeOut > 0 ? connTimeOut : OkHttpUtils.DEFAULT_MILLISECONDS; + + clone = OkHttpUtils.getInstance().getOkHttpClient().newBuilder() + .readTimeout(readTimeOut, TimeUnit.MILLISECONDS) + .writeTimeout(writeTimeOut, TimeUnit.MILLISECONDS) + .connectTimeout(connTimeOut, TimeUnit.MILLISECONDS) + .build(); + + call = clone.newCall(request); + } else + { + call = OkHttpUtils.getInstance().getOkHttpClient().newCall(request); + } + return call; + } + + private Request generateRequest(BCallback BCallback) + { + return okHttpRequest.generateRequest(BCallback); + } + + public void execute(BCallback BCallback) + { + buildCall(BCallback); + + if (BCallback != null) + { + BCallback.onBefore(request, getOkHttpRequest().getId()); + } + + OkHttpUtils.getInstance().execute(this, BCallback); + } + + public Call getCall() + { + return call; + } + + public Request getRequest() + { + return request; + } + + public OkHttpRequest getOkHttpRequest() + { + return okHttpRequest; + } + + public Response execute() throws IOException + { + buildCall(null); + return call.execute(); + } + + public void cancel() + { + if (call != null) + { + call.cancel(); + } + } + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/utils/Exceptions.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/utils/Exceptions.java new file mode 100644 index 0000000..a3891e1 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/utils/Exceptions.java @@ -0,0 +1,14 @@ +package com.aopcloud.beam.app.http.utils; + +/** + * Created by zhy on 15/12/14. + */ +public class Exceptions +{ + public static void illegalArgument(String msg, Object... params) + { + throw new IllegalArgumentException(String.format(msg, params)); + } + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/http/utils/L.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/utils/L.java new file mode 100644 index 0000000..46ef4bd --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/http/utils/L.java @@ -0,0 +1,19 @@ +package com.aopcloud.beam.app.http.utils; + + +/** + * Created by zhy on 15/11/6. + */ +public class L +{ + private static boolean debug = false; + + public static void e(String msg) + { + if (debug) + { + } + } + +} + diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/CoinMetadataScheduled.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/CoinMetadataScheduled.java new file mode 100644 index 0000000..4013221 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/CoinMetadataScheduled.java @@ -0,0 +1,229 @@ +package com.aopcloud.beam.app.scheduled; + + +import com.alibaba.fastjson.JSON; +import com.aopcloud.beam.app.api.app.entity.HomeBean; +import com.aopcloud.beam.app.api.app.entity.HomeCoin; +import com.aopcloud.beam.app.api.app.entity.HomeNotice; +import com.aopcloud.beam.app.api.app.service.impl.HomeCoinServiceImpl; +import com.aopcloud.beam.app.api.app.service.impl.HomeNoticeServiceImpl; +import com.aopcloud.beam.app.api.coin.entity.Coin; +import com.aopcloud.beam.app.api.coin.service.impl.CoinServiceImpl; +import com.aopcloud.beam.app.api.member.entity.Member; +import com.aopcloud.beam.app.configurer.AppContextHolder; +import com.aopcloud.beam.app.scheduled.entity.BCHMetadata; +import com.aopcloud.beam.app.scheduled.entity.BSVMetadata; +import com.aopcloud.beam.app.scheduled.entity.BTCMetadata; +import com.aopcloud.beam.app.http.OkHttpUtils; +import com.aopcloud.beam.app.http.callback.StringCallback; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.generator.config.IFileCreate; +import okhttp3.Call; +import org.apache.commons.lang.StringUtils; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + +@Configuration //1.主要用于标记配置类,兼备Component的效果。 +@EnableScheduling // 2.开启定时任务 +public class CoinMetadataScheduled { + + @Resource + private CoinServiceImpl coinService; + + @Resource + private HomeNoticeServiceImpl homeNoticeService; + +// @Scheduled(fixedDelay = 1 * 60 * 1000) + private void configureTasks() { + if (coinService == null) { + coinService = AppContextHolder.getBean(CoinServiceImpl.class); + } + if (homeNoticeService == null) { + homeNoticeService = AppContextHolder.getBean(HomeNoticeServiceImpl.class); + } + + System.err.println("执行静态定时任务 start 时间: " + LocalDateTime.now()); + getBTCMetadata(); + getBCHMetadata(); + getBSVMetadata(); + System.err.println("执行静态定时任务 end 时间: " + LocalDateTime.now()); + } + + String bsv = "https://bsv.tokenview.com/api/blocks/bchsv/1/1"; + String bch = "https://bch.tokenview.com/api/blocks/bch/1/1"; + String btc = "https://chain.api.btc.com/v3/block/latest"; + + private void getBTCMetadata() { + OkHttpUtils.get().url(btc).build().execute(new StringCallback() { + @Override + public void onError(Call call, Exception e, int id) { + + } + + @Override + public void onResponse(String response, int id) { + BTCMetadata btcMetadata = JSON.parseObject(response, BTCMetadata.class); + if (btcMetadata.getStatus().equals("success")) { + + int no = btcMetadata.getData().getHeight(); + + QueryWrapper condition = new QueryWrapper<>(); + condition.eq("notice_sn", "" + no) + .last("limit 1"); + HomeNotice notice = homeNoticeService.getBaseMapper().selectOne(new QueryWrapper() + .eq("notice_sn", "" + no).last("limit 1")); + System.out.println("sn:" + no); + if (notice == null) { + notice = new HomeNotice(); + notice.setCoinId(96); + notice.setNoticeSn("" + no); + notice.setCoinName("BTC"); + } + + notice.setRemarks(JSON.toJSONString(btcMetadata.getData())); + notice.setNoticeSource(btcMetadata.getData().getExtras().getPool_name()); + notice.setNoticeTimestamp(btcMetadata.getData().getTimestamp()); + BigDecimal decimal = new BigDecimal(0.00000001); + BigDecimal r = btcMetadata.getData().getReward_block().add(btcMetadata.getData().getReward_fees()).multiply(decimal); + notice.setProfit(r); + boolean save = homeNoticeService.saveOrUpdate(notice); + System.out.println("btc save:" + save); + QueryWrapper queryWrapper = + new QueryWrapper(); + queryWrapper + .orderByDesc("notice_timestamp") + .eq("coin_id", 96) + .last("limit 1"); + List page = homeNoticeService.getBaseMapper().selectList(queryWrapper); + System.out.println("btc getNoticeTimestamp:" + page.get(0).getNoticeTimestamp()); + Coin coin = coinService.getById(96); + coin.setReward(r); + coin.setLatestTime(page.get(0).getNoticeTimestamp()); + boolean update = coinService.updateById(coin); + System.out.println("btc update:" + update); + + + } + } + }); + } + + private void getBCHMetadata() { + OkHttpUtils.get().url(bch).build().execute(new StringCallback() { + @Override + public void onError(Call call, Exception e, int id) { + + } + + @Override + public void onResponse(String response, int id) { + BCHMetadata bchMetadata = JSON.parseObject(response, BCHMetadata.class); + if (bchMetadata.getCode() == 1) { + + String no = "" + bchMetadata.getData().get(0).getBlock_no(); + + + QueryWrapper condition = new QueryWrapper<>(); + condition.eq("notice_sn", "" + no) + .last("limit 1"); + HomeNotice notice = homeNoticeService.getBaseMapper().selectOne(new QueryWrapper() + .eq("notice_sn", "" + no).last("limit 1")); + System.out.println("sn:" + no); + if (notice == null) { + notice = new HomeNotice(); + notice.setCoinId(97); + notice.setNoticeSn(no); + notice.setCoinName("BCH"); + } + + notice.setRemarks(JSON.toJSONString(bchMetadata.getData())); + notice.setNoticeSource(!StringUtils.isEmpty(bchMetadata.getData().get(0).getMiner()) + ? bchMetadata.getData().get(0).getMiner() : "" + bchMetadata.getData().get(0).getMinerAlias()); + notice.setNoticeTimestamp(bchMetadata.getData().get(0).getTime()); + BigDecimal reward = new BigDecimal(bchMetadata.getData().get(0).getReward()); + notice.setProfit(reward); + boolean save = homeNoticeService.saveOrUpdate(notice); + QueryWrapper queryWrapper = + new QueryWrapper(); + queryWrapper + .orderByDesc("notice_timestamp") + .eq("coin_id", 97) + .last("limit 1"); + List page = homeNoticeService.getBaseMapper().selectList(queryWrapper); + System.out.println("BCH getNoticeTimestamp:" + page.get(0).getNoticeTimestamp()); + Coin coin = coinService.getById(97); + coin.setReward(reward); + coin.setLatestTime(page.get(0).getNoticeTimestamp()); + boolean update = coinService.updateById(coin); + System.out.println("BCH update:" + update); + } + + } + }); + + } + + private void getBSVMetadata() { + OkHttpUtils.get().url(bsv).build().execute(new StringCallback() { + @Override + public void onError(Call call, Exception e, int id) { + + } + + @Override + public void onResponse(String response, int id) { + BSVMetadata bsvMetadata = JSON.parseObject(response, BSVMetadata.class); + + if (bsvMetadata.getCode() == 1) { + String no = "" + bsvMetadata.getData().get(0).getBlockNo(); + + + QueryWrapper condition = new QueryWrapper<>(); + condition.eq("notice_sn", "" + no) + .last("limit 1"); + HomeNotice notice = homeNoticeService.getBaseMapper().selectOne(new QueryWrapper() + .eq("notice_sn", "" + no).last("limit 1")); + System.out.println("sn:" + no); + if (notice == null) { + notice = new HomeNotice(); + notice.setCoinId(98); + notice.setNoticeSn(no); + notice.setCoinName("BSV"); + } + notice.setRemarks(JSON.toJSONString(bsvMetadata.getData())); + notice.setNoticeSource(bsvMetadata.getData().get(0).getMiner()); + notice.setNoticeTimestamp(bsvMetadata.getData().get(0).getTime()); + BigDecimal reward = new BigDecimal(bsvMetadata.getData().get(0).getReward()); + BigDecimal fee = new BigDecimal(bsvMetadata.getData().get(0).getFee()); + notice.setProfit(BigDecimal.valueOf(reward.doubleValue() + fee.doubleValue())); + homeNoticeService.saveOrUpdate(notice); + QueryWrapper queryWrapper = + new QueryWrapper(); + queryWrapper + .orderByDesc("notice_timestamp") + .eq("coin_id", 98) + .last("limit 1"); + List page = homeNoticeService.getBaseMapper().selectList(queryWrapper); + System.out.println("BSV getNoticeTimestamp:" + page.get(0).getNoticeTimestamp()); + Coin coin = coinService.getById(98); + coin.setReward(reward); + coin.setLatestTime(page.get(0).getNoticeTimestamp()); + boolean update = coinService.updateById(coin); + System.out.println("BSV update:" + update); + } + } + }); + + } + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/CoinPriceScheduled.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/CoinPriceScheduled.java new file mode 100644 index 0000000..ba3ac4b --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/CoinPriceScheduled.java @@ -0,0 +1,88 @@ +package com.aopcloud.beam.app.scheduled; + + +import com.alibaba.fastjson.JSON; +import com.aopcloud.beam.app.api.app.entity.HomeNotice; +import com.aopcloud.beam.app.api.app.service.impl.HomeNoticeServiceImpl; +import com.aopcloud.beam.app.api.coin.entity.Coin; +import com.aopcloud.beam.app.api.coin.service.impl.CoinServiceImpl; +import com.aopcloud.beam.app.configurer.AppContextHolder; +import com.aopcloud.beam.app.scheduled.entity.BCHMetadata; +import com.aopcloud.beam.app.scheduled.entity.BSVMetadata; +import com.aopcloud.beam.app.scheduled.entity.BTCMetadata; +import com.aopcloud.beam.app.scheduled.entity.CoinCurrentPrice; +import com.aopcloud.beam.app.http.OkHttpUtils; +import com.aopcloud.beam.app.http.callback.StringCallback; +import okhttp3.Call; +import org.apache.commons.lang.StringUtils; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +@Configuration //1.主要用于标记配置类,兼备Component的效果。 +@EnableScheduling // 2.开启定时任务 +public class CoinPriceScheduled { + + @Resource + private CoinServiceImpl coinService; + + +// @Scheduled(fixedDelay = 3 * 60 * 1000) + private void configureTasks() { + if (coinService == null) { + coinService = AppContextHolder.getBean(CoinServiceImpl.class); + } + + System.err.println("执行getCoinPrice task start : " + LocalDateTime.now()); + getCoinPrice(); + System.err.println("执行getCoinPrice task end : " + LocalDateTime.now()); + } + + private void getCoinPrice() { + OkHttpUtils.get().url(coinPrice).build().execute(new StringCallback() { + @Override + public void onError(Call call, Exception e, int id) { + + } + + @Override + public void onResponse(String response, int id) { + if (StringUtils.isEmpty(response)) { + return; + } + List list = JSON.parseArray(response, CoinCurrentPrice.class); + System.out.println(list.size()+"/"+1); + + for (int i = 0; i < list.size(); i++) { + CoinCurrentPrice currentPrice = list.get(i); + System.out.println(currentPrice.getSymbol()+"/"+currentPrice.getCurrentPrice()); + BigDecimal price = new BigDecimal(currentPrice.getCurrentPrice()); + if (currentPrice.getSymbol().equals("btc")) { + Coin coin = coinService.getById(96); + coin.setCurrentPrice(price); + coinService.updateById(coin); + } else if (currentPrice.getSymbol().equals("bch")) { + Coin coin = coinService.getById(97); + coin.setCurrentPrice(price); + coinService.updateById(coin); + } else if (currentPrice.getSymbol().equals("bsv")) { + + Coin coin = coinService.getById(98); + coin.setCurrentPrice(price); + coinService.updateById(coin); + } + } + } + }); + } + + + String coinPrice = "https://api.coingecko.com/api/v3/coins/markets?vs_currency=cny&ids=bitcoin%2Cbitcoin-cash%2Cbitcoin-cash-sv&order=volume_desc&per_page=50&page=1&sparkline=false"; + + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/entity/BCHMetadata.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/entity/BCHMetadata.java new file mode 100644 index 0000000..f259268 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/entity/BCHMetadata.java @@ -0,0 +1,156 @@ +package com.aopcloud.beam.app.scheduled.entity; + +import java.util.List; + +public class BCHMetadata { + + /** + * code : 1 + * msg : 成功 + * data : [{"network":"BCH","block_no":677432,"time":1614946485,"size":1285648,"txCnt":5014,"sentValue":"72031.72457996","miner":"1AyEgvE2XNM65EkdisywrZZghHuMv1ngf8","minerAlias":"BTC.TOP","fee":"0.01775715","reward":"6.26775715","miningDifficulty":"203359846827.2519"}] + */ + + private int code; + private String msg; + private List data; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public static class DataBean { + /** + * network : BCH + * block_no : 677432 + * time : 1614946485 + * size : 1285648 + * txCnt : 5014 + * sentValue : 72031.72457996 + * miner : 1AyEgvE2XNM65EkdisywrZZghHuMv1ngf8 + * minerAlias : BTC.TOP + * fee : 0.01775715 + * reward : 6.26775715 + * miningDifficulty : 203359846827.2519 + */ + + private String network; + private long block_no; + private long time; + private int size; + private int txCnt; + private String sentValue; + private String miner; + private String minerAlias; + private String fee; + private String reward; + private String miningDifficulty; + + public String getNetwork() { + return network; + } + + public void setNetwork(String network) { + this.network = network; + } + + public long getBlock_no() { + return block_no; + } + + public void setBlock_no(int block_no) { + this.block_no = block_no; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + public int getTxCnt() { + return txCnt; + } + + public void setTxCnt(int txCnt) { + this.txCnt = txCnt; + } + + public String getSentValue() { + return sentValue; + } + + public void setSentValue(String sentValue) { + this.sentValue = sentValue; + } + + public String getMiner() { + return miner; + } + + public void setMiner(String miner) { + this.miner = miner; + } + + public String getMinerAlias() { + return minerAlias; + } + + public void setMinerAlias(String minerAlias) { + this.minerAlias = minerAlias; + } + + public String getFee() { + return fee; + } + + public void setFee(String fee) { + this.fee = fee; + } + + public String getReward() { + return reward; + } + + public void setReward(String reward) { + this.reward = reward; + } + + public String getMiningDifficulty() { + return miningDifficulty; + } + + public void setMiningDifficulty(String miningDifficulty) { + this.miningDifficulty = miningDifficulty; + } + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/entity/BSVMetadata.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/entity/BSVMetadata.java new file mode 100644 index 0000000..6cc8c5f --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/entity/BSVMetadata.java @@ -0,0 +1,165 @@ +package com.aopcloud.beam.app.scheduled.entity; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.io.Serializable; +import java.util.List; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class BSVMetadata { + + /** + * code : 1 + * msg : 成功 + * data : [{"network":"BCHSV","block_no":677818,"time":1615378689,"size":8324,"txCnt":20,"sentValue":"1.47874078","miner":"1M4CZGNmAv3o33wYoMLATJp4y4BTDe2okd","fee":"0.00005206","reward":"6.25005206","miningDifficulty":"72479703515.12497"}] + */ + + @JsonProperty("code") + private Integer code; + @JsonProperty("msg") + private String msg; + @JsonProperty("data") + private List data; + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static class DataDTO implements Serializable { + /** + * network : BCHSV + * block_no : 677818 + * time : 1615378689 + * size : 8324 + * txCnt : 20 + * sentValue : 1.47874078 + * miner : 1M4CZGNmAv3o33wYoMLATJp4y4BTDe2okd + * fee : 0.00005206 + * reward : 6.25005206 + * miningDifficulty : 72479703515.12497 + */ + + @JsonProperty("network") + private String network; + @JsonProperty("block_no") + private Integer blockNo; + @JsonProperty("time") + private long time; + @JsonProperty("size") + private Integer size; + @JsonProperty("txCnt") + private Integer txCnt; + @JsonProperty("sentValue") + private String sentValue; + @JsonProperty("miner") + private String miner; + @JsonProperty("fee") + private String fee; + @JsonProperty("reward") + private String reward; + @JsonProperty("miningDifficulty") + private String miningDifficulty; + + public String getNetwork() { + return network; + } + + public void setNetwork(String network) { + this.network = network; + } + + public Integer getBlockNo() { + return blockNo; + } + + public void setBlockNo(Integer blockNo) { + this.blockNo = blockNo; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public Integer getSize() { + return size; + } + + public void setSize(Integer size) { + this.size = size; + } + + public Integer getTxCnt() { + return txCnt; + } + + public void setTxCnt(Integer txCnt) { + this.txCnt = txCnt; + } + + public String getSentValue() { + return sentValue; + } + + public void setSentValue(String sentValue) { + this.sentValue = sentValue; + } + + public String getMiner() { + return miner; + } + + public void setMiner(String miner) { + this.miner = miner; + } + + public String getFee() { + return fee; + } + + public void setFee(String fee) { + this.fee = fee; + } + + public String getReward() { + return reward; + } + + public void setReward(String reward) { + this.reward = reward; + } + + public String getMiningDifficulty() { + return miningDifficulty; + } + + public void setMiningDifficulty(String miningDifficulty) { + this.miningDifficulty = miningDifficulty; + } + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/entity/BTCMetadata.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/entity/BTCMetadata.java new file mode 100644 index 0000000..9c5c431 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/entity/BTCMetadata.java @@ -0,0 +1,332 @@ +package com.aopcloud.beam.app.scheduled.entity; + +import java.math.BigDecimal; + +public class BTCMetadata { + + /** + * data : {"height":673204,"version":541065216,"mrkl_root":"5a34a5bae2f3a1463b38a77ce2b4057b30c58d628dddff0e1dbb925f0d418bf0","timestamp":1614914094,"bits":386725091,"nonce":3555289386,"hash":"00000000000000000007877306221210b41c20b8138761e4a7e1c10c0366132f","prev_block_hash":"00000000000000000003f297d98e495db0e90961a06ea1c2022ffa2619144dc5","next_block_hash":"0000000000000000000000000000000000000000000000000000000000000000","size":1620026,"pool_difficulty":37384380260368,"difficulty":21724134900047,"difficulty_double":2.1724134900047273E13,"tx_count":1690,"reward_block":625000000,"reward_fees":51599088,"confirmations":1,"is_orphan":false,"curr_max_timestamp":1614914094,"is_sw_block":true,"stripped_size":791175,"sigops":15613,"weight":3993551,"extras":{"pool_name":"ViaBTC","pool_link":"https://viabtc.com"}} + * err_code : 0 + * err_no : 0 + * message : success + * status : success + */ + + private DataBean data; + private int err_code; + private int err_no; + private String message; + private String status; + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public int getErr_code() { + return err_code; + } + + public void setErr_code(int err_code) { + this.err_code = err_code; + } + + public int getErr_no() { + return err_no; + } + + public void setErr_no(int err_no) { + this.err_no = err_no; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public static class DataBean { + /** + * height : 673204 + * version : 541065216 + * mrkl_root : 5a34a5bae2f3a1463b38a77ce2b4057b30c58d628dddff0e1dbb925f0d418bf0 + * timestamp : 1614914094 + * bits : 386725091 + * nonce : 3555289386 + * hash : 00000000000000000007877306221210b41c20b8138761e4a7e1c10c0366132f + * prev_block_hash : 00000000000000000003f297d98e495db0e90961a06ea1c2022ffa2619144dc5 + * next_block_hash : 0000000000000000000000000000000000000000000000000000000000000000 + * size : 1620026 + * pool_difficulty : 37384380260368 + * difficulty : 21724134900047 + * difficulty_double : 2.1724134900047273E13 + * tx_count : 1690 + * reward_block : 625000000 + * reward_fees : 51599088 + * confirmations : 1 + * is_orphan : false + * curr_max_timestamp : 1614914094 + * is_sw_block : true + * stripped_size : 791175 + * sigops : 15613 + * weight : 3993551 + * extras : {"pool_name":"ViaBTC","pool_link":"https://viabtc.com"} + */ + + private int height; + private int version; + private String mrkl_root; + private long timestamp; + private int bits; + private long nonce; + private String hash; + private String prev_block_hash; + private String next_block_hash; + private int size; + private long pool_difficulty; + private long difficulty; + private double difficulty_double; + private int tx_count; + private BigDecimal reward_block; + private BigDecimal reward_fees; + private int confirmations; + private boolean is_orphan; + private int curr_max_timestamp; + private boolean is_sw_block; + private int stripped_size; + private int sigops; + private int weight; + private ExtrasBean extras; + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getVersion() { + return version; + } + + public void setVersion(int version) { + this.version = version; + } + + public String getMrkl_root() { + return mrkl_root; + } + + public void setMrkl_root(String mrkl_root) { + this.mrkl_root = mrkl_root; + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + public int getBits() { + return bits; + } + + public void setBits(int bits) { + this.bits = bits; + } + + public long getNonce() { + return nonce; + } + + public void setNonce(long nonce) { + this.nonce = nonce; + } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + + public String getPrev_block_hash() { + return prev_block_hash; + } + + public void setPrev_block_hash(String prev_block_hash) { + this.prev_block_hash = prev_block_hash; + } + + public String getNext_block_hash() { + return next_block_hash; + } + + public void setNext_block_hash(String next_block_hash) { + this.next_block_hash = next_block_hash; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + public long getPool_difficulty() { + return pool_difficulty; + } + + public void setPool_difficulty(long pool_difficulty) { + this.pool_difficulty = pool_difficulty; + } + + public long getDifficulty() { + return difficulty; + } + + public void setDifficulty(long difficulty) { + this.difficulty = difficulty; + } + + public double getDifficulty_double() { + return difficulty_double; + } + + public void setDifficulty_double(double difficulty_double) { + this.difficulty_double = difficulty_double; + } + + public int getTx_count() { + return tx_count; + } + + public void setTx_count(int tx_count) { + this.tx_count = tx_count; + } + + public BigDecimal getReward_block() { + return reward_block; + } + + public void setReward_block(BigDecimal reward_block) { + this.reward_block = reward_block; + } + + public BigDecimal getReward_fees() { + return reward_fees; + } + + public void setReward_fees(BigDecimal reward_fees) { + this.reward_fees = reward_fees; + } + + public int getConfirmations() { + return confirmations; + } + + public void setConfirmations(int confirmations) { + this.confirmations = confirmations; + } + + public boolean isIs_orphan() { + return is_orphan; + } + + public void setIs_orphan(boolean is_orphan) { + this.is_orphan = is_orphan; + } + + public int getCurr_max_timestamp() { + return curr_max_timestamp; + } + + public void setCurr_max_timestamp(int curr_max_timestamp) { + this.curr_max_timestamp = curr_max_timestamp; + } + + public boolean isIs_sw_block() { + return is_sw_block; + } + + public void setIs_sw_block(boolean is_sw_block) { + this.is_sw_block = is_sw_block; + } + + public int getStripped_size() { + return stripped_size; + } + + public void setStripped_size(int stripped_size) { + this.stripped_size = stripped_size; + } + + public int getSigops() { + return sigops; + } + + public void setSigops(int sigops) { + this.sigops = sigops; + } + + public int getWeight() { + return weight; + } + + public void setWeight(int weight) { + this.weight = weight; + } + + public ExtrasBean getExtras() { + return extras; + } + + public void setExtras(ExtrasBean extras) { + this.extras = extras; + } + + public static class ExtrasBean { + /** + * pool_name : ViaBTC + * pool_link : https://viabtc.com + */ + + private String pool_name; + private String pool_link; + + public String getPool_name() { + return pool_name; + } + + public void setPool_name(String pool_name) { + this.pool_name = pool_name; + } + + public String getPool_link() { + return pool_link; + } + + public void setPool_link(String pool_link) { + this.pool_link = pool_link; + } + } + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/entity/CoinCurrentPrice.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/entity/CoinCurrentPrice.java new file mode 100644 index 0000000..378c52c --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/scheduled/entity/CoinCurrentPrice.java @@ -0,0 +1,302 @@ +package com.aopcloud.beam.app.scheduled.entity; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.math.BigDecimal; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class CoinCurrentPrice { + + + /** + * id : bitcoin + * symbol : btc + * name : Bitcoin + * image : https://assets.coingecko.com/coins/images/1/large/bitcoin.png?1547033579 + * current_price : 365434 + * market_cap : 6821823650257 + * market_cap_rank : 1 + * fully_diluted_valuation : 7681366350165 + * total_volume : 370389504288 + * high_24h : 365807 + * low_24h : 347374 + * price_change_24h : 9870.43 + * price_change_percentage_24h : 2.77599 + * market_cap_change_24h : 187753873850 + * market_cap_change_percentage_24h : 2.83015 + * circulating_supply : 1.8650106E7 + * total_supply : 2.1E7 + * max_supply : 2.1E7 + * ath : 380391 + * ath_change_percentage : -3.95132 + * ath_date : 2021-02-21T19:07:32.042Z + * atl : 407.23 + * atl_change_percentage : 89619.48603 + * atl_date : 2013-07-05T00:00:00.000Z + * roi : null + * last_updated : 2021-03-10T14:54:08.975Z + */ + + @JsonProperty("id") + private String id; + @JsonProperty("symbol") + private String symbol; + @JsonProperty("name") + private String name; + @JsonProperty("image") + private String image; + @JsonProperty("current_price") + private double currentPrice; + @JsonProperty("market_cap") + private Long marketCap; + @JsonProperty("market_cap_rank") + private Integer marketCapRank; + @JsonProperty("fully_diluted_valuation") + private Long fullyDilutedValuation; + @JsonProperty("total_volume") + private Long totalVolume; + @JsonProperty("high_24h") + private Integer high24h; + @JsonProperty("low_24h") + private Integer low24h; + @JsonProperty("price_change_24h") + private Double priceChange24h; + @JsonProperty("price_change_percentage_24h") + private Double priceChangePercentage24h; + @JsonProperty("market_cap_change_24h") + private Long marketCapChange24h; + @JsonProperty("market_cap_change_percentage_24h") + private Double marketCapChangePercentage24h; + @JsonProperty("circulating_supply") + private Double circulatingSupply; + @JsonProperty("total_supply") + private Double totalSupply; + @JsonProperty("max_supply") + private Double maxSupply; + @JsonProperty("ath") + private Integer ath; + @JsonProperty("ath_change_percentage") + private Double athChangePercentage; + @JsonProperty("ath_date") + private String athDate; + @JsonProperty("atl") + private Double atl; + @JsonProperty("atl_change_percentage") + private Double atlChangePercentage; + @JsonProperty("atl_date") + private String atlDate; + @JsonProperty("roi") + private Object roi; + @JsonProperty("last_updated") + private String lastUpdated; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getSymbol() { + return symbol; + } + + public void setSymbol(String symbol) { + this.symbol = symbol; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getImage() { + return image; + } + + public void setImage(String image) { + this.image = image; + } + + public double getCurrentPrice() { + return currentPrice; + } + + public void setCurrentPrice(double currentPrice) { + this.currentPrice = currentPrice; + } + + public Long getMarketCap() { + return marketCap; + } + + public void setMarketCap(Long marketCap) { + this.marketCap = marketCap; + } + + public Integer getMarketCapRank() { + return marketCapRank; + } + + public void setMarketCapRank(Integer marketCapRank) { + this.marketCapRank = marketCapRank; + } + + public Long getFullyDilutedValuation() { + return fullyDilutedValuation; + } + + public void setFullyDilutedValuation(Long fullyDilutedValuation) { + this.fullyDilutedValuation = fullyDilutedValuation; + } + + public Long getTotalVolume() { + return totalVolume; + } + + public void setTotalVolume(Long totalVolume) { + this.totalVolume = totalVolume; + } + + public Integer getHigh24h() { + return high24h; + } + + public void setHigh24h(Integer high24h) { + this.high24h = high24h; + } + + public Integer getLow24h() { + return low24h; + } + + public void setLow24h(Integer low24h) { + this.low24h = low24h; + } + + public Double getPriceChange24h() { + return priceChange24h; + } + + public void setPriceChange24h(Double priceChange24h) { + this.priceChange24h = priceChange24h; + } + + public Double getPriceChangePercentage24h() { + return priceChangePercentage24h; + } + + public void setPriceChangePercentage24h(Double priceChangePercentage24h) { + this.priceChangePercentage24h = priceChangePercentage24h; + } + + public Long getMarketCapChange24h() { + return marketCapChange24h; + } + + public void setMarketCapChange24h(Long marketCapChange24h) { + this.marketCapChange24h = marketCapChange24h; + } + + public Double getMarketCapChangePercentage24h() { + return marketCapChangePercentage24h; + } + + public void setMarketCapChangePercentage24h(Double marketCapChangePercentage24h) { + this.marketCapChangePercentage24h = marketCapChangePercentage24h; + } + + public Double getCirculatingSupply() { + return circulatingSupply; + } + + public void setCirculatingSupply(Double circulatingSupply) { + this.circulatingSupply = circulatingSupply; + } + + public Double getTotalSupply() { + return totalSupply; + } + + public void setTotalSupply(Double totalSupply) { + this.totalSupply = totalSupply; + } + + public Double getMaxSupply() { + return maxSupply; + } + + public void setMaxSupply(Double maxSupply) { + this.maxSupply = maxSupply; + } + + public Integer getAth() { + return ath; + } + + public void setAth(Integer ath) { + this.ath = ath; + } + + public Double getAthChangePercentage() { + return athChangePercentage; + } + + public void setAthChangePercentage(Double athChangePercentage) { + this.athChangePercentage = athChangePercentage; + } + + public String getAthDate() { + return athDate; + } + + public void setAthDate(String athDate) { + this.athDate = athDate; + } + + public Double getAtl() { + return atl; + } + + public void setAtl(Double atl) { + this.atl = atl; + } + + public Double getAtlChangePercentage() { + return atlChangePercentage; + } + + public void setAtlChangePercentage(Double atlChangePercentage) { + this.atlChangePercentage = atlChangePercentage; + } + + public String getAtlDate() { + return atlDate; + } + + public void setAtlDate(String atlDate) { + this.atlDate = atlDate; + } + + public Object getRoi() { + return roi; + } + + public void setRoi(Object roi) { + this.roi = roi; + } + + public String getLastUpdated() { + return lastUpdated; + } + + public void setLastUpdated(String lastUpdated) { + this.lastUpdated = lastUpdated; + } +} + diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/util/AliyunOSSUtil.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/util/AliyunOSSUtil.java new file mode 100644 index 0000000..75fc46b --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/util/AliyunOSSUtil.java @@ -0,0 +1,113 @@ +package com.aopcloud.beam.app.util; + +import com.aliyun.oss.OSS; +import com.aliyun.oss.OSSClient; +import com.aliyun.oss.OSSClientBuilder; +import com.aliyun.oss.OSSException; +import com.aliyun.oss.model.*; +import com.aopcloud.beam.app.common.OSSConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.net.URLDecoder; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.UUID; + +public class AliyunOSSUtil { + + private static AliyunOSSUtil instance = null; + + + public static AliyunOSSUtil getInstance() { + if (null == instance) { + instance = new AliyunOSSUtil(); + } + return instance; + } + + public AliyunOSSUtil() { + init(); + } + + public static String upload(File file) { + return upload(file, OSSConfig.OSS_FILE_HOST); + } + + + public static String uploadApk(File file) { + return upload(file, OSSConfig.OSS_FILE_HOST); + } + + public static String uploadImg(File file) { + return upload(file, "img"); + } + + public static String upload(File file, String path) { + Logger logger = LoggerFactory.getLogger(AliyunOSSUtil.class); + String endpoint = OSSConfig.OSS_END_POINT; + String accessKeyId = OSSConfig.OSS_ACCESS_KEY_ID; + String accessKeySecret = OSSConfig.OSS_ACCESS_KEY_SECRET; + String bucketName = OSSConfig.OSS_BUCKET_NAME; + String fileHost = path; + + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + String dateStr = format.format(new Date()); + if (null == file) { + return null; + } + OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret); + try { + //容器不存在,就创建 + if (!ossClient.doesBucketExist(bucketName)) { + ossClient.createBucket(bucketName); + CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName); + createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead); + ossClient.createBucket(createBucketRequest); + } + + //创建文件路径 + String fileUrl = fileHost + "/" + (dateStr + "/" + UUID.randomUUID().toString().replace("-", "") + "-"); + + String fileName = URLDecoder.decode(file.getName().toString(), "UTF-8").replaceAll(" ", ""); + + fileUrl = fileUrl + fileName; + //上传文件 + PutObjectResult result = ossClient.putObject(new PutObjectRequest(bucketName, fileUrl, file)); + //设置权限 这里是公开读 + ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead); + if (null != result) { + + return "https://" + bucketName + "." + endpoint + "/" + fileUrl; + } + } catch (OSSException | UnsupportedEncodingException oe) { + logger.error(oe.toString()); + } finally { + logger.error("ossClient finally"); + //关闭 + ossClient.shutdown(); + } + return null; + } + + OSS ossClient; + + private void init() { + ossClient = new OSSClientBuilder().build(OSSConfig.OSS_END_POINT, OSSConfig.OSS_ACCESS_KEY_ID, OSSConfig.OSS_ACCESS_KEY_SECRET); + + } + + + public String getFileUrl(String objectName) { + objectName = OSSConfig.OSS_IMG_PATH+objectName; + boolean found = ossClient.doesObjectExist(OSSConfig.OSS_BUCKET_NAME, objectName); + if (found) { + return OSSConfig.OSS_DOMAIN + objectName; + } + return null; + } + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/util/IdUtil.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/util/IdUtil.java new file mode 100644 index 0000000..df1ce52 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/util/IdUtil.java @@ -0,0 +1,54 @@ +package com.aopcloud.beam.app.util; + +import org.apache.commons.lang.StringUtils; + +import java.math.BigInteger; +import java.util.Random; + +public class IdUtil { + private static final long EPOCH = 1479533469598L; //开始时间,固定一个小于当前时间的毫秒数 + private static final int max12bit = 4095; + private static final long max41bit= 1099511627775L; + private static String machineId = "" ; // 机器ID + + /** + * + * 创建ID + * + * @return + * + */ + public static String create(){ + + long time = System.currentTimeMillis() - EPOCH + max41bit; + // 二进制的 毫秒级时间戳 + String base = Long.toBinaryString(time); + + // 序列数 + String randomStr = StringUtils.leftPad(Integer.toBinaryString(new Random().nextInt(max12bit)),12,'0'); + if(StringUtils.isNotEmpty(machineId)){ + machineId = StringUtils.leftPad(machineId, 10, '0'); + } + + //拼接 + String appendStr = base + machineId + randomStr; + // 转化为十进制 返回 + BigInteger bi = new BigInteger(appendStr, 2); + + return Long.valueOf(bi.toString())+""; + } + + /** + * + * 创建ID + * + * @return + * + */ + public static String genNickname(){ + + long time = System.currentTimeMillis() - EPOCH + max41bit; + // 二进制的 毫秒级时间戳 + String base = Long.toBinaryString(time); + return "算力云会员"+ base.substring(base.length()-6,base.length());} +} \ No newline at end of file diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/util/IoUtil.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/util/IoUtil.java new file mode 100644 index 0000000..f81aaa3 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/util/IoUtil.java @@ -0,0 +1,33 @@ +package com.aopcloud.beam.app.util; + +import org.springframework.util.ObjectUtils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +public class IoUtil { + /** + * reuqest body流数据转换为String + * + * @param inputStream + * @return + * @throws IOException + */ + public static String getRequestBodyStr(InputStream inputStream) throws IOException { + StringBuilder builder = new StringBuilder(); + if (!ObjectUtils.isEmpty(inputStream)) { + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + char[] charBuffer = new char[128]; + int bytesRead = -1; + while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { + builder.append(charBuffer, 0, bytesRead); + } + } else { + builder.append(""); + } + return builder.toString(); + } + +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/util/MD5Util.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/util/MD5Util.java new file mode 100644 index 0000000..e494d58 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/util/MD5Util.java @@ -0,0 +1,53 @@ +package com.aopcloud.beam.app.util; + +import java.security.MessageDigest; + +public class MD5Util { + + public final static String encrypt(String s) { + char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f' }; + try { + byte[] btInput = s.getBytes(); + // 获得MD5摘要算法的 MessageDigest 对象 + MessageDigest mdInst = MessageDigest.getInstance("MD5"); + // 使用指定的字节更新摘要 + mdInst.update(btInput); + // 获得密文 + byte[] md = mdInst.digest(); + // 把密文转换成十六进制的字符串形式 + int j = md.length; + char str[] = new char[j * 2]; + int k = 0; + for (int i = 0; i < j; i++) { + byte byte0 = md[i]; + str[k++] = hexDigits[byte0 >>> 4 & 0xf]; + str[k++] = hexDigits[byte0 & 0xf]; + } + return new String(str).toLowerCase(); + } catch (Exception e) { + return null; + } + } + + public final static String getMessageDigest(byte[] buffer) { + char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + try { + MessageDigest mdTemp = MessageDigest.getInstance("MD5"); + mdTemp.update(buffer); + byte[] md = mdTemp.digest(); + int j = md.length; + char str[] = new char[j * 2]; + int k = 0; + for (int i = 0; i < j; i++) { + byte byte0 = md[i]; + str[k++] = hexDigits[byte0 >>> 4 & 0xf]; + str[k++] = hexDigits[byte0 & 0xf]; + } + return new String(str); + } catch (Exception e) { + return null; + } + } +} + diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/util/OrderIdUtil.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/util/OrderIdUtil.java new file mode 100644 index 0000000..4242eb6 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/util/OrderIdUtil.java @@ -0,0 +1,21 @@ +package com.aopcloud.beam.app.util; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class OrderIdUtil { + + public static String createOrderSn(String memberId) { + // 当前时间 + Date date = new Date(); + // 转换格式 + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmm"); + // 格式化 + String time = simpleDateFormat.format(date); + String id = time + memberId.hashCode(); + System.out.println("生成唯一订单号" + id); + return id; + } +} diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/util/RSAUtils.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/util/RSAUtils.java new file mode 100644 index 0000000..76d64e9 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/util/RSAUtils.java @@ -0,0 +1,209 @@ +package com.aopcloud.beam.app.util; + + +import org.apache.tomcat.util.codec.binary.Base64; + +import javax.crypto.Cipher; +import java.security.*; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.HashMap; +import java.util.Map; + +public class RSAUtils { + //非对称密钥算法 + public static final String KEY_ALGORITHM = "RSA"; + + + /** + * 密钥长度,DH算法的默认密钥长度是1024 + * 密钥长度必须是64的倍数,在512到65536位之间 + */ + private static final int KEY_SIZE = 512; + //公钥 + public static final String PUBLIC_KEY = "/nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJpkSi2LFIgkbybBA+m2wmynUfi9L8NDbUKAwBvr+zr9kUTNQ/wyZt43LyfAgpkAfv0KNxli+MxdAWjX3JrAnWUCAwEAAQ=="; + + //私钥 + public static final String PRIVATE_KEY = "/nMIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAmmRKLYsUiCRvJsED6bbCbKdR+L0vw0NtQoDAG+v7Ov2RRM1D/DJm3jcvJ8CCmQB+/Qo3GWL4zF0BaNfcmsCdZQIDAQABAkBkr8sAcJdvQfOLHo1iueGJ4oS+5wJjIXH70ON4UimBih9v/OMB3ZWLCgHiTYUnzNvi0ypJC20xfujJKMxqMmaBAiEA3hrhMYa74r8o0jbaM3oNmkXYbUDZ4Z4JC2TjK5Sxqa0CIQCx9ANLUhJ91yJpOuNXZxnHzJhr4MqCOTRkwLGlMaupmQIgFMxdlB6yz2vpLa43RqTCS1UJDEoLXSZIYInFABq/fE0CIQCvf6AUE0/rTVVBhHMbCrIRKsSTd7EgNrxmNOe9rDvI2QIhALbQezLAceRsovhq56OTmV7QNy1byCz0q/LGP+E+9JKF"; + + /** + * 初始化密钥对 + * + * @return Map 甲方密钥的Map + */ + public static Map initKey() throws Exception { + //实例化密钥生成器 + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM); + //初始化密钥生成器 + keyPairGenerator.initialize(KEY_SIZE); + //生成密钥对 + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + //甲方公钥 + RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); + //甲方私钥 + RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); + //将密钥存储在map中 + Map keyMap = new HashMap(); + keyMap.put(PUBLIC_KEY, publicKey); + keyMap.put(PRIVATE_KEY, privateKey); + return keyMap; + + } + + + /** + * 私钥加密 + * + * @param data 待加密数据 + * @param key 密钥 + * @return byte[] 加密数据 + */ + public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception { + + //取得私钥 + PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key); + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + //生成私钥 + PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); + //数据加密 + Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); + cipher.init(Cipher.ENCRYPT_MODE, privateKey); + return cipher.doFinal(data); + } + + /** + * 公钥加密 + * + * @param data 待加密数据 + * @param key 密钥 + * @return byte[] 加密数据 + */ + public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception { + + //实例化密钥工厂 + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + //初始化公钥 + //密钥材料转换 + X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key); + //产生公钥 + PublicKey pubKey = keyFactory.generatePublic(x509KeySpec); + + //数据加密 + Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); + cipher.init(Cipher.ENCRYPT_MODE, pubKey); + return cipher.doFinal(data); + } + + /** + * 私钥解密 + * + * @param data 待解密数据 + * @param key 密钥 + * @return byte[] 解密数据 + */ + public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception { + //取得私钥 + PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key); + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + //生成私钥 + PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); + //数据解密 + Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + return cipher.doFinal(data); + } + + /** + * 公钥解密 + * + * @param data 待解密数据 + * @param key 密钥 + * @return byte[] 解密数据 + */ + public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception { + + //实例化密钥工厂 + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + //初始化公钥 + //密钥材料转换 + X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key); + //产生公钥 + PublicKey pubKey = keyFactory.generatePublic(x509KeySpec); + //数据解密 + Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); + cipher.init(Cipher.DECRYPT_MODE, pubKey); + return cipher.doFinal(data); + } + + /** + * 取得私钥 + * + * @param keyMap 密钥map + * @return byte[] 私钥 + */ + public static byte[] getPrivateKey(Map keyMap) { + Key key = (Key) keyMap.get(PRIVATE_KEY); + return key.getEncoded(); + } + + /** + * 取得公钥 + * + * @param keyMap 密钥map + * @return byte[] 公钥 + */ + public static byte[] getPublicKey(Map keyMap) throws Exception { + Key key = (Key) keyMap.get(PUBLIC_KEY); + return key.getEncoded(); + } + + /** + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + //初始化密钥 + //生成密钥对 + Map keyMap = RSAUtils.initKey(); + //公钥 + byte[] publicKey = RSAUtils.getPublicKey(keyMap); + + //私钥 + byte[] privateKey = RSAUtils.getPrivateKey(keyMap); + System.out.println("公钥:/n" + Base64.encodeBase64String(publicKey)); + System.out.println("私钥:/n" + Base64.encodeBase64String(privateKey)); + + System.out.println("================密钥对构造完毕,甲方将公钥公布给乙方,开始进行加密数据的传输============="); + String str = "RSA密码交换算法"; + System.out.println("/n===========甲方向乙方发送加密数据=============="); + System.out.println("原文:" + str); + //甲方进行数据的加密 + byte[] code1 = RSAUtils.encryptByPrivateKey(str.getBytes(), privateKey); + System.out.println("加密后的数据:" + Base64.encodeBase64String(code1)); + System.out.println("===========乙方使用甲方提供的公钥对数据进行解密=============="); + //乙方进行数据的解密 + byte[] decode1 = RSAUtils.decryptByPublicKey(code1, publicKey); + System.out.println("乙方解密后的数据:" + new String(decode1) + "/n/n"); + + System.out.println("===========反向进行操作,乙方向甲方发送数据==============/n/n"); + + str = "乙方向甲方发送数据RSA算法"; + + System.out.println("原文:" + str); + + //乙方使用公钥对数据进行加密 + byte[] code2 = RSAUtils.encryptByPublicKey(str.getBytes(), publicKey); + System.out.println("===========乙方使用公钥对数据进行加密=============="); + System.out.println("加密后的数据:" + Base64.encodeBase64String(code2)); + + System.out.println("=============乙方将数据传送给甲方======================"); + System.out.println("===========甲方使用私钥对数据进行解密=============="); + + //甲方使用私钥对数据进行解密 + byte[] decode2 = RSAUtils.decryptByPrivateKey(code2, privateKey); + + System.out.println("甲方解密后的数据:" + new String(decode2)); + } +} \ No newline at end of file diff --git a/sliyun-app/src/main/java/com/aopcloud/beam/app/util/RegUtil.java b/sliyun-app/src/main/java/com/aopcloud/beam/app/util/RegUtil.java new file mode 100644 index 0000000..d763aa9 --- /dev/null +++ b/sliyun-app/src/main/java/com/aopcloud/beam/app/util/RegUtil.java @@ -0,0 +1,282 @@ +package com.aopcloud.beam.app.util; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class RegUtil { + /** + * 验证身份证号码 + * + * @param idCard 居民身份证号码15位或18位,最后一位可能是数字或字母 + * @return 验证成功返回true,验证失败返回false + */ + public static boolean checkIdCard(String idCard) { + String regex = "[1-9]\\d{13,16}[a-zA-Z0-9]{1}"; + return Pattern.matches(regex, idCard); + } + + /** + * 验证手机号码(支持国际格式,+86135xxxx...(中国内地),+00852137xxxx...(中国香港)) + * + * @param mobile 移动、联通、电信运营商的号码段 + *

移动的号段:134(0-8)、135、136、137、138、139、147(预计用于TD上网卡) + * 、150、151、152、157(TD专用)、158、159、187(未启用)、188(TD专用)

+ *

联通的号段:130、131、132、155、156(世界风专用)、185(未启用)、186(3g)

+ *

电信的号段:133、153、180(未启用)、189

+ * @return 验证成功返回true,验证失败返回false + */ + public static boolean checkMobile(String mobile) { + String regex = "(\\+\\d+)?1[23456789]\\d{9}$"; + return Pattern.matches(regex, mobile); + } + + /** + * 验证固定电话号码 + * + * @param phone 电话号码,格式:国家(地区)电话代码 + 区号(城市代码) + 电话号码,如:+8602085588447 + *

国家(地区) 代码 :标识电话号码的国家(地区)的标准国家(地区)代码。它包含从 0 到 9 的一位或多位数字, + * 数字之后是空格分隔的国家(地区)代码。

+ *

区号(城市代码):这可能包含一个或多个从 0 到 9 的数字,地区或城市代码放在圆括号—— + * 对不使用地区或城市代码的国家(地区),则省略该组件。

+ *

电话号码:这包含从 0 到 9 的一个或多个数字

+ * @return 验证成功返回true,验证失败返回false + */ + public static boolean checkPhone(String phone) { + String regex = "(\\+\\d+)?(\\d{3,4}\\-?)?\\d{7,8}$"; + return Pattern.matches(regex, phone); + } + + /** + * 验证整数(正整数和负整数) + * + * @param digit 一位或多位0-9之间的整数 + * @return 验证成功返回true,验证失败返回false + */ + public static boolean checkDigit(String digit) { + String regex = "\\-?[1-9]\\d+"; + return Pattern.matches(regex, digit); + } + + /** + * 验证整数和浮点数(正负整数和正负浮点数) + * + * @param decimals 一位或多位0-9之间的浮点数,如:1.23,233.30 + * @return 验证成功返回true,验证失败返回false + */ + public static boolean checkDecimals(String decimals) { + String regex = "\\-?[1-9]\\d+(\\.\\d+)?"; + return Pattern.matches(regex, decimals); + } + + /** + * 验证空白字符 + * + * @param blankSpace 空白字符,包括:空格、\t、\n、\r、\f、\x0B + * @return 验证成功返回true,验证失败返回false + */ + public static boolean checkBlankSpace(String blankSpace) { + String regex = "\\s+"; + return Pattern.matches(regex, blankSpace); + } + + /** + * 验证中文 + * + * @param chinese 中文字符 + * @return 验证成功返回true,验证失败返回false + */ + public static boolean checkChinese(String chinese) { + String regex = "^[\u4E00-\u9FA5]+$"; + return Pattern.matches(regex, chinese); + } + + /** + * 验证日期(年月日) + * + * @param birthday 日期,格式:1992-09-03,或1992.09.03 + * @return 验证成功返回true,验证失败返回false + */ + public static boolean checkBirthday(String birthday) { + String regex = "[1-9]{4}([-./])\\d{1,2}\\1\\d{1,2}"; + return Pattern.matches(regex, birthday); + } + + /** + * 验证URL地址 + * + * @param url 格式:http://blog.csdn.net:80/xyang81/article/details/7705960? 或 http://www.csdn.net:80 + * @return 验证成功返回true,验证失败返回false + */ + public static boolean checkURL(String url) { + String regex = "(http|https?://(w{3}\\.)?)?\\w+\\.\\w+(\\.[a-zA-Z]+)*(:\\d{1,5})?(/\\w*)*(\\??(.+=.*)?(&.+=.*)?)?"; + return Pattern.matches(regex, url); + } + + /** + * 匹配中国邮政编码 + * + * @param postcode 邮政编码 + * @return 验证成功返回true,验证失败返回false + */ + public static boolean checkPostcode(String postcode) { + String regex = "[1-9]\\d{5}"; + return Pattern.matches(regex, postcode); + } + + /** + * 匹配IP地址(简单匹配,格式,如:192.168.1.1,127.0.0.1,没有匹配IP段的大小) + * + * @param ipAddress IPv4标准地址 + * @return 验证成功返回true,验证失败返回false + */ + public static boolean checkIpAddress(String ipAddress) { + String regex = "[1-9](\\d{1,2})?\\.(0|([1-9](\\d{1,2})?))\\.(0|([1-9](\\d{1,2})?))\\.(0|([1-9](\\d{1,2})?))"; + return Pattern.matches(regex, ipAddress); + } + private static Pattern numericPattern = Pattern.compile("^[0-9\\-]+$"); + private static Pattern numericStringPattern = Pattern.compile("^[0-9\\-\\-]+$"); + private static Pattern floatNumericPattern = Pattern.compile("^[0-9\\-\\.]+$"); + private static Pattern abcPattern = Pattern.compile("^[a-z|A-Z]+$"); + + + public static final String splitStrPattern = ",|,|;|;|、|\\.|。|-|_|\\(|\\)|\\[|\\]|\\{|\\}|\\\\|/| | |\""; + /** + * 判断是否数字表示 + * + * @param src 源字符串 + * @return 是否数字的标志 + */ + public static boolean isNumeric(String src) { + boolean return_value = false; + if (src != null && src.length() > 0) { + Matcher m = numericPattern.matcher(src); + if (m.find()) { + return_value = true; + } + } + return return_value; + } + + /** + * 判断是否纯字母组合 + * + * @param src 源字符串 + * @return 是否纯字母组合的标志 + */ + public static boolean isABC(String src) { + boolean return_value = false; + if (src != null && src.length() > 0) { + Matcher m = abcPattern.matcher(src); + if (m.find()) { + return_value = true; + } + } + return return_value; + } + + /** + * 判断是否数字表示 + * + * @param src 源字符串 + * @return 是否数字的标志 + */ + public static boolean isNumericString(String src) { + boolean return_value = false; + if (src != null && src.length() > 0) { + Matcher m = numericStringPattern.matcher(src); + if (m.find()) { + return_value = true; + } + } + return return_value; + } + /** + * 判断是否浮点数字表示 + * + * @param src 源字符串 + * @return 是否数字的标志 + */ + public static boolean isFloatNumeric(String src) { + boolean return_value = false; + if (src != null && src.length() > 0) { + Matcher m = floatNumericPattern.matcher(src); + if (m.find()) { + return_value = true; + } + } + return return_value; + } + + /** + * 判断字符串str是否符合正则表达式reg + * @param str + * @param reg + * @return + */ + public static boolean isMatche(String str,String reg){ + Pattern pattern = Pattern.compile(reg); + Matcher isNum = pattern.matcher(str); + if( !isNum.matches() ){ + return false; + } + return true; + } + + /** + * 获取符合reg正则表达式的字符串在String中出现的次数 + * + * @param str + * @param reg + * @return + */ + public static int countSubStrReg(String str, String reg) { + Pattern p = Pattern.compile(reg); + Matcher m = p.matcher(str); + int i = 0; + while (m.find()) { + String temp = m.group(0); + i += temp.length(); + } + return i; + } + + /** + * @param str + * @return + * @Method:判断是否是整数 + */ + public static boolean isInteger(String str) { + String reg = "^[-\\+]?[\\d]+$"; + Pattern pattern = Pattern.compile(reg); + return pattern.matcher(str).matches(); + } + + + /** + * @param email + * @return + * @Method:判断是否是符合邮箱 + */ + public static boolean isEmail(String email) { + if (email == null || email.length() < 1 || email.length() > 256) { + return false; + } + String reg = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$"; + Pattern pattern = Pattern + .compile(reg); + return pattern.matcher(email).matches(); + } + + /** + * is url + * + * @return + */ + public static boolean isUrl(String url) { + String reg ="^([hH][tT]{2}[pP]://|[hH][tT]{2}[pP][sS]://)(([A-Za-z0-9-~]+).)+([A-Za-z0-9-~\\/])+$"; + Pattern pattern = Pattern.compile(reg); + return pattern.matcher(url).matches(); + } + +} + diff --git a/sliyun-app/src/main/resources/application-dev.properties b/sliyun-app/src/main/resources/application-dev.properties new file mode 100644 index 0000000..ddf06a8 --- /dev/null +++ b/sliyun-app/src/main/resources/application-dev.properties @@ -0,0 +1,11 @@ +# 开发环境配置 +# 数据源配置,请修改为你项目的实际配置 +spring.datasource.url=jdbc:mysql://rm-wz99smt6zjv8tt10x1250109m.mysql.rds.aliyuncs.com:3306/live_solution?characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false +spring.datasource.username=live_solution +spring.datasource.password=Nf46KD8MCTN3jWKZ +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver + +#mybatis-plus配置控制台打印完整带参数SQL语句 +mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl +mybatis-plus.global-config.db-config.capital-mode=true +logging.level.com.baomidou.mybatisplus=debug \ No newline at end of file diff --git a/sliyun-app/src/main/resources/application-prod.properties b/sliyun-app/src/main/resources/application-prod.properties new file mode 100644 index 0000000..32a540d --- /dev/null +++ b/sliyun-app/src/main/resources/application-prod.properties @@ -0,0 +1 @@ +# 生产环境配置 diff --git a/sliyun-app/src/main/resources/application-test.properties b/sliyun-app/src/main/resources/application-test.properties new file mode 100644 index 0000000..287da7b --- /dev/null +++ b/sliyun-app/src/main/resources/application-test.properties @@ -0,0 +1 @@ +# 测试环境配置 diff --git a/sliyun-app/src/main/resources/application.properties b/sliyun-app/src/main/resources/application.properties new file mode 100644 index 0000000..fb0d5e2 --- /dev/null +++ b/sliyun-app/src/main/resources/application.properties @@ -0,0 +1,45 @@ +# 开发环境配置 +# 数据源配置,请修改为你项目的实际配置 +spring.datasource.url=jdbc:mysql://rm-wz99smt6zjv8tt10x1250109m.mysql.rds.aliyuncs.com:3306/sliyun?characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false +spring.datasource.username=live_solution +spring.datasource.password=Nf46KD8MCTN3jWKZ +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +druid.mysql.usePingMethod=false +#mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl + +# 自定义404 +#出现错误时, 直接抛出异常 +spring.mvc.throw-exception-if-no-handler-found=true +spring.mvc.throwExceptionIfNoHandlerFound=true +#不要为我们工程中的资源文件建立映射 +spring.resources.add-mappings=false + + +server.servlet.context-path= /v1 +spring.devtools.restart.enabled=true + + + +spring.jackson.date-formate=yyyy-MM-dd HH:mm:ss +spring.jackson.time-zone=GMT+8 +spring.jackson.serialization.write-dates-as-timestamps=true + + +server.port=8892 + +#永兴支付 + +xy.pay.appid=yx4c873e2a84e94ff0 +xy.pay.key=5a2ebc17213243b4a22f9053cb4d7637 +xy.pay.order.create-url=http://m.kfj188.com/MyBank/Handler/addPayChannelRecord.ashx +xy.pay.order.query-url=http://m.kfj188.com/MyBank/Handler/queryPayChannelRecord.ashx +xy.pay.notify-url=http://mapi.sliyun.cn/v1/notify/pay/yx + + +#OSS suanliyun@dev-cloud.onaliyun.com +#OSS suanliyun@dev-cloud.onaliyun.com +oss.file.endpoint=oss-cn-shenzhen.aliyuncs.com +oss.file.keyid=LTAI4Fzx7TLLrN9UegkH6kxT +oss.file.keysecret=5bEch3N7yWRDCudGvtfrh7pwaMIQO1 +oss.file.filehost= +oss.file.bucketname=suanlicloud \ No newline at end of file diff --git a/sliyun-app/src/main/resources/banner.txt b/sliyun-app/src/main/resources/banner.txt new file mode 100644 index 0000000..15b45aa --- /dev/null +++ b/sliyun-app/src/main/resources/banner.txt @@ -0,0 +1,26 @@ +//////////////////////////////////////////////////////////////////// +// _ooOoo_ // +// o8888888o // +// 88" . "88 // +// (| ^_^ |) // +// O\ = /O // +// ____/`---'\____ // +// .' \\| |// `. // +// / \\||| : |||// \ // +// / _||||| -:- |||||- \ // +// | | \\\ - /// | | // +// | \_| ''\---/'' | | // +// \ .-\__ `-` ___/-. / // +// ___`. .' /--.--\ `. . ___ // +// ."" '< `.___\_<|>_/___.' >'"". // +// | | : `- \`.;`\ _ /`;.`/ - ` : | | // +// \ \ `-. \_ __\ /__ _/ .-` / / // +// ========`-.____`-.___\_____/___.-`____.-'======== // +// `=---=' // +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // +// 佛祖保佑 永不宕机 永无BUG // +//////////////////////////////////////////////////////////////////// +application.version: ${application.version} +application.formatted-version: ${application.formatted-version} +springboot -version: ${spring-boot.version} +springboot-formatted-version: ${spring-boot.formatted-version} \ No newline at end of file diff --git a/sliyun-app/src/test/java/com/aopcloud/beam/app/BeamAppApplicationTests.java b/sliyun-app/src/test/java/com/aopcloud/beam/app/BeamAppApplicationTests.java new file mode 100644 index 0000000..f2386d4 --- /dev/null +++ b/sliyun-app/src/test/java/com/aopcloud/beam/app/BeamAppApplicationTests.java @@ -0,0 +1,13 @@ +package com.aopcloud.beam.app; + +import org.junit.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class BeamAppApplicationTests { + + @Test + void contextLoads() { + } + +}