From 16f9f82db40e5d7ee23a51ad362b470da56906e1 Mon Sep 17 00:00:00 2001 From: zpc Date: Wed, 23 Apr 2025 19:20:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=A1=B9=E7=9B=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 30 + ChouBox.Code/AppExtend/ChouBoxCodeBase.cs | 224 + ChouBox.Code/ChouBox.Code.csproj | 24 + .../Contract/ISendVerificationCode.cs | 22 + ChouBox.Code/GlobalUsings.cs | 2 + ChouBox.Code/Goods/GoodsBLL.cs | 26 + .../SignatureVerifyMiddleware.cs | Bin 0 -> 24342 bytes .../SignatureVerifyMiddlewareExtensions.cs | 20 + ChouBox.Code/Other/SMSBLL.cs | 59 + .../Model/TencentBaseConfig.cs | 22 + .../Model/TencentSMSConfig.cs | 37 + .../TencentSMSSendVerificationCode.cs | 140 + ChouBox.Model/ChouBox.Model.csproj | 23 + ChouBox.Model/Class1.cs | 7 + .../CodeTemplates/EFCore/DbContext.t4 | 363 ++ .../CodeTemplates/EFCore/EntityType.t4 | 173 + ChouBox.Model/Entities/Admin.cs | 64 + ChouBox.Model/Entities/AdminGoodsLog.cs | 35 + ChouBox.Model/Entities/AdminLoginLog.cs | 27 + ChouBox.Model/Entities/AdminOperationLog.cs | 34 + ChouBox.Model/Entities/AdminQuanxian.cs | 27 + ChouBox.Model/Entities/Ads.cs | 31 + ChouBox.Model/Entities/Advert.cs | 54 + ChouBox.Model/Entities/AdvertType.cs | 13 + ChouBox.Model/Entities/CardLevel.cs | 29 + ChouBox.Model/Entities/Category.cs | 32 + ChouBox.Model/Entities/Code.cs | 40 + ChouBox.Model/Entities/Collect.cs | 34 + ChouBox.Model/Entities/Config.cs | 13 + ChouBox.Model/Entities/Coupon.cs | 57 + ChouBox.Model/Entities/CouponReceive.cs | 56 + ChouBox.Model/Entities/Danye.cs | 37 + ChouBox.Model/Entities/Delivery.cs | 22 + ChouBox.Model/Entities/ErrorLog.cs | 15 + ChouBox.Model/Entities/FloatBallConfig.cs | 105 + ChouBox.Model/Entities/Give.cs | 28 + ChouBox.Model/Entities/Goods.cs | 299 + ChouBox.Model/Entities/GoodsExtend.cs | 50 + ChouBox.Model/Entities/GoodsExtendList.cs | 42 + ChouBox.Model/Entities/GoodsKingRank.cs | 43 + ChouBox.Model/Entities/GoodsList.cs | 156 + ChouBox.Model/Entities/GoodsLock.cs | 29 + ChouBox.Model/Entities/GoodsOffshelfLog.cs | 42 + ChouBox.Model/Entities/GoodsType.cs | 82 + ChouBox.Model/Entities/ItemCard.cs | 39 + ChouBox.Model/Entities/KkOrder.cs | 79 + ChouBox.Model/Entities/KkOrderGood.cs | 67 + ChouBox.Model/Entities/KkOrderSend.cs | 54 + ChouBox.Model/Entities/KkProduct.cs | 82 + ChouBox.Model/Entities/KkProductCate.cs | 47 + ChouBox.Model/Entities/KkProductCategory.cs | 47 + ChouBox.Model/Entities/KkProductSpec.cs | 52 + ChouBox.Model/Entities/KkSeckill.cs | 32 + ChouBox.Model/Entities/KkShare.cs | 32 + ChouBox.Model/Entities/Market.cs | 42 + ChouBox.Model/Entities/MarketOrder.cs | 61 + ChouBox.Model/Entities/Migrations.cs | 17 + ChouBox.Model/Entities/NotifyLog.cs | 15 + ChouBox.Model/Entities/Order.cs | 176 + ChouBox.Model/Entities/OrderList.cs | 159 + ChouBox.Model/Entities/OrderListRecovery.cs | 34 + ChouBox.Model/Entities/OrderListSend.cs | 117 + ChouBox.Model/Entities/Picture.cs | 25 + ChouBox.Model/Entities/ProfitDraw.cs | 49 + ChouBox.Model/Entities/ProfitExpenses.cs | 45 + ChouBox.Model/Entities/ProfitIntegral.cs | 49 + ChouBox.Model/Entities/ProfitMoney.cs | 49 + ChouBox.Model/Entities/ProfitMoney2.cs | 49 + ChouBox.Model/Entities/ProfitOuQi.cs | 44 + ChouBox.Model/Entities/ProfitPay.cs | 42 + ChouBox.Model/Entities/ProfitRevenue.cs | 55 + ChouBox.Model/Entities/ProfitScore.cs | 49 + ChouBox.Model/Entities/QuanYiLevel.cs | 27 + ChouBox.Model/Entities/QuanYiLevelJiang.cs | 83 + ChouBox.Model/Entities/RankMonth.cs | 46 + ChouBox.Model/Entities/RankWeek.cs | 46 + ChouBox.Model/Entities/Reward.cs | 41 + ChouBox.Model/Entities/Shang.cs | 25 + ChouBox.Model/Entities/SignConfig.cs | 56 + ChouBox.Model/Entities/TaskList.cs | 53 + ChouBox.Model/Entities/User.cs | 133 + ChouBox.Model/Entities/UserAccount.cs | 44 + ChouBox.Model/Entities/UserCoupon.cs | 94 + ChouBox.Model/Entities/UserGoodsLianJi.cs | 27 + ChouBox.Model/Entities/UserItemCard.cs | 42 + ChouBox.Model/Entities/UserLoginIp.cs | 29 + ChouBox.Model/Entities/UserLoginLog.cs | 60 + ChouBox.Model/Entities/UserPosterCache.cs | 65 + .../Entities/UserQuanYiLevelJiang.cs | 87 + ChouBox.Model/Entities/UserRage.cs | 27 + ChouBox.Model/Entities/UserRecharge.cs | 42 + ChouBox.Model/Entities/UserSign.cs | 65 + ChouBox.Model/Entities/UserStatistics.cs | 110 + ChouBox.Model/Entities/UserTaskList.cs | 47 + ChouBox.Model/Entities/UserVip.cs | 42 + ChouBox.Model/Entities/WelfareHouse.cs | 47 + ChouBox.Model/Entities/Withdraw.cs | 74 + ChouBox.Model/Entities/WxpayLog.cs | 33 + ChouBox.Model/Entities/YoudaContext.cs | 4975 +++++++++++++++++ ChouBox.Model/Entities/Yushou.cs | 44 + ChouBox.Model/efcore-gen.md | 12 + ChouBox.WebApi/ChouBox.WebApi.csproj | 26 + ChouBox.WebApi/ChouBox.WebApi.http | 6 + .../Controllers/AccountController.cs | 33 + ChouBox.WebApi/Controllers/GoodsController.cs | 11 + .../Controllers/WeatherForecastController.cs | 46 + ChouBox.WebApi/Dockerfile | 32 + ChouBox.WebApi/Filters/ResultFormatFilter.cs | 81 + .../Middleware/ResponseFormatterMiddleware.cs | 117 + ChouBox.WebApi/Program.cs | 118 + ChouBox.WebApi/Properties/launchSettings.json | 52 + ChouBox.WebApi/WeatherForecast.cs | 13 + ChouBox.WebApi/appsettings.Development.json | 12 + ChouBox.WebApi/appsettings.json | 21 + ChouBox.sln | 48 + .../AttributeExtend/ImagesAttribute.cs | 26 + .../AttributeExtend/MessageAttribute.cs | 29 + Utile/HuanMeng.DotNetCore/Base/BLLBase.cs | 27 + .../HuanMeng.DotNetCore/Base/BaseResponse.cs | 102 + Utile/HuanMeng.DotNetCore/Base/DaoBase.cs | 32 + .../HuanMeng.DotNetCore/Base/EfCoreDaoBase.cs | 162 + Utile/HuanMeng.DotNetCore/Base/IResponse.cs | 22 + Utile/HuanMeng.DotNetCore/Base/MessageBox.cs | 126 + .../HuanMeng.DotNetCore/Base/ResponseCode.cs | 94 + .../Base/ResultWithMessage.cs | 44 + .../CacheHelper/CommonDataEntityCache.cs | 228 + .../CacheHelper/Contract/ICacheClearData.cs | 20 + .../Contract/ICacheClearLocalData.cs | 19 + .../CacheHelper/Contract/ICacheReloadData.cs | 19 + .../CacheHelper/MemoryCacheHelper.cs | 55 + .../CustomExtension/CorsExtension.cs | 33 + .../Extensions/ControllerExtensions.cs | 34 + .../Extensions/HttpContextExtensions.cs | 48 + .../HuanMeng.DotNetCore.csproj | 31 + .../Json/CustomDateTimeConverter.cs | 30 + .../Interface/IJwtAuthManager.cs | 55 + .../JwtInfrastructure/JwtAuthManager.cs | 168 + .../JwtInfrastructure/JwtAuthResult.cs | 27 + .../JwtInfrastructure/JwtManager.cs | 167 + .../JwtInfrastructure/JwtRefreshToken.cs | 33 + .../JwtInfrastructure/JwtTokenConfig.cs | 47 + .../MiddlewareExtend/ExceptionMiddleware.cs | 64 + .../ExecutionTimeMiddleware.cs | 26 + .../MiddlewareExtend/MiddlewareExtends.cs | 54 + .../MiddlewareExtend/SignBaseMiddleware.cs | 101 + .../MultiTenant/Contract/IMultiTenant.cs | 19 + .../Contract/IMultiTenantDbContext.cs | 19 + .../Contract/IMultiTenantEntity.cs | 15 + .../MultiTenant/Contract/ITenantInfo.cs | 24 + .../MultiTenant/MultiTenantDbContext.cs | 101 + .../MultiTenant/MultiTenantEntity.cs | 22 + .../MultiTenant/TenantInfo.cs | 38 + .../Processors/BaseProcessor.cs | 58 + .../Processors/ITaskProcessor.cs | 18 + .../Processors/ThreadProcessor.cs | 81 + .../QuartzExtend/QuartzExtensions.cs | 68 + .../QuartzExtend/QuartzTriggerAttribute.cs | 53 + .../Redis/RedisConnection.cs | 336 ++ .../HuanMeng.DotNetCore/Redis/RedisHelper.cs | 39 + .../SwaggerUtile/LowercaseParameterFilter.cs | 59 + .../TextCensor/CheckTextVerification.cs | 157 + .../TextCensor/ITextCensor.cs | 28 + .../SensitiveWord/SensitiveWordFilter.cs | 145 + .../SensitiveWordFilterFrozen.cs | 149 + .../TextCensor/TextCensorExtend.cs | 122 + .../Utility/AssemblyHelper/AssemblyInfo.cs | 55 + .../AssemblyHelper/AssemblyInfoHelper.cs | 39 + .../Utility/DateTimeExtensions.cs | 32 + .../Utility/HttpContextExtensions.cs | 64 + .../Utility/HttpRequestMessageExtensions.cs | 28 + .../Utility/HttpResponseMessageExtensions.cs | 40 + .../Utility/MD5Encryption.cs | 43 + .../Utility/ObjectExtensions.cs | 168 + .../Utility/OtherExtensions.cs | 133 + .../Utility/PhoneNumberValidator.cs | 25 + .../Utility/StringExtend.cs | 36 + .../HuanMeng.DotNetCore/WeChat/MiniProgram.cs | 148 + .../WeChat/WXBizDataCrypt.cs | 124 + 178 files changed, 15777 insertions(+) create mode 100644 .dockerignore create mode 100644 ChouBox.Code/AppExtend/ChouBoxCodeBase.cs create mode 100644 ChouBox.Code/ChouBox.Code.csproj create mode 100644 ChouBox.Code/Contract/ISendVerificationCode.cs create mode 100644 ChouBox.Code/GlobalUsings.cs create mode 100644 ChouBox.Code/Goods/GoodsBLL.cs create mode 100644 ChouBox.Code/MiddlewareExtend/SignatureVerifyMiddleware.cs create mode 100644 ChouBox.Code/MiddlewareExtend/SignatureVerifyMiddlewareExtensions.cs create mode 100644 ChouBox.Code/Other/SMSBLL.cs create mode 100644 ChouBox.Code/TencentCloudExtend/Model/TencentBaseConfig.cs create mode 100644 ChouBox.Code/TencentCloudExtend/Model/TencentSMSConfig.cs create mode 100644 ChouBox.Code/TencentCloudExtend/TencentSMSSendVerificationCode.cs create mode 100644 ChouBox.Model/ChouBox.Model.csproj create mode 100644 ChouBox.Model/Class1.cs create mode 100644 ChouBox.Model/CodeTemplates/EFCore/DbContext.t4 create mode 100644 ChouBox.Model/CodeTemplates/EFCore/EntityType.t4 create mode 100644 ChouBox.Model/Entities/Admin.cs create mode 100644 ChouBox.Model/Entities/AdminGoodsLog.cs create mode 100644 ChouBox.Model/Entities/AdminLoginLog.cs create mode 100644 ChouBox.Model/Entities/AdminOperationLog.cs create mode 100644 ChouBox.Model/Entities/AdminQuanxian.cs create mode 100644 ChouBox.Model/Entities/Ads.cs create mode 100644 ChouBox.Model/Entities/Advert.cs create mode 100644 ChouBox.Model/Entities/AdvertType.cs create mode 100644 ChouBox.Model/Entities/CardLevel.cs create mode 100644 ChouBox.Model/Entities/Category.cs create mode 100644 ChouBox.Model/Entities/Code.cs create mode 100644 ChouBox.Model/Entities/Collect.cs create mode 100644 ChouBox.Model/Entities/Config.cs create mode 100644 ChouBox.Model/Entities/Coupon.cs create mode 100644 ChouBox.Model/Entities/CouponReceive.cs create mode 100644 ChouBox.Model/Entities/Danye.cs create mode 100644 ChouBox.Model/Entities/Delivery.cs create mode 100644 ChouBox.Model/Entities/ErrorLog.cs create mode 100644 ChouBox.Model/Entities/FloatBallConfig.cs create mode 100644 ChouBox.Model/Entities/Give.cs create mode 100644 ChouBox.Model/Entities/Goods.cs create mode 100644 ChouBox.Model/Entities/GoodsExtend.cs create mode 100644 ChouBox.Model/Entities/GoodsExtendList.cs create mode 100644 ChouBox.Model/Entities/GoodsKingRank.cs create mode 100644 ChouBox.Model/Entities/GoodsList.cs create mode 100644 ChouBox.Model/Entities/GoodsLock.cs create mode 100644 ChouBox.Model/Entities/GoodsOffshelfLog.cs create mode 100644 ChouBox.Model/Entities/GoodsType.cs create mode 100644 ChouBox.Model/Entities/ItemCard.cs create mode 100644 ChouBox.Model/Entities/KkOrder.cs create mode 100644 ChouBox.Model/Entities/KkOrderGood.cs create mode 100644 ChouBox.Model/Entities/KkOrderSend.cs create mode 100644 ChouBox.Model/Entities/KkProduct.cs create mode 100644 ChouBox.Model/Entities/KkProductCate.cs create mode 100644 ChouBox.Model/Entities/KkProductCategory.cs create mode 100644 ChouBox.Model/Entities/KkProductSpec.cs create mode 100644 ChouBox.Model/Entities/KkSeckill.cs create mode 100644 ChouBox.Model/Entities/KkShare.cs create mode 100644 ChouBox.Model/Entities/Market.cs create mode 100644 ChouBox.Model/Entities/MarketOrder.cs create mode 100644 ChouBox.Model/Entities/Migrations.cs create mode 100644 ChouBox.Model/Entities/NotifyLog.cs create mode 100644 ChouBox.Model/Entities/Order.cs create mode 100644 ChouBox.Model/Entities/OrderList.cs create mode 100644 ChouBox.Model/Entities/OrderListRecovery.cs create mode 100644 ChouBox.Model/Entities/OrderListSend.cs create mode 100644 ChouBox.Model/Entities/Picture.cs create mode 100644 ChouBox.Model/Entities/ProfitDraw.cs create mode 100644 ChouBox.Model/Entities/ProfitExpenses.cs create mode 100644 ChouBox.Model/Entities/ProfitIntegral.cs create mode 100644 ChouBox.Model/Entities/ProfitMoney.cs create mode 100644 ChouBox.Model/Entities/ProfitMoney2.cs create mode 100644 ChouBox.Model/Entities/ProfitOuQi.cs create mode 100644 ChouBox.Model/Entities/ProfitPay.cs create mode 100644 ChouBox.Model/Entities/ProfitRevenue.cs create mode 100644 ChouBox.Model/Entities/ProfitScore.cs create mode 100644 ChouBox.Model/Entities/QuanYiLevel.cs create mode 100644 ChouBox.Model/Entities/QuanYiLevelJiang.cs create mode 100644 ChouBox.Model/Entities/RankMonth.cs create mode 100644 ChouBox.Model/Entities/RankWeek.cs create mode 100644 ChouBox.Model/Entities/Reward.cs create mode 100644 ChouBox.Model/Entities/Shang.cs create mode 100644 ChouBox.Model/Entities/SignConfig.cs create mode 100644 ChouBox.Model/Entities/TaskList.cs create mode 100644 ChouBox.Model/Entities/User.cs create mode 100644 ChouBox.Model/Entities/UserAccount.cs create mode 100644 ChouBox.Model/Entities/UserCoupon.cs create mode 100644 ChouBox.Model/Entities/UserGoodsLianJi.cs create mode 100644 ChouBox.Model/Entities/UserItemCard.cs create mode 100644 ChouBox.Model/Entities/UserLoginIp.cs create mode 100644 ChouBox.Model/Entities/UserLoginLog.cs create mode 100644 ChouBox.Model/Entities/UserPosterCache.cs create mode 100644 ChouBox.Model/Entities/UserQuanYiLevelJiang.cs create mode 100644 ChouBox.Model/Entities/UserRage.cs create mode 100644 ChouBox.Model/Entities/UserRecharge.cs create mode 100644 ChouBox.Model/Entities/UserSign.cs create mode 100644 ChouBox.Model/Entities/UserStatistics.cs create mode 100644 ChouBox.Model/Entities/UserTaskList.cs create mode 100644 ChouBox.Model/Entities/UserVip.cs create mode 100644 ChouBox.Model/Entities/WelfareHouse.cs create mode 100644 ChouBox.Model/Entities/Withdraw.cs create mode 100644 ChouBox.Model/Entities/WxpayLog.cs create mode 100644 ChouBox.Model/Entities/YoudaContext.cs create mode 100644 ChouBox.Model/Entities/Yushou.cs create mode 100644 ChouBox.Model/efcore-gen.md create mode 100644 ChouBox.WebApi/ChouBox.WebApi.csproj create mode 100644 ChouBox.WebApi/ChouBox.WebApi.http create mode 100644 ChouBox.WebApi/Controllers/AccountController.cs create mode 100644 ChouBox.WebApi/Controllers/GoodsController.cs create mode 100644 ChouBox.WebApi/Controllers/WeatherForecastController.cs create mode 100644 ChouBox.WebApi/Dockerfile create mode 100644 ChouBox.WebApi/Filters/ResultFormatFilter.cs create mode 100644 ChouBox.WebApi/Middleware/ResponseFormatterMiddleware.cs create mode 100644 ChouBox.WebApi/Program.cs create mode 100644 ChouBox.WebApi/Properties/launchSettings.json create mode 100644 ChouBox.WebApi/WeatherForecast.cs create mode 100644 ChouBox.WebApi/appsettings.Development.json create mode 100644 ChouBox.WebApi/appsettings.json create mode 100644 ChouBox.sln create mode 100644 Utile/HuanMeng.DotNetCore/AttributeExtend/ImagesAttribute.cs create mode 100644 Utile/HuanMeng.DotNetCore/AttributeExtend/MessageAttribute.cs create mode 100644 Utile/HuanMeng.DotNetCore/Base/BLLBase.cs create mode 100644 Utile/HuanMeng.DotNetCore/Base/BaseResponse.cs create mode 100644 Utile/HuanMeng.DotNetCore/Base/DaoBase.cs create mode 100644 Utile/HuanMeng.DotNetCore/Base/EfCoreDaoBase.cs create mode 100644 Utile/HuanMeng.DotNetCore/Base/IResponse.cs create mode 100644 Utile/HuanMeng.DotNetCore/Base/MessageBox.cs create mode 100644 Utile/HuanMeng.DotNetCore/Base/ResponseCode.cs create mode 100644 Utile/HuanMeng.DotNetCore/Base/ResultWithMessage.cs create mode 100644 Utile/HuanMeng.DotNetCore/CacheHelper/CommonDataEntityCache.cs create mode 100644 Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheClearData.cs create mode 100644 Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheClearLocalData.cs create mode 100644 Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheReloadData.cs create mode 100644 Utile/HuanMeng.DotNetCore/CacheHelper/MemoryCacheHelper.cs create mode 100644 Utile/HuanMeng.DotNetCore/CustomExtension/CorsExtension.cs create mode 100644 Utile/HuanMeng.DotNetCore/Extensions/ControllerExtensions.cs create mode 100644 Utile/HuanMeng.DotNetCore/Extensions/HttpContextExtensions.cs create mode 100644 Utile/HuanMeng.DotNetCore/HuanMeng.DotNetCore.csproj create mode 100644 Utile/HuanMeng.DotNetCore/Json/CustomDateTimeConverter.cs create mode 100644 Utile/HuanMeng.DotNetCore/JwtInfrastructure/Interface/IJwtAuthManager.cs create mode 100644 Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtAuthManager.cs create mode 100644 Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtAuthResult.cs create mode 100644 Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtManager.cs create mode 100644 Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtRefreshToken.cs create mode 100644 Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtTokenConfig.cs create mode 100644 Utile/HuanMeng.DotNetCore/MiddlewareExtend/ExceptionMiddleware.cs create mode 100644 Utile/HuanMeng.DotNetCore/MiddlewareExtend/ExecutionTimeMiddleware.cs create mode 100644 Utile/HuanMeng.DotNetCore/MiddlewareExtend/MiddlewareExtends.cs create mode 100644 Utile/HuanMeng.DotNetCore/MiddlewareExtend/SignBaseMiddleware.cs create mode 100644 Utile/HuanMeng.DotNetCore/MultiTenant/Contract/IMultiTenant.cs create mode 100644 Utile/HuanMeng.DotNetCore/MultiTenant/Contract/IMultiTenantDbContext.cs create mode 100644 Utile/HuanMeng.DotNetCore/MultiTenant/Contract/IMultiTenantEntity.cs create mode 100644 Utile/HuanMeng.DotNetCore/MultiTenant/Contract/ITenantInfo.cs create mode 100644 Utile/HuanMeng.DotNetCore/MultiTenant/MultiTenantDbContext.cs create mode 100644 Utile/HuanMeng.DotNetCore/MultiTenant/MultiTenantEntity.cs create mode 100644 Utile/HuanMeng.DotNetCore/MultiTenant/TenantInfo.cs create mode 100644 Utile/HuanMeng.DotNetCore/Processors/BaseProcessor.cs create mode 100644 Utile/HuanMeng.DotNetCore/Processors/ITaskProcessor.cs create mode 100644 Utile/HuanMeng.DotNetCore/Processors/ThreadProcessor.cs create mode 100644 Utile/HuanMeng.DotNetCore/QuartzExtend/QuartzExtensions.cs create mode 100644 Utile/HuanMeng.DotNetCore/QuartzExtend/QuartzTriggerAttribute.cs create mode 100644 Utile/HuanMeng.DotNetCore/Redis/RedisConnection.cs create mode 100644 Utile/HuanMeng.DotNetCore/Redis/RedisHelper.cs create mode 100644 Utile/HuanMeng.DotNetCore/SwaggerUtile/LowercaseParameterFilter.cs create mode 100644 Utile/HuanMeng.DotNetCore/TextCensor/CheckTextVerification.cs create mode 100644 Utile/HuanMeng.DotNetCore/TextCensor/ITextCensor.cs create mode 100644 Utile/HuanMeng.DotNetCore/TextCensor/SensitiveWord/SensitiveWordFilter.cs create mode 100644 Utile/HuanMeng.DotNetCore/TextCensor/SensitiveWord/SensitiveWordFilterFrozen.cs create mode 100644 Utile/HuanMeng.DotNetCore/TextCensor/TextCensorExtend.cs create mode 100644 Utile/HuanMeng.DotNetCore/Utility/AssemblyHelper/AssemblyInfo.cs create mode 100644 Utile/HuanMeng.DotNetCore/Utility/AssemblyHelper/AssemblyInfoHelper.cs create mode 100644 Utile/HuanMeng.DotNetCore/Utility/DateTimeExtensions.cs create mode 100644 Utile/HuanMeng.DotNetCore/Utility/HttpContextExtensions.cs create mode 100644 Utile/HuanMeng.DotNetCore/Utility/HttpRequestMessageExtensions.cs create mode 100644 Utile/HuanMeng.DotNetCore/Utility/HttpResponseMessageExtensions.cs create mode 100644 Utile/HuanMeng.DotNetCore/Utility/MD5Encryption.cs create mode 100644 Utile/HuanMeng.DotNetCore/Utility/ObjectExtensions.cs create mode 100644 Utile/HuanMeng.DotNetCore/Utility/OtherExtensions.cs create mode 100644 Utile/HuanMeng.DotNetCore/Utility/PhoneNumberValidator.cs create mode 100644 Utile/HuanMeng.DotNetCore/Utility/StringExtend.cs create mode 100644 Utile/HuanMeng.DotNetCore/WeChat/MiniProgram.cs create mode 100644 Utile/HuanMeng.DotNetCore/WeChat/WXBizDataCrypt.cs diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..fe1152b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,30 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md +!**/.gitignore +!.git/HEAD +!.git/config +!.git/packed-refs +!.git/refs/heads/** \ No newline at end of file diff --git a/ChouBox.Code/AppExtend/ChouBoxCodeBase.cs b/ChouBox.Code/AppExtend/ChouBoxCodeBase.cs new file mode 100644 index 0000000..72cfabb --- /dev/null +++ b/ChouBox.Code/AppExtend/ChouBoxCodeBase.cs @@ -0,0 +1,224 @@ +using AutoMapper; + +using ChouBox.Code.TencentCloudExtend.Model; +using ChouBox.Model.Entities; + +using HuanMeng.DotNetCore.Base; + +using Microsoft.AspNetCore.Http; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +using Newtonsoft.Json; + +using StackExchange.Redis; + +using System.Threading.Tasks; + +namespace ChouBox.Code.AppExtend; + +/// +/// bll 基础类 +/// +public class ChouBoxCodeBase +{ + /// + /// _serviceProvider,提供基本依赖注入支持 + /// + protected readonly IServiceProvider _serviceProvider; + /// + /// 构造函数 + /// + /// + public ChouBoxCodeBase(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + private EfCoreDaoBase? _dao; + /// + /// 数据库, + /// 更新删除,尽量只操作本bll实例dao获取到的对象,取和存要同一个dao + /// + public EfCoreDaoBase Dao + { + get + { + if (_dao == null) + { + _dao = new EfCoreDaoBase(_serviceProvider.GetRequiredService()); + + } + return _dao; + } + } + + #region 映射 + private IMapper _mapper; + /// + /// DTO 映射 + /// + public virtual IMapper Mapper + { + get + { + if (_mapper == null) + { + _mapper = _serviceProvider.GetRequiredService(); + } + return _mapper; + } + set + { + _mapper = value; + } + } + #endregion + + #region 请求信息 + private IHttpContextAccessor _httpContextAccessor; + /// + /// HttpContextAccessor + /// + public IHttpContextAccessor HttpContextAccessor + { + get + { + if (_httpContextAccessor == null) + { + _httpContextAccessor = _serviceProvider.GetRequiredService(); + } + return _httpContextAccessor; + } + } + #endregion + + #region 日志 + private ILogger _logger; + /// + /// 日志 + /// + public ILogger Logger + { + get + { + if (_logger == null) + { + _logger = _serviceProvider.GetRequiredService>(); + } + return _logger; + } + } + #endregion + + public IConfiguration Configuration() + { + return _serviceProvider.GetRequiredService(); + } + + #region Redis + private IDatabase _redis; + /// + /// Redis 缓存 + /// + public IDatabase RedisCache + { + get + { + if (_redis == null) + { + var connectionMultiplexer = _serviceProvider.GetRequiredService(); + _redis = connectionMultiplexer.GetDatabase(); + } + return _redis; + } + } + + #endregion + + /// + /// 获取腾讯云短信配置 + /// + /// + public async Task GetTencentSMSConfigAsync() + { + var config = await this.GetConfigAsync("tencent_sms_config"); + if (config == null) + { + config = new TencentSMSConfig() + { + SecretId = "AKIDLbhdP0Vs57yd7QZWu8A2jFbno8JKBUp6", + SecretKey = "", + ReqMethod = "POST", + Timeout = 30, + SmsSdkAppId = "1400923253", + SignName = "上海寰梦科技发展", + TemplateId = "2209122" + + }; + } + return config; + } + + /// + /// 获取系统配置 + /// + /// 配置关键词 + /// 配置信息 + public Dictionary GetConfig(string type) + { + // 生成缓存键 + string cacheKey = $"config:{type}"; + + // 尝试从缓存获取数据 + var cachedData = RedisCache.StringGet>(cacheKey); + if (cachedData != null) + { + return cachedData; + } + + // 从数据库查询 + var content = Dao.Context.Config.Where(it => it.Key == type).FirstOrDefault(); + Dictionary config = null; + + if (content != null) + { + + var d = JsonConvert.DeserializeObject>(content.Value); + RedisCache.StringSet(cacheKey, content.Value, TimeSpan.FromMinutes(10)); + return d; + } + return null; + } + + /// + /// 获取系统配置 + /// + /// 实体类 + /// 配置key + /// + public async Task GetConfigAsync(string type) where T : class + { + // 生成缓存键 + string cacheKey = $"config:{type}"; + + // 尝试从缓存获取数据 + var cachedData = RedisCache.StringGet(cacheKey); + if (cachedData != null) + { + return cachedData; + } + // 从数据库查询 + var content = await Dao.Context.Config.Where(it => it.Key == type).FirstOrDefaultAsync(); + + if (content != null && !string.IsNullOrEmpty(content.Value)) + { + var d = JsonConvert.DeserializeObject(content.Value); + RedisCache.StringSet(cacheKey, content.Value, TimeSpan.FromMinutes(10)); + return d; + } + return null; + } +} diff --git a/ChouBox.Code/ChouBox.Code.csproj b/ChouBox.Code/ChouBox.Code.csproj new file mode 100644 index 0000000..099e6d9 --- /dev/null +++ b/ChouBox.Code/ChouBox.Code.csproj @@ -0,0 +1,24 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + + + + + + diff --git a/ChouBox.Code/Contract/ISendVerificationCode.cs b/ChouBox.Code/Contract/ISendVerificationCode.cs new file mode 100644 index 0000000..af513c8 --- /dev/null +++ b/ChouBox.Code/Contract/ISendVerificationCode.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ChouBox.Code.Contract; + +/// +/// 发送验证码 +/// +public interface ISendVerificationCode +{ + /// + /// 发送验证码 + /// + /// + /// + /// + public Task SendVerificationCode(string code, int expireTime); + +} diff --git a/ChouBox.Code/GlobalUsings.cs b/ChouBox.Code/GlobalUsings.cs new file mode 100644 index 0000000..221ea1c --- /dev/null +++ b/ChouBox.Code/GlobalUsings.cs @@ -0,0 +1,2 @@ +global using ChouBox.Code; +global using HuanMeng.DotNetCore.Redis; \ No newline at end of file diff --git a/ChouBox.Code/Goods/GoodsBLL.cs b/ChouBox.Code/Goods/GoodsBLL.cs new file mode 100644 index 0000000..a396cd8 --- /dev/null +++ b/ChouBox.Code/Goods/GoodsBLL.cs @@ -0,0 +1,26 @@ +using ChouBox.Code.AppExtend; +using ChouBox.Model.Entities; + +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Primitives; + +using Newtonsoft.Json; + +using StackExchange.Redis; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ChouBox.Code.Goods; + +public class GoodsBLL : ChouBoxCodeBase +{ + public GoodsBLL(IServiceProvider serviceProvider) : base(serviceProvider) + { + } + +} + diff --git a/ChouBox.Code/MiddlewareExtend/SignatureVerifyMiddleware.cs b/ChouBox.Code/MiddlewareExtend/SignatureVerifyMiddleware.cs new file mode 100644 index 0000000000000000000000000000000000000000..6c707c392ec799a9dd35564082661ef984cd914c GIT binary patch literal 24342 zcmd^HU2Ggz6&|UmBqb5>f<&b%TMLp+n{0ldrAS|mgtP*W-)6;M^d3yp-TR;2>-efR9~o!Pl_ zXLjwR4`{U>@9w?lo_qe!xo2kKzsG}WFcORhl^_@F4u*q?;CQeLe@_Mle4YpfgEIcx z8BF4}2j5QP^EkfU9^6)Yg(0*9)<7_Yc~!iJFq(6#m|MiWX#;V}K-`N@)A*in(jeG% ziR%Q`uNv(7vDR=6`$F&_{;LA!6t2erlb8yg&BEtOLx5HRw5gyU5M}k|aoz{)D|iXT zg@$45NTm~4NA{=`e8f<5yhiiz_!7pF3Qri`kQ)7lm*iQO**|F#U#Aqz8d{Zuu^0!! zzljWt2BUyAu(*Fx|6zPHjyI`2kOE_$+3%Anqe^BCQhEd{%^D6*;W}yPQ865t#13au z;B*5H<+Pql(S7MCp%Xbg3ffH>I!@wR27RowrNJ6DGx{NK!r4O54QN&HMX5iI&tnGa zB>o$~e?EPq9u49}x}Pw3l_T1BTQCQ`$<RmRMW*W3lH_|E>l<-{zQbA22AIrf(yvffYaLu(R zyLNa#x-ar!B$zSqNH0Ppjj0`@fS5Bf{v_5Sx29nM%7$W<#Tk7@MpYUVu3ppOw;7A& zwgS1J54-o-2wg|7S=LhvLAtdzLD3zcN*|~oc7{+WyNZEcvtUB&KW^w}HNPFS9tEXG zpp}%(lXy>=70DY)f3-$2+6FsMaERlPMRFBq9ox0IQsHWQS8&D$)hEXax1JWlQ_54$ zNEKyJ{9_k%@WG%BT7V$gy2ZtS@a??^S5_Y^3JKhgU zbb~7Uu=g%}Bh(RDAQi$iAO%)K3iwv8>Q(6UPRIS_vz6TC|8!24U8ADbw{eS`cdo5C zP`7;clv+(|y1@&@Z#9!`W*XGxu#I8Mn6_Rc7SM11);sAn=loWAVSSg#lG1*A%B*Di z3Y_HM(;$awC$Pfbq|NqINZ|R$xK}u3=;6{8(Wno{e$aLF@Vduddgk>Kit0*Y(68JendTtbQpHu)VdaDM%jg+C)_d!8IKp#V8Hp9M zd4zDR$KB5wkCt1EZ*#Evh1%jbDhaE7**%6ej8ToF?lfe!?>InP|kH1`NiFDz>IqOyEvfK^KnAQ^qUNYIU6HS zwNm-mIuZlwEccZq(xcvcf!# zvcl>|HhF0e&7hP_1P4I#Nqjp64vB^*?S*v<8!1y-XH6z&rHEV$OBL-6<(V}J!IkSU z17rM24xGTX8MumTGL2N~>S-jA@57MyZp6Avm8l_6kg^~Z9!k0LhH}QLMGjOO$KR+l z$2Gar=q_pM!%2CQMc#F+ivx#%mEc!EhET?;M}Q+~W52f+MI?o`MD2yrU)M;wQvRFy zjrKu2n4gdP5zjKdT{c_G&$V^ ziDdN1ipeh6qanO#v8Aq%Rp)iJaQ#=UqS#8->KW^Vy+E|;*@oQ}O!Oi%#!Mv3nwog3 zw4Lx|U=W%`kHlSZJmYEBM+)$H-O$GS%&)X*jG8!-x&PMSi;?gBK2i6oSKa5a+WOsq zEYT$Q8je81ln`&g-O(cx-@!oeIuU9l0J(K*Cy*5i$IT>Z6~wG@U*!{eX~a|z9< zgwA?evfKPNV10=>~UNffwg9gnI=MWb|Cw6(Ve_jd>g$g z=i~dkv!>g^{YE@TJq}BuzrxDy3+s2X6wGz?<=BD3TDp&v>~NxHTdif!k`*cz&0e#3 z*Cg1@%xz}Q0Ca8|TE+}K51Vxo|CbS=SsO`<-i%x!<3=Q3D<_Ree3+ts z$)<)CaE>A;?)}g|W^GxtDyt0pB_Nv=RZ*ligy+3PsZ!DAiTRqYhG?_ zh(+2NzG9(cSuNBGXt-*)F?6P1Kc^L|q@Og_*T5N9P9SDtwKu)m7>-wM<&~OpBWuE1 zJ6%~h*ZGgjA0K{sKG|kygcY^3zUq4~s z>8MXjtj;c?X~>joL|R^~@Y#Vf0ywPt5RyQy=d5G{tc}`QtMGdal1<)m?oMQggP^|H zq8ky@spPSPB3`wZek<;zAA4e-8~sgmfBu{Y(GgW|RGWogDl-bPeKD5Kqted~ zNXoDNsu2lKF#NKjz99<^I<|4y(V0HWB0kX<@?vooaOuW!YSphx*K{ zlxKT-#uv|{NsVo1K7BY!bFS~w6ou{982#1qQ@XCijBB!WPrp#Xc-o z7n;Jc{AJ&W)Qr2ar&(jWc!F7mzjN{aPy&ySL}D$4%1EbP9&RT6B~uq#Wy#h3)YmwN z(nQ`fMwE(Y84;!Iv%{PzkbbOm9>CuLoMLdio<@&j*-_qJ{;<=hBVle!@2GG*Nh|DXEjVlT>3AHn*iV6<-rIV&u{+w)%9WBWxvs_B zo;eO>gZfUH4DTwOM|VLcd6vYx3j{M-HKP@f0 zPfn9KR|2o~WRq5AI>NbRiBTV6F&Ex$@JN}?X~792v+i{0YA;L1%Zx+P9x^_a9bHk2 z=(1*M@I?-jM~NSOwMhH3vB-?c9arkURErq<+U_*1N&4-AjbOwoq+#{`u{$m@I$O2y z;q2gZtBb+&jM@D0n&PKxF$0mFB+cP8PH83i(blruKFMh0=NY7^nlqYV;)G^i( zc-qJaOyJqhZ_@Mt&f50{eu`#=ZlhDKp*{9o#YWj_9A7z5d9rYIb@vB{h!Z>HzBO>^ zX!0z}ZJvxUpOR7220+ zXjczt%Y2BsHfMBKbGMmw`zfT$P1<4_qOiO zzIK+qWf`MhK`f-+PtKbCAavN;xUesfd(L%C3;YGOwtlXak@#;dIAd9kh&p_?!P%L= z^x*EYc&?HS_t&2I z;E+FuQF%zpVWguij{j0+BYU-!__NNRrMtl;9sDjXPt=!2&+}iq^yb0OUcEm5w~mR& zd=Q&C!FQiFggY~`pDfUZX^x+()!nO*E_QCvyRz0pt3wON_*Z1nt?xcPSLvqguxEjH zo(n9AxZ^ZZ%j<)xW4H_YfA&*bi%fj8R1(H8i_c79HC9d@ECrJB(zOT8%Kf$ZdCi*Xw5wmi#3&IG1GWp+~x!KU8_k4{fjkCT25*QL_&>@jjo zJa>XFdgo$N%$pWxhUHW(sN$v9<+B!yN_eWB)Q4d$P&4+T&GgIjX(EiR_3i~eVZ`b_ z^LOzuX{YpYe)%+1Eaw(TX)bu<`#+kueFZBPp6=aLexvy2!CNlee);VaZF56c}JkgcKm%f5loU%pz z>%$sTz@JuO+&niYTSd18XI#XP(Jk*mPNJ;rJUZ6jsbX;ze@0w+AJ1sQ8nOa=&-^q< zv)uw`tC9X!i|tp&&wR7|9y$`UcG#rVA+kuTdS0=h@(ipbz41K-NAG%<>bhEbR&5wN zkKnl|aj2{!Q;MaAst{Te^^*5rWUDV|ESk2f=v@}ttLLA^ymZ{uHkZG$Bv~BwgLk~9 zSu?G3i*MC_EpIw%y_`JGnGoUU{P&x z<8pKS{}$W>`6XEO&9%3jSt`DIm0hwP@aDmvR5$m0r6*1$9jjM#{NUw=r(<{(*reV} zaBq-pjcnek-cM!W(2ep_J{~X4SGgfeRZ`;M8|9_kE3>nW`KRWKE>Gp2`B8bRBy4t@ ze9`5x+%x{)y%zQB#(OO{?Qg8-qCdXB)PBXCpU{Fe@3-t-EE;2mJE_B&t=_dlf5)hc znVRc&c38*lbGjG1aA>%byNu6Od#$l5&qjDgC3w(NQRC%X_v#A4hlP%b#w@hRJUe%B zSZBCn6#Z4WbNl7?D{JStKSq7?9Z&ae1J3I}$7lx3rzSN@0gZ0McSy9DY}y}pXQ771 z45SM4Q|T?>9XUtw&ILR->011a&vvSs3KpL;qR&`TPVqE~V_D~t=e;uPIgFQP{w)~6 z|JkQZ$SuL=@b=MOsT}267^5~|6qad~6Ur}V$*%ax&guY;nwhcpt_`EeDURO_+*vR5 z+gra(5RTqynlp8no6))d!};gu=d&Am_g7rz zebO0z-iLh-(wI5Zk;ql{NzEXwB}$hwocKyAL%tPtjOqjHAA&o(cPQanF=rmYyqJBP z(Pw~Y-fm~)%^0OY7CG1T`BZD3Tv=GMZ=r!$1or%sy5-P0mkV!^^qfJS~);TJetWn|G+QZYJlbtdozxcHHfhDP2vkSvam^ zx$F9q_Bb|t+SL(^i=Q91z; + /// 签名验证中间件扩展方法 + /// + public static class SignatureVerifyMiddlewareExtensions + { + /// + /// 使用请求签名验证中间件 + /// + /// 应用程序构建器 + /// 应用程序构建器 + public static IApplicationBuilder UseSignatureVerify(this IApplicationBuilder builder) + { + return builder.UseMiddleware(); + } + } +} \ No newline at end of file diff --git a/ChouBox.Code/Other/SMSBLL.cs b/ChouBox.Code/Other/SMSBLL.cs new file mode 100644 index 0000000..ea70f7d --- /dev/null +++ b/ChouBox.Code/Other/SMSBLL.cs @@ -0,0 +1,59 @@ +using AutoMapper; + +using ChouBox.Code.AppExtend; +using ChouBox.Code.TencentCloudExtend; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ChouBox.Code.Other; + +/// +/// 发送验证码服务 +/// +public class SMSBLL : ChouBoxCodeBase +{ + public SMSBLL(IServiceProvider serviceProvider) : base(serviceProvider) + { + } + /// + /// 发送验证码 + /// + /// + /// + /// + /// + public async Task SendPhoneAsync(string phone) + { + if (string.IsNullOrEmpty(phone)) + { + throw new ArgumentNullException("手机号不能为空"); + } + var smsConfig = await this.GetTencentSMSConfigAsync(); + if (smsConfig == null) + { + throw new ArgumentNullException("暂未开放发送验证码!"); + } + Random random = new Random(); + var verificationCode = random.Next(1000, 9999); + var redisKey = $"VerificationCode:{phone}"; + var redisVerificationCode = RedisCache.StringGet(redisKey); + if (redisVerificationCode != null && !string.IsNullOrEmpty(redisVerificationCode)) + { + throw new Exception("验证码已发送!"); + } + + TencentSMSSendVerificationCode tencentSMSSendVerificationCode = new TencentSMSSendVerificationCode(smsConfig, phone); + var result = await tencentSMSSendVerificationCode.SendVerificationCode(verificationCode.ToString(), 5); + if (!result) + { + throw new Exception("验证码发送失败"); + } + await RedisCache.StringSetAsync(redisKey, verificationCode.ToString(), TimeSpan.FromMinutes(5)); + + return "验证码已发送"; + } +} diff --git a/ChouBox.Code/TencentCloudExtend/Model/TencentBaseConfig.cs b/ChouBox.Code/TencentCloudExtend/Model/TencentBaseConfig.cs new file mode 100644 index 0000000..c871a84 --- /dev/null +++ b/ChouBox.Code/TencentCloudExtend/Model/TencentBaseConfig.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ChouBox.Code.TencentCloudExtend.Model; + +/// +/// 腾讯云配置 +/// +public class TencentBaseConfig +{ + /// + /// 腾讯云id + /// + public string SecretId { get; set; } + /// + /// 密钥 + /// + public string SecretKey { get; set; } +} diff --git a/ChouBox.Code/TencentCloudExtend/Model/TencentSMSConfig.cs b/ChouBox.Code/TencentCloudExtend/Model/TencentSMSConfig.cs new file mode 100644 index 0000000..82af077 --- /dev/null +++ b/ChouBox.Code/TencentCloudExtend/Model/TencentSMSConfig.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ChouBox.Code.TencentCloudExtend.Model; + +/// +/// 模板短信 +/// +public class TencentSMSConfig : TencentBaseConfig +{ + /// + /// 请求方式 + /// + public string ReqMethod { get; set; } + + /// + /// 超时时间,秒 + /// + public int Timeout { get; set; } + /// + /// 短信应用ID: + /// + public string SmsSdkAppId { get; set; } + + /// + /// 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名 + /// + public string SignName { get; set; } + + /// + /// 短信模板Id,必须填写已审核通过的模板 + /// + public string TemplateId { get; set; } +} diff --git a/ChouBox.Code/TencentCloudExtend/TencentSMSSendVerificationCode.cs b/ChouBox.Code/TencentCloudExtend/TencentSMSSendVerificationCode.cs new file mode 100644 index 0000000..490e676 --- /dev/null +++ b/ChouBox.Code/TencentCloudExtend/TencentSMSSendVerificationCode.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TencentCloud.Common; +using TencentCloud.Common.Profile; +using TencentCloud.Sms.V20210111; +using TencentCloud.Sms.V20210111.Models; +using ChouBox.Code.Contract; +using ChouBox.Model.Entities; +using ChouBox.Code.TencentCloudExtend.Model; + +namespace ChouBox.Code.TencentCloudExtend; + +/// +/// 腾讯云发送短信 +/// +/// +public class TencentSMSSendVerificationCode(TencentSMSConfig tencentSMSConfig, string PhoneNum) : ISendVerificationCode +{ + public async Task SendVerificationCode(string code, int expireTime) + { + + if (string.IsNullOrEmpty(code)) + { + throw new ArgumentNullException("参数错误"); + } + string phoneNum = PhoneNum; + string verificationCode = code; + if (!phoneNum.StartsWith("+86")) + { + phoneNum = "+86" + phoneNum; + } + try + { + // 必要步骤: + // 实例化一个认证对象,入参需要传入腾讯云账户密钥对 SecretId,SecretKey。 + // 为了保护密钥安全,建议将密钥设置在环境变量中或者配置文件中。 + // 硬编码密钥到代码中有可能随代码泄露而暴露,有安全隐患,并不推荐。 + // 这里采用的是从环境变量读取的方式,需要在环境变量中先设置这两个值。 + // SecretId、SecretKey 查询:https://console.cloud.tencent.com/cam/capi + Credential cred = new Credential + { + SecretId = tencentSMSConfig.SecretId, + SecretKey = tencentSMSConfig.SecretKey + }; + + + /* 非必要步骤: + * 实例化一个客户端配置对象,可以指定超时时间等配置 */ + ClientProfile clientProfile = new ClientProfile(); + /* SDK默认用TC3-HMAC-SHA256进行签名 + * 非必要请不要修改这个字段 */ + clientProfile.SignMethod = ClientProfile.SIGN_TC3SHA256; + /* 非必要步骤 + * 实例化一个客户端配置对象,可以指定超时时间等配置 */ + HttpProfile httpProfile = new HttpProfile(); + /* SDK默认使用POST方法。 + * 如果您一定要使用GET方法,可以在这里设置。GET方法无法处理一些较大的请求 */ + httpProfile.ReqMethod = tencentSMSConfig.ReqMethod; + httpProfile.Timeout = tencentSMSConfig.Timeout; // 请求连接超时时间,单位为秒(默认60秒) + /* 指定接入地域域名,默认就近地域接入域名为 sms.tencentcloudapi.com ,也支持指定地域域名访问,例如广州地域的域名为 sms.ap-guangzhou.tencentcloudapi.com */ + httpProfile.Endpoint = "sms.tencentcloudapi.com"; + // 代理服务器,当您的环境下有代理服务器时设定(无需要直接忽略) + // httpProfile.WebProxy = Environment.GetEnvironmentVariable("HTTPS_PROXY"); + + + clientProfile.HttpProfile = httpProfile; + /* 实例化要请求产品(以sms为例)的client对象 + * 第二个参数是地域信息,可以直接填写字符串ap-guangzhou,支持的地域列表参考 https://cloud.tencent.com/document/api/382/52071#.E5.9C.B0.E5.9F.9F.E5.88.97.E8.A1.A8 */ + SmsClient client = new SmsClient(cred, "ap-nanjing", clientProfile); + + + /* 实例化一个请求对象,根据调用的接口和实际情况,可以进一步设置请求参数 + * 您可以直接查询SDK源码确定SendSmsRequest有哪些属性可以设置 + * 属性可能是基本类型,也可能引用了另一个数据结构 + * 推荐使用IDE进行开发,可以方便的跳转查阅各个接口和数据结构的文档说明 */ + SendSmsRequest req = new SendSmsRequest(); + + + /* 基本类型的设置: + * SDK采用的是指针风格指定参数,即使对于基本类型您也需要用指针来对参数赋值。 + * SDK提供对基本类型的指针引用封装函数 + * 帮助链接: + * 短信控制台: https://console.cloud.tencent.com/smsv2 + * 腾讯云短信小助手: https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81 */ + /* 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId,示例如1400006666 */ + // 应用 ID 可前往 [短信控制台](https://console.cloud.tencent.com/smsv2/app-manage) 查看 + req.SmsSdkAppId = tencentSMSConfig.SmsSdkAppId; + + + /* 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名 */ + // 签名信息可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-sign) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-sign) 的签名管理查看 + req.SignName = tencentSMSConfig.SignName; + + + /* 模板 ID: 必须填写已审核通过的模板 ID */ + // 模板 ID 可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-template) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-template) 的正文模板管理查看 + req.TemplateId = tencentSMSConfig.TemplateId; + + + /* 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致,若无模板参数,则设置为空 */ + req.TemplateParamSet = new String[] { verificationCode, expireTime.ToString() }; + + + /* 下发手机号码,采用 E.164 标准,+[国家或地区码][手机号] + * 示例如:+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号*/ + req.PhoneNumberSet = new String[] { phoneNum }; + + + /* 用户的 session 内容(无需要可忽略): 可以携带用户侧 ID 等上下文信息,server 会原样返回 */ + req.SessionContext = ""; + + + /* 短信码号扩展号(无需要可忽略): 默认未开通,如需开通请联系 [腾讯云短信小助手] */ + req.ExtendCode = ""; + + + /* 国内短信无需填写该项;国际/港澳台短信已申请独立 SenderId 需要填写该字段,默认使用公共 SenderId,无需填写该字段。注:月度使用量达到指定量级可申请独立 SenderId 使用,详情请联系 [腾讯云短信小助手](https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81)。 */ + req.SenderId = ""; + + SendSmsResponse resp = await client.SendSms(req); + + Console.WriteLine(AbstractModel.ToJsonString(resp)); + + } + catch (Exception e) + { + + Console.WriteLine(e.ToString()); + return false; + } + //Console.Read(); + return true; + + + } +} + \ No newline at end of file diff --git a/ChouBox.Model/ChouBox.Model.csproj b/ChouBox.Model/ChouBox.Model.csproj new file mode 100644 index 0000000..6202356 --- /dev/null +++ b/ChouBox.Model/ChouBox.Model.csproj @@ -0,0 +1,23 @@ + + + + net8.0 + enable + enable + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + diff --git a/ChouBox.Model/Class1.cs b/ChouBox.Model/Class1.cs new file mode 100644 index 0000000..26955c3 --- /dev/null +++ b/ChouBox.Model/Class1.cs @@ -0,0 +1,7 @@ +namespace ChouBox.Model +{ + public class Class1 + { + + } +} diff --git a/ChouBox.Model/CodeTemplates/EFCore/DbContext.t4 b/ChouBox.Model/CodeTemplates/EFCore/DbContext.t4 new file mode 100644 index 0000000..a7ce959 --- /dev/null +++ b/ChouBox.Model/CodeTemplates/EFCore/DbContext.t4 @@ -0,0 +1,363 @@ +<#@ template hostSpecific="true" #> +<#@ assembly name="Microsoft.EntityFrameworkCore" #> +<#@ assembly name="Microsoft.EntityFrameworkCore.Design" #> +<#@ assembly name="Microsoft.EntityFrameworkCore.Relational" #> +<#@ assembly name="Microsoft.Extensions.DependencyInjection.Abstractions" #> +<#@ parameter name="Model" type="Microsoft.EntityFrameworkCore.Metadata.IModel" #> +<#@ parameter name="Options" type="Microsoft.EntityFrameworkCore.Scaffolding.ModelCodeGenerationOptions" #> +<#@ parameter name="NamespaceHint" type="System.String" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="Microsoft.EntityFrameworkCore" #> +<#@ import namespace="Microsoft.EntityFrameworkCore.Design" #> +<#@ import namespace="Microsoft.EntityFrameworkCore.Infrastructure" #> +<#@ import namespace="Microsoft.EntityFrameworkCore.Scaffolding" #> +<#@ import namespace="Microsoft.Extensions.DependencyInjection" #> +<# + if (!ProductInfo.GetVersion().StartsWith("9.0")) + { + Warning("Your templates were created using an older version of Entity Framework. Additional features and bug fixes may be available. See https://aka.ms/efcore-docs-updating-templates for more information."); + } + + var services = (IServiceProvider)Host; + var providerCode = services.GetRequiredService(); + var annotationCodeGenerator = services.GetRequiredService(); + var code = services.GetRequiredService(); + + var usings = new List + { + "System", + "System.Collections.Generic", + "Microsoft.EntityFrameworkCore" + }; + + if (NamespaceHint != Options.ModelNamespace + && !string.IsNullOrEmpty(Options.ModelNamespace)) + { + usings.Add(Options.ModelNamespace); + } + + if (!string.IsNullOrEmpty(NamespaceHint)) + { +#> +namespace <#= NamespaceHint #>; + +<# + } +#> +public partial class <#= Options.ContextName #> : DbContext +{ +<# + if (!Options.SuppressOnConfiguring) + { +#> + public <#= Options.ContextName #>() + { + } + +<# + } +#> + public <#= Options.ContextName #>(DbContextOptions<<#= Options.ContextName #>> options) + : base(options) + { + } + +<# + foreach (var entityType in Model.GetEntityTypes().Where(e => !e.IsSimpleManyToManyJoinEntityType())) + { + var comment = entityType.GetComment(); + var tableName = entityType.GetTableName(); + + // 添加XML文档注释 +#> + /// + /// <#= !string.IsNullOrEmpty(comment) ? comment : tableName #> + /// + public virtual DbSet<<#= entityType.Name #>> <#= entityType.GetDbSetName() #> { get; set; } + +<# + } + + if (!Options.SuppressOnConfiguring) + { +#> + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) +<# + if (!Options.SuppressConnectionStringWarning) + { +#> +<# + } + + var useProviderCall = providerCode.GenerateUseProvider(Options.ConnectionString); + usings.AddRange(useProviderCall.GetRequiredUsings()); +#> + { + //optionsBuilder.UseMySql("server=192.168.1.56;database=youda;user=youda;password=youda", Microsoft.EntityFrameworkCore.ServerVersion.Parse("5.7.44-mysql")); + } + +<# + } + +#> + protected override void OnModelCreating(ModelBuilder modelBuilder) + { +<# + var anyConfiguration = false; + + var modelFluentApiCalls = Model.GetFluentApiCalls(annotationCodeGenerator); + if (modelFluentApiCalls != null) + { + usings.AddRange(modelFluentApiCalls.GetRequiredUsings()); +#> + modelBuilder<#= code.Fragment(modelFluentApiCalls, indent: 3) #>; +<# + anyConfiguration = true; + } + + StringBuilder mainEnvironment; + foreach (var entityType in Model.GetEntityTypes().Where(e => !e.IsSimpleManyToManyJoinEntityType())) + { + // Save all previously generated code, and start generating into a new temporary environment + mainEnvironment = GenerationEnvironment; + GenerationEnvironment = new StringBuilder(); + + if (anyConfiguration) + { + WriteLine(""); + } + + var anyEntityTypeConfiguration = false; +#> + modelBuilder.Entity<<#= entityType.Name #>>(entity => + { +<# + var key = entityType.FindPrimaryKey(); + if (key != null) + { + var keyFluentApiCalls = key.GetFluentApiCalls(annotationCodeGenerator); + if (keyFluentApiCalls != null + || (!key.IsHandledByConvention() && !Options.UseDataAnnotations)) + { + if (keyFluentApiCalls != null) + { + usings.AddRange(keyFluentApiCalls.GetRequiredUsings()); + } +#> + entity.HasKey(<#= code.Lambda(key.Properties, "e") #>)<#= code.Fragment(keyFluentApiCalls, indent: 4) #>; +<# + anyEntityTypeConfiguration = true; + } + } + + var entityTypeFluentApiCalls = entityType.GetFluentApiCalls(annotationCodeGenerator) + ?.FilterChain(c => !(Options.UseDataAnnotations && c.IsHandledByDataAnnotations)); + if (entityTypeFluentApiCalls != null) + { + usings.AddRange(entityTypeFluentApiCalls.GetRequiredUsings()); + + if (anyEntityTypeConfiguration) + { + WriteLine(""); + } +#> + entity<#= code.Fragment(entityTypeFluentApiCalls, indent: 4) #>; +<# + anyEntityTypeConfiguration = true; + } + + foreach (var index in entityType.GetIndexes() + .Where(i => !(Options.UseDataAnnotations && i.IsHandledByDataAnnotations(annotationCodeGenerator)))) + { + if (anyEntityTypeConfiguration) + { + WriteLine(""); + } + + var indexFluentApiCalls = index.GetFluentApiCalls(annotationCodeGenerator); + if (indexFluentApiCalls != null) + { + usings.AddRange(indexFluentApiCalls.GetRequiredUsings()); + } +#> + entity.HasIndex(<#= code.Lambda(index.Properties, "e") #>, <#= code.Literal(index.GetDatabaseName()) #>)<#= code.Fragment(indexFluentApiCalls, indent: 4) #>; +<# + anyEntityTypeConfiguration = true; + } + + var firstProperty = true; + foreach (var property in entityType.GetProperties()) + { + var propertyFluentApiCalls = property.GetFluentApiCalls(annotationCodeGenerator) + ?.FilterChain(c => !(Options.UseDataAnnotations && c.IsHandledByDataAnnotations) + && !(c.Method == "IsRequired" && Options.UseNullableReferenceTypes && !property.ClrType.IsValueType)); + if (propertyFluentApiCalls == null) + { + continue; + } + + usings.AddRange(propertyFluentApiCalls.GetRequiredUsings()); + + if (anyEntityTypeConfiguration && firstProperty) + { + WriteLine(""); + } +#> + entity.Property(e => e.<#= property.Name #>)<#= code.Fragment(propertyFluentApiCalls, indent: 4) #>; +<# + anyEntityTypeConfiguration = true; + firstProperty = false; + } + + foreach (var foreignKey in entityType.GetForeignKeys()) + { + var foreignKeyFluentApiCalls = foreignKey.GetFluentApiCalls(annotationCodeGenerator) + ?.FilterChain(c => !(Options.UseDataAnnotations && c.IsHandledByDataAnnotations)); + if (foreignKeyFluentApiCalls == null) + { + continue; + } + + usings.AddRange(foreignKeyFluentApiCalls.GetRequiredUsings()); + + if (anyEntityTypeConfiguration) + { + WriteLine(""); + } +#> + entity.HasOne(d => d.<#= foreignKey.DependentToPrincipal.Name #>).<#= foreignKey.IsUnique ? "WithOne" : "WithMany" #>(<#= foreignKey.PrincipalToDependent != null ? $"p => p.{foreignKey.PrincipalToDependent.Name}" : "" #>)<#= code.Fragment(foreignKeyFluentApiCalls, indent: 4) #>; +<# + anyEntityTypeConfiguration = true; + } + + foreach (var skipNavigation in entityType.GetSkipNavigations().Where(n => n.IsLeftNavigation())) + { + if (anyEntityTypeConfiguration) + { + WriteLine(""); + } + + var left = skipNavigation.ForeignKey; + var leftFluentApiCalls = left.GetFluentApiCalls(annotationCodeGenerator, useStrings: true); + var right = skipNavigation.Inverse.ForeignKey; + var rightFluentApiCalls = right.GetFluentApiCalls(annotationCodeGenerator, useStrings: true); + var joinEntityType = skipNavigation.JoinEntityType; + + if (leftFluentApiCalls != null) + { + usings.AddRange(leftFluentApiCalls.GetRequiredUsings()); + } + + if (rightFluentApiCalls != null) + { + usings.AddRange(rightFluentApiCalls.GetRequiredUsings()); + } +#> + entity.HasMany(d => d.<#= skipNavigation.Name #>).WithMany(p => p.<#= skipNavigation.Inverse.Name #>) + .UsingEntity>( + <#= code.Literal(joinEntityType.Name) #>, + r => r.HasOne<<#= right.PrincipalEntityType.Name #>>().WithMany()<#= code.Fragment(rightFluentApiCalls, indent: 6) #>, + l => l.HasOne<<#= left.PrincipalEntityType.Name #>>().WithMany()<#= code.Fragment(leftFluentApiCalls, indent: 6) #>, + j => + { +<# + var joinKey = joinEntityType.FindPrimaryKey(); + var joinKeyFluentApiCalls = joinKey.GetFluentApiCalls(annotationCodeGenerator); + + if (joinKeyFluentApiCalls != null) + { + usings.AddRange(joinKeyFluentApiCalls.GetRequiredUsings()); + } +#> + j.HasKey(<#= code.Arguments(joinKey.Properties.Select(e => e.Name)) #>)<#= code.Fragment(joinKeyFluentApiCalls, indent: 7) #>; +<# + var joinEntityTypeFluentApiCalls = joinEntityType.GetFluentApiCalls(annotationCodeGenerator); + if (joinEntityTypeFluentApiCalls != null) + { + usings.AddRange(joinEntityTypeFluentApiCalls.GetRequiredUsings()); +#> + j<#= code.Fragment(joinEntityTypeFluentApiCalls, indent: 7) #>; +<# + } + + foreach (var index in joinEntityType.GetIndexes()) + { + var indexFluentApiCalls = index.GetFluentApiCalls(annotationCodeGenerator); + if (indexFluentApiCalls != null) + { + usings.AddRange(indexFluentApiCalls.GetRequiredUsings()); + } +#> + j.HasIndex(<#= code.Literal(index.Properties.Select(e => e.Name).ToArray()) #>, <#= code.Literal(index.GetDatabaseName()) #>)<#= code.Fragment(indexFluentApiCalls, indent: 7) #>; +<# + } + + foreach (var property in joinEntityType.GetProperties()) + { + var propertyFluentApiCalls = property.GetFluentApiCalls(annotationCodeGenerator); + if (propertyFluentApiCalls == null) + { + continue; + } + + usings.AddRange(propertyFluentApiCalls.GetRequiredUsings()); +#> + j.IndexerProperty<<#= code.Reference(property.ClrType) #>>(<#= code.Literal(property.Name) #>)<#= code.Fragment(propertyFluentApiCalls, indent: 7) #>; +<# + } +#> + }); +<# + anyEntityTypeConfiguration = true; + } +#> + }); +<# + // If any signicant code was generated, append it to the main environment + if (anyEntityTypeConfiguration) + { + mainEnvironment.Append(GenerationEnvironment); + anyConfiguration = true; + } + + // Resume generating code into the main environment + GenerationEnvironment = mainEnvironment; + } + + foreach (var sequence in Model.GetSequences()) + { + var needsType = sequence.Type != typeof(long); + var needsSchema = !string.IsNullOrEmpty(sequence.Schema) && sequence.Schema != sequence.Model.GetDefaultSchema(); + var sequenceFluentApiCalls = sequence.GetFluentApiCalls(annotationCodeGenerator); +#> + modelBuilder.HasSequence<#= needsType ? $"<{code.Reference(sequence.Type)}>" : "" #>(<#= code.Literal(sequence.Name) #><#= needsSchema ? $", {code.Literal(sequence.Schema)}" : "" #>)<#= code.Fragment(sequenceFluentApiCalls, indent: 3) #>; +<# + } + + if (anyConfiguration) + { + WriteLine(""); + } +#> + OnModelCreatingPartial(modelBuilder); + } + + partial void OnModelCreatingPartial(ModelBuilder modelBuilder); +} +<# + mainEnvironment = GenerationEnvironment; + GenerationEnvironment = new StringBuilder(); + + foreach (var ns in usings.Distinct().OrderBy(x => x, new NamespaceComparer())) + { +#> +using <#= ns #>; +<# + } + + WriteLine(""); + + GenerationEnvironment.Append(mainEnvironment); +#> diff --git a/ChouBox.Model/CodeTemplates/EFCore/EntityType.t4 b/ChouBox.Model/CodeTemplates/EFCore/EntityType.t4 new file mode 100644 index 0000000..6c6c708 --- /dev/null +++ b/ChouBox.Model/CodeTemplates/EFCore/EntityType.t4 @@ -0,0 +1,173 @@ +<#@ template hostSpecific="true" #> +<#@ assembly name="Microsoft.EntityFrameworkCore" #> +<#@ assembly name="Microsoft.EntityFrameworkCore.Design" #> +<#@ assembly name="Microsoft.EntityFrameworkCore.Relational" #> +<#@ assembly name="Microsoft.Extensions.DependencyInjection.Abstractions" #> +<#@ parameter name="EntityType" type="Microsoft.EntityFrameworkCore.Metadata.IEntityType" #> +<#@ parameter name="Options" type="Microsoft.EntityFrameworkCore.Scaffolding.ModelCodeGenerationOptions" #> +<#@ parameter name="NamespaceHint" type="System.String" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="Microsoft.EntityFrameworkCore" #> +<#@ import namespace="Microsoft.EntityFrameworkCore.Design" #> +<#@ import namespace="Microsoft.Extensions.DependencyInjection" #> +<# + if (EntityType.IsSimpleManyToManyJoinEntityType()) + { + // Don't scaffold these + return ""; + } + + var services = (IServiceProvider)Host; + var annotationCodeGenerator = services.GetRequiredService(); + var code = services.GetRequiredService(); + + var usings = new List + { + "System", + "System.Collections.Generic" + }; + + if (Options.UseDataAnnotations) + { + usings.Add("System.ComponentModel.DataAnnotations"); + usings.Add("System.ComponentModel.DataAnnotations.Schema"); + usings.Add("Microsoft.EntityFrameworkCore"); + } + + if (!string.IsNullOrEmpty(NamespaceHint)) + { +#> +namespace <#= NamespaceHint #>; + +<# + } + + if (!string.IsNullOrEmpty(EntityType.GetComment())) + { +#> +/// +/// <#= code.XmlComment(EntityType.GetComment()) #> +/// +<# + } + + if (Options.UseDataAnnotations) + { + foreach (var dataAnnotation in EntityType.GetDataAnnotations(annotationCodeGenerator)) + { +#> +<#= code.Fragment(dataAnnotation) #> +<# + } + } +#> +public partial class <#= EntityType.Name #> +{ +<# + var firstProperty = true; + foreach (var property in EntityType.GetProperties().OrderBy(p => p.GetColumnOrder() ?? -1)) + { + if (!firstProperty) + { + WriteLine(""); + } + + if (!string.IsNullOrEmpty(property.GetComment())) + { +#> + /// + /// <#= code.XmlComment(property.GetComment(), indent: 1) #> + /// +<# + } + + if (Options.UseDataAnnotations) + { + var dataAnnotations = property.GetDataAnnotations(annotationCodeGenerator) + .Where(a => !(a.Type == typeof(RequiredAttribute) && Options.UseNullableReferenceTypes && !property.ClrType.IsValueType)); + foreach (var dataAnnotation in dataAnnotations) + { +#> + <#= code.Fragment(dataAnnotation) #> +<# + } + } + + usings.AddRange(code.GetRequiredUsings(property.ClrType)); + + var needsNullable = Options.UseNullableReferenceTypes && property.IsNullable && !property.ClrType.IsValueType; + var needsInitializer = Options.UseNullableReferenceTypes && !property.IsNullable && !property.ClrType.IsValueType; +#> + public <#= code.Reference(property.ClrType) #><#= needsNullable ? "?" : "" #> <#= property.Name #> { get; set; }<#= needsInitializer ? " = null!;" : "" #> +<# + firstProperty = false; + } + + foreach (var navigation in EntityType.GetNavigations()) + { + WriteLine(""); + + if (Options.UseDataAnnotations) + { + foreach (var dataAnnotation in navigation.GetDataAnnotations(annotationCodeGenerator)) + { +#> + <#= code.Fragment(dataAnnotation) #> +<# + } + } + + var targetType = navigation.TargetEntityType.Name; + if (navigation.IsCollection) + { +#> + public virtual ICollection<<#= targetType #>> <#= navigation.Name #> { get; set; } = new List<<#= targetType #>>(); +<# + } + else + { + var needsNullable = Options.UseNullableReferenceTypes && !(navigation.ForeignKey.IsRequired && navigation.IsOnDependent); + var needsInitializer = Options.UseNullableReferenceTypes && navigation.ForeignKey.IsRequired && navigation.IsOnDependent; +#> + public virtual <#= targetType #><#= needsNullable ? "?" : "" #> <#= navigation.Name #> { get; set; }<#= needsInitializer ? " = null!;" : "" #> +<# + } + } + + foreach (var skipNavigation in EntityType.GetSkipNavigations()) + { + WriteLine(""); + + if (Options.UseDataAnnotations) + { + foreach (var dataAnnotation in skipNavigation.GetDataAnnotations(annotationCodeGenerator)) + { +#> + <#= code.Fragment(dataAnnotation) #> +<# + } + } +#> + public virtual ICollection<<#= skipNavigation.TargetEntityType.Name #>> <#= skipNavigation.Name #> { get; set; } = new List<<#= skipNavigation.TargetEntityType.Name #>>(); +<# + } +#> +} +<# + var previousOutput = GenerationEnvironment; + GenerationEnvironment = new StringBuilder(); + + foreach (var ns in usings.Distinct().OrderBy(x => x, new NamespaceComparer())) + { +#> +using <#= ns #>; +<# + } + + WriteLine(""); + + GenerationEnvironment.Append(previousOutput); +#> diff --git a/ChouBox.Model/Entities/Admin.cs b/ChouBox.Model/Entities/Admin.cs new file mode 100644 index 0000000..1a428a1 --- /dev/null +++ b/ChouBox.Model/Entities/Admin.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 管理员 +/// +public partial class Admin +{ + public int Id { get; set; } + + /// + /// 账号 + /// + public string? Username { get; set; } + + /// + /// 姓名 + /// + public string Nickname { get; set; } = null!; + + /// + /// 登录密码 + /// + public string? Password { get; set; } + + /// + /// 权限ID + /// + public uint? Qid { get; set; } + + /// + /// 0正常 1禁用 + /// + public uint? Status { get; set; } + + /// + /// 登录刷新时间 + /// + public uint GetTime { get; set; } + + /// + /// token随机数 + /// + public string Random { get; set; } = null!; + + /// + /// token + /// + public string? Token { get; set; } + + /// + /// 操作人 + /// + public uint AdminId { get; set; } + + public uint Addtime { get; set; } + + /// + /// 修改时间 + /// + public uint UpdateTime { get; set; } +} diff --git a/ChouBox.Model/Entities/AdminGoodsLog.cs b/ChouBox.Model/Entities/AdminGoodsLog.cs new file mode 100644 index 0000000..52903c0 --- /dev/null +++ b/ChouBox.Model/Entities/AdminGoodsLog.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 管理员登录日志 +/// +public partial class AdminGoodsLog +{ + public int Id { get; set; } + + /// + /// 管理员ID + /// + public int AId { get; set; } + + public int? GoodsId { get; set; } + + public int? GoodsListId { get; set; } + + public string? OriginalData { get; set; } + + public string? NewData { get; set; } + + /// + /// 登录ip + /// + public string Ip { get; set; } = null!; + + /// + /// 登录时间 + /// + public uint Addtime { get; set; } +} diff --git a/ChouBox.Model/Entities/AdminLoginLog.cs b/ChouBox.Model/Entities/AdminLoginLog.cs new file mode 100644 index 0000000..f9469d2 --- /dev/null +++ b/ChouBox.Model/Entities/AdminLoginLog.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 管理员登录日志 +/// +public partial class AdminLoginLog +{ + public int Id { get; set; } + + /// + /// 管理员ID + /// + public int AId { get; set; } + + /// + /// 登录ip + /// + public string Ip { get; set; } = null!; + + /// + /// 登录时间 + /// + public uint Addtime { get; set; } +} diff --git a/ChouBox.Model/Entities/AdminOperationLog.cs b/ChouBox.Model/Entities/AdminOperationLog.cs new file mode 100644 index 0000000..86b9236 --- /dev/null +++ b/ChouBox.Model/Entities/AdminOperationLog.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 管理员操作日志 +/// +public partial class AdminOperationLog +{ + public int Id { get; set; } + + /// + /// 管理员ID + /// + public int AId { get; set; } + + /// + /// 操作ip + /// + public string Ip { get; set; } = null!; + + /// + /// 操作控制器 + /// + public string? Operation { get; set; } + + public string? Content { get; set; } + + /// + /// 操作时间 + /// + public uint Addtime { get; set; } +} diff --git a/ChouBox.Model/Entities/AdminQuanxian.cs b/ChouBox.Model/Entities/AdminQuanxian.cs new file mode 100644 index 0000000..8ec4e0e --- /dev/null +++ b/ChouBox.Model/Entities/AdminQuanxian.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 权限 +/// +public partial class AdminQuanxian +{ + public int Id { get; set; } + + public string? Title { get; set; } + + public string? Describe { get; set; } + + public string? Quanxian { get; set; } + + public int? Addtime { get; set; } + + public int? UpdateTime { get; set; } + + /// + /// 操作人 + /// + public int? AdminId { get; set; } +} diff --git a/ChouBox.Model/Entities/Ads.cs b/ChouBox.Model/Entities/Ads.cs new file mode 100644 index 0000000..947a7c3 --- /dev/null +++ b/ChouBox.Model/Entities/Ads.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +public partial class Ads +{ + public int Id { get; set; } + + /// + /// 序号 + /// + public int? Ads1 { get; set; } + + public string? Title { get; set; } + + public string? AccountId { get; set; } + + public string? AccessToken { get; set; } + + public string? UserActionSetId { get; set; } + + /// + /// 1.正常 2.已禁用 + /// + public int? Status { get; set; } + + public string? CreateTime { get; set; } + + public string? UpdateTime { get; set; } +} diff --git a/ChouBox.Model/Entities/Advert.cs b/ChouBox.Model/Entities/Advert.cs new file mode 100644 index 0000000..118cd27 --- /dev/null +++ b/ChouBox.Model/Entities/Advert.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +public partial class Advert +{ + public int Id { get; set; } + + /// + /// 图片 + /// + public string Imgurl { get; set; } = null!; + + /// + /// 跳转路径 + /// + public string? Url { get; set; } + + /// + /// 排序 + /// + public uint Sort { get; set; } + + /// + /// 类型 1首页轮播图 2抽卡机轮播图 + /// + public byte Type { get; set; } + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + /// + /// 修改时间 + /// + public uint UpdateTime { get; set; } + + /// + /// 跳转类型 0不跳转 1优惠券 2一番赏 3无限赏 + /// + public byte? Ttype { get; set; } + + /// + /// 优惠券id + /// + public uint? CouponId { get; set; } + + /// + /// 盒子id + /// + public uint? GoodsId { get; set; } +} diff --git a/ChouBox.Model/Entities/AdvertType.cs b/ChouBox.Model/Entities/AdvertType.cs new file mode 100644 index 0000000..981f54b --- /dev/null +++ b/ChouBox.Model/Entities/AdvertType.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +public partial class AdvertType +{ + public int Id { get; set; } + + public string Name { get; set; } = null!; + + public int? Sort { get; set; } +} diff --git a/ChouBox.Model/Entities/CardLevel.cs b/ChouBox.Model/Entities/CardLevel.cs new file mode 100644 index 0000000..6e37673 --- /dev/null +++ b/ChouBox.Model/Entities/CardLevel.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +public partial class CardLevel +{ + public uint Id { get; set; } + + /// + /// 卡名称 + /// + public string Title { get; set; } = null!; + + /// + /// 等级图片 + /// + public string? Imgurl { get; set; } + + /// + /// 排序 + /// + public int? Sort { get; set; } + + /// + /// 添加时间 + /// + public int? Addtime { get; set; } +} diff --git a/ChouBox.Model/Entities/Category.cs b/ChouBox.Model/Entities/Category.cs new file mode 100644 index 0000000..eec1a81 --- /dev/null +++ b/ChouBox.Model/Entities/Category.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 盒子分类 +/// +public partial class Category +{ + public uint Id { get; set; } + + /// + /// 商品名称 + /// + public string Title { get; set; } = null!; + + /// + /// 排序 + /// + public uint Sort { get; set; } + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + /// + /// 修改时间 + /// + public uint UpdateTime { get; set; } +} diff --git a/ChouBox.Model/Entities/Code.cs b/ChouBox.Model/Entities/Code.cs new file mode 100644 index 0000000..6f659f5 --- /dev/null +++ b/ChouBox.Model/Entities/Code.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 短信记录 +/// +public partial class Code +{ + /// + /// 验证码id + /// + public uint Id { get; set; } + + /// + /// 手机号 + /// + public string Phone { get; set; } = null!; + + /// + /// 验证码 + /// + public string Code1 { get; set; } = null!; + + /// + /// 添加时间 + /// + public int Addtime { get; set; } + + /// + /// 类型,1 登录注册 + /// + public bool Type { get; set; } + + /// + /// 状态 0正常,-1失效 + /// + public bool Status { get; set; } +} diff --git a/ChouBox.Model/Entities/Collect.cs b/ChouBox.Model/Entities/Collect.cs new file mode 100644 index 0000000..b00b9af --- /dev/null +++ b/ChouBox.Model/Entities/Collect.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +public partial class Collect +{ + public uint Id { get; set; } + + /// + /// 用户id + /// + public uint UserId { get; set; } + + /// + /// 盒子ID + /// + public uint GoodsId { get; set; } + + /// + /// 箱号 + /// + public uint Num { get; set; } + + /// + /// 1一番赏 2无限赏 3擂台赏 4抽卡机 5积分赏 6全局赏 7福利盲盒 8领主赏 9连击赏 + /// + public byte Type { get; set; } + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } +} diff --git a/ChouBox.Model/Entities/Config.cs b/ChouBox.Model/Entities/Config.cs new file mode 100644 index 0000000..f8623c7 --- /dev/null +++ b/ChouBox.Model/Entities/Config.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +public partial class Config +{ + public int Id { get; set; } + + public string Key { get; set; } = null!; + + public string? Value { get; set; } +} diff --git a/ChouBox.Model/Entities/Coupon.cs b/ChouBox.Model/Entities/Coupon.cs new file mode 100644 index 0000000..00806dc --- /dev/null +++ b/ChouBox.Model/Entities/Coupon.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 优惠券表 +/// +public partial class Coupon +{ + public uint Id { get; set; } + + /// + /// 1新人优惠券 2权益优惠卷 + /// + public byte? Type { get; set; } + + /// + /// 商品名称 + /// + public string Title { get; set; } = null!; + + /// + /// 排序值 + /// + public uint? Sort { get; set; } + + /// + /// 减多少 + /// + public decimal? Price { get; set; } + + /// + /// 满多少减多少 + /// + public decimal? ManPrice { get; set; } + + /// + /// 有效时间(天) + /// + public int? EffectiveDay { get; set; } + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + /// + /// 0上架 2下架 4已删除 + /// + public bool Status { get; set; } + + /// + /// 是否限制使用 0不限制 1一番赏 2无限赏 3擂台赏 6全局赏 9领主赏 9连击赏 + /// + public byte? Ttype { get; set; } +} diff --git a/ChouBox.Model/Entities/CouponReceive.cs b/ChouBox.Model/Entities/CouponReceive.cs new file mode 100644 index 0000000..13c8bdd --- /dev/null +++ b/ChouBox.Model/Entities/CouponReceive.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 用户优惠券表 +/// +public partial class CouponReceive +{ + public uint Id { get; set; } + + /// + /// 商品名称 + /// + public string Title { get; set; } = null!; + + /// + /// 商品价格 + /// + public decimal? Price { get; set; } + + /// + /// 满多少减多少 + /// + public decimal? ManPrice { get; set; } + + /// + /// 过期时间 + /// + public int? EndTime { get; set; } + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + /// + /// 0未使用1已使用2已过期 + /// + public bool Status { get; set; } + + /// + /// 会员id + /// + public int? UserId { get; set; } + + public int? CouponId { get; set; } + + /// + /// 是否限制使用 0不限制 1一番赏 2无限赏 3擂台赏 6全局赏 9领主赏 9连击赏 + /// + public byte? State { get; set; } + + public int Ttype { get; set; } +} diff --git a/ChouBox.Model/Entities/Danye.cs b/ChouBox.Model/Entities/Danye.cs new file mode 100644 index 0000000..bbfa732 --- /dev/null +++ b/ChouBox.Model/Entities/Danye.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +public partial class Danye +{ + /// + /// 类型,1服务协议,2隐私政策 + /// + public uint Id { get; set; } + + /// + /// 标题 + /// + public string Title { get; set; } = null!; + + /// + /// 内容 + /// + public string Content { get; set; } = null!; + + /// + /// 修改时间 + /// + public uint UpdateTime { get; set; } + + /// + /// 0正常 1隐藏 + /// + public byte Status { get; set; } + + /// + /// 是否开启图片优化 + /// + public sbyte IsImageOptimizer { get; set; } +} diff --git a/ChouBox.Model/Entities/Delivery.cs b/ChouBox.Model/Entities/Delivery.cs new file mode 100644 index 0000000..1371f34 --- /dev/null +++ b/ChouBox.Model/Entities/Delivery.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 快递公司 +/// +public partial class Delivery +{ + public ushort Id { get; set; } + + /// + /// 快递公司 + /// + public string Name { get; set; } = null!; + + /// + /// 快递编码 + /// + public string Code { get; set; } = null!; +} diff --git a/ChouBox.Model/Entities/ErrorLog.cs b/ChouBox.Model/Entities/ErrorLog.cs new file mode 100644 index 0000000..26f4f62 --- /dev/null +++ b/ChouBox.Model/Entities/ErrorLog.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +public partial class ErrorLog +{ + public int Id { get; set; } + + public int UserId { get; set; } + + public int GoodsId { get; set; } + + public int Addtime { get; set; } +} diff --git a/ChouBox.Model/Entities/FloatBallConfig.cs b/ChouBox.Model/Entities/FloatBallConfig.cs new file mode 100644 index 0000000..4b79215 --- /dev/null +++ b/ChouBox.Model/Entities/FloatBallConfig.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 悬浮球配置表 +/// +public partial class FloatBallConfig +{ + /// + /// 主键ID + /// + public int Id { get; set; } + + /// + /// 状态 0=关闭 1=开启 + /// + public bool Status { get; set; } + + /// + /// 类型 1=展示图片 2=跳转页面 + /// + public bool? Type { get; set; } + + /// + /// 图片路径 + /// + public string Image { get; set; } = null!; + + /// + /// 跳转链接 + /// + public string LinkUrl { get; set; } = null!; + + /// + /// X坐标位置 + /// + public string PositionX { get; set; } = null!; + + /// + /// Y坐标位置 + /// + public string PositionY { get; set; } = null!; + + /// + /// 宽度 + /// + public string Width { get; set; } = null!; + + /// + /// 高度 + /// + public string Height { get; set; } = null!; + + /// + /// 特效 0=无 1=特效1 + /// + public bool Effect { get; set; } + + /// + /// 创建时间 + /// + public int CreateTime { get; set; } + + /// + /// 更新时间 + /// + public int UpdateTime { get; set; } + + /// + /// 标题 + /// + public string? Title { get; set; } + + /// + /// 展示的图片 + /// + public string? ImageDetails { get; set; } + + /// + /// 背景图 + /// + public string? ImageBj { get; set; } + + /// + /// 详情图坐标 + /// + public string? ImageDetailsX { get; set; } + + /// + /// 详情图y + /// + public string? ImageDetailsY { get; set; } + + /// + /// 宽度 + /// + public string? ImageDetailsW { get; set; } + + /// + /// 高度 + /// + public string? ImageDetailsH { get; set; } +} diff --git a/ChouBox.Model/Entities/Give.cs b/ChouBox.Model/Entities/Give.cs new file mode 100644 index 0000000..e1708ea --- /dev/null +++ b/ChouBox.Model/Entities/Give.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 无限令领取记录 +/// +public partial class Give +{ + public uint Id { get; set; } + + /// + /// 会员id + /// + public uint UserId { get; set; } + + public string? TimeInt { get; set; } + + public string? TimeDate { get; set; } + + /// + /// 消费金额 + /// + public decimal Money { get; set; } + + public uint Addtime { get; set; } +} diff --git a/ChouBox.Model/Entities/Goods.cs b/ChouBox.Model/Entities/Goods.cs new file mode 100644 index 0000000..64c5fae --- /dev/null +++ b/ChouBox.Model/Entities/Goods.cs @@ -0,0 +1,299 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 盒子 +/// +public partial class Goods +{ + public uint Id { get; set; } + + /// + /// 分类ID + /// + public uint CategoryId { get; set; } + + /// + /// 盒子名称 + /// + public string Title { get; set; } = null!; + + /// + /// 盒子封面图 + /// + public string Imgurl { get; set; } = null!; + + /// + /// 盒子详情图 + /// + public string ImgurlDetail { get; set; } = null!; + + /// + /// 商品价格 + /// + public decimal? Price { get; set; } + + /// + /// 套数 + /// + public uint? Stock { get; set; } + + /// + /// 销量库存 + /// + public uint SaleStock { get; set; } + + /// + /// 锁箱 0否 1是 + /// + public byte LockIs { get; set; } + + /// + /// 锁箱时间 + /// + public uint LockTime { get; set; } + + /// + /// 发券开关0关闭 1开启 + /// + public byte CouponIs { get; set; } + + /// + /// 发券概率 + /// + public uint CouponPro { get; set; } + + /// + /// 发积分开关0关闭 1开启 + /// + public byte IntegralIs { get; set; } + + /// + /// 擂台赏抽全局赏数量 + /// + public uint PrizeNum { get; set; } + + /// + /// 1上架 2下架 3售罄 + /// + public byte Status { get; set; } + + /// + /// 排序值 + /// + public uint? Sort { get; set; } + + /// + /// 1一番赏 2无限赏 3擂台赏 4抽卡机 5积分赏 6全局赏 7福利盲盒 8领主赏 9连击赏 + /// + public byte? Type { get; set; } + + /// + /// 首页显示 0是 1否 + /// + public byte ShowIs { get; set; } + + /// + /// 卡册显示价格 + /// + public string? ShowPrice { get; set; } + + /// + /// 抽卡机卡牌背面图 + /// + public string? PrizeImgurl { get; set; } + + /// + /// 卡册banner + /// + public string? CardBanner { get; set; } + + /// + /// 抽卡机抽奖设置 + /// + public string? CardSet { get; set; } + + /// + /// 抽卡机描述 + /// + public string? CardNotice { get; set; } + + /// + /// 预售时间 + /// + public uint SaleTime { get; set; } + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + /// + /// 修改时间 + /// + public uint UpdateTime { get; set; } + + public int? DeleteTime { get; set; } + + /// + /// 一包几张 + /// + public int? CardNum { get; set; } + + /// + /// 怒气值开关 0关 1开 + /// + public byte? RageIs { get; set; } + + /// + /// 怒气值 + /// + public uint? Rage { get; set; } + + /// + /// 道具卡ID + /// + public uint? ItemCardId { get; set; } + + /// + /// 领主开关 0关 1开 + /// + public bool? LingzhuIs { get; set; } + + /// + /// 领主每发返 + /// + public int? LingzhuFan { get; set; } + + /// + /// 请选择抽中领主 + /// + public int? LingzhuShangId { get; set; } + + /// + /// 当前领主 + /// + public int? KingUserId { get; set; } + + /// + /// 连击赏连击次数 + /// + public int? LianJiNum { get; set; } + + /// + /// 连击赏赏id + /// + public int? LianJiShangId { get; set; } + + /// + /// 是否首抽五折 1是 0否 + /// + public byte? IsShouZhe { get; set; } + + /// + /// 最新开关0关闭 1开启 + /// + public byte NewIs { get; set; } + + /// + /// 描述 + /// + public string? GoodsDescribe { get; set; } + + /// + /// 全局赏限购次数 + /// + public int? QuanjuXiangou { get; set; } + + /// + /// 需要的流水 + /// + public decimal DayPrice { get; set; } + + /// + /// 月总流水 + /// + public decimal MouthPrice { get; set; } + + /// + /// 月实付 + /// + public decimal MouthPayPrice { get; set; } + + /// + /// 日实付 + /// + public decimal DayPayPrice { get; set; } + + /// + /// 多少级之下能买 + /// + public int UserLv { get; set; } + + /// + /// 是否福利屋 + /// + public int IsFlw { get; set; } + + /// + /// 福利屋开始时间 + /// + public int FlwStartTime { get; set; } + + /// + /// 福利屋结束时间 + /// + public int FlwEndTime { get; set; } + + /// + /// 开奖时间 + /// + public int OpenTime { get; set; } + + /// + /// 0未开奖 1已开奖 + /// + public int IsOpen { get; set; } + + /// + /// 抽奖门槛 + /// + public int ChoujiangXianzhi { get; set; } + + /// + /// 同步编码,guid + /// + public string? AsyncCode { get; set; } + + /// + /// 最后一次同步时间 + /// + public DateTime? AsyncDate { get; set; } + + /// + /// 是否自动下架 + /// + public sbyte IsAutoXiajia { get; set; } + + /// + /// 下架利润率 + /// + public int XiajiaLirun { get; set; } + + /// + /// 下架生效抽数 + /// + public int XiajiaAutoCoushu { get; set; } + + /// + /// 消费多少额度解锁盒子 + /// + public decimal UnlockAmount { get; set; } + + /// + /// 每日限购次数 + /// + public int DailyXiangou { get; set; } +} diff --git a/ChouBox.Model/Entities/GoodsExtend.cs b/ChouBox.Model/Entities/GoodsExtend.cs new file mode 100644 index 0000000..3a54503 --- /dev/null +++ b/ChouBox.Model/Entities/GoodsExtend.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 盒子扩展表 +/// +public partial class GoodsExtend +{ + /// + /// 主键 + /// + public uint Id { get; set; } + + /// + /// 奖品Id + /// + public int GoodsId { get; set; } + + /// + /// 微信支付 + /// + public bool? PayWechat { get; set; } + + /// + /// 余额支付 + /// + public bool? PayBalance { get; set; } + + /// + /// 货币支付 + /// + public bool? PayCurrency { get; set; } + + /// + /// 货币2支付 + /// + public bool? PayCurrency2 { get; set; } + + /// + /// 优惠券支付 + /// + public bool? PayCoupon { get; set; } + + /// + /// 是否抵扣 1:抵扣 0:支付 + /// + public bool? IsDeduction { get; set; } +} diff --git a/ChouBox.Model/Entities/GoodsExtendList.cs b/ChouBox.Model/Entities/GoodsExtendList.cs new file mode 100644 index 0000000..578b3fd --- /dev/null +++ b/ChouBox.Model/Entities/GoodsExtendList.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +public partial class GoodsExtendList +{ + /// + /// 主键 + /// + public uint Id { get; set; } + + /// + /// 奖品Id + /// + public int GoodsId { get; set; } + + /// + /// 盲盒id + /// + public int GoodsListId { get; set; } + + /// + /// 最低抽奖次数 + /// + public int RewardNum { get; set; } + + /// + /// 奖品编号 + /// + public string PrizeCode { get; set; } = null!; + + /// + /// 1,默认最低抽奖次数,2指定多少抽出,3指定范围内必出,4:指定用户 + /// + public int RawrdType { get; set; } + + /// + /// 最低抽奖次数 + /// + public int? RewardNum1 { get; set; } +} diff --git a/ChouBox.Model/Entities/GoodsKingRank.cs b/ChouBox.Model/Entities/GoodsKingRank.cs new file mode 100644 index 0000000..01a0a07 --- /dev/null +++ b/ChouBox.Model/Entities/GoodsKingRank.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 无限赏领主 +/// +public partial class GoodsKingRank +{ + public uint Id { get; set; } + + public uint UserId { get; set; } + + public int GoodsId { get; set; } + + /// + /// 多少发升级为领主 + /// + public int? Count { get; set; } + + /// + /// 占领了多少发 + /// + public uint? ZNums { get; set; } + + public decimal? Money { get; set; } + + /// + /// 奖品ID + /// + public int? OrderListId { get; set; } + + /// + /// 开始时间 + /// + public int? Addtime { get; set; } + + /// + /// 结束时间 + /// + public int? EndTime { get; set; } +} diff --git a/ChouBox.Model/Entities/GoodsList.cs b/ChouBox.Model/Entities/GoodsList.cs new file mode 100644 index 0000000..9de3fdd --- /dev/null +++ b/ChouBox.Model/Entities/GoodsList.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 盒子奖品 +/// +public partial class GoodsList +{ + public uint Id { get; set; } + + /// + /// 盲盒id 0无限令 -1周榜 -2月榜 + /// + public int GoodsId { get; set; } + + /// + /// 第几套 + /// + public uint Num { get; set; } + + /// + /// 奖品名称 + /// + public string Title { get; set; } = null!; + + /// + /// 奖品图片 + /// + public string Imgurl { get; set; } = null!; + + /// + /// 库存 + /// + public uint Stock { get; set; } + + /// + /// 剩余库存 + /// + public uint SurplusStock { get; set; } + + /// + /// 奖品价值 + /// + public decimal Price { get; set; } + + /// + /// 奖品兑换价 + /// + public decimal Money { get; set; } + + /// + /// 市场参考价 + /// + public decimal? ScMoney { get; set; } + + /// + /// 真实概率 + /// + public decimal RealPro { get; set; } + + /// + /// 1现货 2预售 + /// + public byte GoodsType { get; set; } + + /// + /// 预售时间 + /// + public uint SaleTime { get; set; } + + /// + /// 排序 + /// + public uint Sort { get; set; } + + /// + /// 赏ID + /// + public int? ShangId { get; set; } + + public uint RewardNum { get; set; } + + /// + /// 榜单排名 + /// + public uint Rank { get; set; } + + /// + /// 消费阀值 + /// + public uint GiveMoney { get; set; } + + /// + /// 抽卡机特殊库存 + /// + public int SpecialStock { get; set; } + + /// + /// 奖品赠送编号 + /// + public string? CardNo { get; set; } + + /// + /// 奖品编号 + /// + public string? PrizeCode { get; set; } + + /// + /// 添加时间 + /// + public int? Addtime { get; set; } + + public uint UpdateTime { get; set; } + + /// + /// 擂台赏抽全局赏数量 + /// + public int? PrizeNum { get; set; } + + /// + /// 7抽奖券的奖品 + /// + public bool? Type { get; set; } + + /// + /// 连击赏奖池分类 1秘宝池 0否 + /// + public bool? LianJiType { get; set; } + + /// + /// 发放奖励id + /// + public string? RewardId { get; set; } + + /// + /// 商品详情图 + /// + public string? ImgurlDetail { get; set; } + + /// + /// 倍率 + /// + public int Doubling { get; set; } + + /// + /// 父节点id + /// + public int GoodsListId { get; set; } + + /// + /// 是否为领主 + /// + public bool IsLingzhu { get; set; } +} diff --git a/ChouBox.Model/Entities/GoodsLock.cs b/ChouBox.Model/Entities/GoodsLock.cs new file mode 100644 index 0000000..cca71f9 --- /dev/null +++ b/ChouBox.Model/Entities/GoodsLock.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 盒子锁箱信息 +/// +public partial class GoodsLock +{ + public uint Id { get; set; } + + /// + /// 用户ID + /// + public uint UserId { get; set; } + + /// + /// 盒子id_num + /// + public string GoodsIdNum { get; set; } = null!; + + /// + /// 过期时间 + /// + public uint Endtime { get; set; } + + public uint UpdateTime { get; set; } +} diff --git a/ChouBox.Model/Entities/GoodsOffshelfLog.cs b/ChouBox.Model/Entities/GoodsOffshelfLog.cs new file mode 100644 index 0000000..1f60f65 --- /dev/null +++ b/ChouBox.Model/Entities/GoodsOffshelfLog.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 盒子自动下架日志表 +/// +public partial class GoodsOffshelfLog +{ + public int Id { get; set; } + + /// + /// 盒子ID + /// + public int GoodsId { get; set; } + + /// + /// 当前利润率 + /// + public decimal ProfitRate { get; set; } + + /// + /// 配置的下架利润阈值 + /// + public decimal XiajiaLirun { get; set; } + + /// + /// 订单总价值 + /// + public decimal OrderTotal { get; set; } + + /// + /// 出货总价值 + /// + public decimal GoodsTotal { get; set; } + + /// + /// 下架时间 + /// + public int CreateTime { get; set; } +} diff --git a/ChouBox.Model/Entities/GoodsType.cs b/ChouBox.Model/Entities/GoodsType.cs new file mode 100644 index 0000000..9f66682 --- /dev/null +++ b/ChouBox.Model/Entities/GoodsType.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +public partial class GoodsType +{ + /// + /// 主键 + /// + public int Id { get; set; } + + /// + /// 名称 + /// + public string Name { get; set; } = null!; + + /// + /// key + /// + public int Value { get; set; } + + /// + /// 排序字段 + /// + public int SortOrder { get; set; } + + /// + /// 是否首页显示 + /// + public bool IsShow { get; set; } + + /// + /// 备注 + /// + public string? Remark { get; set; } + + /// + /// 微信支付 + /// + public bool? PayWechat { get; set; } + + /// + /// 余额支付 + /// + public bool? PayBalance { get; set; } + + /// + /// 货币支付 + /// + public bool? PayCurrency { get; set; } + + /// + /// 货币2支付 + /// + public bool? PayCurrency2 { get; set; } + + /// + /// 优惠券支付 + /// + public bool? PayCoupon { get; set; } + + /// + /// 是否抵扣 1:抵扣 0:支付 + /// + public bool? IsDeduction { get; set; } + + /// + /// 是否显示在分类中 + /// + public sbyte IsFenlei { get; set; } + + /// + /// 分类名称 + /// + public string FlName { get; set; } = null!; + + /// + /// 角标文字 + /// + public string? CornerText { get; set; } +} diff --git a/ChouBox.Model/Entities/ItemCard.cs b/ChouBox.Model/Entities/ItemCard.cs new file mode 100644 index 0000000..6a07ab8 --- /dev/null +++ b/ChouBox.Model/Entities/ItemCard.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 道具卡 +/// +public partial class ItemCard +{ + public uint Id { get; set; } + + /// + /// 1重抽卡 + /// + public byte? Type { get; set; } + + /// + /// 名称 + /// + public string Title { get; set; } = null!; + + /// + /// 排序值 + /// + public uint? Sort { get; set; } + + /// + /// 1正常 2下架 3删除 + /// + public bool? Status { get; set; } + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + public int Updatetime { get; set; } +} diff --git a/ChouBox.Model/Entities/KkOrder.cs b/ChouBox.Model/Entities/KkOrder.cs new file mode 100644 index 0000000..0241d71 --- /dev/null +++ b/ChouBox.Model/Entities/KkOrder.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 发货订单表 +/// +public partial class KkOrder +{ + public uint Id { get; set; } + + /// + /// 会员id + /// + public uint UserId { get; set; } + + /// + /// 订单号 + /// + public string OrderNo { get; set; } = null!; + + /// + /// 商品总金额 + /// + public decimal TotalPrice { get; set; } + + /// + /// 实付金额 + /// + public decimal Price { get; set; } + + /// + /// 余额抵扣 + /// + public decimal? Money { get; set; } + + /// + /// Woo币抵扣 + /// + public decimal? Integral { get; set; } + + /// + /// 运费金额 + /// + public decimal FreightPrice { get; set; } + + /// + /// 0待付款 1待发货 2待收货 3确认收货 + /// + public bool Status { get; set; } + + /// + /// 留言 + /// + public string Content { get; set; } = null!; + + /// + /// 创建时间 + /// + public uint Addtime { get; set; } + + /// + /// 支付时间 + /// + public uint PayTime { get; set; } + + /// + /// 发货时间 + /// + public uint DeliverTime { get; set; } + + /// + /// 收货时间 + /// + public uint ConfirmTime { get; set; } + + public int? UpdateTime { get; set; } +} diff --git a/ChouBox.Model/Entities/KkOrderGood.cs b/ChouBox.Model/Entities/KkOrderGood.cs new file mode 100644 index 0000000..c4c2228 --- /dev/null +++ b/ChouBox.Model/Entities/KkOrderGood.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 订单商品 +/// +public partial class KkOrderGood +{ + public uint Id { get; set; } + + /// + /// 会员id + /// + public uint UserId { get; set; } + + /// + /// 订单id + /// + public uint OrderId { get; set; } + + /// + /// 商品id + /// + public uint GoodsId { get; set; } + + /// + /// 商品名称 + /// + public string GoodsName { get; set; } = null!; + + /// + /// 商品主图 + /// + public string GoodsImage { get; set; } = null!; + + /// + /// 商品规格id + /// + public uint GoodsSpecId { get; set; } + + /// + /// 商品规格 + /// + public string GoodsSpec { get; set; } = null!; + + /// + /// 商品售价 + /// + public decimal GoodsPrice { get; set; } + + /// + /// 商品秒杀价 + /// + public decimal GoodsSeckillPrice { get; set; } + + /// + /// 数量 + /// + public uint GoodsNum { get; set; } + + /// + /// 创建时间 + /// + public uint Addtime { get; set; } +} diff --git a/ChouBox.Model/Entities/KkOrderSend.cs b/ChouBox.Model/Entities/KkOrderSend.cs new file mode 100644 index 0000000..c13b4ec --- /dev/null +++ b/ChouBox.Model/Entities/KkOrderSend.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 发货订单地址物流信息 +/// +public partial class KkOrderSend +{ + public uint Id { get; set; } + + /// + /// 会员id + /// + public uint UserId { get; set; } + + /// + /// 订单ID + /// + public uint OrderId { get; set; } + + /// + /// 收货人姓名 + /// + public string? ShouName { get; set; } + + /// + /// 收货人手机号 + /// + public string? ShouMobile { get; set; } + + /// + /// 所在地区 省/市/区(名称) + /// + public string? ShouRegion { get; set; } + + /// + /// 详细地址 + /// + public string? Address { get; set; } + + /// + /// 物流名称 + /// + public string? DeliveryName { get; set; } + + /// + /// 物流单号 + /// + public string? DeliveryNo { get; set; } + + public int? UpdateTime { get; set; } +} diff --git a/ChouBox.Model/Entities/KkProduct.cs b/ChouBox.Model/Entities/KkProduct.cs new file mode 100644 index 0000000..15d45f1 --- /dev/null +++ b/ChouBox.Model/Entities/KkProduct.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 商品表 +/// +public partial class KkProduct +{ + public uint Id { get; set; } + + /// + /// 秒杀时间段id + /// + public uint SeckillId { get; set; } + + /// + /// 分类父级id + /// + public uint CateId1 { get; set; } + + /// + /// 分类子级id + /// + public uint CateId2 { get; set; } + + /// + /// 商品名称 + /// + public string Title { get; set; } = null!; + + /// + /// 商品主图 + /// + public string Image { get; set; } = null!; + + /// + /// 详情图 + /// + public string DetailImage { get; set; } = null!; + + /// + /// 商品详情 + /// + public string? Content { get; set; } + + /// + /// 运费 + /// + public decimal Freight { get; set; } + + /// + /// 销量 + /// + public uint SaleNum { get; set; } + + /// + /// 商品排序 + /// + public uint Sort { get; set; } + + /// + /// 0上架 1下架 + /// + public byte Status { get; set; } + + /// + /// 规格信息 + /// + public string? SpecData { get; set; } + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + /// + /// 修改时间 + /// + public uint UpdateTime { get; set; } +} diff --git a/ChouBox.Model/Entities/KkProductCate.cs b/ChouBox.Model/Entities/KkProductCate.cs new file mode 100644 index 0000000..f3f8841 --- /dev/null +++ b/ChouBox.Model/Entities/KkProductCate.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 商品分类 +/// +public partial class KkProductCate +{ + public uint Id { get; set; } + + /// + /// 分类标题 + /// + public string Title { get; set; } = null!; + + /// + /// 分类图片 + /// + public string? Imgurl { get; set; } + + /// + /// 排序值 + /// + public uint? Sort { get; set; } + + /// + /// 1 正常 2 删除 + /// + public byte? Status { get; set; } + + /// + /// 上级id + /// + public int? Pid { get; set; } + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + /// + /// 英文标题 + /// + public string? Title2 { get; set; } +} diff --git a/ChouBox.Model/Entities/KkProductCategory.cs b/ChouBox.Model/Entities/KkProductCategory.cs new file mode 100644 index 0000000..57058d4 --- /dev/null +++ b/ChouBox.Model/Entities/KkProductCategory.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 普通商城商品分类 +/// +public partial class KkProductCategory +{ + public uint Id { get; set; } + + /// + /// 父级id + /// + public uint Pid { get; set; } + + /// + /// 商品名称 + /// + public string Title { get; set; } = null!; + + /// + /// 分类图片 + /// + public string Imgurl { get; set; } = null!; + + /// + /// 1显示 0隐藏 + /// + public byte Status { get; set; } + + /// + /// 0 + /// + public uint Sort { get; set; } + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + /// + /// 修改时间 + /// + public uint UpdateTime { get; set; } +} diff --git a/ChouBox.Model/Entities/KkProductSpec.cs b/ChouBox.Model/Entities/KkProductSpec.cs new file mode 100644 index 0000000..7b48c5f --- /dev/null +++ b/ChouBox.Model/Entities/KkProductSpec.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 商品规格 +/// +public partial class KkProductSpec +{ + public uint Id { get; set; } + + /// + /// 商品id + /// + public int ProId { get; set; } + + /// + /// 名称 + /// + public string Name { get; set; } = null!; + + /// + /// 售价 + /// + public decimal Price { get; set; } + + /// + /// 秒杀价 + /// + public decimal SeckillPrice { get; set; } + + /// + /// 库存 + /// + public uint Stock { get; set; } + + /// + /// 图片 + /// + public string? Pic { get; set; } + + /// + /// 标识 + /// + public string? Ks { get; set; } + + /// + /// 添加时间 + /// + public uint Time { get; set; } +} diff --git a/ChouBox.Model/Entities/KkSeckill.cs b/ChouBox.Model/Entities/KkSeckill.cs new file mode 100644 index 0000000..57a5e50 --- /dev/null +++ b/ChouBox.Model/Entities/KkSeckill.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 秒杀设置 +/// +public partial class KkSeckill +{ + public uint Id { get; set; } + + /// + /// 秒杀时间段 + /// + public string SeckillTime { get; set; } = null!; + + /// + /// 商品限购数量 + /// + public uint GoodsNum { get; set; } + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + /// + /// 修改时间 + /// + public uint UpdateTime { get; set; } +} diff --git a/ChouBox.Model/Entities/KkShare.cs b/ChouBox.Model/Entities/KkShare.cs new file mode 100644 index 0000000..2d4cd34 --- /dev/null +++ b/ChouBox.Model/Entities/KkShare.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 商品分享记录表 +/// +public partial class KkShare +{ + public uint Id { get; set; } + + /// + /// 点击人ID + /// + public uint UserId { get; set; } + + /// + /// 商品id + /// + public uint GoodsId { get; set; } + + /// + /// 分享用户id + /// + public uint ShareUserId { get; set; } + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } +} diff --git a/ChouBox.Model/Entities/Market.cs b/ChouBox.Model/Entities/Market.cs new file mode 100644 index 0000000..9c20137 --- /dev/null +++ b/ChouBox.Model/Entities/Market.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 集市 +/// +public partial class Market +{ + public uint Id { get; set; } + + public int UserId { get; set; } + + /// + /// 挂售单号 + /// + public string OrderNum { get; set; } = null!; + + /// + /// 价格 + /// + public decimal Price { get; set; } + + /// + /// id字符串 + /// + public string OrderListIds { get; set; } = null!; + + /// + /// 0在售 1已售 2已撤回 + /// + public byte? Status { get; set; } + + public byte Stock { get; set; } + + public int Addtime { get; set; } + + public int UpdateTime { get; set; } + + public int? Deltime { get; set; } +} diff --git a/ChouBox.Model/Entities/MarketOrder.cs b/ChouBox.Model/Entities/MarketOrder.cs new file mode 100644 index 0000000..fc4111b --- /dev/null +++ b/ChouBox.Model/Entities/MarketOrder.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 集市订单 +/// +public partial class MarketOrder +{ + public uint Id { get; set; } + + public int MarketId { get; set; } + + public int UserId { get; set; } + + /// + /// 挂售单号 + /// + public string OrderNum { get; set; } = null!; + + /// + /// 价格 + /// + public decimal Price { get; set; } + + /// + /// id字符串 + /// + public string OrderListIds { get; set; } = null!; + + /// + /// 1未支付 2已支付 3卡单 + /// + public byte? Status { get; set; } + + public int? PayTime { get; set; } + + /// + /// 总价 + /// + public decimal Total { get; set; } + + /// + /// 实际支付 + /// + public decimal TotalPrice { get; set; } + + /// + /// 支付了多少市集余额 + /// + public decimal Money { get; set; } + + public int Addtime { get; set; } + + public int UpdateTime { get; set; } + + public int? Deltime { get; set; } + + public byte ZdfhIs { get; set; } +} diff --git a/ChouBox.Model/Entities/Migrations.cs b/ChouBox.Model/Entities/Migrations.cs new file mode 100644 index 0000000..0e8b0cd --- /dev/null +++ b/ChouBox.Model/Entities/Migrations.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +public partial class Migrations +{ + public long Version { get; set; } + + public string? MigrationName { get; set; } + + public DateTime? StartTime { get; set; } + + public DateTime? EndTime { get; set; } + + public bool Breakpoint { get; set; } +} diff --git a/ChouBox.Model/Entities/NotifyLog.cs b/ChouBox.Model/Entities/NotifyLog.cs new file mode 100644 index 0000000..d35a0f0 --- /dev/null +++ b/ChouBox.Model/Entities/NotifyLog.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +public partial class NotifyLog +{ + public int Id { get; set; } + + public string OrderNo { get; set; } = null!; + + public int Addtime { get; set; } + + public string? Xml { get; set; } +} diff --git a/ChouBox.Model/Entities/Order.cs b/ChouBox.Model/Entities/Order.cs new file mode 100644 index 0000000..f1ae0d6 --- /dev/null +++ b/ChouBox.Model/Entities/Order.cs @@ -0,0 +1,176 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 订单表 +/// +public partial class Order +{ + public uint Id { get; set; } + + /// + /// 用户ID + /// + public uint UserId { get; set; } + + /// + /// 订单号 + /// + public string OrderNum { get; set; } = null!; + + /// + /// 订单总金额 + /// + public decimal OrderTotal { get; set; } + + /// + /// 订单折扣金额 + /// + public decimal OrderZheTotal { get; set; } + + /// + /// 微信支付 + /// + public decimal Price { get; set; } + + /// + /// 钻石支付 + /// + public decimal UseMoney { get; set; } + + /// + /// UU币支付 + /// + public decimal UseIntegral { get; set; } + + /// + /// 积分抵扣,未使用 + /// + public decimal UseScore { get; set; } + + /// + /// 抽奖券抵扣 + /// + public int? UseDraw { get; set; } + + /// + /// 道具卡抵扣 (使用的数量) + /// + public int? UseItemCard { get; set; } + + /// + /// 折扣 + /// + public decimal Zhe { get; set; } + + /// + /// 盒子id + /// + public uint GoodsId { get; set; } + + /// + /// 第几套 + /// + public uint Num { get; set; } + + /// + /// 盒子单价 + /// + public decimal GoodsPrice { get; set; } + + /// + /// 盒子标题 + /// + public string? GoodsTitle { get; set; } + + /// + /// 盒子图片 + /// + public string? GoodsImgurl { get; set; } + + /// + /// 抽奖数量 + /// + public uint PrizeNum { get; set; } + + /// + /// 抽卡机必出设置 + /// + public string? PrizeCardSet { get; set; } + + /// + /// 0未支付 1支付 + /// + public byte Status { get; set; } + + /// + /// 下单时间 + /// + public uint Addtime { get; set; } + + /// + /// 付款时间 + /// + public uint PayTime { get; set; } + + /// + /// 1微信 2支付宝 + /// + public byte PayType { get; set; } + + /// + /// 盒子类型 + /// + public byte OrderType { get; set; } + + /// + /// 1卡单 + /// + public byte KdIs { get; set; } + + /// + /// 优惠券id + /// + public int? CouponId { get; set; } + + /// + /// 优惠券抵扣 + /// + public decimal? UseCoupon { get; set; } + + /// + /// 连击赏下 是否是抽的秘宝池 1是 0否 + /// + public bool? IsMibao { get; set; } + + /// + /// 是否首抽五折 + /// + public bool? IsShouZhe { get; set; } + + public byte ZdfhIs { get; set; } + + /// + /// 广告id + /// + public int? AdId { get; set; } + + public int? ClickId { get; set; } + + /// + /// 是否为福利屋 + /// + public int IsFlw { get; set; } + + /// + /// 自动发货时间 + /// + public int? ZdfhTime { get; set; } + + /// + /// 达达卷支付 + /// + public decimal UseMoney2 { get; set; } +} diff --git a/ChouBox.Model/Entities/OrderList.cs b/ChouBox.Model/Entities/OrderList.cs new file mode 100644 index 0000000..8ce7319 --- /dev/null +++ b/ChouBox.Model/Entities/OrderList.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 订单明细 +/// +public partial class OrderList +{ + public uint Id { get; set; } + + /// + /// 订单id + /// + public uint OrderId { get; set; } + + /// + /// 用户id + /// + public uint UserId { get; set; } + + /// + /// 回收订单 + /// + public string? RecoveryNum { get; set; } + + /// + /// 发货订单号 + /// + public string? SendNum { get; set; } + + /// + /// 0待选择 1回收 2选择发货 3发布集市 + /// + public byte Status { get; set; } + + /// + /// 盒子ID + /// + public int? GoodsId { get; set; } + + /// + /// 第几箱 + /// + public uint Num { get; set; } + + /// + /// 赏ID + /// + public uint ShangId { get; set; } + + /// + /// 奖品id + /// + public uint GoodslistId { get; set; } + + /// + /// 奖品名称 + /// + public string? GoodslistTitle { get; set; } + + /// + /// 奖品封面图 + /// + public string? GoodslistImgurl { get; set; } + + /// + /// 奖品价值 + /// + public decimal GoodslistPrice { get; set; } + + /// + /// 奖品回收 + /// + public decimal GoodslistMoney { get; set; } + + /// + /// 1现货 2预售,3货币,4 宝箱 + /// + public byte GoodslistType { get; set; } + + /// + /// 预售时间 + /// + public uint GoodslistSaleTime { get; set; } + + /// + /// 创建时间 + /// + public uint Addtime { get; set; } + + /// + /// 选择发货/回收时间 + /// + public uint ChoiceTime { get; set; } + + /// + /// 保险柜0否 1是 + /// + public byte InsuranceIs { get; set; } + + /// + /// 盒子类型 + /// + public byte OrderType { get; set; } + + /// + /// 特殊奖品中奖订单id + /// + public uint OrderListId { get; set; } + + /// + /// 抽奖序号 + /// + public uint LuckNo { get; set; } + + /// + /// 奖品code + /// + public string? PrizeCode { get; set; } + + /// + /// 是否使用重抽卡 0否 1是 + /// + public bool? IsChong { get; set; } + + public int? Deltime { get; set; } + + /// + /// 1抽奖 2集市购买 + /// + public byte? Source { get; set; } + + /// + /// 发货状态,1已发货,2未发货 + /// + public int FhStatus { get; set; } + + /// + /// 发货备注 + /// + public string? FhRemarks { get; set; } + + /// + /// 抽奖倍率 + /// + public int Doubling { get; set; } + + /// + /// 所属宝箱id + /// + public int ParentGoodsListId { get; set; } + + /// + /// 是否是领主奖品 + /// + public sbyte IsLingzhu { get; set; } +} diff --git a/ChouBox.Model/Entities/OrderListRecovery.cs b/ChouBox.Model/Entities/OrderListRecovery.cs new file mode 100644 index 0000000..442578d --- /dev/null +++ b/ChouBox.Model/Entities/OrderListRecovery.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 打包记录 +/// +public partial class OrderListRecovery +{ + public uint Id { get; set; } + + public uint UserId { get; set; } + + /// + /// 打包订单号 + /// + public string RecoveryNum { get; set; } = null!; + + /// + /// 打包金额 + /// + public decimal Money { get; set; } + + /// + /// 打包数量 + /// + public uint Count { get; set; } + + /// + /// 打包时间 + /// + public uint Addtime { get; set; } +} diff --git a/ChouBox.Model/Entities/OrderListSend.cs b/ChouBox.Model/Entities/OrderListSend.cs new file mode 100644 index 0000000..2a32e28 --- /dev/null +++ b/ChouBox.Model/Entities/OrderListSend.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 发货记录 +/// +public partial class OrderListSend +{ + public uint Id { get; set; } + + /// + /// 用户id + /// + public uint UserId { get; set; } + + /// + /// 发货订单号 + /// + public string SendNum { get; set; } = null!; + + /// + /// 运费 + /// + public decimal Freight { get; set; } + + /// + /// 0待支付 1待发货 2待收货 3已完成 4后台取消 + /// + public byte Status { get; set; } + + /// + /// 发货数量 + /// + public uint Count { get; set; } + + /// + /// 收货人姓名 + /// + public string? Name { get; set; } + + /// + /// 收货人电话 + /// + public string? Mobile { get; set; } + + /// + /// 收货地址 + /// + public string? Address { get; set; } + + /// + /// 备注 + /// + public string? Message { get; set; } + + /// + /// 快递单号 + /// + public string? CourierNumber { get; set; } + + /// + /// 快递名称 + /// + public string? CourierName { get; set; } + + /// + /// 快递code + /// + public string? CourierCode { get; set; } + + /// + /// 物流轨迹信息 + /// + public string? DeliveryList { get; set; } + + /// + /// 物流状态 + /// + public bool? DeliveryStatus { get; set; } + + /// + /// 物流请求时间 + /// + public uint DeliveryTime { get; set; } + + /// + /// 下单时间 + /// + public uint Addtime { get; set; } + + /// + /// 支付时间 + /// + public uint PayTime { get; set; } + + /// + /// 发货时间 + /// + public uint SendTime { get; set; } + + /// + /// 收货时间 + /// + public uint ShouTime { get; set; } + + /// + /// 取消时间 + /// + public uint CancelTime { get; set; } + + /// + /// 管理员id + /// + public uint AdminId { get; set; } +} diff --git a/ChouBox.Model/Entities/Picture.cs b/ChouBox.Model/Entities/Picture.cs new file mode 100644 index 0000000..db9ac64 --- /dev/null +++ b/ChouBox.Model/Entities/Picture.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +public partial class Picture +{ + public uint Id { get; set; } + + public string Imgurl { get; set; } = null!; + + public string Token { get; set; } = null!; + + public uint Addtime { get; set; } + + /// + /// 1 正常 2 删除 + /// + public byte Status { get; set; } + + /// + /// 存储位置 1=本地 2= 阿里云 + /// + public bool? Type { get; set; } +} diff --git a/ChouBox.Model/Entities/ProfitDraw.cs b/ChouBox.Model/Entities/ProfitDraw.cs new file mode 100644 index 0000000..f00edba --- /dev/null +++ b/ChouBox.Model/Entities/ProfitDraw.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 财务明细 +/// +public partial class ProfitDraw +{ + public uint Id { get; set; } + + /// + /// 用户id + /// + public uint UserId { get; set; } + + /// + /// 变化的金额 + /// + public decimal ChangeMoney { get; set; } + + /// + /// 变化后的金额 + /// + public decimal Money { get; set; } + + /// + /// 1后台充值 2在线充值 3抽赏消费 4背包回收 5推荐奖励 + /// + public byte Type { get; set; } + + /// + /// 描述 + /// + public string Content { get; set; } = null!; + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + /// + /// 来源ID + /// + public uint ShareUid { get; set; } + + public string? Other { get; set; } +} diff --git a/ChouBox.Model/Entities/ProfitExpenses.cs b/ChouBox.Model/Entities/ProfitExpenses.cs new file mode 100644 index 0000000..979ab43 --- /dev/null +++ b/ChouBox.Model/Entities/ProfitExpenses.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 利润支出表 +/// +public partial class ProfitExpenses +{ + /// + /// 主键 + /// + public int Id { get; set; } + + /// + /// 支出类型 + /// + public int ExpenseType { get; set; } + + /// + /// 支出金额 + /// + public decimal Amount { get; set; } + + /// + /// 说明 + /// + public string? Description { get; set; } + + /// + /// 创建时间 + /// + public DateTime? CreatedAt { get; set; } + + /// + /// 修改时间 + /// + public DateTime? UpdatedAt { get; set; } + + /// + /// 账单日期 + /// + public DateOnly ProfitDate { get; set; } +} diff --git a/ChouBox.Model/Entities/ProfitIntegral.cs b/ChouBox.Model/Entities/ProfitIntegral.cs new file mode 100644 index 0000000..3e5d1b1 --- /dev/null +++ b/ChouBox.Model/Entities/ProfitIntegral.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 财务明细 +/// +public partial class ProfitIntegral +{ + public uint Id { get; set; } + + /// + /// 用户id + /// + public uint UserId { get; set; } + + /// + /// 变化的金额 + /// + public decimal ChangeMoney { get; set; } + + /// + /// 变化后的金额 + /// + public decimal Money { get; set; } + + /// + /// 1后台充值 2抽赏消费 3开券获得 4领主返币 5分享欧气券 + /// + public byte Type { get; set; } + + /// + /// 描述 + /// + public string Content { get; set; } = null!; + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + /// + /// 来源ID + /// + public uint ShareUid { get; set; } + + public string? Other { get; set; } +} diff --git a/ChouBox.Model/Entities/ProfitMoney.cs b/ChouBox.Model/Entities/ProfitMoney.cs new file mode 100644 index 0000000..851ffcd --- /dev/null +++ b/ChouBox.Model/Entities/ProfitMoney.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 财务明细 +/// +public partial class ProfitMoney +{ + public uint Id { get; set; } + + /// + /// 用户id + /// + public uint UserId { get; set; } + + /// + /// 变化的金额 + /// + public decimal ChangeMoney { get; set; } + + /// + /// 变化后的金额 + /// + public decimal Money { get; set; } + + /// + /// 1后台充值 2在线充值 3抽赏消费 4背包回收 5推荐奖励 + /// + public byte Type { get; set; } + + /// + /// 描述 + /// + public string Content { get; set; } = null!; + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + /// + /// 来源ID + /// + public uint ShareUid { get; set; } + + public string? Other { get; set; } +} diff --git a/ChouBox.Model/Entities/ProfitMoney2.cs b/ChouBox.Model/Entities/ProfitMoney2.cs new file mode 100644 index 0000000..dcdc7fb --- /dev/null +++ b/ChouBox.Model/Entities/ProfitMoney2.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 财务明细 +/// +public partial class ProfitMoney2 +{ + public uint Id { get; set; } + + /// + /// 用户id + /// + public uint UserId { get; set; } + + /// + /// 变化的金额 + /// + public decimal ChangeMoney { get; set; } + + /// + /// 变化后的金额 + /// + public decimal Money { get; set; } + + /// + /// 1后台充值 2在线充值 3市集消费 4市集售卖 5提现 6提现驳回 7提现手续费 + /// + public byte Type { get; set; } + + /// + /// 描述 + /// + public string Content { get; set; } = null!; + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + /// + /// 来源ID + /// + public uint ShareUid { get; set; } + + public string? Other { get; set; } +} diff --git a/ChouBox.Model/Entities/ProfitOuQi.cs b/ChouBox.Model/Entities/ProfitOuQi.cs new file mode 100644 index 0000000..9dbe73b --- /dev/null +++ b/ChouBox.Model/Entities/ProfitOuQi.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 欧气值明细 +/// +public partial class ProfitOuQi +{ + public uint Id { get; set; } + + /// + /// 用户id + /// + public uint UserId { get; set; } + + /// + /// 变化的金额 + /// + public decimal ChangeMoney { get; set; } + + /// + /// 变化后的金额 + /// + public decimal Money { get; set; } + + /// + /// 1完成任务 2消费赠送 3升级清空 4升级后多出 + /// + public byte Type { get; set; } + + /// + /// 描述 + /// + public string Content { get; set; } = null!; + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + public string? Other { get; set; } +} diff --git a/ChouBox.Model/Entities/ProfitPay.cs b/ChouBox.Model/Entities/ProfitPay.cs new file mode 100644 index 0000000..ac7c56c --- /dev/null +++ b/ChouBox.Model/Entities/ProfitPay.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// (微信/支付宝)支付 +/// +public partial class ProfitPay +{ + public uint Id { get; set; } + + /// + /// 用户id + /// + public uint UserId { get; set; } + + /// + /// 订单号 + /// + public string OrderNum { get; set; } = null!; + + /// + /// 变化的金额 + /// + public decimal ChangeMoney { get; set; } + + /// + /// 描述 + /// + public string Content { get; set; } = null!; + + /// + /// 1微信 2支付宝 + /// + public byte PayType { get; set; } + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } +} diff --git a/ChouBox.Model/Entities/ProfitRevenue.cs b/ChouBox.Model/Entities/ProfitRevenue.cs new file mode 100644 index 0000000..c75e74d --- /dev/null +++ b/ChouBox.Model/Entities/ProfitRevenue.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 利润收入表 +/// +public partial class ProfitRevenue +{ + /// + /// 主键 + /// + public int Id { get; set; } + + /// + /// 收入类型 + /// + public int ExpenseType { get; set; } + + /// + /// 收入金额 + /// + public decimal Price { get; set; } + + /// + /// 用户id + /// + public int UserId { get; set; } + + /// + /// 发放货币 + /// + public decimal Amount { get; set; } + + /// + /// 说明 + /// + public string? Description { get; set; } + + /// + /// 创建时间 + /// + public DateTime? CreatedAt { get; set; } + + /// + /// 修改时间 + /// + public DateTime? UpdatedAt { get; set; } + + /// + /// 账单日期 + /// + public DateOnly ProfitDate { get; set; } +} diff --git a/ChouBox.Model/Entities/ProfitScore.cs b/ChouBox.Model/Entities/ProfitScore.cs new file mode 100644 index 0000000..05e9caa --- /dev/null +++ b/ChouBox.Model/Entities/ProfitScore.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 财务明细 +/// +public partial class ProfitScore +{ + public uint Id { get; set; } + + /// + /// 用户id + /// + public uint UserId { get; set; } + + /// + /// 变化的金额 + /// + public decimal ChangeMoney { get; set; } + + /// + /// 变化后的金额 + /// + public decimal Money { get; set; } + + /// + /// 1后台充值 2抽赏消费 3升级获得 4抽赏奖励 + /// + public byte Type { get; set; } + + /// + /// 描述 + /// + public string Content { get; set; } = null!; + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + /// + /// 来源ID + /// + public uint ShareUid { get; set; } + + public string? Other { get; set; } +} diff --git a/ChouBox.Model/Entities/QuanYiLevel.cs b/ChouBox.Model/Entities/QuanYiLevel.cs new file mode 100644 index 0000000..aac0c3c --- /dev/null +++ b/ChouBox.Model/Entities/QuanYiLevel.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 权益等级表 +/// +public partial class QuanYiLevel +{ + public uint Id { get; set; } + + public int Level { get; set; } + + public string Title { get; set; } = null!; + + /// + /// 需要多少欧气值 + /// + public int Number { get; set; } + + public int Addtime { get; set; } + + public int Updatetime { get; set; } + + public int? Deltime { get; set; } +} diff --git a/ChouBox.Model/Entities/QuanYiLevelJiang.cs b/ChouBox.Model/Entities/QuanYiLevelJiang.cs new file mode 100644 index 0000000..91ecefb --- /dev/null +++ b/ChouBox.Model/Entities/QuanYiLevelJiang.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 权益中心等级奖品 +/// +public partial class QuanYiLevelJiang +{ + public uint Id { get; set; } + + public int QyLevelId { get; set; } + + public int? QyLevel { get; set; } + + /// + /// 1普通降临(优惠券) 2高级奖励(奖品) + /// + public bool Type { get; set; } + + public string Title { get; set; } = null!; + + /// + /// 减多少 + /// + public decimal? JianPrice { get; set; } + + public uint? CouponId { get; set; } + + /// + /// 满多少 + /// + public decimal? ManPrice { get; set; } + + /// + /// 概率 + /// + public decimal? Probability { get; set; } + + /// + /// 有效时间(天) + /// + public int? EffectiveDay { get; set; } + + /// + /// 优惠券赠送多少 + /// + public uint? ZNum { get; set; } + + /// + /// 奖品图片 + /// + public string? Imgurl { get; set; } + + public int? ShangId { get; set; } + + /// + /// 奖品价值 + /// + public decimal? JiangPrice { get; set; } + + /// + /// 奖品兑换价 + /// + public decimal? Money { get; set; } + + /// + /// 市场参考价 + /// + public decimal? ScMoney { get; set; } + + /// + /// 奖品编号 + /// + public string? PrizeCode { get; set; } + + public int Addtime { get; set; } + + public int Updatetime { get; set; } + + public int? Deltime { get; set; } +} diff --git a/ChouBox.Model/Entities/RankMonth.cs b/ChouBox.Model/Entities/RankMonth.cs new file mode 100644 index 0000000..c3b4f1a --- /dev/null +++ b/ChouBox.Model/Entities/RankMonth.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 排行榜月榜 +/// +public partial class RankMonth +{ + public uint Id { get; set; } + + /// + /// 用户ID + /// + public uint UserId { get; set; } + + /// + /// 排名 + /// + public uint Rank { get; set; } + + /// + /// 消费金额 + /// + public decimal Money { get; set; } + + /// + /// 统计范围 + /// + public string MonthTime { get; set; } = null!; + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + /// + /// 奖品ID + /// + public uint OrderListId { get; set; } + + public string? PrizeTitle { get; set; } + + public string? PrizeImgurl { get; set; } +} diff --git a/ChouBox.Model/Entities/RankWeek.cs b/ChouBox.Model/Entities/RankWeek.cs new file mode 100644 index 0000000..4ce867a --- /dev/null +++ b/ChouBox.Model/Entities/RankWeek.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 排行榜周榜 +/// +public partial class RankWeek +{ + public uint Id { get; set; } + + /// + /// 用户ID + /// + public uint UserId { get; set; } + + /// + /// 排名 + /// + public uint Rank { get; set; } + + /// + /// 消费金额 + /// + public decimal Money { get; set; } + + /// + /// 统计范围 + /// + public string WeekTime { get; set; } = null!; + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + /// + /// 奖品ID + /// + public uint OrderListId { get; set; } + + public string? PrizeTitle { get; set; } + + public string? PrizeImgurl { get; set; } +} diff --git a/ChouBox.Model/Entities/Reward.cs b/ChouBox.Model/Entities/Reward.cs new file mode 100644 index 0000000..2cdd2b1 --- /dev/null +++ b/ChouBox.Model/Entities/Reward.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 奖励表 +/// +public partial class Reward +{ + public int Id { get; set; } + + /// + /// 奖励类型(1:钻石,2:货币1,3:货币2,4:优惠券) + /// + public int RewardType { get; set; } + + /// + /// 奖励ID(当reward_type=1时为优惠券ID) + /// + public int? RewardExtend { get; set; } + + /// + /// 奖励值 + /// + public decimal RewardValue { get; set; } + + /// + /// 奖励描述 + /// + public string? Description { get; set; } + + public int? CreateTime { get; set; } + + public int? UpdateTime { get; set; } + + /// + /// 关联表id + /// + public string RewardId { get; set; } = null!; +} diff --git a/ChouBox.Model/Entities/Shang.cs b/ChouBox.Model/Entities/Shang.cs new file mode 100644 index 0000000..a518ee2 --- /dev/null +++ b/ChouBox.Model/Entities/Shang.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +public partial class Shang +{ + public uint Id { get; set; } + + public string Title { get; set; } = null!; + + public decimal Pro { get; set; } + + public string? Imgurl { get; set; } + + public string? Color { get; set; } + + public uint GoodsId { get; set; } + + public string? SpecialImgurl { get; set; } + + public uint Sort { get; set; } + + public uint? UpdateTime { get; set; } +} diff --git a/ChouBox.Model/Entities/SignConfig.cs b/ChouBox.Model/Entities/SignConfig.cs new file mode 100644 index 0000000..5ad69ff --- /dev/null +++ b/ChouBox.Model/Entities/SignConfig.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 签到配置表 +/// +public partial class SignConfig +{ + public int Id { get; set; } + + /// + /// 配置类型(1:累计签到配置,2:每日签到配置) + /// + public bool Type { get; set; } + + /// + /// 指定星期几(type=2时有效,1-7代表周一到周日) + /// + public bool? Day { get; set; } + + /// + /// 配置标题 + /// + public string? Title { get; set; } + + /// + /// 图标 + /// + public string? Icon { get; set; } + + /// + /// 状态(0禁用,1启用) + /// + public bool? Status { get; set; } + + /// + /// 排序 + /// + public int? Sort { get; set; } + + public int? CreateTime { get; set; } + + public int? UpdateTime { get; set; } + + /// + /// 奖励id + /// + public string RewardId { get; set; } = null!; + + /// + /// 备注 + /// + public string? Description { get; set; } +} diff --git a/ChouBox.Model/Entities/TaskList.cs b/ChouBox.Model/Entities/TaskList.cs new file mode 100644 index 0000000..c15bc83 --- /dev/null +++ b/ChouBox.Model/Entities/TaskList.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 任务表 +/// +public partial class TaskList +{ + public uint Id { get; set; } + + /// + /// 任务名称 + /// + public string Title { get; set; } = null!; + + /// + /// 1每日任务 2每周任务 + /// + public bool Type { get; set; } + + /// + /// 任务分类 1邀请好友注册 2抽赏任务 + /// + public bool Cate { get; set; } + + /// + /// 是否是重要任务 1是 0否 + /// + public bool? IsImportant { get; set; } + + /// + /// 需要完成任务几次 + /// + public int? Number { get; set; } + + /// + /// 赠送多少欧气值 + /// + public uint? ZNumber { get; set; } + + /// + /// 排序 + /// + public uint? Sort { get; set; } + + public int Addtime { get; set; } + + public int Updatetime { get; set; } + + public int? Deltime { get; set; } +} diff --git a/ChouBox.Model/Entities/User.cs b/ChouBox.Model/Entities/User.cs new file mode 100644 index 0000000..a9cf90b --- /dev/null +++ b/ChouBox.Model/Entities/User.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +public partial class User +{ + public uint Id { get; set; } + + /// + /// 微信openid + /// + public string Openid { get; set; } = null!; + + /// + /// 手机号 + /// + public string? Mobile { get; set; } + + /// + /// 昵称 + /// + public string Nickname { get; set; } = null!; + + /// + /// 头像 + /// + public string Headimg { get; set; } = null!; + + /// + /// 父级id + /// + public uint Pid { get; set; } + + /// + /// 余额 + /// + public decimal Money { get; set; } + + /// + /// 集市余额 + /// + public decimal? Money2 { get; set; } + + /// + /// 幸运币 + /// + public decimal Integral { get; set; } + + /// + /// 积分 + /// + public decimal Score { get; set; } + + /// + /// 欧气值 + /// + public uint? OuQi { get; set; } + + /// + /// 欧气值等级 + /// + public uint? OuQiLevel { get; set; } + + /// + /// vip等级 + /// + public byte Vip { get; set; } + + /// + /// 分享海报 + /// + public string? ShareImage { get; set; } + + /// + /// 状态:1正常,2禁用 + /// + public bool? Status { get; set; } + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + /// + /// 修改时间 + /// + public uint UpdateTime { get; set; } + + /// + /// 最后操作时间 + /// + public uint LastLoginTime { get; set; } + + /// + /// 优惠券的数量 + /// + public int? DrawNum { get; set; } + + /// + /// 0未领取1已领取 + /// + public sbyte? IsUseCoupon { get; set; } + + /// + /// 连击赏秘宝池抽奖次数 + /// + public uint? MbNumber { get; set; } + + public int? ClickId { get; set; } + + /// + /// 用户唯一id + /// + public string? Unionid { get; set; } + + /// + /// 公众号openid + /// + public string? GzhOpenid { get; set; } + + public string? Password { get; set; } + + /// + /// 是否测试账号 + /// + public int Istest { get; set; } + + /// + /// 唯一编号 + /// + public string Uid { get; set; } = null!; +} diff --git a/ChouBox.Model/Entities/UserAccount.cs b/ChouBox.Model/Entities/UserAccount.cs new file mode 100644 index 0000000..db8dce4 --- /dev/null +++ b/ChouBox.Model/Entities/UserAccount.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +public partial class UserAccount +{ + public uint Id { get; set; } + + public uint UserId { get; set; } + + /// + /// 登陆秘钥 + /// + public string AccountToken { get; set; } = null!; + + /// + /// 秘钥随机数 + /// + public string TokenNum { get; set; } = null!; + + /// + /// 秘钥时间戳 + /// + public uint TokenTime { get; set; } + + public uint LastLoginTime { get; set; } + + public string LastLoginIp { get; set; } = null!; + + /// + /// ip + /// + public string? LastLoginIp1 { get; set; } + + /// + /// ip邮编 + /// + public string? IpAdcode { get; set; } + + public string? IpProvince { get; set; } + + public string? IpCity { get; set; } +} diff --git a/ChouBox.Model/Entities/UserCoupon.cs b/ChouBox.Model/Entities/UserCoupon.cs new file mode 100644 index 0000000..639f7cf --- /dev/null +++ b/ChouBox.Model/Entities/UserCoupon.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 欧气劵 +/// +public partial class UserCoupon +{ + public int Id { get; set; } + + /// + /// 用户的id + /// + public uint UserId { get; set; } + + /// + /// 1特级赏券 2终极赏券 3高级赏券 4普通赏券 + /// + public uint? Level { get; set; } + + /// + /// 开奖总金额 + /// + public uint Num { get; set; } + + /// + /// 领取多少 + /// + public decimal? LNum { get; set; } + + /// + /// 1未分享 2已分享 3已领取 4被消耗融合 + /// + public byte Status { get; set; } + + /// + /// 1下单赠送 2领取 3融合得到 + /// + public byte Type { get; set; } + + /// + /// 劵名称 + /// + public string Title { get; set; } = null!; + + /// + /// 来源id (订单、领取) + /// + public string FromId { get; set; } = null!; + + /// + /// 分享时间 + /// + public int? ShareTime { get; set; } + + /// + /// 获取时间 + /// + public uint Addtime { get; set; } + + public int? Updatetime { get; set; } + + /// + /// 自己可以获得多少 + /// + public decimal? Own { get; set; } + + /// + /// 自己可以获得多少 + /// + public decimal? Own2 { get; set; } + + /// + /// 其他人可以获得多少 + /// + public decimal? Other { get; set; } + + /// + /// 其他人可以获得多少 + /// + public decimal? Other2 { get; set; } + + /// + /// 最多可参与人数 + /// + public uint? KlNum { get; set; } + + /// + /// 最多可参与人数 + /// + public uint? KlNum2 { get; set; } +} diff --git a/ChouBox.Model/Entities/UserGoodsLianJi.cs b/ChouBox.Model/Entities/UserGoodsLianJi.cs new file mode 100644 index 0000000..bc15184 --- /dev/null +++ b/ChouBox.Model/Entities/UserGoodsLianJi.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 用户连击赏连击次数 +/// +public partial class UserGoodsLianJi +{ + public uint Id { get; set; } + + public int UserId { get; set; } + + public int GoodsId { get; set; } + + /// + /// 连击次数 + /// + public uint Number { get; set; } + + public int Addtime { get; set; } + + public int Updatetime { get; set; } + + public int? Deltime { get; set; } +} diff --git a/ChouBox.Model/Entities/UserItemCard.cs b/ChouBox.Model/Entities/UserItemCard.cs new file mode 100644 index 0000000..cc95628 --- /dev/null +++ b/ChouBox.Model/Entities/UserItemCard.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 用户的道具卡 +/// +public partial class UserItemCard +{ + public uint Id { get; set; } + + public int UserId { get; set; } + + /// + /// 类型 + /// + public byte? Type { get; set; } + + public int ItemCardId { get; set; } + + /// + /// 名称 + /// + public string Title { get; set; } = null!; + + /// + /// 1未使用 2已使用 + /// + public bool? Status { get; set; } + + /// + /// 抵扣的订单ID + /// + public int? OrderId { get; set; } + + public uint Addtime { get; set; } + + public int Updatetime { get; set; } + + public int? Deltime { get; set; } +} diff --git a/ChouBox.Model/Entities/UserLoginIp.cs b/ChouBox.Model/Entities/UserLoginIp.cs new file mode 100644 index 0000000..353a767 --- /dev/null +++ b/ChouBox.Model/Entities/UserLoginIp.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +public partial class UserLoginIp +{ + public uint Id { get; set; } + + public uint UserId { get; set; } + + public uint LastLoginTime { get; set; } + + public string LastLoginIp { get; set; } = null!; + + /// + /// ip + /// + public string? LastLoginIp1 { get; set; } + + /// + /// ip邮编 + /// + public string? IpAdcode { get; set; } + + public string? IpProvince { get; set; } + + public string? IpCity { get; set; } +} diff --git a/ChouBox.Model/Entities/UserLoginLog.cs b/ChouBox.Model/Entities/UserLoginLog.cs new file mode 100644 index 0000000..630c498 --- /dev/null +++ b/ChouBox.Model/Entities/UserLoginLog.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 用户登录记录表 +/// +public partial class UserLoginLog +{ + /// + /// 主键ID + /// + public uint Id { get; set; } + + /// + /// 用户ID + /// + public uint UserId { get; set; } + + /// + /// 登录日期 + /// + public DateOnly LoginDate { get; set; } + + /// + /// 登录时间戳 + /// + public uint LoginTime { get; set; } + + /// + /// 登录设备 + /// + public string? Device { get; set; } + + /// + /// 登录IP + /// + public string? Ip { get; set; } + + /// + /// 登录地点 + /// + public string? Location { get; set; } + + /// + /// 年份 + /// + public uint Year { get; set; } + + /// + /// 月份 + /// + public uint Month { get; set; } + + /// + /// 周数 + /// + public uint Week { get; set; } +} diff --git a/ChouBox.Model/Entities/UserPosterCache.cs b/ChouBox.Model/Entities/UserPosterCache.cs new file mode 100644 index 0000000..dbf7b81 --- /dev/null +++ b/ChouBox.Model/Entities/UserPosterCache.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 用户海报COS存储记录 +/// +public partial class UserPosterCache +{ + /// + /// 主键ID + /// + public ulong Id { get; set; } + + /// + /// 用户ID + /// + public long UserId { get; set; } + + /// + /// 微信APPID + /// + public string AppId { get; set; } = null!; + + /// + /// 模板内容哈希值 + /// + public string TemplateHash { get; set; } = null!; + + /// + /// COS访问URL + /// + public string CosUrl { get; set; } = null!; + + /// + /// 文件大小(字节) + /// + public uint? FileSize { get; set; } + + /// + /// 文件类型 + /// + public string? MimeType { get; set; } + + /// + /// 状态(1-有效 0-无效) + /// + public bool? Status { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreatedAt { get; set; } + + /// + /// 更新时间 + /// + public DateTime UpdatedAt { get; set; } + + /// + /// 过期时间 + /// + public DateTime? ExpiresAt { get; set; } +} diff --git a/ChouBox.Model/Entities/UserQuanYiLevelJiang.cs b/ChouBox.Model/Entities/UserQuanYiLevelJiang.cs new file mode 100644 index 0000000..5b8b001 --- /dev/null +++ b/ChouBox.Model/Entities/UserQuanYiLevelJiang.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 用户领取的权益中心等级奖品 +/// +public partial class UserQuanYiLevelJiang +{ + public uint Id { get; set; } + + public int? UserId { get; set; } + + public int QyLevelId { get; set; } + + public int? QyLevel { get; set; } + + public uint? CouponId { get; set; } + + /// + /// 1普通降临(优惠券) 2高级奖励(奖品) + /// + public bool Type { get; set; } + + public string Title { get; set; } = null!; + + /// + /// 减多少 + /// + public decimal? JianPrice { get; set; } + + /// + /// 满多少 + /// + public decimal? ManPrice { get; set; } + + /// + /// 有效时间(天) + /// + public int? EffectiveDay { get; set; } + + public int? EndTime { get; set; } + + /// + /// 优惠券赠送多少 + /// + public uint? ZNum { get; set; } + + /// + /// 奖品图片 + /// + public string? Imgurl { get; set; } + + public int? ShangId { get; set; } + + /// + /// 奖品价值 + /// + public decimal? JiangPrice { get; set; } + + /// + /// 奖品兑换价 + /// + public decimal? Money { get; set; } + + /// + /// 市场参考价 + /// + public decimal? ScMoney { get; set; } + + /// + /// 奖品编号 + /// + public string? PrizeCode { get; set; } + + /// + /// 概率 + /// + public decimal? Probability { get; set; } + + public int Addtime { get; set; } + + public int Updatetime { get; set; } + + public int? Deltime { get; set; } +} diff --git a/ChouBox.Model/Entities/UserRage.cs b/ChouBox.Model/Entities/UserRage.cs new file mode 100644 index 0000000..6490cc9 --- /dev/null +++ b/ChouBox.Model/Entities/UserRage.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 用户的怒气值 +/// +public partial class UserRage +{ + public uint Id { get; set; } + + public int UserId { get; set; } + + public int GoodsId { get; set; } + + /// + /// 怒气值 + /// + public int Rage { get; set; } + + public int Addtime { get; set; } + + public int Updatetime { get; set; } + + public int? Deltime { get; set; } +} diff --git a/ChouBox.Model/Entities/UserRecharge.cs b/ChouBox.Model/Entities/UserRecharge.cs new file mode 100644 index 0000000..76709ff --- /dev/null +++ b/ChouBox.Model/Entities/UserRecharge.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 用户充值表 +/// +public partial class UserRecharge +{ + public uint Id { get; set; } + + /// + /// 用户ID + /// + public uint UserId { get; set; } + + /// + /// 订单号 + /// + public string OrderNum { get; set; } = null!; + + /// + /// 充值金额 + /// + public decimal Money { get; set; } + + /// + /// 1待支付 2已完成 + /// + public byte Status { get; set; } + + /// + /// 创建订单时间 + /// + public uint Addtime { get; set; } + + /// + /// 支付时间 + /// + public uint PayTime { get; set; } +} diff --git a/ChouBox.Model/Entities/UserSign.cs b/ChouBox.Model/Entities/UserSign.cs new file mode 100644 index 0000000..f7c44f7 --- /dev/null +++ b/ChouBox.Model/Entities/UserSign.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 用户签到表 +/// +public partial class UserSign +{ + /// + /// 主键id + /// + public uint Id { get; set; } + + /// + /// 用户id + /// + public uint UserId { get; set; } + + /// + /// 签到日期 + /// + public string SignDate { get; set; } = null!; + + /// + /// 签到当月天数 + /// + public byte SignDay { get; set; } + + /// + /// 连续签到天数 + /// + public uint Days { get; set; } + + /// + /// 签到月份 + /// + public int? Month { get; set; } + + /// + /// 签到年份 + /// + public int? Year { get; set; } + + /// + /// 签到数量 + /// + public int Num { get; set; } + + /// + /// 签到时间 + /// + public uint CreateTime { get; set; } + + /// + /// 更新时间 + /// + public uint UpdateTime { get; set; } + + /// + /// 月签到还是累计签到 + /// + public sbyte SignType { get; set; } +} diff --git a/ChouBox.Model/Entities/UserStatistics.cs b/ChouBox.Model/Entities/UserStatistics.cs new file mode 100644 index 0000000..3ab456b --- /dev/null +++ b/ChouBox.Model/Entities/UserStatistics.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 用户统计表 +/// +public partial class UserStatistics +{ + /// + /// 主键 + /// + public int Id { get; set; } + + /// + /// 登录人数 + /// + public int? LoginCount { get; set; } + + /// + /// 注册人数 + /// + public int? RegisterCount { get; set; } + + /// + /// 创建时间 + /// + public DateTime? CreatedAt { get; set; } + + /// + /// 修改时间 + /// + public DateTime? UpdatedAt { get; set; } + + /// + /// 记录日期 + /// + public DateOnly RecordDate { get; set; } + + /// + /// 充值金额 + /// + public decimal RechargeAmount { get; set; } + + /// + /// 记录当天消费的用户人数(去重) + /// + public int ConsumeUserCount { get; set; } + + /// + /// 记录当天用户使用余额消费的总金额(单位:元)。 + /// + public decimal BalanceConsume { get; set; } + + /// + /// 记录当天系统发放给用户的余额总金额 + /// + public decimal BalanceIssue { get; set; } + + /// + /// 支付的订单笔数 + /// + public int ConsumeOrderCount { get; set; } + + /// + /// 消费rmb人数 + /// + public int ConsumeRmbCount { get; set; } + + /// + /// 今日总收入 + /// + public decimal RechargeSum { get; set; } + + /// + /// 出货价值 + /// + public decimal ShipmentMoney { get; set; } + + /// + /// 发货价值 + /// + public decimal SendMoney { get; set; } + + /// + /// 回收价值 + /// + public decimal RecycleMoney { get; set; } + + /// + /// 利润率 + /// + public decimal ProfitMoney { get; set; } + + /// + /// 总支出 + /// + public decimal AllShipmentMoney { get; set; } + + /// + /// 总收入 + /// + public decimal AllRecycleMoney { get; set; } + + /// + /// 总利润 + /// + public decimal AllMoney { get; set; } +} diff --git a/ChouBox.Model/Entities/UserTaskList.cs b/ChouBox.Model/Entities/UserTaskList.cs new file mode 100644 index 0000000..d894672 --- /dev/null +++ b/ChouBox.Model/Entities/UserTaskList.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 用户完成任务记录表 +/// +public partial class UserTaskList +{ + public uint Id { get; set; } + + public int UserId { get; set; } + + public int TaskListId { get; set; } + + /// + /// 1每日任务 2每周任务 + /// + public bool Type { get; set; } + + /// + /// 任务分类 1邀请好友注册 2抽赏任务 + /// + public bool Cate { get; set; } + + /// + /// 是否是重要任务 1是 0否 + /// + public bool? IsImportant { get; set; } + + /// + /// 需要完成任务几次 + /// + public int? Number { get; set; } + + /// + /// 赠送多少欧气值 + /// + public uint? ZNumber { get; set; } + + public int Addtime { get; set; } + + public int Updatetime { get; set; } + + public int? Deltime { get; set; } +} diff --git a/ChouBox.Model/Entities/UserVip.cs b/ChouBox.Model/Entities/UserVip.cs new file mode 100644 index 0000000..f9883ac --- /dev/null +++ b/ChouBox.Model/Entities/UserVip.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 会员vip +/// +public partial class UserVip +{ + public uint Id { get; set; } + + /// + /// 等级名称 + /// + public string Title { get; set; } = null!; + + /// + /// 图标 + /// + public string Imgurl { get; set; } = null!; + + /// + /// 升级消费 + /// + public uint Condition { get; set; } + + /// + /// 享受折扣 + /// + public decimal Discount { get; set; } + + /// + /// 权益说明 + /// + public string Notice { get; set; } = null!; + + /// + /// 更新时间 + /// + public uint UpdateTime { get; set; } +} diff --git a/ChouBox.Model/Entities/WelfareHouse.cs b/ChouBox.Model/Entities/WelfareHouse.cs new file mode 100644 index 0000000..5eac677 --- /dev/null +++ b/ChouBox.Model/Entities/WelfareHouse.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 福利屋管理 +/// +public partial class WelfareHouse +{ + public int Id { get; set; } + + /// + /// 名称 + /// + public string Name { get; set; } = null!; + + /// + /// 图片路径 + /// + public string Image { get; set; } = null!; + + /// + /// 跳转路径 + /// + public string Url { get; set; } = null!; + + /// + /// 排序(数字越小越靠前) + /// + public int? Sort { get; set; } + + /// + /// 状态:0=禁用,1=启用 + /// + public bool? Status { get; set; } + + /// + /// 创建时间 + /// + public int? CreateTime { get; set; } + + /// + /// 更新时间 + /// + public int? UpdateTime { get; set; } +} diff --git a/ChouBox.Model/Entities/Withdraw.cs b/ChouBox.Model/Entities/Withdraw.cs new file mode 100644 index 0000000..dc8cd78 --- /dev/null +++ b/ChouBox.Model/Entities/Withdraw.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +public partial class Withdraw +{ + public uint Id { get; set; } + + /// + /// 提现人 + /// + public uint? UserId { get; set; } + + /// + /// 提现:1=未审核,2=已通过3=未通过 + /// + public byte? Status { get; set; } + + /// + /// 提现时间 + /// + public uint? Addtime { get; set; } + + /// + /// 审核时间 + /// + public uint? EndTime { get; set; } + + /// + /// 原因 + /// + public string? Reason { get; set; } + + /// + /// 提现金额 + /// + public decimal TalMoney { get; set; } + + /// + /// 到账金额 + /// + public decimal Money { get; set; } + + /// + /// 手续费 + /// + public decimal Sxf { get; set; } + + /// + /// 提现方式:1=微信,2=银行卡 3支付宝 + /// + public byte Type { get; set; } + + /// + /// 收款二维码 + /// + public string? Imgurl { get; set; } + + /// + /// 提现姓名/银行户名 + /// + public string? Name { get; set; } + + /// + /// 支付宝账号/银行卡号 + /// + public string? Number { get; set; } + + /// + /// 开户行 + /// + public string? Bank { get; set; } +} diff --git a/ChouBox.Model/Entities/WxpayLog.cs b/ChouBox.Model/Entities/WxpayLog.cs new file mode 100644 index 0000000..7e59e3b --- /dev/null +++ b/ChouBox.Model/Entities/WxpayLog.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 微信/支付宝支付信息 +/// +public partial class WxpayLog +{ + public uint Id { get; set; } + + public uint UserId { get; set; } + + /// + /// 订单号 + /// + public string? OrderNo { get; set; } + + /// + /// 说明 + /// + public string? Content { get; set; } + + public byte? Type { get; set; } + + /// + /// 1微信 2支付宝 + /// + public int Channel { get; set; } + + public uint? Addtime { get; set; } +} diff --git a/ChouBox.Model/Entities/YoudaContext.cs b/ChouBox.Model/Entities/YoudaContext.cs new file mode 100644 index 0000000..74c257e --- /dev/null +++ b/ChouBox.Model/Entities/YoudaContext.cs @@ -0,0 +1,4975 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore; +using Pomelo.EntityFrameworkCore.MySql.Scaffolding.Internal; + +namespace ChouBox.Model.Entities; + +/// +public partial class YoudaContext : DbContext +{ + public YoudaContext() + { + } + + public YoudaContext(DbContextOptions options) + : base(options) + { + } + + /// + /// 管理员 + /// + public virtual DbSet Admin { get; set; } + + /// + /// 管理员登录日志 + /// + public virtual DbSet AdminGoodsLog { get; set; } + + /// + /// 管理员登录日志 + /// + public virtual DbSet AdminLoginLog { get; set; } + + /// + /// 管理员操作日志 + /// + public virtual DbSet AdminOperationLog { get; set; } + + /// + /// 权限 + /// + public virtual DbSet AdminQuanxian { get; set; } + + /// + /// ads + /// + public virtual DbSet Ads { get; set; } + + /// + /// advert + /// + public virtual DbSet Advert { get; set; } + + /// + /// advert_type + /// + public virtual DbSet AdvertType { get; set; } + + /// + /// card_level + /// + public virtual DbSet CardLevel { get; set; } + + /// + /// 盒子分类 + /// + public virtual DbSet Category { get; set; } + + /// + /// 短信记录 + /// + public virtual DbSet Code { get; set; } + + /// + /// collect + /// + public virtual DbSet Collect { get; set; } + + /// + /// config + /// + public virtual DbSet Config { get; set; } + + /// + /// 优惠券表 + /// + public virtual DbSet Coupon { get; set; } + + /// + /// 用户优惠券表 + /// + public virtual DbSet CouponReceive { get; set; } + + /// + /// danye + /// + public virtual DbSet Danye { get; set; } + + /// + /// 快递公司 + /// + public virtual DbSet Delivery { get; set; } + + /// + /// error_log + /// + public virtual DbSet ErrorLog { get; set; } + + /// + /// 悬浮球配置表 + /// + public virtual DbSet FloatBallConfig { get; set; } + + /// + /// 无限令领取记录 + /// + public virtual DbSet Give { get; set; } + + /// + /// 盒子 + /// + public virtual DbSet Goods { get; set; } + + /// + /// 盒子扩展表 + /// + public virtual DbSet GoodsExtend { get; set; } + + /// + /// goods_extend_list + /// + public virtual DbSet GoodsExtendList { get; set; } + + /// + /// 无限赏领主 + /// + public virtual DbSet GoodsKingRank { get; set; } + + /// + /// 盒子奖品 + /// + public virtual DbSet GoodsList { get; set; } + + /// + /// 盒子锁箱信息 + /// + public virtual DbSet GoodsLock { get; set; } + + /// + /// 盒子自动下架日志表 + /// + public virtual DbSet GoodsOffshelfLog { get; set; } + + /// + /// goods_type + /// + public virtual DbSet GoodsType { get; set; } + + /// + /// 道具卡 + /// + public virtual DbSet ItemCard { get; set; } + + /// + /// 发货订单表 + /// + public virtual DbSet KkOrder { get; set; } + + /// + /// 订单商品 + /// + public virtual DbSet KkOrderGood { get; set; } + + /// + /// 发货订单地址物流信息 + /// + public virtual DbSet KkOrderSend { get; set; } + + /// + /// 商品表 + /// + public virtual DbSet KkProduct { get; set; } + + /// + /// 商品分类 + /// + public virtual DbSet KkProductCate { get; set; } + + /// + /// 普通商城商品分类 + /// + public virtual DbSet KkProductCategory { get; set; } + + /// + /// 商品规格 + /// + public virtual DbSet KkProductSpec { get; set; } + + /// + /// 秒杀设置 + /// + public virtual DbSet KkSeckill { get; set; } + + /// + /// 商品分享记录表 + /// + public virtual DbSet KkShare { get; set; } + + /// + /// 集市 + /// + public virtual DbSet Market { get; set; } + + /// + /// 集市订单 + /// + public virtual DbSet MarketOrder { get; set; } + + /// + /// migrations + /// + public virtual DbSet Migrations { get; set; } + + /// + /// notify_log + /// + public virtual DbSet NotifyLog { get; set; } + + /// + /// 订单表 + /// + public virtual DbSet Order { get; set; } + + /// + /// 订单明细 + /// + public virtual DbSet OrderList { get; set; } + + /// + /// 打包记录 + /// + public virtual DbSet OrderListRecovery { get; set; } + + /// + /// 发货记录 + /// + public virtual DbSet OrderListSend { get; set; } + + /// + /// picture + /// + public virtual DbSet Picture { get; set; } + + /// + /// 财务明细 + /// + public virtual DbSet ProfitDraw { get; set; } + + /// + /// 利润支出表 + /// + public virtual DbSet ProfitExpenses { get; set; } + + /// + /// 财务明细 + /// + public virtual DbSet ProfitIntegral { get; set; } + + /// + /// 财务明细 + /// + public virtual DbSet ProfitMoney { get; set; } + + /// + /// 财务明细 + /// + public virtual DbSet ProfitMoney2 { get; set; } + + /// + /// 欧气值明细 + /// + public virtual DbSet ProfitOuQi { get; set; } + + /// + /// (微信/支付宝)支付 + /// + public virtual DbSet ProfitPay { get; set; } + + /// + /// 利润收入表 + /// + public virtual DbSet ProfitRevenue { get; set; } + + /// + /// 财务明细 + /// + public virtual DbSet ProfitScore { get; set; } + + /// + /// 权益等级表 + /// + public virtual DbSet QuanYiLevel { get; set; } + + /// + /// 权益中心等级奖品 + /// + public virtual DbSet QuanYiLevelJiang { get; set; } + + /// + /// 排行榜月榜 + /// + public virtual DbSet RankMonth { get; set; } + + /// + /// 排行榜周榜 + /// + public virtual DbSet RankWeek { get; set; } + + /// + /// 奖励表 + /// + public virtual DbSet Reward { get; set; } + + /// + /// shang + /// + public virtual DbSet Shang { get; set; } + + /// + /// 签到配置表 + /// + public virtual DbSet SignConfig { get; set; } + + /// + /// 任务表 + /// + public virtual DbSet TaskList { get; set; } + + /// + /// user + /// + public virtual DbSet User { get; set; } + + /// + /// user_account + /// + public virtual DbSet UserAccount { get; set; } + + /// + /// 欧气劵 + /// + public virtual DbSet UserCoupon { get; set; } + + /// + /// 用户连击赏连击次数 + /// + public virtual DbSet UserGoodsLianJi { get; set; } + + /// + /// 用户的道具卡 + /// + public virtual DbSet UserItemCard { get; set; } + + /// + /// user_login_ip + /// + public virtual DbSet UserLoginIp { get; set; } + + /// + /// 用户登录记录表 + /// + public virtual DbSet UserLoginLog { get; set; } + + /// + /// 用户海报COS存储记录 + /// + public virtual DbSet UserPosterCache { get; set; } + + /// + /// 用户领取的权益中心等级奖品 + /// + public virtual DbSet UserQuanYiLevelJiang { get; set; } + + /// + /// 用户的怒气值 + /// + public virtual DbSet UserRage { get; set; } + + /// + /// 用户充值表 + /// + public virtual DbSet UserRecharge { get; set; } + + /// + /// 用户签到表 + /// + public virtual DbSet UserSign { get; set; } + + /// + /// 用户统计表 + /// + public virtual DbSet UserStatistics { get; set; } + + /// + /// 用户完成任务记录表 + /// + public virtual DbSet UserTaskList { get; set; } + + /// + /// 会员vip + /// + public virtual DbSet UserVip { get; set; } + + /// + /// 福利屋管理 + /// + public virtual DbSet WelfareHouse { get; set; } + + /// + /// withdraw + /// + public virtual DbSet Withdraw { get; set; } + + /// + /// 微信/支付宝支付信息 + /// + public virtual DbSet WxpayLog { get; set; } + + /// + /// 预售日历 + /// + public virtual DbSet Yushou { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + //optionsBuilder.UseMySql("server=192.168.1.56;database=youda;user=youda;password=youda", Microsoft.EntityFrameworkCore.ServerVersion.Parse("5.7.44-mysql")); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder + .UseCollation("utf8mb4_general_ci") + .HasCharSet("utf8mb4"); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("admin", tb => tb.HasComment("管理员")) + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.Property(e => e.Id) + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.AdminId) + .HasComment("操作人") + .HasColumnType("int(11) unsigned") + .HasColumnName("admin_id"); + entity.Property(e => e.GetTime) + .HasComment("登录刷新时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("get_time"); + entity.Property(e => e.Nickname) + .HasMaxLength(20) + .HasComment("姓名") + .HasColumnName("nickname"); + entity.Property(e => e.Password) + .HasMaxLength(40) + .HasComment("登录密码") + .HasColumnName("password") + .UseCollation("gbk_chinese_ci") + .HasCharSet("gbk"); + entity.Property(e => e.Qid) + .HasComment("权限ID") + .HasColumnType("int(10) unsigned") + .HasColumnName("qid"); + entity.Property(e => e.Random) + .HasMaxLength(20) + .HasComment("token随机数") + .HasColumnName("random") + .UseCollation("utf8_general_ci"); + entity.Property(e => e.Status) + .HasDefaultValueSql("'0'") + .HasComment("0正常 1禁用") + .HasColumnType("int(11) unsigned") + .HasColumnName("status"); + entity.Property(e => e.Token) + .HasMaxLength(100) + .HasComment("token") + .HasColumnName("token"); + entity.Property(e => e.UpdateTime) + .HasComment("修改时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("update_time"); + entity.Property(e => e.Username) + .HasMaxLength(20) + .HasComment("账号") + .HasColumnName("username") + .UseCollation("gbk_chinese_ci") + .HasCharSet("gbk"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("admin_goods_log", tb => tb.HasComment("管理员登录日志")) + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.Property(e => e.Id) + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.AId) + .HasComment("管理员ID") + .HasColumnType("int(11)") + .HasColumnName("a_id"); + entity.Property(e => e.Addtime) + .HasComment("登录时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.GoodsId) + .HasDefaultValueSql("'0'") + .HasColumnType("int(11)") + .HasColumnName("goods_id"); + entity.Property(e => e.GoodsListId) + .HasDefaultValueSql("'0'") + .HasColumnType("int(11)") + .HasColumnName("goods_list_id"); + entity.Property(e => e.Ip) + .HasMaxLength(50) + .HasComment("登录ip") + .HasColumnName("ip"); + entity.Property(e => e.NewData) + .HasColumnType("text") + .HasColumnName("new_data"); + entity.Property(e => e.OriginalData) + .HasColumnType("text") + .HasColumnName("original_data"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("admin_login_log", tb => tb.HasComment("管理员登录日志")) + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.Property(e => e.Id) + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.AId) + .HasComment("管理员ID") + .HasColumnType("int(11)") + .HasColumnName("a_id"); + entity.Property(e => e.Addtime) + .HasComment("登录时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.Ip) + .HasMaxLength(50) + .HasComment("登录ip") + .HasColumnName("ip"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("admin_operation_log", tb => tb.HasComment("管理员操作日志")) + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.Property(e => e.Id) + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.AId) + .HasComment("管理员ID") + .HasColumnType("int(11)") + .HasColumnName("a_id"); + entity.Property(e => e.Addtime) + .HasComment("操作时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.Content) + .HasColumnType("text") + .HasColumnName("content"); + entity.Property(e => e.Ip) + .HasMaxLength(50) + .HasComment("操作ip") + .HasColumnName("ip"); + entity.Property(e => e.Operation) + .HasMaxLength(255) + .HasComment("操作控制器") + .HasColumnName("operation"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("admin_quanxian", tb => tb.HasComment("权限")) + .HasCharSet("gbk") + .UseCollation("gbk_chinese_ci"); + + entity.Property(e => e.Id) + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasColumnType("int(11)") + .HasColumnName("addtime"); + entity.Property(e => e.AdminId) + .HasComment("操作人") + .HasColumnType("int(11)") + .HasColumnName("admin_id"); + entity.Property(e => e.Describe).HasColumnName("describe"); + entity.Property(e => e.Quanxian) + .HasColumnType("text") + .HasColumnName("quanxian"); + entity.Property(e => e.Title) + .HasMaxLength(100) + .HasColumnName("title"); + entity.Property(e => e.UpdateTime) + .HasColumnType("int(11)") + .HasColumnName("update_time"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("ads"); + + entity.Property(e => e.Id) + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.AccessToken) + .HasMaxLength(255) + .HasColumnName("access_token"); + entity.Property(e => e.AccountId) + .HasMaxLength(255) + .HasColumnName("account_id"); + entity.Property(e => e.Ads1) + .HasComment("序号") + .HasColumnType("int(11)") + .HasColumnName("ads"); + entity.Property(e => e.CreateTime) + .HasMaxLength(255) + .HasColumnName("create_time"); + entity.Property(e => e.Status) + .HasDefaultValueSql("'1'") + .HasComment("1.正常 2.已禁用") + .HasColumnType("int(11)") + .HasColumnName("status"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasColumnName("title"); + entity.Property(e => e.UpdateTime) + .HasMaxLength(255) + .HasColumnName("update_time"); + entity.Property(e => e.UserActionSetId) + .HasMaxLength(255) + .HasColumnName("user_action_set_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("advert") + .HasCharSet("gbk") + .UseCollation("gbk_chinese_ci"); + + entity.Property(e => e.Id) + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.CouponId) + .HasDefaultValueSql("'0'") + .HasComment("优惠券id") + .HasColumnType("int(11) unsigned") + .HasColumnName("coupon_id"); + entity.Property(e => e.GoodsId) + .HasDefaultValueSql("'0'") + .HasComment("盒子id") + .HasColumnType("int(11) unsigned") + .HasColumnName("goods_id"); + entity.Property(e => e.Imgurl) + .HasMaxLength(100) + .HasComment("图片") + .HasColumnName("imgurl"); + entity.Property(e => e.Sort) + .HasComment("排序") + .HasColumnType("int(11) unsigned") + .HasColumnName("sort"); + entity.Property(e => e.Ttype) + .HasDefaultValueSql("'0'") + .HasComment("跳转类型 0不跳转 1优惠券 2一番赏 3无限赏") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("ttype"); + entity.Property(e => e.Type) + .HasDefaultValueSql("'1'") + .HasComment("类型 1首页轮播图 2抽卡机轮播图") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("type"); + entity.Property(e => e.UpdateTime) + .HasComment("修改时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("update_time"); + entity.Property(e => e.Url) + .HasMaxLength(225) + .HasComment("跳转路径") + .HasColumnName("url"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("advert_type"); + + entity.Property(e => e.Id) + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.Name) + .HasMaxLength(50) + .HasColumnName("name"); + entity.Property(e => e.Sort) + .HasDefaultValueSql("'0'") + .HasColumnType("int(10)") + .HasColumnName("sort"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("card_level") + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(11)") + .HasColumnName("addtime"); + entity.Property(e => e.Imgurl) + .HasMaxLength(255) + .HasComment("等级图片") + .HasColumnName("imgurl") + .UseCollation("utf8mb4_general_ci") + .HasCharSet("utf8mb4"); + entity.Property(e => e.Sort) + .HasComment("排序") + .HasColumnType("int(11)") + .HasColumnName("sort"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasComment("卡名称") + .HasColumnName("title") + .UseCollation("utf8mb4_general_ci") + .HasCharSet("utf8mb4"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("category", tb => tb.HasComment("盒子分类")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(10) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.Sort) + .HasComment("排序") + .HasColumnType("int(11) unsigned") + .HasColumnName("sort"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasComment("商品名称") + .HasColumnName("title"); + entity.Property(e => e.UpdateTime) + .HasComment("修改时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("update_time"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("code", tb => tb.HasComment("短信记录")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.Property(e => e.Id) + .HasComment("验证码id") + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(11)") + .HasColumnName("addtime"); + entity.Property(e => e.Code1) + .HasMaxLength(6) + .HasComment("验证码") + .HasColumnName("code"); + entity.Property(e => e.Phone) + .HasMaxLength(11) + .HasComment("手机号") + .HasColumnName("phone"); + entity.Property(e => e.Status) + .HasComment("状态 0正常,-1失效") + .HasColumnName("status"); + entity.Property(e => e.Type) + .HasComment("类型,1 登录注册") + .HasColumnName("type"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("collect") + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.GoodsId) + .HasComment("盒子ID") + .HasColumnType("int(11) unsigned") + .HasColumnName("goods_id"); + entity.Property(e => e.Num) + .HasComment("箱号") + .HasColumnType("int(10) unsigned") + .HasColumnName("num"); + entity.Property(e => e.Type) + .HasComment("1一番赏 2无限赏 3擂台赏 4抽卡机 5积分赏 6全局赏 7福利盲盒 8领主赏 9连击赏") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("type"); + entity.Property(e => e.UserId) + .HasComment("用户id") + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("config") + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.Property(e => e.Id) + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.Key) + .HasMaxLength(255) + .HasColumnName("key"); + entity.Property(e => e.Value) + .HasColumnType("text") + .HasColumnName("value"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("coupon", tb => tb.HasComment("优惠券表")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(10) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.EffectiveDay) + .HasComment("有效时间(天)") + .HasColumnType("int(11)") + .HasColumnName("effective_day"); + entity.Property(e => e.ManPrice) + .HasPrecision(10, 2) + .HasComment("满多少减多少") + .HasColumnName("man_price"); + entity.Property(e => e.Price) + .HasComment("减多少") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("price"); + entity.Property(e => e.Sort) + .HasDefaultValueSql("'1'") + .HasComment("排序值") + .HasColumnType("int(10) unsigned") + .HasColumnName("sort"); + entity.Property(e => e.Status) + .HasComment("0上架 2下架 4已删除") + .HasColumnName("status"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasComment("商品名称") + .HasColumnName("title"); + entity.Property(e => e.Ttype) + .HasDefaultValueSql("'0'") + .HasComment("是否限制使用 0不限制 1一番赏 2无限赏 3擂台赏 6全局赏 9领主赏 9连击赏") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("ttype"); + entity.Property(e => e.Type) + .HasDefaultValueSql("'0'") + .HasComment("1新人优惠券 2权益优惠卷") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("type"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("coupon_receive", tb => tb.HasComment("用户优惠券表")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(10) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.CouponId) + .HasColumnType("int(11)") + .HasColumnName("coupon_id"); + entity.Property(e => e.EndTime) + .HasComment("过期时间") + .HasColumnType("int(11)") + .HasColumnName("end_time"); + entity.Property(e => e.ManPrice) + .HasPrecision(10, 2) + .HasComment("满多少减多少") + .HasColumnName("man_price"); + entity.Property(e => e.Price) + .HasComment("商品价格") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("price"); + entity.Property(e => e.State) + .HasDefaultValueSql("'0'") + .HasComment("是否限制使用 0不限制 1一番赏 2无限赏 3擂台赏 6全局赏 9领主赏 9连击赏") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("state"); + entity.Property(e => e.Status) + .HasComment("0未使用1已使用2已过期") + .HasColumnName("status"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasComment("商品名称") + .HasColumnName("title"); + entity.Property(e => e.Ttype) + .HasColumnType("int(2)") + .HasColumnName("ttype"); + entity.Property(e => e.UserId) + .HasComment("会员id") + .HasColumnType("int(11)") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("danye") + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.Property(e => e.Id) + .HasComment("类型,1服务协议,2隐私政策") + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Content) + .HasComment("内容") + .HasColumnType("text") + .HasColumnName("content"); + entity.Property(e => e.IsImageOptimizer) + .HasComment("是否开启图片优化") + .HasColumnType("tinyint(4)") + .HasColumnName("is_image_optimizer"); + entity.Property(e => e.Status) + .HasComment("0正常 1隐藏") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("status"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasDefaultValueSql("''") + .HasComment("标题") + .HasColumnName("title"); + entity.Property(e => e.UpdateTime) + .HasComment("修改时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("update_time"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("delivery", tb => tb.HasComment("快递公司")) + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.Property(e => e.Id) + .HasColumnType("smallint(5) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Code) + .HasMaxLength(30) + .HasComment("快递编码") + .HasColumnName("code"); + entity.Property(e => e.Name) + .HasMaxLength(50) + .HasComment("快递公司") + .HasColumnName("name"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("error_log"); + + entity.Property(e => e.Id) + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasColumnType("int(11)") + .HasColumnName("addtime"); + entity.Property(e => e.GoodsId) + .HasColumnType("int(11)") + .HasColumnName("goods_id"); + entity.Property(e => e.UserId) + .HasColumnType("int(11)") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("float_ball_config", tb => tb.HasComment("悬浮球配置表")); + + entity.Property(e => e.Id) + .HasComment("主键ID") + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.CreateTime) + .HasComment("创建时间") + .HasColumnType("int(11)") + .HasColumnName("create_time"); + entity.Property(e => e.Effect) + .HasComment("特效 0=无 1=特效1") + .HasColumnName("effect"); + entity.Property(e => e.Height) + .HasMaxLength(30) + .HasDefaultValueSql("''") + .HasComment("高度") + .HasColumnName("height"); + entity.Property(e => e.Image) + .HasMaxLength(255) + .HasDefaultValueSql("''") + .HasComment("图片路径") + .HasColumnName("image"); + entity.Property(e => e.ImageBj) + .HasMaxLength(255) + .HasComment("背景图") + .HasColumnName("image_bj"); + entity.Property(e => e.ImageDetails) + .HasMaxLength(255) + .HasComment("展示的图片") + .HasColumnName("image_details"); + entity.Property(e => e.ImageDetailsH) + .HasMaxLength(255) + .HasComment("高度") + .HasColumnName("image_details_h"); + entity.Property(e => e.ImageDetailsW) + .HasMaxLength(255) + .HasComment("宽度") + .HasColumnName("image_details_w"); + entity.Property(e => e.ImageDetailsX) + .HasMaxLength(255) + .HasComment("详情图坐标") + .HasColumnName("image_details_x"); + entity.Property(e => e.ImageDetailsY) + .HasMaxLength(255) + .HasComment("详情图y") + .HasColumnName("image_details_y"); + entity.Property(e => e.LinkUrl) + .HasMaxLength(255) + .HasDefaultValueSql("''") + .HasComment("跳转链接") + .HasColumnName("link_url"); + entity.Property(e => e.PositionX) + .HasMaxLength(30) + .HasDefaultValueSql("''") + .HasComment("X坐标位置") + .HasColumnName("position_x"); + entity.Property(e => e.PositionY) + .HasMaxLength(30) + .HasDefaultValueSql("''") + .HasComment("Y坐标位置") + .HasColumnName("position_y"); + entity.Property(e => e.Status) + .HasComment("状态 0=关闭 1=开启") + .HasColumnName("status"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasComment("标题") + .HasColumnName("title"); + entity.Property(e => e.Type) + .IsRequired() + .HasDefaultValueSql("'1'") + .HasComment("类型 1=展示图片 2=跳转页面") + .HasColumnName("type"); + entity.Property(e => e.UpdateTime) + .HasComment("更新时间") + .HasColumnType("int(11)") + .HasColumnName("update_time"); + entity.Property(e => e.Width) + .HasMaxLength(30) + .HasDefaultValueSql("''") + .HasComment("宽度") + .HasColumnName("width"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("give", tb => tb.HasComment("无限令领取记录")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.Money) + .HasComment("消费金额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money"); + entity.Property(e => e.TimeDate) + .HasMaxLength(100) + .HasColumnName("time_date"); + entity.Property(e => e.TimeInt) + .HasMaxLength(100) + .HasColumnName("time_int"); + entity.Property(e => e.UserId) + .HasComment("会员id") + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("goods", tb => tb.HasComment("盒子")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.HasIndex(e => e.Status, "status"); + + entity.HasIndex(e => e.Type, "type"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(10) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.AsyncCode) + .HasMaxLength(64) + .HasComment("同步编码,guid") + .HasColumnName("async_code"); + entity.Property(e => e.AsyncDate) + .HasComment("最后一次同步时间") + .HasColumnType("datetime") + .HasColumnName("async_date"); + entity.Property(e => e.CardBanner) + .HasMaxLength(255) + .HasComment("卡册banner") + .HasColumnName("card_banner"); + entity.Property(e => e.CardNotice) + .HasMaxLength(255) + .HasComment("抽卡机描述") + .HasColumnName("card_notice"); + entity.Property(e => e.CardNum) + .HasDefaultValueSql("'1'") + .HasComment("一包几张") + .HasColumnType("int(11)") + .HasColumnName("card_num"); + entity.Property(e => e.CardSet) + .HasComment("抽卡机抽奖设置") + .HasColumnType("text") + .HasColumnName("card_set"); + entity.Property(e => e.CategoryId) + .HasComment("分类ID") + .HasColumnType("int(11) unsigned") + .HasColumnName("category_id"); + entity.Property(e => e.ChoujiangXianzhi) + .HasComment("抽奖门槛") + .HasColumnType("int(11)") + .HasColumnName("choujiang_xianzhi"); + entity.Property(e => e.CouponIs) + .HasComment("发券开关0关闭 1开启") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("coupon_is"); + entity.Property(e => e.CouponPro) + .HasComment("发券概率") + .HasColumnType("int(10) unsigned") + .HasColumnName("coupon_pro"); + entity.Property(e => e.DailyXiangou) + .HasComment("每日限购次数") + .HasColumnType("int(11)") + .HasColumnName("daily_xiangou"); + entity.Property(e => e.DayPayPrice) + .HasPrecision(10, 2) + .HasComment("日实付") + .HasColumnName("day_pay_price"); + entity.Property(e => e.DayPrice) + .HasPrecision(10, 2) + .HasComment("需要的流水") + .HasColumnName("day_price"); + entity.Property(e => e.DeleteTime) + .HasColumnType("int(11)") + .HasColumnName("delete_time"); + entity.Property(e => e.FlwEndTime) + .HasComment("福利屋结束时间") + .HasColumnType("int(10)") + .HasColumnName("flw_end_time"); + entity.Property(e => e.FlwStartTime) + .HasComment("福利屋开始时间") + .HasColumnType("int(10)") + .HasColumnName("flw_start_time"); + entity.Property(e => e.GoodsDescribe) + .HasMaxLength(300) + .HasComment("描述") + .HasColumnName("goods_describe"); + entity.Property(e => e.Imgurl) + .HasMaxLength(255) + .HasComment("盒子封面图") + .HasColumnName("imgurl"); + entity.Property(e => e.ImgurlDetail) + .HasMaxLength(255) + .HasComment("盒子详情图") + .HasColumnName("imgurl_detail"); + entity.Property(e => e.IntegralIs) + .HasComment("发积分开关0关闭 1开启") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("integral_is"); + entity.Property(e => e.IsAutoXiajia) + .HasComment("是否自动下架") + .HasColumnType("tinyint(4)") + .HasColumnName("is_auto_xiajia"); + entity.Property(e => e.IsFlw) + .HasComment("是否福利屋") + .HasColumnType("int(1)") + .HasColumnName("is_flw"); + entity.Property(e => e.IsOpen) + .HasComment("0未开奖 1已开奖") + .HasColumnType("int(2)") + .HasColumnName("is_open"); + entity.Property(e => e.IsShouZhe) + .HasDefaultValueSql("'0'") + .HasComment("是否首抽五折 1是 0否") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("is_shou_zhe"); + entity.Property(e => e.ItemCardId) + .HasDefaultValueSql("'0'") + .HasComment("道具卡ID") + .HasColumnType("int(11) unsigned") + .HasColumnName("item_card_id"); + entity.Property(e => e.KingUserId) + .HasDefaultValueSql("'0'") + .HasComment("当前领主") + .HasColumnType("int(11)") + .HasColumnName("king_user_id"); + entity.Property(e => e.LianJiNum) + .HasDefaultValueSql("'0'") + .HasComment("连击赏连击次数") + .HasColumnType("int(11)") + .HasColumnName("lian_ji_num"); + entity.Property(e => e.LianJiShangId) + .HasDefaultValueSql("'0'") + .HasComment("连击赏赏id") + .HasColumnType("int(11)") + .HasColumnName("lian_ji_shang_id"); + entity.Property(e => e.LingzhuFan) + .HasDefaultValueSql("'0'") + .HasComment("领主每发返") + .HasColumnType("int(11)") + .HasColumnName("lingzhu_fan"); + entity.Property(e => e.LingzhuIs) + .HasDefaultValueSql("'0'") + .HasComment("领主开关 0关 1开") + .HasColumnName("lingzhu_is"); + entity.Property(e => e.LingzhuShangId) + .HasDefaultValueSql("'0'") + .HasComment("请选择抽中领主") + .HasColumnType("int(11)") + .HasColumnName("lingzhu_shang_id"); + entity.Property(e => e.LockIs) + .HasComment("锁箱 0否 1是") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("lock_is"); + entity.Property(e => e.LockTime) + .HasComment("锁箱时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("lock_time"); + entity.Property(e => e.MouthPayPrice) + .HasPrecision(10, 2) + .HasComment("月实付") + .HasColumnName("mouth_pay_price"); + entity.Property(e => e.MouthPrice) + .HasPrecision(10, 2) + .HasComment("月总流水") + .HasColumnName("mouth_price"); + entity.Property(e => e.NewIs) + .HasComment("最新开关0关闭 1开启") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("new_is"); + entity.Property(e => e.OpenTime) + .HasComment("开奖时间") + .HasColumnType("int(10)") + .HasColumnName("open_time"); + entity.Property(e => e.Price) + .HasDefaultValueSql("'0.00'") + .HasComment("商品价格") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("price"); + entity.Property(e => e.PrizeImgurl) + .HasMaxLength(255) + .HasComment("抽卡机卡牌背面图") + .HasColumnName("prize_imgurl"); + entity.Property(e => e.PrizeNum) + .HasComment("擂台赏抽全局赏数量") + .HasColumnType("int(11) unsigned") + .HasColumnName("prize_num"); + entity.Property(e => e.QuanjuXiangou) + .HasDefaultValueSql("'0'") + .HasComment("全局赏限购次数") + .HasColumnType("int(11)") + .HasColumnName("quanju_xiangou"); + entity.Property(e => e.Rage) + .HasDefaultValueSql("'0'") + .HasComment("怒气值") + .HasColumnType("int(11) unsigned") + .HasColumnName("rage"); + entity.Property(e => e.RageIs) + .HasDefaultValueSql("'0'") + .HasComment("怒气值开关 0关 1开") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("rage_is"); + entity.Property(e => e.SaleStock) + .HasComment("销量库存") + .HasColumnType("int(11) unsigned") + .HasColumnName("sale_stock"); + entity.Property(e => e.SaleTime) + .HasComment("预售时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("sale_time"); + entity.Property(e => e.ShowIs) + .HasComment("首页显示 0是 1否") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("show_is"); + entity.Property(e => e.ShowPrice) + .HasMaxLength(100) + .HasComment("卡册显示价格") + .HasColumnName("show_price"); + entity.Property(e => e.Sort) + .HasDefaultValueSql("'1'") + .HasComment("排序值") + .HasColumnType("int(10) unsigned") + .HasColumnName("sort"); + entity.Property(e => e.Status) + .HasDefaultValueSql("'1'") + .HasComment("1上架 2下架 3售罄") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("status"); + entity.Property(e => e.Stock) + .HasDefaultValueSql("'0'") + .HasComment("套数") + .HasColumnType("int(10) unsigned") + .HasColumnName("stock"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasComment("盒子名称") + .HasColumnName("title"); + entity.Property(e => e.Type) + .HasDefaultValueSql("'0'") + .HasComment("1一番赏 2无限赏 3擂台赏 4抽卡机 5积分赏 6全局赏 7福利盲盒 8领主赏 9连击赏") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("type"); + entity.Property(e => e.UnlockAmount) + .HasPrecision(10, 2) + .HasComment("消费多少额度解锁盒子") + .HasColumnName("unlock_amount"); + entity.Property(e => e.UpdateTime) + .HasComment("修改时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("update_time"); + entity.Property(e => e.UserLv) + .HasDefaultValueSql("'-1'") + .HasComment("多少级之下能买") + .HasColumnType("int(11)") + .HasColumnName("user_lv"); + entity.Property(e => e.XiajiaAutoCoushu) + .HasComment("下架生效抽数") + .HasColumnType("int(11)") + .HasColumnName("xiajia_auto_coushu"); + entity.Property(e => e.XiajiaLirun) + .HasComment("下架利润率") + .HasColumnType("int(11)") + .HasColumnName("xiajia_lirun"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("goods_extend", tb => tb.HasComment("盒子扩展表")); + + entity.Property(e => e.Id) + .HasComment("主键") + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.GoodsId) + .HasComment("奖品Id") + .HasColumnType("int(11)") + .HasColumnName("goods_id"); + entity.Property(e => e.IsDeduction) + .IsRequired() + .HasDefaultValueSql("'1'") + .HasComment("是否抵扣 1:抵扣 0:支付") + .HasColumnName("is_deduction"); + entity.Property(e => e.PayBalance) + .IsRequired() + .HasDefaultValueSql("'1'") + .HasComment("余额支付") + .HasColumnName("pay_balance"); + entity.Property(e => e.PayCoupon) + .IsRequired() + .HasDefaultValueSql("'1'") + .HasComment("优惠券支付") + .HasColumnName("pay_coupon"); + entity.Property(e => e.PayCurrency) + .IsRequired() + .HasDefaultValueSql("'1'") + .HasComment("货币支付") + .HasColumnName("pay_currency"); + entity.Property(e => e.PayCurrency2) + .IsRequired() + .HasDefaultValueSql("'1'") + .HasComment("货币2支付") + .HasColumnName("pay_currency2"); + entity.Property(e => e.PayWechat) + .IsRequired() + .HasDefaultValueSql("'1'") + .HasComment("微信支付") + .HasColumnName("pay_wechat"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("goods_extend_list"); + + entity.Property(e => e.Id) + .HasComment("主键") + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.GoodsId) + .HasComment("奖品Id") + .HasColumnType("int(11)") + .HasColumnName("goods_id"); + entity.Property(e => e.GoodsListId) + .HasComment("盲盒id") + .HasColumnType("int(11)") + .HasColumnName("goods_list_id"); + entity.Property(e => e.PrizeCode) + .HasMaxLength(30) + .HasComment("奖品编号") + .HasColumnName("prize_code"); + entity.Property(e => e.RawrdType) + .HasComment("1,默认最低抽奖次数,2指定多少抽出,3指定范围内必出,4:指定用户") + .HasColumnType("int(11)") + .HasColumnName("rawrd_type"); + entity.Property(e => e.RewardNum) + .HasComment("最低抽奖次数") + .HasColumnType("int(11)") + .HasColumnName("reward_num"); + entity.Property(e => e.RewardNum1) + .HasComment("最低抽奖次数") + .HasColumnType("int(11)") + .HasColumnName("reward_num_1"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("goods_king_rank", tb => tb.HasComment("无限赏领主")); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("开始时间") + .HasColumnType("int(11)") + .HasColumnName("addtime"); + entity.Property(e => e.Count) + .HasDefaultValueSql("'0'") + .HasComment("多少发升级为领主") + .HasColumnType("int(11)") + .HasColumnName("count"); + entity.Property(e => e.EndTime) + .HasComment("结束时间") + .HasColumnType("int(11)") + .HasColumnName("end_time"); + entity.Property(e => e.GoodsId) + .HasColumnType("int(11)") + .HasColumnName("goods_id"); + entity.Property(e => e.Money) + .HasDefaultValueSql("'0.00'") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money"); + entity.Property(e => e.OrderListId) + .HasDefaultValueSql("'0'") + .HasComment("奖品ID") + .HasColumnType("int(11)") + .HasColumnName("order_list_id"); + entity.Property(e => e.UserId) + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + entity.Property(e => e.ZNums) + .HasDefaultValueSql("'0'") + .HasComment("占领了多少发") + .HasColumnType("int(11) unsigned") + .HasColumnName("z_nums"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("goods_list", tb => tb.HasComment("盒子奖品")) + .UseCollation("utf8mb4_unicode_ci"); + + entity.HasIndex(e => e.CardNo, "card_no"); + + entity.HasIndex(e => e.Num, "goods_id"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.HasIndex(e => e.PrizeCode, "prize_code"); + + entity.HasIndex(e => e.RealPro, "real_pro"); + + entity.HasIndex(e => e.ShangId, "shang_id"); + + entity.HasIndex(e => e.Stock, "stock"); + + entity.HasIndex(e => e.SurplusStock, "surplus_stock"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(10)") + .HasColumnName("addtime"); + entity.Property(e => e.CardNo) + .HasMaxLength(100) + .HasComment("奖品赠送编号") + .HasColumnName("card_no"); + entity.Property(e => e.Doubling) + .HasComment("倍率") + .HasColumnType("int(11)") + .HasColumnName("doubling"); + entity.Property(e => e.GiveMoney) + .HasComment("消费阀值") + .HasColumnType("int(11) unsigned") + .HasColumnName("give_money"); + entity.Property(e => e.GoodsId) + .HasComment("盲盒id 0无限令 -1周榜 -2月榜") + .HasColumnType("int(11)") + .HasColumnName("goods_id"); + entity.Property(e => e.GoodsListId) + .HasComment("父节点id") + .HasColumnType("int(11)") + .HasColumnName("goods_list_id"); + entity.Property(e => e.GoodsType) + .HasDefaultValueSql("'1'") + .HasComment("1现货 2预售") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("goods_type"); + entity.Property(e => e.Imgurl) + .HasMaxLength(255) + .HasComment("奖品图片") + .HasColumnName("imgurl"); + entity.Property(e => e.ImgurlDetail) + .HasMaxLength(255) + .HasComment("商品详情图") + .HasColumnName("imgurl_detail"); + entity.Property(e => e.IsLingzhu) + .HasComment("是否为领主") + .HasColumnName("is_lingzhu"); + entity.Property(e => e.LianJiType) + .HasDefaultValueSql("'0'") + .HasComment("连击赏奖池分类 1秘宝池 0否") + .HasColumnName("lian_ji_type"); + entity.Property(e => e.Money) + .HasComment("奖品兑换价") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money"); + entity.Property(e => e.Num) + .HasComment("第几套") + .HasColumnType("int(11) unsigned") + .HasColumnName("num"); + entity.Property(e => e.Price) + .HasComment("奖品价值") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("price"); + entity.Property(e => e.PrizeCode) + .HasMaxLength(30) + .HasComment("奖品编号") + .HasColumnName("prize_code"); + entity.Property(e => e.PrizeNum) + .HasDefaultValueSql("'0'") + .HasComment("擂台赏抽全局赏数量") + .HasColumnType("int(11)") + .HasColumnName("prize_num"); + entity.Property(e => e.Rank) + .HasComment("榜单排名") + .HasColumnType("int(11) unsigned") + .HasColumnName("rank"); + entity.Property(e => e.RealPro) + .HasComment("真实概率") + .HasColumnType("decimal(10,5) unsigned") + .HasColumnName("real_pro"); + entity.Property(e => e.RewardId) + .HasMaxLength(64) + .HasComment("发放奖励id") + .HasColumnName("reward_id"); + entity.Property(e => e.RewardNum) + .HasColumnType("int(11) unsigned") + .HasColumnName("reward_num"); + entity.Property(e => e.SaleTime) + .HasComment("预售时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("sale_time"); + entity.Property(e => e.ScMoney) + .HasDefaultValueSql("'0.00'") + .HasComment("市场参考价") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("sc_money"); + entity.Property(e => e.ShangId) + .HasComment("赏ID") + .HasColumnType("int(255)") + .HasColumnName("shang_id"); + entity.Property(e => e.Sort) + .HasComment("排序") + .HasColumnType("int(11) unsigned") + .HasColumnName("sort"); + entity.Property(e => e.SpecialStock) + .HasDefaultValueSql("'-100'") + .HasComment("抽卡机特殊库存") + .HasColumnType("int(10)") + .HasColumnName("special_stock"); + entity.Property(e => e.Stock) + .HasComment("库存") + .HasColumnType("int(11) unsigned") + .HasColumnName("stock"); + entity.Property(e => e.SurplusStock) + .HasComment("剩余库存") + .HasColumnType("int(11) unsigned") + .HasColumnName("surplus_stock"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasComment("奖品名称") + .HasColumnName("title"); + entity.Property(e => e.Type) + .HasDefaultValueSql("'0'") + .HasComment("7抽奖券的奖品") + .HasColumnName("type"); + entity.Property(e => e.UpdateTime) + .HasColumnType("int(11) unsigned") + .HasColumnName("update_time"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("goods_lock", tb => tb.HasComment("盒子锁箱信息")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Endtime) + .HasComment("过期时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("endtime"); + entity.Property(e => e.GoodsIdNum) + .HasMaxLength(20) + .HasComment("盒子id_num") + .HasColumnName("goods_id_num"); + entity.Property(e => e.UpdateTime) + .HasColumnType("int(11) unsigned") + .HasColumnName("update_time"); + entity.Property(e => e.UserId) + .HasComment("用户ID") + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("goods_offshelf_log", tb => tb.HasComment("盒子自动下架日志表")); + + entity.HasIndex(e => e.CreateTime, "idx_create_time"); + + entity.HasIndex(e => e.GoodsId, "idx_goods_id"); + + entity.Property(e => e.Id) + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.CreateTime) + .HasComment("下架时间") + .HasColumnType("int(11)") + .HasColumnName("create_time"); + entity.Property(e => e.GoodsId) + .HasComment("盒子ID") + .HasColumnType("int(11)") + .HasColumnName("goods_id"); + entity.Property(e => e.GoodsTotal) + .HasPrecision(10, 2) + .HasComment("出货总价值") + .HasColumnName("goods_total"); + entity.Property(e => e.OrderTotal) + .HasPrecision(10, 2) + .HasComment("订单总价值") + .HasColumnName("order_total"); + entity.Property(e => e.ProfitRate) + .HasPrecision(10, 2) + .HasComment("当前利润率") + .HasColumnName("profit_rate"); + entity.Property(e => e.XiajiaLirun) + .HasPrecision(10, 2) + .HasComment("配置的下架利润阈值") + .HasColumnName("xiajia_lirun"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("goods_type"); + + entity.Property(e => e.Id) + .HasComment("主键") + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.CornerText) + .HasMaxLength(255) + .HasComment("角标文字") + .HasColumnName("corner_text"); + entity.Property(e => e.FlName) + .HasMaxLength(30) + .HasComment("分类名称") + .HasColumnName("fl_name"); + entity.Property(e => e.IsDeduction) + .IsRequired() + .HasDefaultValueSql("'1'") + .HasComment("是否抵扣 1:抵扣 0:支付") + .HasColumnName("is_deduction"); + entity.Property(e => e.IsFenlei) + .HasComment("是否显示在分类中") + .HasColumnType("tinyint(4)") + .HasColumnName("is_fenlei"); + entity.Property(e => e.IsShow) + .HasComment("是否首页显示") + .HasColumnName("is_show"); + entity.Property(e => e.Name) + .HasMaxLength(30) + .HasComment("名称") + .HasColumnName("name"); + entity.Property(e => e.PayBalance) + .IsRequired() + .HasDefaultValueSql("'1'") + .HasComment("余额支付") + .HasColumnName("pay_balance"); + entity.Property(e => e.PayCoupon) + .IsRequired() + .HasDefaultValueSql("'1'") + .HasComment("优惠券支付") + .HasColumnName("pay_coupon"); + entity.Property(e => e.PayCurrency) + .IsRequired() + .HasDefaultValueSql("'1'") + .HasComment("货币支付") + .HasColumnName("pay_currency"); + entity.Property(e => e.PayCurrency2) + .IsRequired() + .HasDefaultValueSql("'1'") + .HasComment("货币2支付") + .HasColumnName("pay_currency2"); + entity.Property(e => e.PayWechat) + .IsRequired() + .HasDefaultValueSql("'1'") + .HasComment("微信支付") + .HasColumnName("pay_wechat"); + entity.Property(e => e.Remark) + .HasMaxLength(255) + .HasComment("备注") + .HasColumnName("remark"); + entity.Property(e => e.SortOrder) + .HasComment("排序字段") + .HasColumnType("int(11)") + .HasColumnName("sort_order"); + entity.Property(e => e.Value) + .HasComment("key") + .HasColumnType("int(11)") + .HasColumnName("value"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("item_card", tb => tb.HasComment("道具卡")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(10) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.Sort) + .HasDefaultValueSql("'1'") + .HasComment("排序值") + .HasColumnType("int(10) unsigned") + .HasColumnName("sort"); + entity.Property(e => e.Status) + .HasDefaultValueSql("'0'") + .HasComment("1正常 2下架 3删除") + .HasColumnName("status"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasComment("名称") + .HasColumnName("title"); + entity.Property(e => e.Type) + .HasDefaultValueSql("'0'") + .HasComment("1重抽卡") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("type"); + entity.Property(e => e.Updatetime) + .HasColumnType("int(11)") + .HasColumnName("updatetime"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("kk_order", tb => tb.HasComment("发货订单表")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.HasIndex(e => e.OrderNo, "order_no").IsUnique(); + + entity.HasIndex(e => e.Status, "status"); + + entity.HasIndex(e => e.UserId, "user_id"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("创建时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.ConfirmTime) + .HasComment("收货时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("confirm_time"); + entity.Property(e => e.Content) + .HasMaxLength(200) + .HasComment("留言") + .HasColumnName("content"); + entity.Property(e => e.DeliverTime) + .HasComment("发货时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("deliver_time"); + entity.Property(e => e.FreightPrice) + .HasComment("运费金额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("freight_price"); + entity.Property(e => e.Integral) + .HasDefaultValueSql("'0.00'") + .HasComment("Woo币抵扣") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("integral"); + entity.Property(e => e.Money) + .HasDefaultValueSql("'0.00'") + .HasComment("余额抵扣") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money"); + entity.Property(e => e.OrderNo) + .HasMaxLength(100) + .HasComment("订单号") + .HasColumnName("order_no"); + entity.Property(e => e.PayTime) + .HasComment("支付时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("pay_time"); + entity.Property(e => e.Price) + .HasComment("实付金额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("price"); + entity.Property(e => e.Status) + .HasComment("0待付款 1待发货 2待收货 3确认收货") + .HasColumnName("status"); + entity.Property(e => e.TotalPrice) + .HasComment("商品总金额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("total_price"); + entity.Property(e => e.UpdateTime) + .HasColumnType("int(11)") + .HasColumnName("update_time"); + entity.Property(e => e.UserId) + .HasComment("会员id") + .HasColumnType("int(10) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("kk_order_good", tb => tb.HasComment("订单商品")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("创建时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.GoodsId) + .HasComment("商品id") + .HasColumnType("int(11) unsigned") + .HasColumnName("goods_id"); + entity.Property(e => e.GoodsImage) + .HasMaxLength(255) + .HasComment("商品主图") + .HasColumnName("goods_image"); + entity.Property(e => e.GoodsName) + .HasMaxLength(255) + .HasComment("商品名称") + .HasColumnName("goods_name"); + entity.Property(e => e.GoodsNum) + .HasComment("数量") + .HasColumnType("int(11) unsigned") + .HasColumnName("goods_num"); + entity.Property(e => e.GoodsPrice) + .HasComment("商品售价") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("goods_price"); + entity.Property(e => e.GoodsSeckillPrice) + .HasComment("商品秒杀价") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("goods_seckill_price"); + entity.Property(e => e.GoodsSpec) + .HasMaxLength(255) + .HasComment("商品规格") + .HasColumnName("goods_spec"); + entity.Property(e => e.GoodsSpecId) + .HasComment("商品规格id") + .HasColumnType("int(11) unsigned") + .HasColumnName("goods_spec_id"); + entity.Property(e => e.OrderId) + .HasComment("订单id") + .HasColumnType("int(11) unsigned") + .HasColumnName("order_id"); + entity.Property(e => e.UserId) + .HasComment("会员id") + .HasColumnType("int(10) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("kk_order_send", tb => tb.HasComment("发货订单地址物流信息")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.HasIndex(e => e.OrderId, "order_id").IsUnique(); + + entity.HasIndex(e => e.UserId, "user_id"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Address) + .HasMaxLength(255) + .HasComment("详细地址") + .HasColumnName("address"); + entity.Property(e => e.DeliveryName) + .HasMaxLength(255) + .HasComment("物流名称") + .HasColumnName("delivery_name"); + entity.Property(e => e.DeliveryNo) + .HasMaxLength(255) + .HasComment("物流单号") + .HasColumnName("delivery_no"); + entity.Property(e => e.OrderId) + .HasComment("订单ID") + .HasColumnType("int(11) unsigned") + .HasColumnName("order_id"); + entity.Property(e => e.ShouMobile) + .HasMaxLength(255) + .HasComment("收货人手机号") + .HasColumnName("shou_mobile"); + entity.Property(e => e.ShouName) + .HasMaxLength(255) + .HasComment("收货人姓名") + .HasColumnName("shou_name"); + entity.Property(e => e.ShouRegion) + .HasMaxLength(255) + .HasComment("所在地区 省/市/区(名称)") + .HasColumnName("shou_region"); + entity.Property(e => e.UpdateTime) + .HasColumnType("int(11)") + .HasColumnName("update_time"); + entity.Property(e => e.UserId) + .HasComment("会员id") + .HasColumnType("int(10) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("kk_product", tb => tb.HasComment("商品表")) + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.HasIndex(e => e.Status, "status"); + + entity.HasIndex(e => e.Title, "title"); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.CateId1) + .HasComment("分类父级id") + .HasColumnType("int(11) unsigned") + .HasColumnName("cate_id1"); + entity.Property(e => e.CateId2) + .HasComment("分类子级id") + .HasColumnType("int(11) unsigned") + .HasColumnName("cate_id2"); + entity.Property(e => e.Content) + .HasComment("商品详情") + .HasColumnName("content"); + entity.Property(e => e.DetailImage) + .HasComment("详情图") + .HasColumnType("text") + .HasColumnName("detail_image"); + entity.Property(e => e.Freight) + .HasComment("运费") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("freight"); + entity.Property(e => e.Image) + .HasMaxLength(200) + .HasComment("商品主图") + .HasColumnName("image"); + entity.Property(e => e.SaleNum) + .HasComment("销量") + .HasColumnType("int(9) unsigned") + .HasColumnName("sale_num"); + entity.Property(e => e.SeckillId) + .HasComment("秒杀时间段id") + .HasColumnType("int(11) unsigned") + .HasColumnName("seckill_id"); + entity.Property(e => e.Sort) + .HasComment("商品排序") + .HasColumnType("int(7) unsigned") + .HasColumnName("sort"); + entity.Property(e => e.SpecData) + .HasComment("规格信息") + .HasColumnName("spec_data"); + entity.Property(e => e.Status) + .HasComment("0上架 1下架") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("status"); + entity.Property(e => e.Title) + .HasComment("商品名称") + .HasColumnName("title"); + entity.Property(e => e.UpdateTime) + .HasComment("修改时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("update_time"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("kk_product_cate", tb => tb.HasComment("商品分类")) + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(10) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.Imgurl) + .HasMaxLength(100) + .HasComment("分类图片") + .HasColumnName("imgurl"); + entity.Property(e => e.Pid) + .HasDefaultValueSql("'0'") + .HasComment("上级id") + .HasColumnType("int(11)") + .HasColumnName("pid"); + entity.Property(e => e.Sort) + .HasDefaultValueSql("'1'") + .HasComment("排序值") + .HasColumnType("int(5) unsigned") + .HasColumnName("sort"); + entity.Property(e => e.Status) + .HasDefaultValueSql("'1'") + .HasComment("1 正常 2 删除") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("status"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasComment("分类标题") + .HasColumnName("title"); + entity.Property(e => e.Title2) + .HasMaxLength(255) + .HasComment("英文标题") + .HasColumnName("title2"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("kk_product_category", tb => tb.HasComment("普通商城商品分类")) + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.Imgurl) + .HasMaxLength(255) + .HasComment("分类图片") + .HasColumnName("imgurl"); + entity.Property(e => e.Pid) + .HasComment("父级id") + .HasColumnType("int(11) unsigned") + .HasColumnName("pid"); + entity.Property(e => e.Sort) + .HasComment("0") + .HasColumnType("int(11) unsigned") + .HasColumnName("sort"); + entity.Property(e => e.Status) + .HasDefaultValueSql("'1'") + .HasComment("1显示 0隐藏") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("status"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasComment("商品名称") + .HasColumnName("title"); + entity.Property(e => e.UpdateTime) + .HasComment("修改时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("update_time"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("kk_product_spec", tb => tb.HasComment("商品规格")) + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.HasIndex(e => e.Ks, "ks"); + + entity.HasIndex(e => e.ProId, "pro_id"); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Ks) + .HasComment("标识") + .HasColumnName("ks"); + entity.Property(e => e.Name) + .HasMaxLength(255) + .HasComment("名称") + .HasColumnName("name"); + entity.Property(e => e.Pic) + .HasMaxLength(255) + .HasComment("图片") + .HasColumnName("pic"); + entity.Property(e => e.Price) + .HasComment("售价") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("price"); + entity.Property(e => e.ProId) + .HasComment("商品id") + .HasColumnType("int(11)") + .HasColumnName("pro_id"); + entity.Property(e => e.SeckillPrice) + .HasComment("秒杀价") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("seckill_price"); + entity.Property(e => e.Stock) + .HasComment("库存") + .HasColumnType("int(9) unsigned") + .HasColumnName("stock"); + entity.Property(e => e.Time) + .HasComment("添加时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("time"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("kk_seckill", tb => tb.HasComment("秒杀设置")) + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.GoodsNum) + .HasComment("商品限购数量") + .HasColumnType("int(11) unsigned") + .HasColumnName("goods_num"); + entity.Property(e => e.SeckillTime) + .HasMaxLength(100) + .HasComment("秒杀时间段") + .HasColumnName("seckill_time"); + entity.Property(e => e.UpdateTime) + .HasComment("修改时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("update_time"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("kk_share", tb => tb.HasComment("商品分享记录表")) + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.GoodsId) + .HasComment("商品id") + .HasColumnType("int(11) unsigned") + .HasColumnName("goods_id"); + entity.Property(e => e.ShareUserId) + .HasComment("分享用户id") + .HasColumnType("int(11) unsigned") + .HasColumnName("share_user_id"); + entity.Property(e => e.UserId) + .HasComment("点击人ID") + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("market", tb => tb.HasComment("集市")); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasColumnType("int(11)") + .HasColumnName("addtime"); + entity.Property(e => e.Deltime) + .HasColumnType("int(11)") + .HasColumnName("deltime"); + entity.Property(e => e.OrderListIds) + .HasComment("id字符串") + .HasColumnName("order_list_ids"); + entity.Property(e => e.OrderNum) + .HasMaxLength(255) + .HasComment("挂售单号") + .HasColumnName("order_num"); + entity.Property(e => e.Price) + .HasComment("价格") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("price"); + entity.Property(e => e.Status) + .HasDefaultValueSql("'0'") + .HasComment("0在售 1已售 2已撤回") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("status"); + entity.Property(e => e.Stock) + .HasDefaultValueSql("'1'") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("stock"); + entity.Property(e => e.UpdateTime) + .HasColumnType("int(11)") + .HasColumnName("update_time"); + entity.Property(e => e.UserId) + .HasColumnType("int(11)") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("market_order", tb => tb.HasComment("集市订单")); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasColumnType("int(11)") + .HasColumnName("addtime"); + entity.Property(e => e.Deltime) + .HasColumnType("int(11)") + .HasColumnName("deltime"); + entity.Property(e => e.MarketId) + .HasColumnType("int(11)") + .HasColumnName("market_id"); + entity.Property(e => e.Money) + .HasComment("支付了多少市集余额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money"); + entity.Property(e => e.OrderListIds) + .HasComment("id字符串") + .HasColumnName("order_list_ids"); + entity.Property(e => e.OrderNum) + .HasMaxLength(255) + .HasComment("挂售单号") + .HasColumnName("order_num"); + entity.Property(e => e.PayTime) + .HasColumnType("int(11)") + .HasColumnName("pay_time"); + entity.Property(e => e.Price) + .HasComment("价格") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("price"); + entity.Property(e => e.Status) + .HasDefaultValueSql("'0'") + .HasComment("1未支付 2已支付 3卡单") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("status"); + entity.Property(e => e.Total) + .HasComment("总价") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("total"); + entity.Property(e => e.TotalPrice) + .HasComment("实际支付") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("total_price"); + entity.Property(e => e.UpdateTime) + .HasColumnType("int(11)") + .HasColumnName("update_time"); + entity.Property(e => e.UserId) + .HasColumnType("int(11)") + .HasColumnName("user_id"); + entity.Property(e => e.ZdfhIs) + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("zdfh_is"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Version).HasName("PRIMARY"); + + entity + .ToTable("migrations") + .UseCollation("utf8mb4_unicode_ci"); + + entity.Property(e => e.Version) + .ValueGeneratedNever() + .HasColumnType("bigint(20)") + .HasColumnName("version"); + entity.Property(e => e.Breakpoint).HasColumnName("breakpoint"); + entity.Property(e => e.EndTime) + .HasColumnType("timestamp") + .HasColumnName("end_time"); + entity.Property(e => e.MigrationName) + .HasMaxLength(100) + .HasColumnName("migration_name"); + entity.Property(e => e.StartTime) + .HasColumnType("timestamp") + .HasColumnName("start_time"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("notify_log"); + + entity.Property(e => e.Id) + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasColumnType("int(11)") + .HasColumnName("addtime"); + entity.Property(e => e.OrderNo) + .HasMaxLength(40) + .HasColumnName("order_no"); + entity.Property(e => e.Xml) + .HasColumnType("text") + .HasColumnName("xml"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("order", tb => tb.HasComment("订单表")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.GoodsId, "goods_id"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.HasIndex(e => e.Num, "num"); + + entity.HasIndex(e => e.OrderNum, "order_num").IsUnique(); + + entity.HasIndex(e => e.Status, "status"); + + entity.HasIndex(e => e.UserId, "user_id"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.AdId) + .HasDefaultValueSql("'0'") + .HasComment("广告id") + .HasColumnType("int(11)") + .HasColumnName("ad_id"); + entity.Property(e => e.Addtime) + .HasComment("下单时间") + .HasColumnType("int(10) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.ClickId) + .HasColumnType("int(11)") + .HasColumnName("click_id"); + entity.Property(e => e.CouponId) + .HasDefaultValueSql("'0'") + .HasComment("优惠券id") + .HasColumnType("int(11)") + .HasColumnName("coupon_id"); + entity.Property(e => e.GoodsId) + .HasComment("盒子id") + .HasColumnType("int(11) unsigned") + .HasColumnName("goods_id"); + entity.Property(e => e.GoodsImgurl) + .HasMaxLength(200) + .HasComment("盒子图片") + .HasColumnName("goods_imgurl"); + entity.Property(e => e.GoodsPrice) + .HasComment("盒子单价") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("goods_price"); + entity.Property(e => e.GoodsTitle) + .HasMaxLength(100) + .HasComment("盒子标题") + .HasColumnName("goods_title"); + entity.Property(e => e.IsFlw) + .HasComment("是否为福利屋") + .HasColumnType("int(1)") + .HasColumnName("is_flw"); + entity.Property(e => e.IsMibao) + .HasDefaultValueSql("'0'") + .HasComment("连击赏下 是否是抽的秘宝池 1是 0否") + .HasColumnName("is_mibao"); + entity.Property(e => e.IsShouZhe) + .HasDefaultValueSql("'0'") + .HasComment("是否首抽五折") + .HasColumnName("is_shou_zhe"); + entity.Property(e => e.KdIs) + .HasComment("1卡单") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("kd_is"); + entity.Property(e => e.Num) + .HasComment("第几套") + .HasColumnType("int(11) unsigned") + .HasColumnName("num"); + entity.Property(e => e.OrderNum) + .HasMaxLength(60) + .HasComment("订单号") + .HasColumnName("order_num"); + entity.Property(e => e.OrderTotal) + .HasComment("订单总金额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("order_total"); + entity.Property(e => e.OrderType) + .HasComment("盒子类型") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("order_type"); + entity.Property(e => e.OrderZheTotal) + .HasComment("订单折扣金额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("order_zhe_total"); + entity.Property(e => e.PayTime) + .HasComment("付款时间") + .HasColumnType("int(10) unsigned") + .HasColumnName("pay_time"); + entity.Property(e => e.PayType) + .HasDefaultValueSql("'1'") + .HasComment("1微信 2支付宝") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("pay_type"); + entity.Property(e => e.Price) + .HasComment("微信支付") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("price"); + entity.Property(e => e.PrizeCardSet) + .HasComment("抽卡机必出设置") + .HasColumnType("text") + .HasColumnName("prize_card_set"); + entity.Property(e => e.PrizeNum) + .HasComment("抽奖数量") + .HasColumnType("int(11) unsigned") + .HasColumnName("prize_num"); + entity.Property(e => e.Status) + .HasComment("0未支付 1支付") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("status"); + entity.Property(e => e.UseCoupon) + .HasPrecision(10, 2) + .HasDefaultValueSql("'0.00'") + .HasComment("优惠券抵扣") + .HasColumnName("use_coupon"); + entity.Property(e => e.UseDraw) + .HasDefaultValueSql("'0'") + .HasComment("抽奖券抵扣") + .HasColumnType("int(11)") + .HasColumnName("use_draw"); + entity.Property(e => e.UseIntegral) + .HasComment("UU币支付") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("use_integral"); + entity.Property(e => e.UseItemCard) + .HasDefaultValueSql("'0'") + .HasComment("道具卡抵扣 (使用的数量)") + .HasColumnType("int(11)") + .HasColumnName("use_item_card"); + entity.Property(e => e.UseMoney) + .HasComment("钻石支付") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("use_money"); + entity.Property(e => e.UseMoney2) + .HasPrecision(10, 2) + .HasComment("达达卷支付") + .HasColumnName("use_money2"); + entity.Property(e => e.UseScore) + .HasComment("积分抵扣,未使用") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("use_score"); + entity.Property(e => e.UserId) + .HasComment("用户ID") + .HasColumnType("int(10) unsigned") + .HasColumnName("user_id"); + entity.Property(e => e.ZdfhIs) + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("zdfh_is"); + entity.Property(e => e.ZdfhTime) + .HasDefaultValueSql("'0'") + .HasComment("自动发货时间") + .HasColumnType("int(10)") + .HasColumnName("zdfh_time"); + entity.Property(e => e.Zhe) + .HasComment("折扣") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("zhe"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("order_list", tb => tb.HasComment("订单明细")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.GoodsId, "goods_id"); + + entity.HasIndex(e => e.GoodslistId, "goodslist_id"); + + entity.HasIndex(e => e.GoodslistType, "goodslist_type"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.HasIndex(e => new { e.GoodsId, e.UserId, e.Addtime }, "idx_gid_uid_time"); + + entity.HasIndex(e => new { e.UserId, e.Addtime }, "idx_user_addtime"); + + entity.HasIndex(e => e.InsuranceIs, "insurance_is"); + + entity.HasIndex(e => e.Num, "num"); + + entity.HasIndex(e => e.OrderId, "order_id"); + + entity.HasIndex(e => e.OrderType, "order_type"); + + entity.HasIndex(e => e.PrizeCode, "prize_code"); + + entity.HasIndex(e => e.RecoveryNum, "recovery_num"); + + entity.HasIndex(e => e.SendNum, "send_num"); + + entity.HasIndex(e => e.ShangId, "shang_id"); + + entity.HasIndex(e => e.Status, "status"); + + entity.HasIndex(e => e.UserId, "user_id"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("创建时间") + .HasColumnType("int(10) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.ChoiceTime) + .HasComment("选择发货/回收时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("choice_time"); + entity.Property(e => e.Deltime) + .HasColumnType("int(11)") + .HasColumnName("deltime"); + entity.Property(e => e.Doubling) + .HasComment("抽奖倍率") + .HasColumnType("int(11)") + .HasColumnName("doubling"); + entity.Property(e => e.FhRemarks) + .HasMaxLength(255) + .HasComment("发货备注") + .HasColumnName("fh_remarks"); + entity.Property(e => e.FhStatus) + .HasComment("发货状态,1已发货,2未发货") + .HasColumnType("int(11)") + .HasColumnName("fh_status"); + entity.Property(e => e.GoodsId) + .HasDefaultValueSql("'0'") + .HasComment("盒子ID") + .HasColumnType("int(11)") + .HasColumnName("goods_id"); + entity.Property(e => e.GoodslistId) + .HasComment("奖品id") + .HasColumnType("int(10) unsigned") + .HasColumnName("goodslist_id"); + entity.Property(e => e.GoodslistImgurl) + .HasMaxLength(255) + .HasComment("奖品封面图") + .HasColumnName("goodslist_imgurl"); + entity.Property(e => e.GoodslistMoney) + .HasComment("奖品回收") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("goodslist_money"); + entity.Property(e => e.GoodslistPrice) + .HasComment("奖品价值") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("goodslist_price"); + entity.Property(e => e.GoodslistSaleTime) + .HasComment("预售时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("goodslist_sale_time"); + entity.Property(e => e.GoodslistTitle) + .HasMaxLength(100) + .HasComment("奖品名称") + .HasColumnName("goodslist_title"); + entity.Property(e => e.GoodslistType) + .HasDefaultValueSql("'1'") + .HasComment("1现货 2预售,3货币,4 宝箱") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("goodslist_type"); + entity.Property(e => e.InsuranceIs) + .HasComment("保险柜0否 1是") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("insurance_is"); + entity.Property(e => e.IsChong) + .HasDefaultValueSql("'0'") + .HasComment("是否使用重抽卡 0否 1是") + .HasColumnName("is_chong"); + entity.Property(e => e.IsLingzhu) + .HasComment("是否是领主奖品") + .HasColumnType("tinyint(4)") + .HasColumnName("is_lingzhu"); + entity.Property(e => e.LuckNo) + .HasComment("抽奖序号") + .HasColumnType("int(11) unsigned") + .HasColumnName("luck_no"); + entity.Property(e => e.Num) + .HasComment("第几箱") + .HasColumnType("int(10) unsigned") + .HasColumnName("num"); + entity.Property(e => e.OrderId) + .HasComment("订单id") + .HasColumnType("int(11) unsigned") + .HasColumnName("order_id"); + entity.Property(e => e.OrderListId) + .HasComment("特殊奖品中奖订单id") + .HasColumnType("int(11) unsigned") + .HasColumnName("order_list_id"); + entity.Property(e => e.OrderType) + .HasComment("盒子类型") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("order_type"); + entity.Property(e => e.ParentGoodsListId) + .HasComment("所属宝箱id") + .HasColumnType("int(11)") + .HasColumnName("parent_goods_list_id"); + entity.Property(e => e.PrizeCode) + .HasMaxLength(30) + .HasComment("奖品code") + .HasColumnName("prize_code") + .UseCollation("utf8mb4_unicode_ci") + .HasCharSet("utf8mb4"); + entity.Property(e => e.RecoveryNum) + .HasMaxLength(100) + .HasComment("回收订单") + .HasColumnName("recovery_num"); + entity.Property(e => e.SendNum) + .HasMaxLength(100) + .HasComment("发货订单号") + .HasColumnName("send_num"); + entity.Property(e => e.ShangId) + .HasComment("赏ID") + .HasColumnType("int(11) unsigned") + .HasColumnName("shang_id"); + entity.Property(e => e.Source) + .HasDefaultValueSql("'1'") + .HasComment("1抽奖 2集市购买") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("source"); + entity.Property(e => e.Status) + .HasComment("0待选择 1回收 2选择发货 3发布集市") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("status"); + entity.Property(e => e.UserId) + .HasComment("用户id") + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("order_list_recovery", tb => tb.HasComment("打包记录")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.HasIndex(e => e.RecoveryNum, "recovery_num").IsUnique(); + + entity.HasIndex(e => e.UserId, "user_id"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("打包时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.Count) + .HasComment("打包数量") + .HasColumnType("int(11) unsigned") + .HasColumnName("count"); + entity.Property(e => e.Money) + .HasComment("打包金额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money"); + entity.Property(e => e.RecoveryNum) + .HasMaxLength(100) + .HasComment("打包订单号") + .HasColumnName("recovery_num"); + entity.Property(e => e.UserId) + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("order_list_send", tb => tb.HasComment("发货记录")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.HasIndex(e => e.SendNum, "send_num").IsUnique(); + + entity.HasIndex(e => e.Status, "status"); + + entity.HasIndex(e => e.UserId, "user_id"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Address) + .HasMaxLength(255) + .HasComment("收货地址") + .HasColumnName("address"); + entity.Property(e => e.Addtime) + .HasComment("下单时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.AdminId) + .HasComment("管理员id") + .HasColumnType("int(11) unsigned") + .HasColumnName("admin_id"); + entity.Property(e => e.CancelTime) + .HasComment("取消时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("cancel_time"); + entity.Property(e => e.Count) + .HasComment("发货数量") + .HasColumnType("int(11) unsigned") + .HasColumnName("count"); + entity.Property(e => e.CourierCode) + .HasMaxLength(50) + .HasComment("快递code") + .HasColumnName("courier_code"); + entity.Property(e => e.CourierName) + .HasMaxLength(255) + .HasComment("快递名称") + .HasColumnName("courier_name"); + entity.Property(e => e.CourierNumber) + .HasMaxLength(50) + .HasComment("快递单号") + .HasColumnName("courier_number"); + entity.Property(e => e.DeliveryList) + .HasComment("物流轨迹信息") + .HasColumnType("text") + .HasColumnName("delivery_list"); + entity.Property(e => e.DeliveryStatus) + .IsRequired() + .HasDefaultValueSql("'-1'") + .HasComment("物流状态") + .HasColumnName("delivery_status"); + entity.Property(e => e.DeliveryTime) + .HasComment("物流请求时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("delivery_time"); + entity.Property(e => e.Freight) + .HasComment("运费") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("freight"); + entity.Property(e => e.Message) + .HasMaxLength(255) + .HasComment("备注") + .HasColumnName("message"); + entity.Property(e => e.Mobile) + .HasMaxLength(255) + .HasComment("收货人电话") + .HasColumnName("mobile"); + entity.Property(e => e.Name) + .HasMaxLength(255) + .HasComment("收货人姓名") + .HasColumnName("name"); + entity.Property(e => e.PayTime) + .HasComment("支付时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("pay_time"); + entity.Property(e => e.SendNum) + .HasMaxLength(100) + .HasComment("发货订单号") + .HasColumnName("send_num"); + entity.Property(e => e.SendTime) + .HasComment("发货时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("send_time"); + entity.Property(e => e.ShouTime) + .HasComment("收货时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("shou_time"); + entity.Property(e => e.Status) + .HasComment("0待支付 1待发货 2待收货 3已完成 4后台取消") + .HasColumnType("tinyint(3) unsigned") + .HasColumnName("status"); + entity.Property(e => e.UserId) + .HasComment("用户id") + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("picture") + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasColumnType("int(10) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.Imgurl) + .HasMaxLength(255) + .HasColumnName("imgurl"); + entity.Property(e => e.Status) + .HasDefaultValueSql("'1'") + .HasComment("1 正常 2 删除") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("status"); + entity.Property(e => e.Token) + .HasMaxLength(255) + .HasColumnName("token"); + entity.Property(e => e.Type) + .HasComment("存储位置 1=本地 2= 阿里云") + .HasColumnName("type"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("profit_draw", tb => tb.HasComment("财务明细")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.HasIndex(e => e.UserId, "user_id"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.ChangeMoney) + .HasPrecision(10, 2) + .HasComment("变化的金额") + .HasColumnName("change_money"); + entity.Property(e => e.Content) + .HasMaxLength(255) + .HasComment("描述") + .HasColumnName("content"); + entity.Property(e => e.Money) + .HasComment("变化后的金额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money"); + entity.Property(e => e.Other) + .HasMaxLength(255) + .HasColumnName("other"); + entity.Property(e => e.ShareUid) + .HasComment("来源ID") + .HasColumnType("int(11) unsigned") + .HasColumnName("share_uid"); + entity.Property(e => e.Type) + .HasComment("1后台充值 2在线充值 3抽赏消费 4背包回收 5推荐奖励") + .HasColumnType("tinyint(2) unsigned") + .HasColumnName("type"); + entity.Property(e => e.UserId) + .HasComment("用户id") + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("profit_expenses", tb => tb.HasComment("利润支出表")); + + entity.Property(e => e.Id) + .HasComment("主键") + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.Amount) + .HasPrecision(10, 2) + .HasComment("支出金额") + .HasColumnName("amount"); + entity.Property(e => e.CreatedAt) + .HasDefaultValueSql("CURRENT_TIMESTAMP") + .HasComment("创建时间") + .HasColumnType("timestamp") + .HasColumnName("created_at"); + entity.Property(e => e.Description) + .HasMaxLength(255) + .HasComment("说明") + .HasColumnName("description"); + entity.Property(e => e.ExpenseType) + .HasComment("支出类型") + .HasColumnType("int(10)") + .HasColumnName("expense_type"); + entity.Property(e => e.ProfitDate) + .HasComment("账单日期") + .HasColumnName("profit_date"); + entity.Property(e => e.UpdatedAt) + .ValueGeneratedOnAddOrUpdate() + .HasDefaultValueSql("CURRENT_TIMESTAMP") + .HasComment("修改时间") + .HasColumnType("timestamp") + .HasColumnName("updated_at"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("profit_integral", tb => tb.HasComment("财务明细")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.HasIndex(e => e.UserId, "user_id"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.ChangeMoney) + .HasPrecision(10, 2) + .HasComment("变化的金额") + .HasColumnName("change_money"); + entity.Property(e => e.Content) + .HasMaxLength(255) + .HasComment("描述") + .HasColumnName("content"); + entity.Property(e => e.Money) + .HasComment("变化后的金额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money"); + entity.Property(e => e.Other) + .HasMaxLength(255) + .HasColumnName("other"); + entity.Property(e => e.ShareUid) + .HasComment("来源ID") + .HasColumnType("int(11) unsigned") + .HasColumnName("share_uid"); + entity.Property(e => e.Type) + .HasComment("1后台充值 2抽赏消费 3开券获得 4领主返币 5分享欧气券") + .HasColumnType("tinyint(2) unsigned") + .HasColumnName("type"); + entity.Property(e => e.UserId) + .HasComment("用户id") + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("profit_money", tb => tb.HasComment("财务明细")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.HasIndex(e => e.UserId, "user_id"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.ChangeMoney) + .HasPrecision(10, 2) + .HasComment("变化的金额") + .HasColumnName("change_money"); + entity.Property(e => e.Content) + .HasMaxLength(255) + .HasComment("描述") + .HasColumnName("content"); + entity.Property(e => e.Money) + .HasComment("变化后的金额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money"); + entity.Property(e => e.Other) + .HasMaxLength(255) + .HasColumnName("other"); + entity.Property(e => e.ShareUid) + .HasComment("来源ID") + .HasColumnType("int(11) unsigned") + .HasColumnName("share_uid"); + entity.Property(e => e.Type) + .HasComment("1后台充值 2在线充值 3抽赏消费 4背包回收 5推荐奖励") + .HasColumnType("tinyint(2) unsigned") + .HasColumnName("type"); + entity.Property(e => e.UserId) + .HasComment("用户id") + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("profit_money2", tb => tb.HasComment("财务明细")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.HasIndex(e => e.UserId, "user_id"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.ChangeMoney) + .HasPrecision(10, 2) + .HasComment("变化的金额") + .HasColumnName("change_money"); + entity.Property(e => e.Content) + .HasMaxLength(255) + .HasComment("描述") + .HasColumnName("content"); + entity.Property(e => e.Money) + .HasComment("变化后的金额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money"); + entity.Property(e => e.Other) + .HasMaxLength(255) + .HasColumnName("other"); + entity.Property(e => e.ShareUid) + .HasComment("来源ID") + .HasColumnType("int(11) unsigned") + .HasColumnName("share_uid"); + entity.Property(e => e.Type) + .HasComment("1后台充值 2在线充值 3市集消费 4市集售卖 5提现 6提现驳回 7提现手续费") + .HasColumnType("tinyint(2) unsigned") + .HasColumnName("type"); + entity.Property(e => e.UserId) + .HasComment("用户id") + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("profit_ou_qi", tb => tb.HasComment("欧气值明细")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.HasIndex(e => e.UserId, "user_id"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.ChangeMoney) + .HasPrecision(10, 2) + .HasComment("变化的金额") + .HasColumnName("change_money"); + entity.Property(e => e.Content) + .HasMaxLength(255) + .HasComment("描述") + .HasColumnName("content"); + entity.Property(e => e.Money) + .HasComment("变化后的金额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money"); + entity.Property(e => e.Other) + .HasMaxLength(255) + .HasColumnName("other"); + entity.Property(e => e.Type) + .HasComment("1完成任务 2消费赠送 3升级清空 4升级后多出") + .HasColumnType("tinyint(2) unsigned") + .HasColumnName("type"); + entity.Property(e => e.UserId) + .HasComment("用户id") + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("profit_pay", tb => tb.HasComment("(微信/支付宝)支付")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.HasIndex(e => e.UserId, "user_id"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.ChangeMoney) + .HasPrecision(10, 2) + .HasComment("变化的金额") + .HasColumnName("change_money"); + entity.Property(e => e.Content) + .HasMaxLength(255) + .HasComment("描述") + .HasColumnName("content"); + entity.Property(e => e.OrderNum) + .HasMaxLength(100) + .HasComment("订单号") + .HasColumnName("order_num"); + entity.Property(e => e.PayType) + .HasComment("1微信 2支付宝") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("pay_type"); + entity.Property(e => e.UserId) + .HasComment("用户id") + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("profit_revenue", tb => tb.HasComment("利润收入表")); + + entity.Property(e => e.Id) + .HasComment("主键") + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.Amount) + .HasPrecision(10, 2) + .HasComment("发放货币") + .HasColumnName("amount"); + entity.Property(e => e.CreatedAt) + .HasDefaultValueSql("CURRENT_TIMESTAMP") + .HasComment("创建时间") + .HasColumnType("timestamp") + .HasColumnName("created_at"); + entity.Property(e => e.Description) + .HasMaxLength(255) + .HasComment("说明") + .HasColumnName("description"); + entity.Property(e => e.ExpenseType) + .HasComment("收入类型") + .HasColumnType("int(10)") + .HasColumnName("expense_type"); + entity.Property(e => e.Price) + .HasPrecision(10, 2) + .HasComment("收入金额") + .HasColumnName("price"); + entity.Property(e => e.ProfitDate) + .HasComment("账单日期") + .HasColumnName("profit_date"); + entity.Property(e => e.UpdatedAt) + .ValueGeneratedOnAddOrUpdate() + .HasDefaultValueSql("CURRENT_TIMESTAMP") + .HasComment("修改时间") + .HasColumnType("timestamp") + .HasColumnName("updated_at"); + entity.Property(e => e.UserId) + .HasComment("用户id") + .HasColumnType("int(10)") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("profit_score", tb => tb.HasComment("财务明细")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.HasIndex(e => e.UserId, "user_id"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.ChangeMoney) + .HasPrecision(10, 2) + .HasComment("变化的金额") + .HasColumnName("change_money"); + entity.Property(e => e.Content) + .HasMaxLength(255) + .HasComment("描述") + .HasColumnName("content"); + entity.Property(e => e.Money) + .HasComment("变化后的金额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money"); + entity.Property(e => e.Other) + .HasMaxLength(255) + .HasColumnName("other"); + entity.Property(e => e.ShareUid) + .HasComment("来源ID") + .HasColumnType("int(11) unsigned") + .HasColumnName("share_uid"); + entity.Property(e => e.Type) + .HasComment("1后台充值 2抽赏消费 3升级获得 4抽赏奖励") + .HasColumnType("tinyint(2) unsigned") + .HasColumnName("type"); + entity.Property(e => e.UserId) + .HasComment("用户id") + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("quan_yi_level", tb => tb.HasComment("权益等级表")); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasColumnType("int(11)") + .HasColumnName("addtime"); + entity.Property(e => e.Deltime) + .HasColumnType("int(11)") + .HasColumnName("deltime"); + entity.Property(e => e.Level) + .HasColumnType("int(11)") + .HasColumnName("level"); + entity.Property(e => e.Number) + .HasComment("需要多少欧气值") + .HasColumnType("int(11)") + .HasColumnName("number"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasColumnName("title"); + entity.Property(e => e.Updatetime) + .HasColumnType("int(11)") + .HasColumnName("updatetime"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("quan_yi_level_jiang", tb => tb.HasComment("权益中心等级奖品")); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasColumnType("int(11)") + .HasColumnName("addtime"); + entity.Property(e => e.CouponId) + .HasDefaultValueSql("'0'") + .HasColumnType("int(11) unsigned") + .HasColumnName("coupon_id"); + entity.Property(e => e.Deltime) + .HasColumnType("int(11)") + .HasColumnName("deltime"); + entity.Property(e => e.EffectiveDay) + .HasComment("有效时间(天)") + .HasColumnType("int(11)") + .HasColumnName("effective_day"); + entity.Property(e => e.Imgurl) + .HasMaxLength(255) + .HasComment("奖品图片") + .HasColumnName("imgurl"); + entity.Property(e => e.JianPrice) + .HasDefaultValueSql("'0.00'") + .HasComment("减多少") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("jian_price"); + entity.Property(e => e.JiangPrice) + .HasDefaultValueSql("'0.00'") + .HasComment("奖品价值") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("jiang_price"); + entity.Property(e => e.ManPrice) + .HasDefaultValueSql("'0.00'") + .HasComment("满多少") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("man_price"); + entity.Property(e => e.Money) + .HasDefaultValueSql("'0.00'") + .HasComment("奖品兑换价") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money"); + entity.Property(e => e.PrizeCode) + .HasMaxLength(30) + .HasComment("奖品编号") + .HasColumnName("prize_code") + .UseCollation("utf8mb4_unicode_ci"); + entity.Property(e => e.Probability) + .HasDefaultValueSql("'0.00'") + .HasComment("概率") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("probability"); + entity.Property(e => e.QyLevel) + .HasColumnType("int(11)") + .HasColumnName("qy_level"); + entity.Property(e => e.QyLevelId) + .HasColumnType("int(11)") + .HasColumnName("qy_level_id"); + entity.Property(e => e.ScMoney) + .HasDefaultValueSql("'0.00'") + .HasComment("市场参考价") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("sc_money"); + entity.Property(e => e.ShangId) + .HasColumnType("int(11)") + .HasColumnName("shang_id"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasColumnName("title"); + entity.Property(e => e.Type) + .HasComment("1普通降临(优惠券) 2高级奖励(奖品)") + .HasColumnName("type"); + entity.Property(e => e.Updatetime) + .HasColumnType("int(11)") + .HasColumnName("updatetime"); + entity.Property(e => e.ZNum) + .HasDefaultValueSql("'0'") + .HasComment("优惠券赠送多少") + .HasColumnType("int(11) unsigned") + .HasColumnName("z_num"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("rank_month", tb => tb.HasComment("排行榜月榜")) + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.HasIndex(e => e.UserId, "user_id"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.Money) + .HasComment("消费金额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money"); + entity.Property(e => e.MonthTime) + .HasMaxLength(100) + .HasComment("统计范围") + .HasColumnName("month_time"); + entity.Property(e => e.OrderListId) + .HasComment("奖品ID") + .HasColumnType("int(11) unsigned") + .HasColumnName("order_list_id"); + entity.Property(e => e.PrizeImgurl) + .HasMaxLength(255) + .HasColumnName("prize_imgurl"); + entity.Property(e => e.PrizeTitle) + .HasMaxLength(255) + .HasColumnName("prize_title"); + entity.Property(e => e.Rank) + .HasComment("排名") + .HasColumnType("int(11) unsigned") + .HasColumnName("rank"); + entity.Property(e => e.UserId) + .HasComment("用户ID") + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("rank_week", tb => tb.HasComment("排行榜周榜")) + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.HasIndex(e => e.UserId, "user_id"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.Money) + .HasComment("消费金额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money"); + entity.Property(e => e.OrderListId) + .HasComment("奖品ID") + .HasColumnType("int(11) unsigned") + .HasColumnName("order_list_id"); + entity.Property(e => e.PrizeImgurl) + .HasMaxLength(255) + .HasColumnName("prize_imgurl"); + entity.Property(e => e.PrizeTitle) + .HasMaxLength(255) + .HasColumnName("prize_title"); + entity.Property(e => e.Rank) + .HasComment("排名") + .HasColumnType("int(11) unsigned") + .HasColumnName("rank"); + entity.Property(e => e.UserId) + .HasComment("用户ID") + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + entity.Property(e => e.WeekTime) + .HasMaxLength(100) + .HasComment("统计范围") + .HasColumnName("week_time"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("reward", tb => tb.HasComment("奖励表")); + + entity.Property(e => e.Id) + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.CreateTime) + .HasColumnType("int(11)") + .HasColumnName("create_time"); + entity.Property(e => e.Description) + .HasMaxLength(255) + .HasComment("奖励描述") + .HasColumnName("description"); + entity.Property(e => e.RewardExtend) + .HasComment("奖励ID(当reward_type=1时为优惠券ID)") + .HasColumnType("int(11)") + .HasColumnName("reward_extend"); + entity.Property(e => e.RewardId) + .HasMaxLength(64) + .HasComment("关联表id") + .HasColumnName("reward_id"); + entity.Property(e => e.RewardType) + .HasComment("奖励类型(1:钻石,2:货币1,3:货币2,4:优惠券)") + .HasColumnType("int(11)") + .HasColumnName("reward_type"); + entity.Property(e => e.RewardValue) + .HasPrecision(10, 2) + .HasComment("奖励值") + .HasColumnName("reward_value"); + entity.Property(e => e.UpdateTime) + .HasColumnType("int(11)") + .HasColumnName("update_time"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("shang") + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Color) + .HasMaxLength(30) + .HasColumnName("color"); + entity.Property(e => e.GoodsId) + .HasColumnType("int(11) unsigned") + .HasColumnName("goods_id"); + entity.Property(e => e.Imgurl) + .HasMaxLength(200) + .HasColumnName("imgurl"); + entity.Property(e => e.Pro) + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("pro"); + entity.Property(e => e.Sort) + .HasColumnType("int(11) unsigned") + .HasColumnName("sort"); + entity.Property(e => e.SpecialImgurl) + .HasMaxLength(200) + .HasColumnName("special_imgurl") + .UseCollation("utf8mb4_unicode_ci") + .HasCharSet("utf8mb4"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasColumnName("title"); + entity.Property(e => e.UpdateTime) + .HasDefaultValueSql("'0'") + .HasColumnType("int(11) unsigned") + .HasColumnName("update_time"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("sign_config", tb => tb.HasComment("签到配置表")); + + entity.Property(e => e.Id) + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.CreateTime) + .HasColumnType("int(11)") + .HasColumnName("create_time"); + entity.Property(e => e.Day) + .HasComment("指定星期几(type=2时有效,1-7代表周一到周日)") + .HasColumnName("day"); + entity.Property(e => e.Description) + .HasMaxLength(255) + .HasComment("备注") + .HasColumnName("description"); + entity.Property(e => e.Icon) + .HasMaxLength(255) + .HasComment("图标") + .HasColumnName("icon"); + entity.Property(e => e.RewardId) + .HasMaxLength(64) + .HasComment("奖励id") + .HasColumnName("reward_id"); + entity.Property(e => e.Sort) + .HasDefaultValueSql("'0'") + .HasComment("排序") + .HasColumnType("int(11)") + .HasColumnName("sort"); + entity.Property(e => e.Status) + .IsRequired() + .HasDefaultValueSql("'1'") + .HasComment("状态(0禁用,1启用)") + .HasColumnName("status"); + entity.Property(e => e.Title) + .HasMaxLength(100) + .HasComment("配置标题") + .HasColumnName("title"); + entity.Property(e => e.Type) + .HasComment("配置类型(1:累计签到配置,2:每日签到配置)") + .HasColumnName("type"); + entity.Property(e => e.UpdateTime) + .HasColumnType("int(11)") + .HasColumnName("update_time"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("task_list", tb => tb.HasComment("任务表")); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasColumnType("int(11)") + .HasColumnName("addtime"); + entity.Property(e => e.Cate) + .HasComment("任务分类 1邀请好友注册 2抽赏任务 ") + .HasColumnName("cate"); + entity.Property(e => e.Deltime) + .HasColumnType("int(11)") + .HasColumnName("deltime"); + entity.Property(e => e.IsImportant) + .HasDefaultValueSql("'0'") + .HasComment("是否是重要任务 1是 0否") + .HasColumnName("is_important"); + entity.Property(e => e.Number) + .HasDefaultValueSql("'0'") + .HasComment("需要完成任务几次") + .HasColumnType("int(11)") + .HasColumnName("number"); + entity.Property(e => e.Sort) + .HasDefaultValueSql("'0'") + .HasComment("排序") + .HasColumnType("int(11) unsigned") + .HasColumnName("sort"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasComment("任务名称") + .HasColumnName("title"); + entity.Property(e => e.Type) + .HasComment("1每日任务 2每周任务") + .HasColumnName("type"); + entity.Property(e => e.Updatetime) + .HasColumnType("int(11)") + .HasColumnName("updatetime"); + entity.Property(e => e.ZNumber) + .HasDefaultValueSql("'0'") + .HasComment("赠送多少欧气值") + .HasColumnType("int(11) unsigned") + .HasColumnName("z_number"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("user") + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.ClickId) + .HasDefaultValueSql("'0'") + .HasColumnType("int(11)") + .HasColumnName("click_id"); + entity.Property(e => e.DrawNum) + .HasDefaultValueSql("'0'") + .HasComment("优惠券的数量") + .HasColumnType("int(11)") + .HasColumnName("draw_num"); + entity.Property(e => e.GzhOpenid) + .HasMaxLength(255) + .HasComment("公众号openid") + .HasColumnName("gzh_openid"); + entity.Property(e => e.Headimg) + .HasMaxLength(255) + .HasComment("头像") + .HasColumnName("headimg"); + entity.Property(e => e.Integral) + .HasComment("幸运币") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("integral"); + entity.Property(e => e.IsUseCoupon) + .HasDefaultValueSql("'0'") + .HasComment("0未领取1已领取") + .HasColumnType("tinyint(3)") + .HasColumnName("is_use_coupon"); + entity.Property(e => e.Istest) + .HasComment("是否测试账号") + .HasColumnType("int(11)") + .HasColumnName("istest"); + entity.Property(e => e.LastLoginTime) + .HasComment("最后操作时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("last_login_time"); + entity.Property(e => e.MbNumber) + .HasDefaultValueSql("'0'") + .HasComment("连击赏秘宝池抽奖次数") + .HasColumnType("int(11) unsigned") + .HasColumnName("mb_number"); + entity.Property(e => e.Mobile) + .HasMaxLength(11) + .HasComment("手机号") + .HasColumnName("mobile"); + entity.Property(e => e.Money) + .HasComment("余额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money"); + entity.Property(e => e.Money2) + .HasDefaultValueSql("'0.00'") + .HasComment("集市余额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money2"); + entity.Property(e => e.Nickname) + .HasMaxLength(255) + .HasComment("昵称") + .HasColumnName("nickname") + .UseCollation("utf8mb4_unicode_ci") + .HasCharSet("utf8mb4"); + entity.Property(e => e.Openid) + .HasMaxLength(50) + .HasDefaultValueSql("''") + .HasComment("微信openid") + .HasColumnName("openid"); + entity.Property(e => e.OuQi) + .HasDefaultValueSql("'0'") + .HasComment("欧气值") + .HasColumnType("int(11) unsigned") + .HasColumnName("ou_qi"); + entity.Property(e => e.OuQiLevel) + .HasDefaultValueSql("'0'") + .HasComment("欧气值等级") + .HasColumnType("int(11) unsigned") + .HasColumnName("ou_qi_level"); + entity.Property(e => e.Password) + .HasMaxLength(40) + .HasColumnName("password"); + entity.Property(e => e.Pid) + .HasComment("父级id") + .HasColumnType("int(11) unsigned") + .HasColumnName("pid"); + entity.Property(e => e.Score) + .HasComment("积分") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("score"); + entity.Property(e => e.ShareImage) + .HasMaxLength(255) + .HasComment("分享海报") + .HasColumnName("share_image"); + entity.Property(e => e.Status) + .IsRequired() + .HasDefaultValueSql("'1'") + .HasComment("状态:1正常,2禁用") + .HasColumnName("status"); + entity.Property(e => e.Uid) + .HasMaxLength(16) + .HasComment("唯一编号") + .HasColumnName("uid"); + entity.Property(e => e.Unionid) + .HasMaxLength(255) + .HasComment("用户唯一id") + .HasColumnName("unionid"); + entity.Property(e => e.UpdateTime) + .HasComment("修改时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("update_time"); + entity.Property(e => e.Vip) + .HasDefaultValueSql("'1'") + .HasComment("vip等级") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("vip"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("user_account") + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.AccountToken) + .HasMaxLength(255) + .HasComment("登陆秘钥") + .HasColumnName("account_token"); + entity.Property(e => e.IpAdcode) + .HasMaxLength(255) + .HasComment("ip邮编") + .HasColumnName("ip_adcode"); + entity.Property(e => e.IpCity) + .HasMaxLength(50) + .HasColumnName("ip_city"); + entity.Property(e => e.IpProvince) + .HasMaxLength(50) + .HasColumnName("ip_province"); + entity.Property(e => e.LastLoginIp) + .HasMaxLength(50) + .HasColumnName("last_login_ip"); + entity.Property(e => e.LastLoginIp1) + .HasMaxLength(255) + .HasComment("ip") + .HasColumnName("last_login_ip1"); + entity.Property(e => e.LastLoginTime) + .HasColumnType("int(11) unsigned") + .HasColumnName("last_login_time"); + entity.Property(e => e.TokenNum) + .HasMaxLength(50) + .HasComment("秘钥随机数") + .HasColumnName("token_num"); + entity.Property(e => e.TokenTime) + .HasComment("秘钥时间戳") + .HasColumnType("int(11) unsigned") + .HasColumnName("token_time"); + entity.Property(e => e.UserId) + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("user_coupon", tb => tb.HasComment("欧气劵")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.HasIndex(e => e.UserId, "user_id"); + + entity.Property(e => e.Id) + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("获取时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.FromId) + .HasMaxLength(50) + .HasDefaultValueSql("'0'") + .HasComment("来源id (订单、领取)") + .HasColumnName("from_id"); + entity.Property(e => e.KlNum) + .HasDefaultValueSql("'0'") + .HasComment("最多可参与人数") + .HasColumnType("int(11) unsigned") + .HasColumnName("kl_num"); + entity.Property(e => e.KlNum2) + .HasDefaultValueSql("'0'") + .HasComment("最多可参与人数") + .HasColumnType("int(11) unsigned") + .HasColumnName("kl_num2"); + entity.Property(e => e.LNum) + .HasDefaultValueSql("'0.00'") + .HasComment("领取多少") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("l_num"); + entity.Property(e => e.Level) + .HasDefaultValueSql("'0'") + .HasComment("1特级赏券 2终极赏券 3高级赏券 4普通赏券") + .HasColumnType("int(11) unsigned") + .HasColumnName("level"); + entity.Property(e => e.Num) + .HasComment("开奖总金额") + .HasColumnType("int(10) unsigned") + .HasColumnName("num"); + entity.Property(e => e.Other) + .HasDefaultValueSql("'0.00'") + .HasComment("其他人可以获得多少") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("other"); + entity.Property(e => e.Other2) + .HasDefaultValueSql("'0.00'") + .HasComment("其他人可以获得多少") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("other2"); + entity.Property(e => e.Own) + .HasDefaultValueSql("'0.00'") + .HasComment("自己可以获得多少") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("own"); + entity.Property(e => e.Own2) + .HasDefaultValueSql("'0.00'") + .HasComment("自己可以获得多少") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("own2"); + entity.Property(e => e.ShareTime) + .HasComment("分享时间") + .HasColumnType("int(11)") + .HasColumnName("share_time"); + entity.Property(e => e.Status) + .HasDefaultValueSql("'1'") + .HasComment("1未分享 2已分享 3已领取 4被消耗融合") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("status"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasComment("劵名称") + .HasColumnName("title"); + entity.Property(e => e.Type) + .HasComment("1下单赠送 2领取 3融合得到") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("type"); + entity.Property(e => e.Updatetime) + .HasColumnType("int(11)") + .HasColumnName("updatetime"); + entity.Property(e => e.UserId) + .HasComment("用户的id") + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("user_goods_lian_ji", tb => tb.HasComment("用户连击赏连击次数")); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasColumnType("int(11)") + .HasColumnName("addtime"); + entity.Property(e => e.Deltime) + .HasColumnType("int(11)") + .HasColumnName("deltime"); + entity.Property(e => e.GoodsId) + .HasColumnType("int(11)") + .HasColumnName("goods_id"); + entity.Property(e => e.Number) + .HasComment("连击次数") + .HasColumnType("int(11) unsigned") + .HasColumnName("number"); + entity.Property(e => e.Updatetime) + .HasColumnType("int(11)") + .HasColumnName("updatetime"); + entity.Property(e => e.UserId) + .HasColumnType("int(11)") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("user_item_card", tb => tb.HasComment("用户的道具卡")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.Deltime) + .HasColumnType("int(11)") + .HasColumnName("deltime"); + entity.Property(e => e.ItemCardId) + .HasColumnType("int(11)") + .HasColumnName("item_card_id"); + entity.Property(e => e.OrderId) + .HasDefaultValueSql("'0'") + .HasComment("抵扣的订单ID") + .HasColumnType("int(11)") + .HasColumnName("order_id"); + entity.Property(e => e.Status) + .HasDefaultValueSql("'0'") + .HasComment("1未使用 2已使用") + .HasColumnName("status"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasComment("名称") + .HasColumnName("title"); + entity.Property(e => e.Type) + .HasDefaultValueSql("'0'") + .HasComment("类型") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("type"); + entity.Property(e => e.Updatetime) + .HasColumnType("int(11)") + .HasColumnName("updatetime"); + entity.Property(e => e.UserId) + .HasColumnType("int(11)") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("user_login_ip") + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.IpAdcode) + .HasMaxLength(255) + .HasComment("ip邮编") + .HasColumnName("ip_adcode"); + entity.Property(e => e.IpCity) + .HasMaxLength(50) + .HasColumnName("ip_city"); + entity.Property(e => e.IpProvince) + .HasMaxLength(50) + .HasColumnName("ip_province"); + entity.Property(e => e.LastLoginIp) + .HasMaxLength(50) + .HasColumnName("last_login_ip"); + entity.Property(e => e.LastLoginIp1) + .HasMaxLength(255) + .HasComment("ip") + .HasColumnName("last_login_ip1"); + entity.Property(e => e.LastLoginTime) + .HasColumnType("int(11) unsigned") + .HasColumnName("last_login_time"); + entity.Property(e => e.UserId) + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("user_login_log", tb => tb.HasComment("用户登录记录表")); + + entity.HasIndex(e => e.LoginDate, "idx_date"); + + entity.HasIndex(e => new { e.UserId, e.LoginDate }, "idx_user_date"); + + entity.HasIndex(e => new { e.Year, e.Month }, "idx_year_month"); + + entity.HasIndex(e => new { e.Year, e.Week }, "idx_year_week"); + + entity.Property(e => e.Id) + .HasComment("主键ID") + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Device) + .HasMaxLength(50) + .HasDefaultValueSql("''") + .HasComment("登录设备") + .HasColumnName("device"); + entity.Property(e => e.Ip) + .HasMaxLength(50) + .HasDefaultValueSql("''") + .HasComment("登录IP") + .HasColumnName("ip"); + entity.Property(e => e.Location) + .HasMaxLength(100) + .HasDefaultValueSql("''") + .HasComment("登录地点") + .HasColumnName("location"); + entity.Property(e => e.LoginDate) + .HasComment("登录日期") + .HasColumnName("login_date"); + entity.Property(e => e.LoginTime) + .HasComment("登录时间戳") + .HasColumnType("int(11) unsigned") + .HasColumnName("login_time"); + entity.Property(e => e.Month) + .HasComment("月份") + .HasColumnType("int(2) unsigned") + .HasColumnName("month"); + entity.Property(e => e.UserId) + .HasComment("用户ID") + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + entity.Property(e => e.Week) + .HasComment("周数") + .HasColumnType("int(2) unsigned") + .HasColumnName("week"); + entity.Property(e => e.Year) + .HasComment("年份") + .HasColumnType("int(4) unsigned") + .HasColumnName("year"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("user_poster_cache", tb => tb.HasComment("用户海报COS存储记录")); + + entity.HasIndex(e => e.ExpiresAt, "idx_expires"); + + entity.HasIndex(e => e.TemplateHash, "idx_template"); + + entity.HasIndex(e => new { e.UserId, e.TemplateHash, e.AppId }, "uk_user_template_app").IsUnique(); + + entity.Property(e => e.Id) + .HasComment("主键ID") + .HasColumnType("bigint(20) unsigned") + .HasColumnName("id"); + entity.Property(e => e.AppId) + .HasMaxLength(32) + .HasComment("微信APPID") + .HasColumnName("app_id"); + entity.Property(e => e.CosUrl) + .HasMaxLength(512) + .HasComment("COS访问URL") + .HasColumnName("cos_url"); + entity.Property(e => e.CreatedAt) + .HasDefaultValueSql("CURRENT_TIMESTAMP") + .HasComment("创建时间") + .HasColumnType("timestamp") + .HasColumnName("created_at"); + entity.Property(e => e.ExpiresAt) + .HasComment("过期时间") + .HasColumnType("timestamp") + .HasColumnName("expires_at"); + entity.Property(e => e.FileSize) + .HasDefaultValueSql("'0'") + .HasComment("文件大小(字节)") + .HasColumnType("int(11) unsigned") + .HasColumnName("file_size"); + entity.Property(e => e.MimeType) + .HasMaxLength(50) + .HasDefaultValueSql("'image/png'") + .HasComment("文件类型") + .HasColumnName("mime_type"); + entity.Property(e => e.Status) + .HasDefaultValueSql("'1'") + .HasComment("状态(1-有效 0-无效)") + .HasColumnName("status"); + entity.Property(e => e.TemplateHash) + .HasMaxLength(64) + .HasComment("模板内容哈希值") + .HasColumnName("template_hash"); + entity.Property(e => e.UpdatedAt) + .ValueGeneratedOnAddOrUpdate() + .HasDefaultValueSql("CURRENT_TIMESTAMP") + .HasComment("更新时间") + .HasColumnType("timestamp") + .HasColumnName("updated_at"); + entity.Property(e => e.UserId) + .HasComment("用户ID") + .HasColumnType("bigint(20)") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("user_quan_yi_level_jiang", tb => tb.HasComment("用户领取的权益中心等级奖品")); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasColumnType("int(11)") + .HasColumnName("addtime"); + entity.Property(e => e.CouponId) + .HasDefaultValueSql("'0'") + .HasColumnType("int(11) unsigned") + .HasColumnName("coupon_id"); + entity.Property(e => e.Deltime) + .HasColumnType("int(11)") + .HasColumnName("deltime"); + entity.Property(e => e.EffectiveDay) + .HasComment("有效时间(天)") + .HasColumnType("int(11)") + .HasColumnName("effective_day"); + entity.Property(e => e.EndTime) + .HasColumnType("int(11)") + .HasColumnName("end_time"); + entity.Property(e => e.Imgurl) + .HasMaxLength(255) + .HasComment("奖品图片") + .HasColumnName("imgurl"); + entity.Property(e => e.JianPrice) + .HasDefaultValueSql("'0.00'") + .HasComment("减多少") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("jian_price"); + entity.Property(e => e.JiangPrice) + .HasDefaultValueSql("'0.00'") + .HasComment("奖品价值") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("jiang_price"); + entity.Property(e => e.ManPrice) + .HasDefaultValueSql("'0.00'") + .HasComment("满多少") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("man_price"); + entity.Property(e => e.Money) + .HasDefaultValueSql("'0.00'") + .HasComment("奖品兑换价") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money"); + entity.Property(e => e.PrizeCode) + .HasMaxLength(30) + .HasComment("奖品编号") + .HasColumnName("prize_code") + .UseCollation("utf8mb4_unicode_ci"); + entity.Property(e => e.Probability) + .HasComment("概率") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("probability"); + entity.Property(e => e.QyLevel) + .HasDefaultValueSql("'0'") + .HasColumnType("int(11)") + .HasColumnName("qy_level"); + entity.Property(e => e.QyLevelId) + .HasColumnType("int(11)") + .HasColumnName("qy_level_id"); + entity.Property(e => e.ScMoney) + .HasDefaultValueSql("'0.00'") + .HasComment("市场参考价") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("sc_money"); + entity.Property(e => e.ShangId) + .HasColumnType("int(11)") + .HasColumnName("shang_id"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasColumnName("title"); + entity.Property(e => e.Type) + .HasComment("1普通降临(优惠券) 2高级奖励(奖品)") + .HasColumnName("type"); + entity.Property(e => e.Updatetime) + .HasColumnType("int(11)") + .HasColumnName("updatetime"); + entity.Property(e => e.UserId) + .HasColumnType("int(11)") + .HasColumnName("user_id"); + entity.Property(e => e.ZNum) + .HasDefaultValueSql("'0'") + .HasComment("优惠券赠送多少") + .HasColumnType("int(11) unsigned") + .HasColumnName("z_num"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("user_rage", tb => tb.HasComment("用户的怒气值")); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasColumnType("int(11)") + .HasColumnName("addtime"); + entity.Property(e => e.Deltime) + .HasColumnType("int(11)") + .HasColumnName("deltime"); + entity.Property(e => e.GoodsId) + .HasColumnType("int(11)") + .HasColumnName("goods_id"); + entity.Property(e => e.Rage) + .HasComment("怒气值") + .HasColumnType("int(11)") + .HasColumnName("rage"); + entity.Property(e => e.Updatetime) + .HasColumnType("int(11)") + .HasColumnName("updatetime"); + entity.Property(e => e.UserId) + .HasColumnType("int(11)") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("user_recharge", tb => tb.HasComment("用户充值表")) + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.HasIndex(e => e.OrderNum, "order_num").IsUnique(); + + entity.HasIndex(e => e.UserId, "user_id"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("创建订单时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.Money) + .HasComment("充值金额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money"); + entity.Property(e => e.OrderNum) + .HasMaxLength(100) + .HasComment("订单号") + .HasColumnName("order_num"); + entity.Property(e => e.PayTime) + .HasComment("支付时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("pay_time"); + entity.Property(e => e.Status) + .HasDefaultValueSql("'1'") + .HasComment("1待支付 2已完成") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("status"); + entity.Property(e => e.UserId) + .HasComment("用户ID") + .HasColumnType("int(11) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("user_sign", tb => tb.HasComment("用户签到表")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.Property(e => e.Id) + .HasComment("主键id") + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.CreateTime) + .HasComment("签到时间") + .HasColumnType("int(10) unsigned") + .HasColumnName("create_time"); + entity.Property(e => e.Days) + .HasComment("连续签到天数") + .HasColumnType("int(10) unsigned") + .HasColumnName("days"); + entity.Property(e => e.Month) + .HasComment("签到月份") + .HasColumnType("int(11)") + .HasColumnName("month"); + entity.Property(e => e.Num) + .HasComment("签到数量") + .HasColumnType("int(128)") + .HasColumnName("num"); + entity.Property(e => e.SignDate) + .HasMaxLength(24) + .HasDefaultValueSql("''") + .HasComment("签到日期") + .HasColumnName("sign_date"); + entity.Property(e => e.SignDay) + .HasComment("签到当月天数") + .HasColumnType("tinyint(2) unsigned") + .HasColumnName("sign_day"); + entity.Property(e => e.SignType) + .HasComment("月签到还是累计签到") + .HasColumnType("tinyint(2)") + .HasColumnName("sign_type"); + entity.Property(e => e.UpdateTime) + .HasComment("更新时间") + .HasColumnType("int(10) unsigned") + .HasColumnName("update_time"); + entity.Property(e => e.UserId) + .HasComment("用户id") + .HasColumnType("int(10) unsigned") + .HasColumnName("user_id"); + entity.Property(e => e.Year) + .HasComment("签到年份") + .HasColumnType("int(11)") + .HasColumnName("year"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("user_statistics", tb => tb.HasComment("用户统计表")); + + entity.Property(e => e.Id) + .HasComment("主键") + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.AllMoney) + .HasPrecision(10, 2) + .HasComment("总利润") + .HasColumnName("all_money"); + entity.Property(e => e.AllRecycleMoney) + .HasPrecision(10, 2) + .HasComment("总收入") + .HasColumnName("all_recycle_money"); + entity.Property(e => e.AllShipmentMoney) + .HasPrecision(10, 2) + .HasComment("总支出") + .HasColumnName("all_shipment_money"); + entity.Property(e => e.BalanceConsume) + .HasPrecision(10, 2) + .HasComment("记录当天用户使用余额消费的总金额(单位:元)。") + .HasColumnName("balance_consume"); + entity.Property(e => e.BalanceIssue) + .HasPrecision(10, 2) + .HasComment("记录当天系统发放给用户的余额总金额") + .HasColumnName("balance_issue"); + entity.Property(e => e.ConsumeOrderCount) + .HasComment("支付的订单笔数") + .HasColumnType("int(11)") + .HasColumnName("consume_order_count"); + entity.Property(e => e.ConsumeRmbCount) + .HasComment("消费rmb人数") + .HasColumnType("int(11)") + .HasColumnName("consume_rmb_count"); + entity.Property(e => e.ConsumeUserCount) + .HasComment("记录当天消费的用户人数(去重)") + .HasColumnType("int(11)") + .HasColumnName("consume_user_count"); + entity.Property(e => e.CreatedAt) + .HasDefaultValueSql("CURRENT_TIMESTAMP") + .HasComment("创建时间") + .HasColumnType("timestamp") + .HasColumnName("created_at"); + entity.Property(e => e.LoginCount) + .HasDefaultValueSql("'0'") + .HasComment("登录人数") + .HasColumnType("int(11)") + .HasColumnName("login_count"); + entity.Property(e => e.ProfitMoney) + .HasPrecision(10, 2) + .HasComment("利润率") + .HasColumnName("profit_money"); + entity.Property(e => e.RechargeAmount) + .HasPrecision(10, 2) + .HasComment("充值金额") + .HasColumnName("recharge_amount"); + entity.Property(e => e.RechargeSum) + .HasPrecision(10, 2) + .HasComment("今日总收入") + .HasColumnName("recharge_sum"); + entity.Property(e => e.RecordDate) + .HasComment("记录日期") + .HasColumnName("record_date"); + entity.Property(e => e.RecycleMoney) + .HasPrecision(10, 2) + .HasComment("回收价值") + .HasColumnName("recycle_money"); + entity.Property(e => e.RegisterCount) + .HasDefaultValueSql("'0'") + .HasComment("注册人数") + .HasColumnType("int(11)") + .HasColumnName("register_count"); + entity.Property(e => e.SendMoney) + .HasPrecision(10, 2) + .HasComment("发货价值") + .HasColumnName("send_money"); + entity.Property(e => e.ShipmentMoney) + .HasPrecision(10, 2) + .HasComment("出货价值") + .HasColumnName("shipment_money"); + entity.Property(e => e.UpdatedAt) + .ValueGeneratedOnAddOrUpdate() + .HasDefaultValueSql("CURRENT_TIMESTAMP") + .HasComment("修改时间") + .HasColumnType("timestamp") + .HasColumnName("updated_at"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("user_task_list", tb => tb.HasComment("用户完成任务记录表")); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasColumnType("int(11)") + .HasColumnName("addtime"); + entity.Property(e => e.Cate) + .HasComment("任务分类 1邀请好友注册 2抽赏任务 ") + .HasColumnName("cate"); + entity.Property(e => e.Deltime) + .HasColumnType("int(11)") + .HasColumnName("deltime"); + entity.Property(e => e.IsImportant) + .HasDefaultValueSql("'0'") + .HasComment("是否是重要任务 1是 0否") + .HasColumnName("is_important"); + entity.Property(e => e.Number) + .HasDefaultValueSql("'0'") + .HasComment("需要完成任务几次") + .HasColumnType("int(11)") + .HasColumnName("number"); + entity.Property(e => e.TaskListId) + .HasColumnType("int(11)") + .HasColumnName("task_list_id"); + entity.Property(e => e.Type) + .HasComment("1每日任务 2每周任务") + .HasColumnName("type"); + entity.Property(e => e.Updatetime) + .HasColumnType("int(11)") + .HasColumnName("updatetime"); + entity.Property(e => e.UserId) + .HasColumnType("int(11)") + .HasColumnName("user_id"); + entity.Property(e => e.ZNumber) + .HasDefaultValueSql("'0'") + .HasComment("赠送多少欧气值") + .HasColumnType("int(11) unsigned") + .HasColumnName("z_number"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("user_vip", tb => tb.HasComment("会员vip")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.Property(e => e.Id) + .HasColumnType("int(11) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Condition) + .HasComment("升级消费") + .HasColumnType("int(11) unsigned") + .HasColumnName("condition"); + entity.Property(e => e.Discount) + .HasComment("享受折扣") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("discount"); + entity.Property(e => e.Imgurl) + .HasMaxLength(200) + .HasComment("图标") + .HasColumnName("imgurl"); + entity.Property(e => e.Notice) + .HasMaxLength(255) + .HasComment("权益说明") + .HasColumnName("notice"); + entity.Property(e => e.Title) + .HasMaxLength(50) + .HasDefaultValueSql("'0'") + .HasComment("等级名称") + .HasColumnName("title"); + entity.Property(e => e.UpdateTime) + .HasComment("更新时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("update_time"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("welfare_house", tb => tb.HasComment("福利屋管理")); + + entity.Property(e => e.Id) + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.CreateTime) + .HasComment("创建时间") + .HasColumnType("int(11)") + .HasColumnName("create_time"); + entity.Property(e => e.Image) + .HasMaxLength(255) + .HasComment("图片路径") + .HasColumnName("image"); + entity.Property(e => e.Name) + .HasMaxLength(100) + .HasComment("名称") + .HasColumnName("name"); + entity.Property(e => e.Sort) + .HasDefaultValueSql("'0'") + .HasComment("排序(数字越小越靠前)") + .HasColumnType("int(11)") + .HasColumnName("sort"); + entity.Property(e => e.Status) + .HasDefaultValueSql("'1'") + .HasComment("状态:0=禁用,1=启用") + .HasColumnName("status"); + entity.Property(e => e.UpdateTime) + .HasComment("更新时间") + .HasColumnType("int(11)") + .HasColumnName("update_time"); + entity.Property(e => e.Url) + .HasMaxLength(255) + .HasComment("跳转路径") + .HasColumnName("url"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("withdraw") + .HasCharSet("utf8") + .UseCollation("utf8_unicode_ci"); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("提现时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.Bank) + .HasMaxLength(255) + .HasComment("开户行") + .HasColumnName("bank"); + entity.Property(e => e.EndTime) + .HasComment("审核时间") + .HasColumnType("int(10) unsigned") + .HasColumnName("end_time"); + entity.Property(e => e.Imgurl) + .HasMaxLength(255) + .HasComment("收款二维码") + .HasColumnName("imgurl"); + entity.Property(e => e.Money) + .HasComment("到账金额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("money"); + entity.Property(e => e.Name) + .HasMaxLength(255) + .HasComment("提现姓名/银行户名") + .HasColumnName("name"); + entity.Property(e => e.Number) + .HasMaxLength(50) + .HasComment("支付宝账号/银行卡号") + .HasColumnName("number"); + entity.Property(e => e.Reason) + .HasMaxLength(255) + .HasComment("原因") + .HasColumnName("reason"); + entity.Property(e => e.Status) + .HasDefaultValueSql("'0'") + .HasComment("提现:1=未审核,2=已通过3=未通过") + .HasColumnType("tinyint(2) unsigned") + .HasColumnName("status"); + entity.Property(e => e.Sxf) + .HasComment("手续费") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("sxf"); + entity.Property(e => e.TalMoney) + .HasComment("提现金额") + .HasColumnType("decimal(10,2) unsigned") + .HasColumnName("tal_money"); + entity.Property(e => e.Type) + .HasDefaultValueSql("'1'") + .HasComment("提现方式:1=微信,2=银行卡 3支付宝") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("type"); + entity.Property(e => e.UserId) + .HasComment("提现人") + .HasColumnType("int(10) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("wxpay_log", tb => tb.HasComment("微信/支付宝支付信息")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.OrderNo, "order_no").IsUnique(); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasColumnType("int(14) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.Channel) + .HasDefaultValueSql("'1'") + .HasComment("1微信 2支付宝 ") + .HasColumnType("int(1)") + .HasColumnName("channel"); + entity.Property(e => e.Content) + .HasComment("说明") + .HasColumnType("text") + .HasColumnName("content"); + entity.Property(e => e.OrderNo) + .HasMaxLength(100) + .HasComment("订单号") + .HasColumnName("order_no"); + entity.Property(e => e.Type) + .HasDefaultValueSql("'1'") + .HasColumnType("tinyint(1) unsigned") + .HasColumnName("type"); + entity.Property(e => e.UserId) + .HasColumnType("int(10) unsigned") + .HasColumnName("user_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity + .ToTable("yushou", tb => tb.HasComment("预售日历")) + .HasCharSet("utf8") + .UseCollation("utf8_general_ci"); + + entity.HasIndex(e => e.Id, "id").IsUnique(); + + entity.Property(e => e.Id) + .HasColumnType("int(10) unsigned") + .HasColumnName("id"); + entity.Property(e => e.Addtime) + .HasComment("添加时间") + .HasColumnType("int(11) unsigned") + .HasColumnName("addtime"); + entity.Property(e => e.GoodsId) + .HasComment("商品id") + .HasColumnType("int(11) unsigned") + .HasColumnName("goods_id"); + entity.Property(e => e.Imgurl) + .HasMaxLength(255) + .HasComment("图片") + .HasColumnName("imgurl"); + entity.Property(e => e.SaleTime) + .HasComment("预售日期") + .HasColumnType("int(11) unsigned") + .HasColumnName("sale_time"); + entity.Property(e => e.Sort) + .HasComment("排序") + .HasColumnType("int(11) unsigned") + .HasColumnName("sort"); + entity.Property(e => e.Title) + .HasMaxLength(255) + .HasComment("标题") + .HasColumnName("title"); + entity.Property(e => e.UpdateTime) + .HasColumnType("int(11)") + .HasColumnName("update_time"); + }); + + OnModelCreatingPartial(modelBuilder); + } + + partial void OnModelCreatingPartial(ModelBuilder modelBuilder); +} diff --git a/ChouBox.Model/Entities/Yushou.cs b/ChouBox.Model/Entities/Yushou.cs new file mode 100644 index 0000000..c37a177 --- /dev/null +++ b/ChouBox.Model/Entities/Yushou.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; + +namespace ChouBox.Model.Entities; + +/// +/// 预售日历 +/// +public partial class Yushou +{ + public uint Id { get; set; } + + /// + /// 标题 + /// + public string Title { get; set; } = null!; + + /// + /// 图片 + /// + public string Imgurl { get; set; } = null!; + + /// + /// 商品id + /// + public uint GoodsId { get; set; } + + /// + /// 预售日期 + /// + public uint SaleTime { get; set; } + + /// + /// 排序 + /// + public uint Sort { get; set; } + + /// + /// 添加时间 + /// + public uint Addtime { get; set; } + + public int UpdateTime { get; set; } +} diff --git a/ChouBox.Model/efcore-gen.md b/ChouBox.Model/efcore-gen.md new file mode 100644 index 0000000..571b694 --- /dev/null +++ b/ChouBox.Model/efcore-gen.md @@ -0,0 +1,12 @@ + +##在API项目里面执行,使用连接字符串名称,生成代码到model项目 +```sh + FreeSql.Generator -Razor 1 -NameOptions 1,0,0,1 -NameSpace ChouBox.Model.Entities -DB "MySql,data source=192.168.1.56;port=3306;user id=youda;password=youda;initial catalog=youda;charset=utf8;sslmode=none;max pool size=2" +dotnet add package Microsoft.EntityFrameworkCore.Design +dotnet ef dbcontext scaffold "Server=192.168.1.56;Database=youda;User=youda;Password=youda;" Pomelo.EntityFrameworkCore.MySql -o Entities/ --use-database-names --no-pluralize --force +dotnet ef dbcontext scaffold "Server=192.168.1.56;Database=youda;User=youda;Password=youda;" Pomelo.EntityFrameworkCore.MySql -o Entities/ --use-database-names --no-pluralize --force + + +dotnet ef dbcontext scaffold "Server=192.168.1.56;Database=youda;User=youda;Password=youda;" Pomelo.EntityFrameworkCore.MySql -o Entities/ --use-database-names --no-pluralize --force --context-dir Context --project ChouBox.Model +dotnet ef dbcontext scaffold "Server=192.168.1.56;Database=youda;User=youda;Password=youda;" Pomelo.EntityFrameworkCore.MySql -o Entities/ --no-pluralize --force +``` \ No newline at end of file diff --git a/ChouBox.WebApi/ChouBox.WebApi.csproj b/ChouBox.WebApi/ChouBox.WebApi.csproj new file mode 100644 index 0000000..95dd72a --- /dev/null +++ b/ChouBox.WebApi/ChouBox.WebApi.csproj @@ -0,0 +1,26 @@ + + + + net8.0 + enable + enable + True + 2b875b21-77df-4599-9ade-f3d3d58542a8 + Linux + + + + + + + + + + + + + + + + + diff --git a/ChouBox.WebApi/ChouBox.WebApi.http b/ChouBox.WebApi/ChouBox.WebApi.http new file mode 100644 index 0000000..584b4d4 --- /dev/null +++ b/ChouBox.WebApi/ChouBox.WebApi.http @@ -0,0 +1,6 @@ +@ChouBox.WebApi_HostAddress = http://localhost:5149 + +GET {{ChouBox.WebApi_HostAddress}}/weatherforecast/ +Accept: application/json + +### diff --git a/ChouBox.WebApi/Controllers/AccountController.cs b/ChouBox.WebApi/Controllers/AccountController.cs new file mode 100644 index 0000000..3e7b7a8 --- /dev/null +++ b/ChouBox.WebApi/Controllers/AccountController.cs @@ -0,0 +1,33 @@ +using ChouBox.Code.Other; + +using HuanMeng.DotNetCore.AttributeExtend; +using HuanMeng.DotNetCore.Base; +using HuanMeng.DotNetCore.Extensions; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace ChouBox.WebApi.Controllers; + +/// +/// +/// +/// +[Route("api/v2/[controller]")] +[ApiController] +public class AccountController(IServiceProvider serviceProvider) : ControllerBase +{ + + + /// + /// 发送验证码 + /// + /// + /// + [HttpPost] + [Route("sendSms")] + public async Task SendPhoneAsync([FromForm]string phone) + { + SMSBLL sms = new SMSBLL(serviceProvider); + return await sms.SendPhoneAsync(phone); + } +} diff --git a/ChouBox.WebApi/Controllers/GoodsController.cs b/ChouBox.WebApi/Controllers/GoodsController.cs new file mode 100644 index 0000000..15b87ea --- /dev/null +++ b/ChouBox.WebApi/Controllers/GoodsController.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace ChouBox.WebApi.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class GoodsController : ControllerBase + { + } +} diff --git a/ChouBox.WebApi/Controllers/WeatherForecastController.cs b/ChouBox.WebApi/Controllers/WeatherForecastController.cs new file mode 100644 index 0000000..0f69bde --- /dev/null +++ b/ChouBox.WebApi/Controllers/WeatherForecastController.cs @@ -0,0 +1,46 @@ +using ChouBox.Code.AppExtend; +using ChouBox.Model.Entities; + +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +using System.Threading.Tasks; + +namespace ChouBox.WebApi.Controllers +{ + [ApiController] + [Route("[controller]")] + public class WeatherForecastController : ControllerBase + { + private static readonly string[] Summaries = new[] + { + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + }; + + private readonly ILogger _logger; + private readonly YoudaContext _dbContext; + private readonly ChouBoxCodeBase _chouBoxCodeBase; + + public WeatherForecastController(ILogger logger, YoudaContext dbContext, ChouBoxCodeBase chouBoxCodeBase) + { + _logger = logger; + _dbContext = dbContext; + _chouBoxCodeBase = chouBoxCodeBase; + + } + + [HttpGet(Name = "GetWeatherForecast")] + public async Task> Get() + { + var list = await _dbContext.Config.ToListAsync(); + var c = await _chouBoxCodeBase.RedisCache.StringGetAsync("aaa"); + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), + TemperatureC = Random.Shared.Next(-20, 55), + Summary = Summaries[Random.Shared.Next(Summaries.Length)] + }) + .ToArray(); + } + } +} diff --git a/ChouBox.WebApi/Dockerfile b/ChouBox.WebApi/Dockerfile new file mode 100644 index 0000000..5fcdae1 --- /dev/null +++ b/ChouBox.WebApi/Dockerfile @@ -0,0 +1,32 @@ +# 请参阅 https://aka.ms/customizecontainer 以了解如何自定义调试容器,以及 Visual Studio 如何使用此 Dockerfile 生成映像以更快地进行调试。 + +# 此阶段用于在快速模式(默认为调试配置)下从 VS 运行时 +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base +USER $APP_UID +WORKDIR /app +EXPOSE 80 + + +# 此阶段用于生成服务项目 +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["ChouBox.WebApi/ChouBox.WebApi.csproj", "ChouBox.WebApi/"] +COPY ["ChouBox.Code/ChouBox.Code.csproj", "ChouBox.Code/"] +COPY ["ChouBox.Model/ChouBox.Model.csproj", "ChouBox.Model/"] +COPY ["Utile/HuanMeng.DotNetCore/HuanMeng.DotNetCore.csproj", "Utile/HuanMeng.DotNetCore/"] +RUN dotnet restore "./ChouBox.WebApi/ChouBox.WebApi.csproj" +COPY . . +WORKDIR "/src/ChouBox.WebApi" +RUN dotnet build "./ChouBox.WebApi.csproj" -c $BUILD_CONFIGURATION -o /app/build + +# 此阶段用于发布要复制到最终阶段的服务项目 +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "./ChouBox.WebApi.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +# 此阶段在生产中使用,或在常规模式下从 VS 运行时使用(在不使用调试配置时为默认值) +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "ChouBox.WebApi.dll"] \ No newline at end of file diff --git a/ChouBox.WebApi/Filters/ResultFormatFilter.cs b/ChouBox.WebApi/Filters/ResultFormatFilter.cs new file mode 100644 index 0000000..958a014 --- /dev/null +++ b/ChouBox.WebApi/Filters/ResultFormatFilter.cs @@ -0,0 +1,81 @@ +using HuanMeng.DotNetCore.AttributeExtend; +using HuanMeng.DotNetCore.Base; +using HuanMeng.DotNetCore.Extensions; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Controllers; +using Microsoft.AspNetCore.Mvc.Filters; +using System.Reflection; + +namespace ChouBox.WebApi.Filters +{ + /// + /// 返回结果格式化过滤器 + /// + public class ResultFormatFilter : IActionFilter, IResultFilter + { + public void OnActionExecuting(ActionExecutingContext context) + { + // 请求处理前的逻辑 + } + + public void OnActionExecuted(ActionExecutedContext context) + { + // 如果已有结果或已处理,则跳过 + if (context.Result == null || context.ExceptionHandled) + return; + + // 如果结果已经是ObjectResult且其Value是BaseResponse,则不进行处理 + if (context.Result is ObjectResult objectResult + && objectResult.Value != null + && objectResult.Value.GetType().IsGenericType + && objectResult.Value.GetType().GetGenericTypeDefinition() == typeof(BaseResponse<>)) + return; + + // 检查是否存在动态消息(从HTTP头部获取) + string customMessage = context.HttpContext.GetDynamicMessage(); + + // 如果没有动态消息,则检查MessageAttribute + if (string.IsNullOrEmpty(customMessage) && context.ActionDescriptor is ControllerActionDescriptor actionDescriptor) + { + var messageAttribute = actionDescriptor.MethodInfo.GetCustomAttribute(); + if (messageAttribute != null) + { + customMessage = messageAttribute.Message; + } + } + + // 处理字符串结果 + if (context.Result is ContentResult contentResult) + { + var response = new BaseResponse + { + Status = 1, + Msg = customMessage, + Data = contentResult.Content + }; + context.Result = new JsonResult(response); + } + // 处理其他类型的结果(如ActionResult) + else if (context.Result is ObjectResult objResult && objResult.Value is string stringValue) + { + var response = new BaseResponse + { + Status = 1, + Msg = customMessage, + Data = stringValue + }; + context.Result = new JsonResult(response); + } + } + + public void OnResultExecuting(ResultExecutingContext context) + { + // 结果执行前的逻辑 + } + + public void OnResultExecuted(ResultExecutedContext context) + { + // 结果执行后的逻辑 + } + } +} \ No newline at end of file diff --git a/ChouBox.WebApi/Middleware/ResponseFormatterMiddleware.cs b/ChouBox.WebApi/Middleware/ResponseFormatterMiddleware.cs new file mode 100644 index 0000000..bcc361a --- /dev/null +++ b/ChouBox.WebApi/Middleware/ResponseFormatterMiddleware.cs @@ -0,0 +1,117 @@ +using HuanMeng.DotNetCore.AttributeExtend; +using HuanMeng.DotNetCore.Base; +using HuanMeng.DotNetCore.Extensions; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc.Controllers; +using Microsoft.Extensions.DependencyInjection; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.IO; +using System.Reflection; +using System.Threading.Tasks; + +namespace ChouBox.WebApi.Middleware +{ + /// + /// 响应格式化中间件 + /// + public class ResponseFormatterMiddleware + { + private readonly RequestDelegate _next; + + public ResponseFormatterMiddleware(RequestDelegate next) + { + _next = next; + } + + public async Task InvokeAsync(HttpContext context) + { + // 保存原始响应流 + var originalBodyStream = context.Response.Body; + + try + { + // 使用内存流替代响应流 + using var memoryStream = new MemoryStream(); + context.Response.Body = memoryStream; + + // 继续处理请求 + await _next(context); + + // 获取可能存在的动态消息(从HTTP头部) + string customMessage = context.GetDynamicMessage(); + + // 如果没有动态消息,则检查MessageAttribute + if (string.IsNullOrEmpty(customMessage)) + { + var endpoint = context.GetEndpoint(); + if (endpoint != null) + { + if (endpoint.Metadata.GetMetadata() is ControllerActionDescriptor actionDescriptor) + { + var messageAttribute = actionDescriptor.MethodInfo.GetCustomAttribute(); + if (messageAttribute != null) + { + customMessage = messageAttribute.Message; + } + } + } + } + + // 如果是API接口请求并且内容类型是JSON + if (context.Request.Path.StartsWithSegments("/api") && + context.Response.ContentType != null && + context.Response.ContentType.Contains("application/json")) + { + memoryStream.Seek(0, SeekOrigin.Begin); + string responseBody = await new StreamReader(memoryStream).ReadToEndAsync(); + + // 如果响应内容是简单字符串(不是JSON格式),将其包装成BaseResponse + if (!string.IsNullOrEmpty(responseBody) && + !responseBody.StartsWith("{") && + !responseBody.StartsWith("[")) + { + var response = new BaseResponse + { + Status = 1, + Msg = customMessage, + Data = responseBody.Trim('"') // 去除JSON序列化添加的引号 + }; + + // 重置流 + memoryStream.SetLength(0); + + // 写入格式化后的响应 + using var writer = new StreamWriter(memoryStream, leaveOpen: true); + await writer.WriteAsync(response.ToString()); + await writer.FlushAsync(); + + // 更新Content-Length + context.Response.ContentLength = memoryStream.Length; + } + } + + // 将内存流复制回原始响应流 + memoryStream.Seek(0, SeekOrigin.Begin); + await memoryStream.CopyToAsync(originalBodyStream); + } + finally + { + // 恢复原始响应流 + context.Response.Body = originalBodyStream; + } + } + } + + /// + /// 中间件扩展方法 + /// + public static class ResponseFormatterMiddlewareExtensions + { + public static IApplicationBuilder UseResponseFormatter(this IApplicationBuilder builder) + { + return builder.UseMiddleware(); + } + } +} \ No newline at end of file diff --git a/ChouBox.WebApi/Program.cs b/ChouBox.WebApi/Program.cs new file mode 100644 index 0000000..27bc983 --- /dev/null +++ b/ChouBox.WebApi/Program.cs @@ -0,0 +1,118 @@ +using ChouBox.Code.AppExtend; +using ChouBox.Code.MiddlewareExtend; +using ChouBox.Model.Entities; +using ChouBox.WebApi.Filters; +//using ChouBox.WebApi.Middleware; + +using HuanMeng.DotNetCore.CustomExtension; +using HuanMeng.DotNetCore.MiddlewareExtend; + +using Microsoft.EntityFrameworkCore; + +using StackExchange.Redis; + +using System.Reflection; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +builder.Services.AddHttpClient(); +builder.Services.AddHttpContextAccessor(); //添加httpContext注入访问 +builder.Services.AddControllers(); + +// Program.cs +builder.Services.AddSingleton(sp => + ConnectionMultiplexer.Connect(builder.Configuration.GetConnectionString("RedisConnectionString")) +); +#region 返回数据解析 +//services.AddControllers(options => +//{ +// // 添加自定义的 ResultFilter 到全局过滤器中 +// options.Filters.Add(); +//}); +builder.Services.AddControllers(options => +{ + // 添加自定义的 ResultFilter 到全局过滤器中 + options.Filters.Add(); + //// 添加自定义的 ResultFilter 到全局过滤器中 + //options.Filters.Add(); + //options.Filters.Add(); +}) + .AddNewtonsoftJson(options => + { + // 配置 Newtonsoft.Json 选项 + options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; // 忽略循环引用 + //options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();// 首字母小写(驼峰样式) + //options.SerializerSettings.ContractResolver = new LanguageContractResolver(builder.Services); + options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";// 时间格式化 + //options.SerializerSettings.Converters.Add(new StringConverter()); + // 设置序列化深度为3(这里你可以根据实际需求修改这个值) + options.SerializerSettings.MaxDepth = 10; + + //options.SerializerSettings.ContractResolver = +#if !DEBUG + options.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.None; +#endif + //options.SerializerSettings.Converters.Add() + // 其他配置... + }); + + +#endregion + +// 获取初始连接字符串 +string userConnectionString = builder.Configuration.GetConnectionString("ConnectionString") ?? ""; +Console.WriteLine("连接字符串:" + userConnectionString); +builder.Services.AddDbContext((options) => +{ + options.UseMySql( + userConnectionString, + // 推荐指定 ServerVersion,特别是生产环境 + new MySqlServerVersion(new Version(5, 7, 44)), // 根据你的 MySQL 服务器版本修改 + mysqlOptions => + { + // 可选的配置项 + mysqlOptions.EnableRetryOnFailure( + maxRetryCount: 5, // 最大重试次数 + maxRetryDelay: TimeSpan.FromSeconds(30), // 每次重试的最大延迟时间 + errorNumbersToAdd: null);// 额外要重试的 MySQL 错误代码(可选) + } + ); +}); +var mapperDomain = AppDomain.CurrentDomain.GetAssemblies().Where(it => it.FullName.Contains("ChouBox")).ToList(); +builder.Services.AddAutoMapper(mapperDomain); +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); +builder.Services.AddScoped(); +#region 添加跨域 +var _myAllowSpecificOrigins = "_myAllowSpecificOrigins"; +builder.Services.AddCustomCors(_myAllowSpecificOrigins); +#endregion +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +app.UseAuthorization(); +//使用跨域 +app.UseCors(_myAllowSpecificOrigins); + +//执行扩展中间件 +app.UseMiddlewareAll(); +app.UseSignatureVerify(); + +// 使用响应格式化中间件(如果选择中间件方案,取消注释此行,并注释掉过滤器注册) +//app.UseResponseFormatter(); + +app.MapControllers(); +app.MapGet("/", () => $"请求成功==>{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}").WithName("默认请求"); +app.Run(); + + diff --git a/ChouBox.WebApi/Properties/launchSettings.json b/ChouBox.WebApi/Properties/launchSettings.json new file mode 100644 index 0000000..228fd45 --- /dev/null +++ b/ChouBox.WebApi/Properties/launchSettings.json @@ -0,0 +1,52 @@ +{ + "profiles": { + "http": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:5149" + }, + "https": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:7281;http://localhost:5149" + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Container (Dockerfile)": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", + "environmentVariables": { + "ASPNETCORE_HTTPS_PORTS": "8081", + "ASPNETCORE_HTTP_PORTS": "8080" + }, + "publishAllPorts": true, + "useSSL": true + } + }, + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:39464", + "sslPort": 44375 + } + } +} \ No newline at end of file diff --git a/ChouBox.WebApi/WeatherForecast.cs b/ChouBox.WebApi/WeatherForecast.cs new file mode 100644 index 0000000..f9457d4 --- /dev/null +++ b/ChouBox.WebApi/WeatherForecast.cs @@ -0,0 +1,13 @@ +namespace ChouBox.WebApi +{ + public class WeatherForecast + { + public DateOnly Date { get; set; } + + public int TemperatureC { get; set; } + + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + + public string? Summary { get; set; } + } +} diff --git a/ChouBox.WebApi/appsettings.Development.json b/ChouBox.WebApi/appsettings.Development.json new file mode 100644 index 0000000..02a4b21 --- /dev/null +++ b/ChouBox.WebApi/appsettings.Development.json @@ -0,0 +1,12 @@ +{ + "ConnectionStrings": { + "ConnectionString": "server=192.168.195.13;port=3306;database=youda_test;user=youda_test;password=youda_test;charset=utf8mb4", + "RedisConnectionString": "192.168.1.56:6379,defaultDatabase=3" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/ChouBox.WebApi/appsettings.json b/ChouBox.WebApi/appsettings.json new file mode 100644 index 0000000..646d48d --- /dev/null +++ b/ChouBox.WebApi/appsettings.json @@ -0,0 +1,21 @@ +{ + "ConnectionStrings": { + "ConnectionString": "server=127.0.0.1;port=3306;database=youda;user=youda;password=youda;charset=utf8mb4", + "RedisConnectionString": "127.0.0.1:6379,defaultDatabase=3" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + //服务器配置 + "Kestrel": { + "Endpoints": { + "Http": { + "Url": "http://*:80" + } + } + } +} diff --git a/ChouBox.sln b/ChouBox.sln new file mode 100644 index 0000000..c097741 --- /dev/null +++ b/ChouBox.sln @@ -0,0 +1,48 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.13.35913.81 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChouBox.Model", "ChouBox.Model\ChouBox.Model.csproj", "{C5297BEB-DA0D-4877-8E61-33360DEC1701}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChouBox.WebApi", "ChouBox.WebApi\ChouBox.WebApi.csproj", "{793C937C-3D7F-4375-914B-6913D8BC42CD}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utile", "Utile", "{9FA3D6BD-1EC1-3BA5-80CB-CE02773A58D5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HuanMeng.DotNetCore", "Utile\HuanMeng.DotNetCore\HuanMeng.DotNetCore.csproj", "{6DE90AEA-0445-541A-DAC3-E14A92E50363}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChouBox.Code", "ChouBox.Code\ChouBox.Code.csproj", "{620E3F3D-A969-47C2-B904-C853D886D26C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C5297BEB-DA0D-4877-8E61-33360DEC1701}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C5297BEB-DA0D-4877-8E61-33360DEC1701}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C5297BEB-DA0D-4877-8E61-33360DEC1701}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C5297BEB-DA0D-4877-8E61-33360DEC1701}.Release|Any CPU.Build.0 = Release|Any CPU + {793C937C-3D7F-4375-914B-6913D8BC42CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {793C937C-3D7F-4375-914B-6913D8BC42CD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {793C937C-3D7F-4375-914B-6913D8BC42CD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {793C937C-3D7F-4375-914B-6913D8BC42CD}.Release|Any CPU.Build.0 = Release|Any CPU + {6DE90AEA-0445-541A-DAC3-E14A92E50363}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6DE90AEA-0445-541A-DAC3-E14A92E50363}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6DE90AEA-0445-541A-DAC3-E14A92E50363}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6DE90AEA-0445-541A-DAC3-E14A92E50363}.Release|Any CPU.Build.0 = Release|Any CPU + {620E3F3D-A969-47C2-B904-C853D886D26C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {620E3F3D-A969-47C2-B904-C853D886D26C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {620E3F3D-A969-47C2-B904-C853D886D26C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {620E3F3D-A969-47C2-B904-C853D886D26C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {6DE90AEA-0445-541A-DAC3-E14A92E50363} = {9FA3D6BD-1EC1-3BA5-80CB-CE02773A58D5} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8856EA66-79F1-47B1-A618-EA89D131DFE4} + EndGlobalSection +EndGlobal diff --git a/Utile/HuanMeng.DotNetCore/AttributeExtend/ImagesAttribute.cs b/Utile/HuanMeng.DotNetCore/AttributeExtend/ImagesAttribute.cs new file mode 100644 index 0000000..1374f47 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/AttributeExtend/ImagesAttribute.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.AttributeExtend; + +/// +/// +/// +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] +public class ImagesAttribute : Attribute +{ + + public string FieldName { get; set; } + /// + /// + /// + /// 生成字段名称 + // 构造函数,用于传递参数 + public ImagesAttribute(string fieldName = "") + { + this.FieldName = fieldName; + } +} diff --git a/Utile/HuanMeng.DotNetCore/AttributeExtend/MessageAttribute.cs b/Utile/HuanMeng.DotNetCore/AttributeExtend/MessageAttribute.cs new file mode 100644 index 0000000..0367a33 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/AttributeExtend/MessageAttribute.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.AttributeExtend +{ + /// + /// 消息特性,用于标记控制器方法返回的消息内容 + /// + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] + public class MessageAttribute : Attribute + { + /// + /// 消息内容 + /// + public string Message { get; } + + /// + /// 构造函数 + /// + /// 消息内容 + public MessageAttribute(string message) + { + Message = message; + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/Base/BLLBase.cs b/Utile/HuanMeng.DotNetCore/Base/BLLBase.cs new file mode 100644 index 0000000..54d58b0 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Base/BLLBase.cs @@ -0,0 +1,27 @@ +namespace HuanMeng.DotNetCore.Base +{ + public abstract class BLLBase where TDao : DaoBase + { + /// + /// _serviceProvider,提供基本依赖注入支持 + /// + protected readonly IServiceProvider _serviceProvider; + + + /// + /// _dao,提供数据访问支持 + /// + public abstract TDao Dao { get; } + + + /// + /// 构造函数 + /// + /// + /// + public BLLBase(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/Base/BaseResponse.cs b/Utile/HuanMeng.DotNetCore/Base/BaseResponse.cs new file mode 100644 index 0000000..f959b61 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Base/BaseResponse.cs @@ -0,0 +1,102 @@ + +using Alipay.EasySDK.Kernel; +using Microsoft.AspNetCore.Http; +using Newtonsoft.Json.Serialization; +using Newtonsoft.Json; + +using System.Runtime.Serialization; + +using XLib.DotNetCore.Base; + +namespace HuanMeng.DotNetCore.Base +{ + /// + /// 接口和服务调用基础响应类 + /// + /// + [DataContract] + [Serializable] + public class BaseResponse : IResponse + { + + ///// + ///// Http状态码 + ///// + //[DataMember] + //public HttpStatusCode StatusCode { get; set; } + + /// + /// 功能执行返回代码 + /// + [DataMember] + public int Status { get; set; } + + /// + /// 消息 + /// + [DataMember] + public string Msg { get; set; } + + /// + /// 数据 + /// + [DataMember] + public T? Data { get; set; } + + /// + /// 构造函数 + /// + public BaseResponse() + { + //StatusCode = HttpStatusCode.OK; + Status = 1; + Msg = ""; + } + /// + /// 构造函数 + /// + public BaseResponse(int status, string message) + { + Status = status; + Msg = message; + Data = default(T); + + } + + + /// + /// 构造函数 + /// + public BaseResponse(int code, string message = "", T? data = default(T)) + { + Status = code; + Msg = message; + Data = data; + } + + /// + /// 构造函数 + /// + public BaseResponse(ResponseCode code, string message = "", T? data = default(T)) + { + Status = (int)code; + Msg = message; + Data = data; + } + + + /// + /// + /// + /// + public override string ToString() + { + var settings = new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }; + return JsonConvert.SerializeObject(this, settings); + } + + } +} diff --git a/Utile/HuanMeng.DotNetCore/Base/DaoBase.cs b/Utile/HuanMeng.DotNetCore/Base/DaoBase.cs new file mode 100644 index 0000000..3cbf519 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Base/DaoBase.cs @@ -0,0 +1,32 @@ +namespace HuanMeng.DotNetCore.Base +{ + public class DaoBase + { + /// + /// _serviceProvider,提供基本依赖注入支持 + /// + protected readonly IServiceProvider _serviceProvider; + + ///// + ///// 构造函数 + ///// + //public DaoBase() + //{ + // // 创建一个空的ServiceCollection + // var webApplication = WebApplication.Current; + // var services = new ServiceCollection(); + + // // 创建ServiceProvider实例 + // _serviceProvider = services.BuildServiceProvider(); + //} + + /// + /// 构造函数 + /// + /// + public DaoBase(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/Base/EfCoreDaoBase.cs b/Utile/HuanMeng.DotNetCore/Base/EfCoreDaoBase.cs new file mode 100644 index 0000000..971ad8c --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Base/EfCoreDaoBase.cs @@ -0,0 +1,162 @@ +using Microsoft.EntityFrameworkCore; + +using System.Linq.Expressions; + +namespace HuanMeng.DotNetCore.Base; + +/// +/// 基本数据库操作,需要安装 Microsoft.EntityFrameworkCore 和 Microsoft.EntityFrameworkCore.Relational +/// +/// +public class EfCoreDaoBase where TDbContext : DbContext +{ + private TDbContext _context; + + public TDbContext Context => _context; + + /// + /// 构造函数 + /// + /// + public EfCoreDaoBase(TDbContext context) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + } + + /// + /// 是否手动提交 + /// + public bool IsManualSubmit { get; set; } + + /// + /// SqlQueryRaw + /// + public async Task SqlQueryAsync(string sql, params object[] parameters) where T : class + { + return await Context.Database.SqlQueryRaw(sql, parameters).FirstOrDefaultAsync(); + } + + /// + /// SqlQueryList + /// + public async Task> SqlQueryListAsync(string sql, params object[] parameters) + { + return await Context.Database.SqlQueryRaw(sql, parameters).ToListAsync(); + } + + /// + /// ExecuteSql + /// + public async Task ExecuteSqlAsync(string sql, params object[] parameters) + { + var result = await Context.Database.ExecuteSqlRawAsync(sql, parameters); + await AutoSaveChangesAsync(); + return result; + } + + /// + /// 添加实体 + /// + public async Task AddAsync(T entity) where T : class + { + Context.Set().Add(entity); + await AutoSaveChangesAsync(); + } + + /// + /// 批量添加实体 + /// + public async Task AddRangeAsync(IEnumerable entities) where T : class + { + Context.Set().AddRange(entities); + await AutoSaveChangesAsync(); + } + + /// + /// 删除某个实体 + /// + public async Task DeleteAsync(T entity) where T : class + { + Context.Entry(entity).State = EntityState.Deleted; + await AutoSaveChangesAsync(); + } + + /// + /// 更新实体 + /// + public async Task UpdateAsync(T entity) where T : class + { + if (Context.Entry(entity).State == EntityState.Detached) + { + Context.Set().Attach(entity); + Context.Entry(entity).State = EntityState.Modified; + } + await AutoSaveChangesAsync(); + } + + /// + /// 清除上下文跟踪 + /// + public void RemoveTracking(T entity) where T : class + { + if (Context.Entry(entity).State != EntityState.Detached) + { + Context.Entry(entity).State = EntityState.Detached; + } + } + + /// + /// 获取实体,根据主键 + /// + public async Task GetModelAsync(params object[] keyValues) where T : class + { + return await Context.Set().FindAsync(keyValues); + } + + /// + /// 获取实体,根据条件 + /// + public async Task GetModelAsync(Expression> where, bool isNoTracking = false) where T : class + { + var query = Context.Set().AsQueryable(); + if (isNoTracking) + query = query.AsNoTracking(); + return await query.FirstOrDefaultAsync(where); + } + + /// + /// 获取列表数据 + /// + public IQueryable GetList(Expression> where, bool isNoTracking = false) where T : class + { + var query = Context.Set().Where(where); + return isNoTracking ? query.AsNoTracking() : query; + } + + /// + /// 获取记录数量 + /// + public async Task GetCountAsync(Expression> where) where T : class + { + return await Context.Set().AsNoTracking().CountAsync(where); + } + + /// + /// 判断是否存在记录 + /// + public async Task ExistsAsync(Expression> where) where T : class + { + return await Context.Set().AsNoTracking().AnyAsync(where); + } + + /// + /// 根据提交状态决定是否自动保存更改 + /// + private async Task AutoSaveChangesAsync() + { + if (!IsManualSubmit) + { + await Context.SaveChangesAsync(); + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/Base/IResponse.cs b/Utile/HuanMeng.DotNetCore/Base/IResponse.cs new file mode 100644 index 0000000..f957a84 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Base/IResponse.cs @@ -0,0 +1,22 @@ +namespace XLib.DotNetCore.Base; + +/// +/// 接口和服务调用通用响应接口 +/// +public interface IResponse +{ + ///// + ///// Http状态码 + ///// + //HttpStatusCode StatusCode { get; set; } + + /// + /// 功能执行返回代码 + /// + int Status { get; set; } + + /// + /// 消息 + /// + string Msg { get; set; } +} diff --git a/Utile/HuanMeng.DotNetCore/Base/MessageBox.cs b/Utile/HuanMeng.DotNetCore/Base/MessageBox.cs new file mode 100644 index 0000000..1c69ab5 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Base/MessageBox.cs @@ -0,0 +1,126 @@ +using Microsoft.AspNetCore.SignalR.Protocol; + +using Newtonsoft.Json.Serialization; +using Newtonsoft.Json; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.Base +{ + /// + /// + /// + public class MessageBox : Exception + { + /// + /// 基础数据 + /// + public BaseResponse BaseResponse { get; set; } + /// + /// + /// + /// + public MessageBox(ResponseCode code) + { + BaseResponse = new Base.BaseResponse(code); + + } + public MessageBox(BaseResponse baseResponse) + { + this.BaseResponse = baseResponse; + + } + /// + /// + /// + /// + /// + /// + public MessageBox(ResponseCode code, string message, object? data = null) + { + BaseResponse = new Base.BaseResponse(code, message, data); + + } + /// + /// + /// + /// + /// + /// + public MessageBox(int code, string message, object? data = null) + { + BaseResponse = new Base.BaseResponse(code, message, data); + } + /// + /// + /// + /// + /// + public MessageBox(string message, object? data = null) + { + BaseResponse = new Base.BaseResponse(0, message, data); + } + + /// + /// + /// + /// + public BaseResponse ToBaseResponse() + { + return BaseResponse; + } + + /// + /// + /// + /// + public override string ToString() + { + return BaseResponse.ToString(); + } + + /// + /// 创建错误消息 + /// + /// + /// + public static MessageBox ErrorShow(string message) => new(ResponseCode.Error, message); + + /// + /// 创建消息 + /// + /// + /// + public static MessageBox Show(string message) => new(message); + + /// + /// 创建消息 输出消息和数据 + /// + /// + /// + public static MessageBox Show(string message, object data) => new(message, data); + + /// + /// 创建消息 输出消息和数据 + /// + /// + /// + /// + /// + public static MessageBox Show(int code, string message, object? data = null) => new(code, message, data); + + /// + /// 创建消息 输出消息和数据 + /// + /// + /// + /// + /// + public static MessageBox Show(ResponseCode code, string message, object? data = null) => new(code, message, data); + } +} diff --git a/Utile/HuanMeng.DotNetCore/Base/ResponseCode.cs b/Utile/HuanMeng.DotNetCore/Base/ResponseCode.cs new file mode 100644 index 0000000..10a79d0 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Base/ResponseCode.cs @@ -0,0 +1,94 @@ +namespace HuanMeng.DotNetCore.Base; +/// +/// 响应编码参考,实际的项目使用可以自行定义 +/// 基本规则: +/// 成功:大于等于0ResponseCode +/// 失败:小于0 +/// + +public enum ResponseCode +{ + // 成功响应码 + /// + /// 成功 + /// + Success = 0, + + /// + /// 正在处理中 + /// + Processing = 102, + + /// + /// 开始排队 + /// + StartQueue = 201, + + // 失败响应码 + /// + /// 通用错误 + /// + Error = -1, + + /// + /// 参数错误 + /// + ParamError = -2, + + /// + /// 没找到数据记录 + /// + NotFoundRecord = -3, + + /// + /// 数据为null + /// + NullOrEmpty = -4, + + /// + /// Sign签名错误 + /// + SignError = -999, + + /// + /// jwt用户签名错误 + /// + JwtError = -998, + + // 客户端错误响应码 + /// + /// 用户未登录 + /// + UserNotLogin = 400, + + /// + /// 用户验证失败 + /// + Unauthorized = 401, + + /// + /// 用户登录过期 + /// + LoginExpired = 402, + + /// + /// 余额不足 + /// + NotMoney = 403, + + /// + /// 重复请求 + /// + ManyRequests = 429, + + // 其他错误响应码 + /// + /// 手机号异常 + /// + PhoneNumberException = 530, + + /// + /// 当日手机号发送已到达上限 + /// + PhoneNumberMaxException = 531, +} diff --git a/Utile/HuanMeng.DotNetCore/Base/ResultWithMessage.cs b/Utile/HuanMeng.DotNetCore/Base/ResultWithMessage.cs new file mode 100644 index 0000000..f0d6884 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Base/ResultWithMessage.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.Base +{ + /// + /// 带消息的返回结果 + /// + /// 数据类型 + public class ResultWithMessage + { + /// + /// 数据 + /// + public T Data { get; set; } + + /// + /// 消息 + /// + public string Message { get; set; } + + /// + /// 构造函数 + /// + public ResultWithMessage() + { + Message = ""; + } + + /// + /// 构造函数 + /// + /// 数据 + /// 消息 + public ResultWithMessage(T data, string message) + { + Data = data; + Message = message; + } + } +} \ No newline at end of file diff --git a/Utile/HuanMeng.DotNetCore/CacheHelper/CommonDataEntityCache.cs b/Utile/HuanMeng.DotNetCore/CacheHelper/CommonDataEntityCache.cs new file mode 100644 index 0000000..d4f5da4 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/CacheHelper/CommonDataEntityCache.cs @@ -0,0 +1,228 @@ +using HuanMeng.DotNetCore.CacheHelper.Contract; +using HuanMeng.DotNetCore.Redis; + +using Microsoft.EntityFrameworkCore.Metadata.Internal; + +using Newtonsoft.Json; + +using StackExchange.Redis; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.CacheHelper; + +/// +/// 缓存扩展- +/// +public abstract class CommonDataEntityCache : ICacheClearData, ICacheReloadData where T : class +{ + /// + /// + /// + protected object lockObj; + /// + /// 过期时间 + /// + protected int cacheTime; + + protected CommonDataEntityCache(object lockObj, int cacheTime = 36000) + { + this.lockObj = lockObj; + this.cacheTime = cacheTime; + } + + + /// + /// + /// + public abstract string key { get; } + + /// + /// 缓存数据 + /// + protected List? _dataList; + + /// + /// 数据 + /// + public virtual List DataList + { + get + { + if (_dataList == null) + { + var tempDataList = MemoryCacheHelper.GetCache>(key); + if (tempDataList == null) + { + lock (lockObj) + { + tempDataList = MemoryCacheHelper.GetCache>(key); + if (tempDataList == null) + { + tempDataList = GetDataList(); + MemoryCacheHelper.SetCache(key, tempDataList, cacheTime); + } + } + } + _dataList = JsonConvert.DeserializeObject>(JsonConvert.SerializeObject(tempDataList)); + } + return _dataList ?? new List(); + } + } + + + /// + /// 获取缓存数据 + /// + public abstract List GetDataList(); + + public virtual bool ClearData() + { + lock (lockObj) + { + MemoryCacheHelper.DelCache(key); + _dataList = null; + } + return true; + } + + public virtual void ReloadData() + { + lock (lockObj) + { + var tempDataList = GetDataList(); + MemoryCacheHelper.SetCache(key, tempDataList, cacheTime); + _dataList = tempDataList; + } + } +} + + +/// +/// 缓存扩展- +/// +public abstract class RedisDataEntityCache : CommonDataEntityCache, ICacheClearLocalData where T : class +{ + public IDatabase database; + /// + /// + /// + protected object lockObj; + /// + /// 过期时间 + /// + protected int cacheTime; + + private string name; + + protected RedisDataEntityCache(IDatabase database, int cacheTime = 36000, string name = "") : base(new object(), cacheTime) + { + this.lockObj = lockObj; + this.cacheTime = cacheTime; + this.database = database; + this.name = name; + } + + public int index = 0; + /// + /// 缓存数据 + /// + protected List? _dataList; + + /// + /// 数据 + /// + public override List DataList + { + get + { + + if (_dataList == null) + { + start: + var tempDataList = database.StringGet>(key); + if (tempDataList == null) + { + if (database.StringSetLock($"lock:{key}", "", 5)) + { + + if (tempDataList == null) + { + + tempDataList = GetDataList(); + if (cacheTime == 0) + { + database.StringSet(key, tempDataList); + } + else + { + database.StringSet(key, tempDataList, TimeSpan.FromSeconds(cacheTime)); + } + } + //_dataList = JsonConvert.DeserializeObject>(JsonConvert.SerializeObject(tempDataList)); + database.KeyDeleteAsync($"lock:{key}").Wait(); + } + else + { + index++; + Thread.Sleep(500); + tempDataList = database.StringGet>(key); + if (tempDataList == null) + { + if (index < 10) + { + goto start; + } + } + } + } + _dataList = tempDataList; + } + return _dataList ?? new List(); + } + } + + + + + public virtual bool ClearData() + { + if (database.StringSetLock($"lock:{key}", "", 5)) + { + database.KeyDelete(key); + _dataList = null; + database.KeyDeleteAsync($"lock:{key}").Wait(); + } + return true; + } + + public virtual void ReloadData() + { + if (database.StringSetLock($"lock:{key}", "", 5)) + { + var tempDataList = GetDataList(); + if (cacheTime == 0) + { + database.StringSet(key, tempDataList); + } + else + { + database.StringSet(key, tempDataList, TimeSpan.FromSeconds(cacheTime)); + } + _dataList = tempDataList; + database.KeyDeleteAsync($"lock:{key}").Wait(); + database.StringSet($"time:{key.Replace(":", ".")}", $"刷新{name}缓存时间{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}"); + + } + } + + public bool ClearLocalData() + { + _dataList = null; + return true; + } +} diff --git a/Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheClearData.cs b/Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheClearData.cs new file mode 100644 index 0000000..f7604e7 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheClearData.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.CacheHelper.Contract +{ + /// + /// 清除缓存 + /// + public interface ICacheClearData + { + /// + /// 清除数据 + /// + /// + bool ClearData(); + } +} diff --git a/Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheClearLocalData.cs b/Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheClearLocalData.cs new file mode 100644 index 0000000..dade31f --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheClearLocalData.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.CacheHelper.Contract; + +/// +/// 清除缓存 +/// +public interface ICacheClearLocalData +{ + /// + /// 清除数据 + /// + /// + bool ClearLocalData(); +} diff --git a/Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheReloadData.cs b/Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheReloadData.cs new file mode 100644 index 0000000..4ccb9c5 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheReloadData.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.CacheHelper.Contract +{ + /// + /// 重新加载数据 + /// + public interface ICacheReloadData + { + /// + /// 重新加载数据 + /// + void ReloadData(); + } +} diff --git a/Utile/HuanMeng.DotNetCore/CacheHelper/MemoryCacheHelper.cs b/Utile/HuanMeng.DotNetCore/CacheHelper/MemoryCacheHelper.cs new file mode 100644 index 0000000..682fdbf --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/CacheHelper/MemoryCacheHelper.cs @@ -0,0 +1,55 @@ +using Microsoft.Extensions.Caching.Memory; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.CacheHelper +{ + /// + /// 内存缓存帮助类 + /// + public class MemoryCacheHelper + { + public static MemoryCache cache = new MemoryCache(new MemoryCacheOptions()); + + /// + /// 获取缓存 + /// + /// + /// + /// + public static T? GetCache(string cacheName) where T : class, new() + { + + return cache.TryGetValue(cacheName, out var value) ? value as T : null; + } + + /// + /// 设置缓存 + /// + /// + /// + /// 单位秒,默认1小时 + public static void SetCache(string cacheName, object val, int cacheTime = 21000) + { + //数据量渐渐大了,每次因为很多都是同时缓存 所以在这里分流一下 + if (cacheTime == 21000) + cacheTime = new Random().Next(21000, 43200); + cache.Set(cacheName, val, TimeSpan.FromSeconds(cacheTime)); + } + + /// + /// 删除缓存 + /// + /// + public static void DelCache(string? cacheName = null) + { + if (!string.IsNullOrEmpty(cacheName)) + cache.Remove(cacheName); + else + cache.Dispose(); + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/CustomExtension/CorsExtension.cs b/Utile/HuanMeng.DotNetCore/CustomExtension/CorsExtension.cs new file mode 100644 index 0000000..92148b4 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/CustomExtension/CorsExtension.cs @@ -0,0 +1,33 @@ +using Microsoft.Extensions.DependencyInjection; + + +namespace HuanMeng.DotNetCore.CustomExtension +{ + /// + /// 添加跨域 + /// + public static class CorsExtension + { + /// + /// 添加跨域 + /// + /// + /// + public static void AddCustomCors(this IServiceCollection services, string policyName) + { + services.AddCors(options => + { + options.AddPolicy(policyName, + builder => + { + builder + .AllowAnyOrigin() + .AllowAnyHeader() + .AllowAnyMethod(); + }); + }); + + + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/Extensions/ControllerExtensions.cs b/Utile/HuanMeng.DotNetCore/Extensions/ControllerExtensions.cs new file mode 100644 index 0000000..aa809f5 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Extensions/ControllerExtensions.cs @@ -0,0 +1,34 @@ +using Microsoft.AspNetCore.Mvc; + +namespace HuanMeng.DotNetCore.Extensions +{ + /// + /// 控制器扩展方法 + /// + public static class ControllerExtensions + { + /// + /// 设置动态消息 + /// + /// 控制器 + /// 消息内容 + public static void SetDynamicMessage(this ControllerBase controller, string message) + { + controller.HttpContext.SetDynamicMessage(message); + } + + /// + /// 设置动态消息并返回结果 + /// + /// 返回结果类型 + /// 控制器 + /// 返回结果 + /// 消息内容 + /// 原始结果 + public static T WithMessage(this ControllerBase controller, T result, string message) + { + controller.SetDynamicMessage(message); + return result; + } + } +} \ No newline at end of file diff --git a/Utile/HuanMeng.DotNetCore/Extensions/HttpContextExtensions.cs b/Utile/HuanMeng.DotNetCore/Extensions/HttpContextExtensions.cs new file mode 100644 index 0000000..1e8ccbd --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Extensions/HttpContextExtensions.cs @@ -0,0 +1,48 @@ +using Microsoft.AspNetCore.Http; +using System.Text; +using System.Web; + +namespace HuanMeng.DotNetCore.Extensions +{ + /// + /// HttpContext扩展方法 + /// + public static class HttpContextExtensions + { + /// + /// 动态消息的头部名称 + /// + public const string DynamicMessageHeaderName = "X-Dynamic-Message"; + + /// + /// 设置动态消息 + /// + /// HTTP上下文 + /// 消息内容 + public static void SetDynamicMessage(this HttpContext httpContext, string message) + { + if (string.IsNullOrEmpty(message)) + return; + + // URL编码消息内容,防止特殊字符导致问题 + string encodedMessage = HttpUtility.UrlEncode(message); + httpContext.Response.Headers[DynamicMessageHeaderName] = encodedMessage; + } + + /// + /// 获取动态消息 + /// + /// HTTP上下文 + /// 消息内容,如果不存在则返回空字符串 + public static string GetDynamicMessage(this HttpContext httpContext) + { + if (httpContext.Response.Headers.TryGetValue(DynamicMessageHeaderName, out var value)) + { + // URL解码消息内容 + return HttpUtility.UrlDecode(value); + } + + return string.Empty; + } + } +} \ No newline at end of file diff --git a/Utile/HuanMeng.DotNetCore/HuanMeng.DotNetCore.csproj b/Utile/HuanMeng.DotNetCore/HuanMeng.DotNetCore.csproj new file mode 100644 index 0000000..91484a0 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/HuanMeng.DotNetCore.csproj @@ -0,0 +1,31 @@ + + + + net8.0 + enable + enable + True + True + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Utile/HuanMeng.DotNetCore/Json/CustomDateTimeConverter.cs b/Utile/HuanMeng.DotNetCore/Json/CustomDateTimeConverter.cs new file mode 100644 index 0000000..d8897e6 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Json/CustomDateTimeConverter.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.Json +{ + public class CustomDateTimeConverter : JsonConverter + { + private readonly string _format; + + public CustomDateTimeConverter(string format) + { + _format = format; + } + + public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return DateTime.Parse(reader.GetString()); + } + + public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) + { + writer.WriteStringValue(value.ToString(_format)); + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/JwtInfrastructure/Interface/IJwtAuthManager.cs b/Utile/HuanMeng.DotNetCore/JwtInfrastructure/Interface/IJwtAuthManager.cs new file mode 100644 index 0000000..23e2e1d --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/JwtInfrastructure/Interface/IJwtAuthManager.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.IdentityModel.Tokens.Jwt; +using System.Linq; +using System.Security.Claims; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.JwtInfrastructure.Interface +{ + /// + /// jwt帮助类 + /// + public interface IJwtAuthManager + { + /// + /// 用户刷新令牌只读词典 + /// + IImmutableDictionary UsersRefreshTokensReadOnlyDictionary { get; } + + /// + /// 生成令牌 + /// + /// 用户名 + /// 用户的有关信息 + /// + /// + JwtAuthResult GenerateTokens(string username, Claim[] claims, DateTime now); + /// + /// 刷新令牌 + /// + /// + /// + /// + /// + JwtAuthResult Refresh(string refreshToken, string accessToken, DateTime now); + /// + /// 删除过期的刷新令牌 + /// + /// + void RemoveExpiredRefreshTokens(DateTime now); + /// + /// 按用户名删除刷新令牌 + /// + /// + void RemoveRefreshTokenByUserName(string userName); + /// + /// 解码JwtToken + /// + /// + /// + (ClaimsPrincipal, JwtSecurityToken?) DecodeJwtToken(string token); + } +} diff --git a/Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtAuthManager.cs b/Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtAuthManager.cs new file mode 100644 index 0000000..780f9b0 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtAuthManager.cs @@ -0,0 +1,168 @@ +using HuanMeng.DotNetCore.JwtInfrastructure.Interface; + +using Microsoft.IdentityModel.Tokens; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.IdentityModel.Tokens.Jwt; +using System.Linq; +using System.Security.Claims; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; + + +namespace HuanMeng.DotNetCore.JwtInfrastructure +{ + /// + /// jwt帮助类 + /// + /// + public class JwtAuthManager(JwtTokenConfig jwtTokenConfig) : IJwtAuthManager + { + /// + /// 保存刷新token + /// + public IImmutableDictionary UsersRefreshTokensReadOnlyDictionary => _usersRefreshTokens.ToImmutableDictionary(); + /// + /// 后面可以存储在数据库或分布式缓存中 + /// + private readonly ConcurrentDictionary _usersRefreshTokens = new(); + /// + /// 获取加密字段 + /// + private readonly byte[] _secret = Encoding.UTF8.GetBytes(jwtTokenConfig.Secret); + + /// + /// 删除过期token + /// + /// + public void RemoveExpiredRefreshTokens(DateTime now) + { + var expiredTokens = _usersRefreshTokens.Where(x => x.Value.ExpireAt < now).ToList(); + foreach (var expiredToken in expiredTokens) + { + _usersRefreshTokens.TryRemove(expiredToken.Key, out _); + } + } + + /// + /// 根据用户名删除token + /// + /// + public void RemoveRefreshTokenByUserName(string userName) + { + var refreshTokens = _usersRefreshTokens.Where(x => x.Value.UserName == userName).ToList(); + foreach (var refreshToken in refreshTokens) + { + _usersRefreshTokens.TryRemove(refreshToken.Key, out _); + } + } + + /// + /// 创建token + /// + /// 用户名 + /// 用户项 + /// 过期时间 + /// + public JwtAuthResult GenerateTokens(string username, Claim[] claims, DateTime now) + { + var shouldAddAudienceClaim = string.IsNullOrWhiteSpace(claims.FirstOrDefault(x => x.Type == JwtRegisteredClaimNames.Aud)?.Value); + //创建token + var jwtToken = new JwtSecurityToken( + jwtTokenConfig.Issuer, + shouldAddAudienceClaim ? jwtTokenConfig.Audience : string.Empty, + claims, + expires: now.AddMinutes(jwtTokenConfig.AccessTokenExpiration), + signingCredentials: new SigningCredentials(new SymmetricSecurityKey(_secret), SecurityAlgorithms.HmacSha256Signature)); + var accessToken = new JwtSecurityTokenHandler().WriteToken(jwtToken); + + //创建刷新token + var refreshToken = new JwtRefreshToken + { + UserName = username, + TokenString = GenerateRefreshTokenString(), + ExpireAt = now.AddMinutes(jwtTokenConfig.RefreshTokenExpiration) + }; + _usersRefreshTokens.AddOrUpdate(refreshToken.TokenString, refreshToken, (_, _) => refreshToken); + + return new JwtAuthResult + { + AccessToken = accessToken, + RefreshToken = refreshToken + }; + } + + /// + /// 刷新token + /// + /// + /// + /// + /// + /// + public JwtAuthResult Refresh(string refreshToken, string accessToken, DateTime now) + { + var (principal, jwtToken) = DecodeJwtToken(accessToken); + if (jwtToken == null || !jwtToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256Signature)) + { + throw new SecurityTokenException("无效的token"); + } + + var userName = principal.Identity?.Name; + if (!_usersRefreshTokens.TryGetValue(refreshToken, out var existingRefreshToken)) + { + throw new SecurityTokenException("token已失效"); + } + if (existingRefreshToken.UserName != userName || existingRefreshToken.ExpireAt < now) + { + throw new SecurityTokenException("token不匹配"); + } + //创建新的token + return GenerateTokens(userName, principal.Claims.ToArray(), now); + } + /// + /// 解析token + /// + /// + /// + /// + public (ClaimsPrincipal, JwtSecurityToken?) DecodeJwtToken(string token) + { + if (string.IsNullOrWhiteSpace(token)) + { + throw new SecurityTokenException("token不能为空"); + } + var principal = new JwtSecurityTokenHandler() + .ValidateToken(token, + new TokenValidationParameters + { + ValidateIssuer = true, + ValidIssuer = jwtTokenConfig.Issuer, + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(_secret), + ValidAudience = jwtTokenConfig.Audience, + ValidateAudience = true, + ValidateLifetime = true, + ClockSkew = TimeSpan.FromMinutes(5) + }, + out var validatedToken); + return (principal, validatedToken as JwtSecurityToken); + } + + + /// + /// 获取刷新的token + /// + /// + private static string GenerateRefreshTokenString() + { + var randomNumber = new byte[32]; + using var randomNumberGenerator = RandomNumberGenerator.Create(); + randomNumberGenerator.GetBytes(randomNumber); + return Convert.ToBase64String(randomNumber); + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtAuthResult.cs b/Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtAuthResult.cs new file mode 100644 index 0000000..6bdbd7b --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtAuthResult.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.JwtInfrastructure +{ + /// + /// 令牌 + /// + public class JwtAuthResult + { + /// + /// 当前token + /// + [JsonPropertyName("accessToken")] + public string AccessToken { get; set; } = string.Empty; + + /// + /// 刷新token + /// + [JsonPropertyName("refreshToken")] + public JwtRefreshToken RefreshToken { get; set; } = new(); + } +} diff --git a/Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtManager.cs b/Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtManager.cs new file mode 100644 index 0000000..bb76c5e --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtManager.cs @@ -0,0 +1,167 @@ +using HuanMeng.DotNetCore.JwtInfrastructure.Interface; +using HuanMeng.DotNetCore.JwtInfrastructure; +using Microsoft.IdentityModel.Tokens; + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.IdentityModel.Tokens.Jwt; +using System.Linq; +using System.Security.Claims; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.JwtInfrastructure +{ + /// + /// jwt,不保存 + /// + /// + public class JwtManager(JwtTokenConfig jwtTokenConfig) : IJwtAuthManager + { + + /// + /// 后面可以存储在数据库或分布式缓存中 + /// + private readonly ConcurrentDictionary _usersRefreshTokens = new(); + /// + /// 获取加密字段 + /// + private readonly byte[] _secret = Encoding.UTF8.GetBytes(jwtTokenConfig.Secret); + + /// + /// 删除过期token + /// + /// + public void RemoveExpiredRefreshTokens(DateTime now) + { + var expiredTokens = _usersRefreshTokens.Where(x => x.Value.ExpireAt < now).ToList(); + foreach (var expiredToken in expiredTokens) + { + _usersRefreshTokens.TryRemove(expiredToken.Key, out _); + } + } + + /// + /// 根据用户名删除token + /// + /// + public void RemoveRefreshTokenByUserName(string userName) + { + var refreshTokens = _usersRefreshTokens.Where(x => x.Value.UserName == userName).ToList(); + foreach (var refreshToken in refreshTokens) + { + _usersRefreshTokens.TryRemove(refreshToken.Key, out _); + } + } + + /// + /// 创建token + /// + /// 用户名 + /// 用户项 + /// 过期时间 + /// + public JwtAuthResult GenerateTokens(string username, Claim[] claims, DateTime now) + { + var shouldAddAudienceClaim = string.IsNullOrWhiteSpace(claims.FirstOrDefault(x => x.Type == JwtRegisteredClaimNames.Aud)?.Value); + //创建token + var jwtToken = new JwtSecurityToken( + jwtTokenConfig.Issuer, + shouldAddAudienceClaim ? jwtTokenConfig.Audience : string.Empty, + claims, + expires: now.AddMinutes(jwtTokenConfig.AccessTokenExpiration), + signingCredentials: new SigningCredentials(new SymmetricSecurityKey(_secret), SecurityAlgorithms.HmacSha256Signature)); + var accessToken = new JwtSecurityTokenHandler().WriteToken(jwtToken); + + //创建刷新token + var refreshToken = new JwtRefreshToken + { + UserName = username, + TokenString = GenerateRefreshTokenString(), + ExpireAt = now.AddMinutes(jwtTokenConfig.RefreshTokenExpiration) + }; + //_usersRefreshTokens.AddOrUpdate(refreshToken.TokenString, refreshToken, (_, _) => refreshToken); + + return new JwtAuthResult + { + AccessToken = accessToken, + RefreshToken = refreshToken + }; + } + + /// + /// 刷新token + /// + /// + /// + /// + /// + /// + public JwtAuthResult Refresh(string refreshToken, string accessToken, DateTime now) + { + var (principal, jwtToken) = DecodeJwtToken(accessToken); + if (jwtToken == null || !jwtToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256Signature)) + { + throw new SecurityTokenException("无效的token"); + } + + var userName = principal.Identity?.Name; + if (!_usersRefreshTokens.TryGetValue(refreshToken, out var existingRefreshToken)) + { + throw new SecurityTokenException("token已失效"); + } + if (existingRefreshToken.UserName != userName || existingRefreshToken.ExpireAt < now) + { + throw new SecurityTokenException("token不匹配"); + } + //创建新的token + return GenerateTokens(userName, principal.Claims.ToArray(), now); + } + /// + /// 解析token + /// + /// + /// + /// + public (ClaimsPrincipal, JwtSecurityToken?) DecodeJwtToken(string token) + { + if (string.IsNullOrWhiteSpace(token)) + { + throw new SecurityTokenException("token不能为空"); + } + var principal = new JwtSecurityTokenHandler() + .ValidateToken(token, + new TokenValidationParameters + { + ValidateIssuer = true, + ValidIssuer = jwtTokenConfig.Issuer, + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(_secret), + ValidAudience = jwtTokenConfig.Audience, + ValidateAudience = true, + ValidateLifetime = true, + ClockSkew = TimeSpan.FromMinutes(5) + }, + out var validatedToken); + return (principal, validatedToken as JwtSecurityToken); + } + + + /// + /// 获取刷新的token + /// + /// + private static string GenerateRefreshTokenString() + { + var randomNumber = new byte[32]; + using var randomNumberGenerator = RandomNumberGenerator.Create(); + randomNumberGenerator.GetBytes(randomNumber); + return Convert.ToBase64String(randomNumber); + } + + public IImmutableDictionary UsersRefreshTokensReadOnlyDictionary => throw new NotImplementedException(); + } +} diff --git a/Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtRefreshToken.cs b/Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtRefreshToken.cs new file mode 100644 index 0000000..f68f04a --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtRefreshToken.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.JwtInfrastructure +{ + /// + /// 刷新token + /// + public class JwtRefreshToken + { + /// + /// 用户名 + /// + [JsonPropertyName("username")] + public string UserName { get; set; } = string.Empty; + + /// + /// token + /// + [JsonPropertyName("tokenString")] + public string TokenString { get; set; } = string.Empty; + + /// + /// 过期时间 + /// + [JsonPropertyName("expireAt")] + public DateTime ExpireAt { get; set; } + } +} diff --git a/Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtTokenConfig.cs b/Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtTokenConfig.cs new file mode 100644 index 0000000..a62d459 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/JwtInfrastructure/JwtTokenConfig.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.JwtInfrastructure +{ + /// + /// JwtToken 配置文件 + /// + public class JwtTokenConfig + { + + /// + /// 加密值 + /// + [JsonPropertyName("secret")] + public string Secret { get; set; } = string.Empty; + + /// + /// 颁发者 + /// + [JsonPropertyName("issuer")] + public string Issuer { get; set; } = string.Empty; + + /// + /// 受众 + /// + [JsonPropertyName("audience")] + public string Audience { get; set; } = string.Empty; + + /// + /// 令牌过期时间 + /// + [JsonPropertyName("accessTokenExpiration")] + public int AccessTokenExpiration { get; set; } + + /// + /// 刷新令牌过期时间(一般会比令牌过期时间长) + /// + [JsonPropertyName("refreshTokenExpiration")] + public int RefreshTokenExpiration { get; set; } + + } +} diff --git a/Utile/HuanMeng.DotNetCore/MiddlewareExtend/ExceptionMiddleware.cs b/Utile/HuanMeng.DotNetCore/MiddlewareExtend/ExceptionMiddleware.cs new file mode 100644 index 0000000..3ce1d62 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/MiddlewareExtend/ExceptionMiddleware.cs @@ -0,0 +1,64 @@ +using HuanMeng.DotNetCore.Base; + +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; + +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +using System; + + +namespace HuanMeng.DotNetCore.MiddlewareExtend +{ + /// + /// 异常中间件 + /// + public class ExceptionMiddleware + { + private readonly RequestDelegate _next; + private readonly ILogger _logger; + + public ExceptionMiddleware(RequestDelegate next, ILogger logger) + { + _next = next; + _logger = logger; + } + + public async Task Invoke(HttpContext context) + { + try + { + await _next(context); + } + catch (ArgumentNullException ex) + { + + + context.Response.StatusCode = StatusCodes.Status200OK; + BaseResponse baseResponse = new BaseResponse(ResponseCode.ParamError, ex.ParamName ?? "参数错误", null) + { + + }; + context.Response.ContentType = "application/json; charset=utf-8"; + // 将异常信息写入 HTTP 响应 + await context.Response.WriteAsync(baseResponse.ToString()); + } + catch (Exception ex) + { + + _logger.LogError(context.Request.Path.ToString(), ex, "异常记录"); + // 设置 HTTP 响应状态码为 500 + context.Response.ContentType = "application/json; charset=utf-8"; + context.Response.StatusCode = StatusCodes.Status200OK; + BaseResponse baseResponse = new BaseResponse(ResponseCode.Error, ex.Message, null); + // 将异常信息写入 HTTP 响应 + await context.Response.WriteAsync(baseResponse.ToString()); + } + finally + { + + } + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/MiddlewareExtend/ExecutionTimeMiddleware.cs b/Utile/HuanMeng.DotNetCore/MiddlewareExtend/ExecutionTimeMiddleware.cs new file mode 100644 index 0000000..6307f6c --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/MiddlewareExtend/ExecutionTimeMiddleware.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNetCore.Http; + +using System.Diagnostics; + +namespace HuanMeng.DotNetCore.MiddlewareExtend +{ + /// + /// 方法执行时间 + /// + public class ExecutionTimeMiddleware(RequestDelegate _next) + { + public async Task Invoke(HttpContext context) + { + // 开始计时 + var sw = Stopwatch.StartNew(); + //在将响应标头发送到之前添加要调用的委托客户此处注册的回调按相反顺序运行。 + context.Response.OnStarting(() => + { + sw.Stop(); + context.Response.Headers.TryAdd("X-Request-Duration", $"{sw.Elapsed.TotalMilliseconds} ms"); + return Task.CompletedTask; + }); + await _next(context); + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/MiddlewareExtend/MiddlewareExtends.cs b/Utile/HuanMeng.DotNetCore/MiddlewareExtend/MiddlewareExtends.cs new file mode 100644 index 0000000..7e5cf42 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/MiddlewareExtend/MiddlewareExtends.cs @@ -0,0 +1,54 @@ +using Microsoft.AspNetCore.Builder; + +namespace HuanMeng.DotNetCore.MiddlewareExtend +{ + /// + /// 中间库扩展 + /// + public static class MiddlewareExtends + { + /// + /// 加载全部中间件 + /// + /// + /// + public static IApplicationBuilder UseMiddlewareAll(this IApplicationBuilder builder) + { + return builder + .UseExceptionMiddleware() + .UseExecutionTimeMiddleware() + //.SignBaseMiddleware() + ; + + } + + /// + /// 异常中间件 + /// + /// + /// + public static IApplicationBuilder UseExecutionTimeMiddleware(this IApplicationBuilder builder) + { + return builder.UseMiddleware(); + } + /// + /// 执行时间中间件 + /// + /// + /// + public static IApplicationBuilder UseExceptionMiddleware(this IApplicationBuilder builder) + { + return builder.UseMiddleware(); + } + + /// + /// 加密验证 + /// + /// + /// + public static IApplicationBuilder SignBaseMiddleware(this IApplicationBuilder builder) + { + return builder.UseMiddleware(); + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/MiddlewareExtend/SignBaseMiddleware.cs b/Utile/HuanMeng.DotNetCore/MiddlewareExtend/SignBaseMiddleware.cs new file mode 100644 index 0000000..9f7b5cd --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/MiddlewareExtend/SignBaseMiddleware.cs @@ -0,0 +1,101 @@ +using Microsoft.AspNetCore.Http; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using Newtonsoft.Json.Linq; +using HuanMeng.DotNetCore.Base; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +namespace HuanMeng.DotNetCore.MiddlewareExtend +{ + /// + /// 参数请求加密验证 + /// + public class SignBaseMiddleware + { + private readonly RequestDelegate _next; + private const string FixedString = "cccc"; // 固定字符串 + public SignBaseMiddleware(RequestDelegate next) + { + _next = next; + } + + public async Task Invoke(HttpContext context) + { + // 读取请求体 + context.Request.EnableBuffering(); // 启用请求流的多次读取功能 + var requestBody = await new StreamReader(context.Request.Body).ReadToEndAsync(); + context.Request.Body.Position = 0; // 重置请求体的位置 + + if (string.IsNullOrEmpty(requestBody)) + { + await _next(context); + return; + } + // 解析请求体为 JSON 对象 + var requestJson = JObject.Parse(requestBody); + // 获取请求中的 sign 值 + var requestSign = requestJson["sign"]?.ToString(); + if (string.IsNullOrEmpty(requestSign)) + { + await _next(context); + return; + } + // 获取所有的键值对,并排序 + var sortedKeys = requestJson.Properties() + .Where(p => p.Name != "sign") + .OrderBy(p => p.Name) + .Select(p => p.Value.ToString()) + .ToList(); + + // 拼接所有的值,并加上固定字符串 + var concatenatedValues = string.Join("", sortedKeys) + FixedString; + + // 计算 MD5 哈希值 + var md5Hash = ComputeMD5Hash(concatenatedValues); + + + + // 验证 MD5 哈希值与请求中的 sign 是否匹配 + if (md5Hash != requestSign) + { + var settings = new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }; + // 返回 500 错误 + context.Response.StatusCode = 500; + BaseResponse baseResponse = new BaseResponse(ResponseCode.SignError, "sign加密验证失败", null) + { + + }; + context.Response.ContentType = "application/json; charset=utf-8"; + // 将异常信息写入 HTTP 响应 + await context.Response.WriteAsync(JsonConvert.SerializeObject(baseResponse)); + //await context.Response.WriteAsync(""); + return; + } + + // 调用下一个中间件 + await _next(context); + } + /// + /// Md5加密 + /// + /// + /// + private string ComputeMD5Hash(string input) + { + using (var md5 = MD5.Create()) + { + var inputBytes = Encoding.UTF8.GetBytes(input); + var hashBytes = md5.ComputeHash(inputBytes); + return BitConverter.ToString(hashBytes).Replace("-", "").ToLower(); + } + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/MultiTenant/Contract/IMultiTenant.cs b/Utile/HuanMeng.DotNetCore/MultiTenant/Contract/IMultiTenant.cs new file mode 100644 index 0000000..a8a5b62 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/MultiTenant/Contract/IMultiTenant.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.MultiTenant.Contract +{ + /// + /// 基本多租户接口 + /// + public interface IMultiTenant + { + /// + /// 租户ID + /// + Guid TenantId { get; set; } + } +} diff --git a/Utile/HuanMeng.DotNetCore/MultiTenant/Contract/IMultiTenantDbContext.cs b/Utile/HuanMeng.DotNetCore/MultiTenant/Contract/IMultiTenantDbContext.cs new file mode 100644 index 0000000..21b2ec2 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/MultiTenant/Contract/IMultiTenantDbContext.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.MultiTenant.Contract +{ + /// + /// 多租户DbContent接口 + /// + public interface IMultiTenantDbContext + { + /// + /// 租户信息 + /// + ITenantInfo TenantInfo { get; } + } +} diff --git a/Utile/HuanMeng.DotNetCore/MultiTenant/Contract/IMultiTenantEntity.cs b/Utile/HuanMeng.DotNetCore/MultiTenant/Contract/IMultiTenantEntity.cs new file mode 100644 index 0000000..7ab6888 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/MultiTenant/Contract/IMultiTenantEntity.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.MultiTenant.Contract +{ + /// + /// 多租户实体类接口 + /// + public interface IMultiTenantEntity : IMultiTenant + { + } +} diff --git a/Utile/HuanMeng.DotNetCore/MultiTenant/Contract/ITenantInfo.cs b/Utile/HuanMeng.DotNetCore/MultiTenant/Contract/ITenantInfo.cs new file mode 100644 index 0000000..252e6e6 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/MultiTenant/Contract/ITenantInfo.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.MultiTenant.Contract +{ + + /// + /// 租户信息接口 + /// + public interface ITenantInfo : IMultiTenant + { + + string? Identifier { get; set; } + + /// + /// Gets or sets a display friendly name for the tenant. + /// + string? Name { get; set; } + + } +} diff --git a/Utile/HuanMeng.DotNetCore/MultiTenant/MultiTenantDbContext.cs b/Utile/HuanMeng.DotNetCore/MultiTenant/MultiTenantDbContext.cs new file mode 100644 index 0000000..99c6ec3 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/MultiTenant/MultiTenantDbContext.cs @@ -0,0 +1,101 @@ +using HuanMeng.DotNetCore.MultiTenant.Contract; + +using Microsoft.EntityFrameworkCore; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.MultiTenant +{ + /// + /// 基本多租户DbContext + /// + public class MultiTenantDbContext : DbContext, IMultiTenantDbContext + { + /// + /// 租户信息 + /// + public ITenantInfo? TenantInfo { get; set; } + + + /// + /// 构造函数 + /// + /// + public MultiTenantDbContext(ITenantInfo? tenantInfo) + { + this.TenantInfo = tenantInfo; + } + + /// + /// 构造函数 + /// + /// + /// + public MultiTenantDbContext(ITenantInfo? tenantInfo, DbContextOptions options) + : base(options) + { + if (tenantInfo == null) + { + tenantInfo = new TenantInfo() + { + TenantId = Guid.NewGuid(), + Identifier = "default", + Name = "default" + }; + } + this.TenantInfo = tenantInfo; + } + + public void SetTenantInfo(ITenantInfo tenantInfo) + { + this.TenantInfo = tenantInfo; + } + + public override int SaveChanges() + { + if (TenantInfo?.TenantId != null) + { + var entries = ChangeTracker.Entries() + .Where(e => e.Entity is IMultiTenantEntity && + (e.State == EntityState.Added || e.State == EntityState.Modified)) + .Select(e => e.Entity as IMultiTenantEntity) + .ToList(); + + foreach (var entity in entries) + { + if (entity?.TenantId == null || entity?.TenantId == Guid.Empty) + { + entity.TenantId = TenantInfo.TenantId; + } + } + } + return base.SaveChanges(); + } + + public override async Task SaveChangesAsync(CancellationToken cancellationToken = default) + { + if (TenantInfo?.TenantId != null) + { + var entries = ChangeTracker.Entries() + .Where(e => e.Entity is IMultiTenantEntity && + (e.State == EntityState.Added || e.State == EntityState.Modified)) + .Select(e => e.Entity as IMultiTenantEntity) + .ToList(); + + foreach (var entity in entries) + { + if (entity?.TenantId == null || entity?.TenantId == Guid.Empty) + { + entity.TenantId = TenantInfo.TenantId; + } + } + } + return await base.SaveChangesAsync(cancellationToken); + } + + } +} diff --git a/Utile/HuanMeng.DotNetCore/MultiTenant/MultiTenantEntity.cs b/Utile/HuanMeng.DotNetCore/MultiTenant/MultiTenantEntity.cs new file mode 100644 index 0000000..d7d58fa --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/MultiTenant/MultiTenantEntity.cs @@ -0,0 +1,22 @@ +using HuanMeng.DotNetCore.MultiTenant.Contract; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.MultiTenant +{ + /// + /// 基本多租户实体类 + /// + public class MultiTenantEntity : IMultiTenantEntity + { + /// + /// 租户ID + /// + public virtual Guid TenantId { get; set; } + + } +} diff --git a/Utile/HuanMeng.DotNetCore/MultiTenant/TenantInfo.cs b/Utile/HuanMeng.DotNetCore/MultiTenant/TenantInfo.cs new file mode 100644 index 0000000..45a74c7 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/MultiTenant/TenantInfo.cs @@ -0,0 +1,38 @@ +using HuanMeng.DotNetCore.MultiTenant.Contract; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.MultiTenant +{ + /// + /// 租户信息 + /// + public class TenantInfo : ITenantInfo + { + + public TenantInfo() + { + } + + /// + /// 租户ID + /// + public Guid TenantId { get; set; } + + /// + /// 租户字符串标志 + /// + public string? Identifier { get; set; } + + /// + /// 租户名称(描述说明) + /// + public string? Name { get; set; } + + + } +} diff --git a/Utile/HuanMeng.DotNetCore/Processors/BaseProcessor.cs b/Utile/HuanMeng.DotNetCore/Processors/BaseProcessor.cs new file mode 100644 index 0000000..17c7372 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Processors/BaseProcessor.cs @@ -0,0 +1,58 @@ + + +namespace HuanMeng.DotNetCore.Processors +{ + /// + /// 任务处理器 + /// + public abstract class BaseProcessor : ITaskProcessor + { + /// + /// 终止内部处理线程的最长等待时间(毫秒) + /// + protected const int WaitTimeMax_StopProc = 20000; + + + /// + /// 构造函数 + /// + public BaseProcessor() + { + //加载配置 + LoadSettings(); + } + + /// + /// 加载配置 + /// + protected virtual void LoadSettings() + { + //初始化 + // LogHelper.Info("BaseProcessor.LoadSettings"); + } + + /// + /// Dispose + /// + public virtual void Dispose() + { + } + + /// + /// 执行任务 + /// + public virtual void Run() + { + //LogHelper.Info("BaseProcessor.Run"); + } + + /// + /// 停止执行任务 + /// + public virtual void Stop() + { + // LogHelper.Info("BaseProcessor.Stop"); + } + } + +} diff --git a/Utile/HuanMeng.DotNetCore/Processors/ITaskProcessor.cs b/Utile/HuanMeng.DotNetCore/Processors/ITaskProcessor.cs new file mode 100644 index 0000000..18a187b --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Processors/ITaskProcessor.cs @@ -0,0 +1,18 @@ +namespace HuanMeng.DotNetCore.Processors +{ + /// + /// 任务处理器接口 + /// + public interface ITaskProcessor : IDisposable + { + /// + /// 运行任务 + /// + void Run(); + + /// + /// 停止运行 + /// + void Stop(); + } +} diff --git a/Utile/HuanMeng.DotNetCore/Processors/ThreadProcessor.cs b/Utile/HuanMeng.DotNetCore/Processors/ThreadProcessor.cs new file mode 100644 index 0000000..128a742 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Processors/ThreadProcessor.cs @@ -0,0 +1,81 @@ +namespace HuanMeng.DotNetCore.Processors +{ + /// + /// 包含处理线程的处理器基类 + /// + public abstract class ThreadProcessor : BaseProcessor + { + protected Thread? _thread; + protected bool _isRunning; + protected string? _threadName; + + /// + /// 构造函数 + /// + public ThreadProcessor() { } + + /// + /// 构造函数 + /// + /// 线程名称 + public ThreadProcessor(string threadName) + { + _threadName = threadName; + } + + /// + /// 执行处理 + /// + /// 如果处理器已经在运行,抛出异常 + public override void Run() + { + if (_isRunning) + { + throw new InvalidOperationException("重复执行线程"); + } + + _isRunning = true; + + _thread = new Thread(Proc_Do) + { + Name = _threadName + }; + _thread.Start(); + } + + /// + /// 线程处理函数,需要在子类中实现 + /// + protected abstract void Proc_Do(); + + /// + /// 停止处理线程 + /// + public override void Stop() + { + if (!_isRunning) + { + return; + } + + _isRunning = false; + + if (_thread != null && _thread.IsAlive) + { + _thread.Join(WaitTimeMax_StopProc); // 等待线程结束 + _thread = null; + } + } + + /// + /// 释放资源 + /// + public override void Dispose() + { + Stop(); + base.Dispose(); + } + + + } +} diff --git a/Utile/HuanMeng.DotNetCore/QuartzExtend/QuartzExtensions.cs b/Utile/HuanMeng.DotNetCore/QuartzExtend/QuartzExtensions.cs new file mode 100644 index 0000000..cdf318f --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/QuartzExtend/QuartzExtensions.cs @@ -0,0 +1,68 @@ +using Microsoft.Extensions.DependencyInjection; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Quartz; +using Microsoft.IdentityModel.Tokens; +namespace HuanMeng.DotNetCore.QuartzExtend; + +/// +/// 提供扩展方法,用于基于 QuartzTriggerAttribute 注册 Quartz 作业和触发器。 +/// +public static class QuartzExtensions +{ + /// + /// 扫描指定程序集中的所有带有 QuartzTriggerAttribute 的作业类,并将它们注册到 Quartz 调度器中。 + /// + /// 依赖注入服务集合。 + /// 要扫描的程序集。 + /// 更新后的服务集合。 + public static IServiceCollection AddQuartzWithAttributes(this IServiceCollection services, Assembly assembly) + { + services.AddQuartz(q => + { + // 查找实现了 IJob 接口并带有 QuartzTriggerAttribute 特性的所有类 + var jobTypes = assembly.GetTypes() + .Where(t => t.IsClass && !t.IsAbstract && typeof(IJob).IsAssignableFrom(t)); + + foreach (var jobType in jobTypes) + { + // 获取 QuartzTriggerAttribute 特性实例 + var attr = jobType.GetCustomAttribute(); + if (attr != null) + { + // 注册作业 + var jobKey = new JobKey(jobType.Name); // 使用类名作为作业的唯一标识 + q.AddJob(jobType, jobKey, opts => opts.WithIdentity(jobKey)); // 将作业注册到调度器 + + // 根据特性中定义的调度配置注册触发器 + if (!string.IsNullOrEmpty(attr.CronExpression)) + { + // 如果定义了 Cron 表达式,使用 Cron 调度 + q.AddTrigger(opts => opts + .ForJob(jobKey) + .WithIdentity(attr.TriggerName) + .WithCronSchedule(attr.CronExpression)); + } + else if (attr.IntervalInSeconds.HasValue && attr.IntervalInSeconds > 0) + { + // 如果定义了简单时间间隔,使用简单调度 + q.AddTrigger(opts => opts + .ForJob(jobKey) + .WithIdentity(attr.TriggerName) + .StartNow() + .WithSimpleSchedule(x => x.WithIntervalInSeconds(attr.IntervalInSeconds.Value).RepeatForever())); + } + } + } + }); + + // 注册 Quartz 的托管服务 + services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true); + return services; + } +} diff --git a/Utile/HuanMeng.DotNetCore/QuartzExtend/QuartzTriggerAttribute.cs b/Utile/HuanMeng.DotNetCore/QuartzExtend/QuartzTriggerAttribute.cs new file mode 100644 index 0000000..3516b9c --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/QuartzExtend/QuartzTriggerAttribute.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.QuartzExtend; + +/// +/// 自定义特性,用于标识 Quartz 作业的触发器配置。 +/// +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +public class QuartzTriggerAttribute : Attribute +{ + /// + /// 获取触发器的名称。 + /// + public string TriggerName { get; } + + /// + /// 获取触发器的时间间隔(秒)。 + /// + public int? IntervalInSeconds { get; } + + /// + /// 获取 Cron 表达式。 + /// + public string CronExpression { get; } + + /// + /// 使用 Cron 表达式初始化特性。 + /// + /// 触发器名称。 + /// Cron 表达式。 + public QuartzTriggerAttribute(string triggerName, string cronExpression = "0/1 * * * * ?") + { + TriggerName = triggerName; + IntervalInSeconds = null; + CronExpression = cronExpression; + } + + /// + /// 使用时间间隔初始化特性。 + /// + /// 触发器名称。 + /// 时间间隔(秒)。 + public QuartzTriggerAttribute(string triggerName, int intervalInSeconds) + { + TriggerName = triggerName; + IntervalInSeconds = intervalInSeconds; + CronExpression = ""; + } +} diff --git a/Utile/HuanMeng.DotNetCore/Redis/RedisConnection.cs b/Utile/HuanMeng.DotNetCore/Redis/RedisConnection.cs new file mode 100644 index 0000000..e571501 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Redis/RedisConnection.cs @@ -0,0 +1,336 @@ +using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.Identity.Client; + +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +using StackExchange.Redis; + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using IDatabase = StackExchange.Redis.IDatabase; +namespace HuanMeng.DotNetCore.Redis +{ + /// + /// 数据库连接字符串 + /// + public static class RedisConnection + { + + /// + /// 数据库连接 + /// + public static ConcurrentDictionary Redis { get; set; } = new ConcurrentDictionary(); + + /// + /// 数据库查询 + /// + public static ConcurrentDictionary RedisServer { get; set; } = new ConcurrentDictionary(); + + + /// + /// + /// + /// + /// + public static IDatabase GetRedis(string redisConnection) + { + if (!Redis.TryGetValue(redisConnection, out var database)) + { + var redis = ConnectionMultiplexer.Connect(redisConnection); + database = redis.GetDatabase(); + //server.key + //redis.GetServer() + Redis.TryAdd(redisConnection, database); + } + return database; + } + + + + /// + /// + /// + /// + /// + public static IServer GetServer(string redisConnection) + { + if (!RedisServer.TryGetValue(redisConnection, out var server)) + { + var redis = ConnectionMultiplexer.Connect(redisConnection); + var serverConn = ParseIpPortAndDatabase(redisConnection); + server = redis.GetServer(serverConn.ip, serverConn.port); + //server.key + //redis.GetServer() + RedisServer.TryAdd(redisConnection, server); + } + return server; + } + private static (string ip, int port, int database) ParseIpPortAndDatabase(string connectionString) + { + // 默认端口号和默认数据库 + int defaultPort = 6379; + int defaultDatabase = 0; + + if (string.IsNullOrEmpty(connectionString)) + { + return ("localhost", defaultPort, defaultDatabase); + } + + // 按逗号分割,获取主机部分和其他参数 + var parts = connectionString.Split(','); + var hostPart = parts[0]; // 例如:"192.168.195.6:6379" + + // 检查是否包含端口号 + string ip; + int port; + + if (hostPart.Contains(":")) + { + var hostParts = hostPart.Split(':'); + ip = hostParts[0]; + port = int.TryParse(hostParts[1], out int parsedPort) ? parsedPort : defaultPort; + } + else + { + // 如果没有端口号,使用默认端口 + ip = hostPart; + port = defaultPort; + } + + // 解析 defaultDatabase 参数 + int database = defaultDatabase; + foreach (var part in parts) + { + if (part.StartsWith("defaultDatabase=", StringComparison.OrdinalIgnoreCase)) + { + var dbPart = part.Split('='); + if (dbPart.Length == 2 && int.TryParse(dbPart[1], out int parsedDb)) + { + database = parsedDb; + } + } + } + + return (ip, port, database); + } + + /// + /// + /// + /// + /// + /// + /// + /// + public static bool StringSetLock(this IDatabase database, string key, string value, int time = 10) + { + return database.StringSet(key, value, TimeSpan.FromSeconds(time), when: When.NotExists); + } + + /// + /// 删除key + /// + /// + /// + /// + public static async Task KeysDeleteds(this IDatabase database, string key) + { + + string luaScript = @" +local keys = redis.call('KEYS', ARGV[1]) +if next(keys) ~= nil then + return redis.call('DEL', unpack(keys)) +else + return 0 +end +"; + + var keysDeleted = (int)await (database.ScriptEvaluateAsync(luaScript, values: new RedisValue[] { key })); + return keysDeleted; + } + + + /// + /// 获取一个key的对象 + /// + /// + /// + /// + public static T? StringGet(this IDatabase database, string key) + { + var value = database.StringGet(key); + // 检查值是否为空 + if (!value.HasValue) + { + return default(T); + } + if (typeof(T).IsPrimitive || typeof(T) == typeof(string) || typeof(T) == typeof(decimal)) + { + try + { + return (T)Convert.ChangeType(value.ToString(), typeof(T)); + } + catch + { + return default; // 或抛出异常,取决于业务需求 + } + } + // 将 RedisValue 转换为 T 类型 + return JsonConvert.DeserializeObject(value); + } + + /// + /// 数据存放在redis + /// + /// + /// + /// + /// + /// + public static async Task StringSetAsync(this IDatabase database, string key, object value, TimeSpan? expiry) + { + return await database.StringSetAsync(key, (value == null ? "" : JsonConvert.SerializeObject(value)), expiry, When.Always); + } + + /// + /// 数据存放在redis + /// + /// + /// + /// + /// + /// + public static bool StringSet(this IDatabase database, string key, object value, TimeSpan? expiry = null) + { + return database.StringSet(key, (value == null ? "" : JsonConvert.SerializeObject(value)), expiry, When.Always); + } + + /// + /// 获取一个key的对象 + /// + /// + /// + /// + public static async Task StringGetAsync(this IDatabase database, string key) + { + + var value = await database.StringGetAsync(key); + // 检查值是否为空 + if (!value.HasValue) + { + return default(T); + } + if (typeof(T).IsPrimitive || typeof(T) == typeof(string) || typeof(T) == typeof(decimal)) + { + try + { + return (T)Convert.ChangeType(value.ToString(), typeof(T)); + } + catch + { + return default; // 或抛出异常,取决于业务需求 + } + } + // 将 RedisValue 转换为 T 类型 + return JsonConvert.DeserializeObject(value); + } + + + /// + /// 模糊查询key + /// + /// + /// + /// + /// + public static List ScanKeys(this IServer server, string pattern, int pageSize = 1000) + { + var matchingKeys = server.Keys(pattern: pattern, pageSize: pageSize).Select(it => it.ToString()).ToList(); + return matchingKeys; + } + /// + /// 异步模糊查询key + /// + /// Redis 服务器实例 + /// 匹配的模式(支持通配符) + /// 每次扫描的页大小 + /// 数据库编号,默认值为 -1 表示全部数据库 + /// 匹配的键的字符串列表 + public static async Task> ScanKeysAsync(this IServer server, string pattern, int pageSize = 1000, int database = -1) + { + var matchingKeys = new List(); + + try + { + await foreach (var key in server.KeysAsync(database: database, pattern: pattern, pageSize: pageSize)) + { + matchingKeys.Add(key.ToString()); + } + } + catch (Exception ex) + { + // 可以记录日志或者处理异常 + Console.WriteLine($"Error while scanning keys: {ex.Message}"); + } + + return matchingKeys; + } + + + /// + /// 模糊查询所有匹配的键的数量 + /// + /// Redis 服务器实例 + /// 匹配的模式(支持通配符) + /// 匹配的键的数量 + public static int ScanKeysCount(this IServer server, string pattern, int database = -1) + { + int count = 0; + long cursor = 0; // 游标,用于记录扫描进度 + + do + { + // 使用 Keys 方法进行分页查询 + var keys = server.Keys(database: database, cursor: cursor, pattern: pattern, pageSize: 1000).ToArray(); + + // 累计匹配到的键的数量 + count += keys.Length; + + // 如果还有更多键,则获取新的游标;否则,循环终止 + cursor = keys.Length == 1000 ? 1 : 0; + + } while (cursor != 0); + + return count; + } + + /// + /// 异步模糊查询所有匹配的键的数量 + /// + /// Redis 服务器实例 + /// 匹配的模式(支持通配符) + /// 每次扫描的页大小 + /// 数据库编号,默认为 -1 表示当前数据库 + /// 匹配的键的数量 + public static async Task ScanKeysCountAsync(this IServer server, string pattern, int pageSize = 1000, int database = -1) + { + int count = 0; + + // 异步遍历 KeysAsync + await foreach (var key in server.KeysAsync(database: database, pattern: pattern, pageSize: pageSize)) + { + count++; + } + + return count; + } + + + } +} diff --git a/Utile/HuanMeng.DotNetCore/Redis/RedisHelper.cs b/Utile/HuanMeng.DotNetCore/Redis/RedisHelper.cs new file mode 100644 index 0000000..76c340c --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Redis/RedisHelper.cs @@ -0,0 +1,39 @@ +using StackExchange.Redis; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.Redis; + +/// +/// redis帮助类 +/// +public class RedisHelper +{ + public RedisHelper(IConnectionMultiplexer redis) + { + _redis = redis; + } + + private readonly IConnectionMultiplexer _redis; + + public async Task GetValue(string key) + { + var db = _redis.GetDatabase(); + return await db.StringGetAsync(key); + } + /// + /// + /// + /// + /// + public IDatabase GetRedis() + { + return _redis.GetDatabase(); + } + + +} diff --git a/Utile/HuanMeng.DotNetCore/SwaggerUtile/LowercaseParameterFilter.cs b/Utile/HuanMeng.DotNetCore/SwaggerUtile/LowercaseParameterFilter.cs new file mode 100644 index 0000000..4e2df45 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/SwaggerUtile/LowercaseParameterFilter.cs @@ -0,0 +1,59 @@ +using Microsoft.OpenApi.Models; + +using Swashbuckle.AspNetCore.SwaggerGen; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.SwaggerUtile +{ + /// + /// 自定义参数过滤器 + /// + public class LowercaseParameterFilter : IParameterFilter + { + /// + /// + /// + /// + /// + public void Apply(OpenApiParameter parameter, ParameterFilterContext context) + { + // 将参数名称改为小写开头 + parameter.Name = Char.ToLower(parameter.Name[0]) + parameter.Name.Substring(1); + } + } + + /// + /// 自定义参数过滤器 + /// + public class LowercaseRequestFilter : IRequestBodyFilter + { + public void Apply(OpenApiRequestBody requestBody, RequestBodyFilterContext context) + { + + if (requestBody.Content != null) + { + foreach (var mediaType in requestBody.Content.Values) + { + if (mediaType.Schema?.Properties != null) + { + var propertiesToRename = new Dictionary(mediaType.Schema.Properties); + // 清空旧的属性 + mediaType.Schema.Properties.Clear(); + + foreach (var property in propertiesToRename) + { + // 创建新的属性,并将名称改为小写开头 + var newPropertyName = Char.ToLower(property.Key[0]) + property.Key.Substring(1); + mediaType.Schema.Properties.Add(newPropertyName, property.Value); + } + } + } + } + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/TextCensor/CheckTextVerification.cs b/Utile/HuanMeng.DotNetCore/TextCensor/CheckTextVerification.cs new file mode 100644 index 0000000..f99e78c --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/TextCensor/CheckTextVerification.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.TextCensor +{ + /// + /// 验证字符串是否违规 + /// + //[Obsolete] + //public static class CheckTextVerification + //{ + // static HashSet ShieldStr = new HashSet(); + + // static List ShieldListStr = new List(); + // static string[] ShieldString = new string[0]; + + + + // static CheckTextVerification() + // { + // var ckPath = Path.GetFullPath("I:\\test\\PrayForBlessings\\PrayForBlessings\\ciku/"); + // var filePath = Directory.EnumerateFiles(ckPath); + // foreach (var item in filePath) + // { + // CheckTextVerification.AddShieldString(item); + // } + // // + // } + + // /// + // /// + // /// + // /// + // /// + // public static void AddShieldString(string path) + // { + + // if (!File.Exists(path)) + // { + // throw new Exception("文件不存在"); + // } + // HashSet strings = new HashSet(); + + // using (StreamReader reader = new StreamReader(path, UnicodeEncoding.UTF8)) + // { + + // while (reader.Peek() > 0) + // { + // var tempStr = (reader.ReadLine() ?? ""); + // //string result = Regex.Replace(tempStr, pattern, ""); + // if (!string.IsNullOrEmpty(tempStr)) + // { + // var tempStringToLower = tempStr.ToLower().Split(new char[] { '、', ',' }); + // string[] filteredArrayToLower = tempStringToLower.Where(s => !string.IsNullOrEmpty(s)).ToArray(); + // strings.UnionWith(filteredArrayToLower); + // } + // } + // ShieldStr.UnionWith(strings); + // ShieldListStr.AddRange(ShieldStr); + // ShieldString = ShieldStr.ToArray(); + // Console.WriteLine(string.Format($"[{Path.GetFileName(path)}]加载完毕,总共加载屏蔽字行数:{ShieldStr.Count}")); + // } + // } + // /// + // /// + // /// + // /// + // /// + // public static bool VerifyTxt(string sourceTxt) + // { + // if (!string.IsNullOrEmpty(sourceTxt)) + // { + // //先去掉空格,特殊字符 + // string cleanedText = CleanedTextString(sourceTxt); + // foreach (var item in ShieldStr) + // { + // if (cleanedText.Contains(item)) + // { + // return false; + // } + // } + // } + // return true; + // } + // /// + // /// + // /// + // /// + // /// + // public static bool VerifyTxtList(string sourceTxt) + // { + // if (!string.IsNullOrEmpty(sourceTxt)) + // { + // //先去掉空格,特殊字符 + // string cleanedText = CleanedTextString(sourceTxt); + // foreach (var item in ShieldListStr) + // { + // if (cleanedText.Contains(item)) + // { + // return false;//2.56 + // } + // } + // } + // return true; + // } + // private static string replaceString = " ,.。,@*12345690_-"; + + // /// + // /// + // /// + // /// + // /// + // private static string CleanedTextString(string sourceTxt) + // { + // string cleanedText = sourceTxt.ToLower() + // .Replace(" ", "") + // .Replace(",", "") + // .Replace(".", "") + // .Replace("。", "") + // .Replace(",", "") + // .Replace("@", "") + // .Replace("-", "") + // .Replace("*", "") + // .Replace("1", "") + // .Replace("2", "") + // .Replace("3", "") + // .Replace("4", "") + // .Replace("5", "") + // .Replace("6", "") + // .Replace("9", "") + // .Replace("0", "") + // .Replace("_", ""); + // return cleanedText; + // } + + // public static bool VerifyTxtString(string sourceTxt) + // { + // if (!string.IsNullOrEmpty(sourceTxt)) + // { + // //先去掉空格,特殊字符 + // string cleanedText = CleanedTextString(sourceTxt); + + // foreach (var item in ShieldString) + // { + // if (cleanedText.Contains(item)) + // { + // return false;//2.56 + // } + // } + // } + // return true; + // } + //} +} diff --git a/Utile/HuanMeng.DotNetCore/TextCensor/ITextCensor.cs b/Utile/HuanMeng.DotNetCore/TextCensor/ITextCensor.cs new file mode 100644 index 0000000..63b7e1a --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/TextCensor/ITextCensor.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.TextCensor +{ + /// + /// 文本审核接口 + /// + public interface ITextCensor + { + /// + /// 文本审核 + /// + /// + /// + bool TextCensor(string text); + + /// + /// 文本审核 + /// + /// + /// + Task TextCensorAsync(string text); + } +} diff --git a/Utile/HuanMeng.DotNetCore/TextCensor/SensitiveWord/SensitiveWordFilter.cs b/Utile/HuanMeng.DotNetCore/TextCensor/SensitiveWord/SensitiveWordFilter.cs new file mode 100644 index 0000000..7994def --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/TextCensor/SensitiveWord/SensitiveWordFilter.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.TextCensor.SensitiveWord +{ + public class SensitiveWordFilter : ITextCensor + { + /// + /// 定义Trie树节点 + /// + private class TrieNode + { + /// + /// 标记是否是一个敏感词的结尾 + /// + public bool IsEnd { get; set; } + /// + /// 存储子节点 + /// + public Dictionary Children { get; set; } + /// + /// + /// + //public FrozenDictionary fChildren { get; set; } + public TrieNode() + { + IsEnd = false; + Children = new Dictionary(); + } + } + + /// + /// 根节点 + /// + private TrieNode Root { get; set; } + public SensitiveWordFilter() + { + Root = new TrieNode(); + } + /// + /// 添加敏感词到Trie树中 + /// + /// + public void AddSensitiveWord(string word) + { + TrieNode currentNode = Root; + word = CleanText(word); + foreach (char c in word.ToLower()) + { + // 如果当前字符不存在于子节点中,则添加 + if (!currentNode.Children.ContainsKey(c)) + { + currentNode.Children[c] = new TrieNode(); + } + currentNode = currentNode.Children[c]; + } + currentNode.IsEnd = true; // 标记当前节点为敏感词结尾 + } + /// + /// 定义要移除的字符集合,包括空格 + /// + private static string replaceString = @"[ \.,。,@\-*12345690_]"; + /// + /// 清理文字 + /// + /// + /// + public string CleanText(string sourceTxt) + { + if (string.IsNullOrEmpty(sourceTxt)) + { + return string.Empty; + } + + // 使用正则表达式替换所有匹配的字符 + //string cleanedText = Regex.Replace(sourceTxt.ToLower(), replaceString, string.Empty); + string cleanedText = sourceTxt + .Replace(',', ' ') + .Replace('.', ' ') + .Replace('。', ' ') + .Replace(',', ' ') + .Replace('@', ' ') + .Replace('-', ' ') + .Replace('*', ' ') + .Replace("1", string.Empty) + .Replace("2", string.Empty) + .Replace("3", string.Empty) + .Replace("4", string.Empty) + .Replace("5", string.Empty) + .Replace("6", string.Empty) + .Replace("9", string.Empty) + .Replace("0", string.Empty) + .Replace("_", string.Empty) + .Replace(" ", string.Empty).ToLower(); + return cleanedText; + } + + /// + /// 判断文本中是否包含敏感词 + /// + /// + /// + public bool ContainsSensitiveWord(string text) + { + //过滤字符串 + text = CleanText(text); + for (int i = 0; i < text.Length; i++) + { + TrieNode currentNode = Root; + int j = i; + // 从当前位置开始匹配敏感词 + while (j < text.Length && currentNode.Children.ContainsKey(text[j])) + { + currentNode = currentNode.Children[text[j]]; + // 如果当前节点是敏感词结尾,返回true + if (currentNode.IsEnd) + { + return true; + } + j++; + } + } + return false; + } + + public bool TextCensor(string text) + { + return ContainsSensitiveWord(text); + } + + public Task TextCensorAsync(string text) + { + return Task.Run(() => + { + return ContainsSensitiveWord(text); + }); + + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/TextCensor/SensitiveWord/SensitiveWordFilterFrozen.cs b/Utile/HuanMeng.DotNetCore/TextCensor/SensitiveWord/SensitiveWordFilterFrozen.cs new file mode 100644 index 0000000..fcfd5d2 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/TextCensor/SensitiveWord/SensitiveWordFilterFrozen.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.TextCensor.SensitiveWord +{ + public class SensitiveWordFilterFrozen : ITextCensor + { + /// + /// 定义Trie树节点 + /// + private class TrieNode + { + /// + /// 标记是否是一个敏感词的结尾 + /// + public bool IsEnd { get; set; } + /// + /// 存储子节点 + /// + public FrozenDictionary Children { get; private set; } + + public TrieNode() + { + IsEnd = false; + Children = null; + } + + /// + /// 将子节点字典冻结为 FrozenDictionary + /// + public void FreezeChildren(Dictionary children) + { + Children = children.ToFrozenDictionary(); + } + } + + /// + /// 根节点 + /// + private TrieNode Root { get; set; } + + public SensitiveWordFilterFrozen() + { + Root = new TrieNode(); + } + + /// + /// 添加敏感词到Trie树中 + /// + /// + public void AddSensitiveWord(string word) + { + TrieNode currentNode = Root; + word = CleanText(word); + foreach (char c in word.ToLower()) + { + // 如果当前字符不存在于子节点中,则添加 + if (currentNode.Children == null || !currentNode.Children.ContainsKey(c)) + { + var children = currentNode.Children?.ToDictionary(kvp => kvp.Key, kvp => kvp.Value) ?? new Dictionary(); + children[c] = new TrieNode(); + currentNode.FreezeChildren(children); + } + currentNode = currentNode.Children[c]; + } + currentNode.IsEnd = true; // 标记当前节点为敏感词结尾 + } + + /// + /// 清理文字 + /// + /// + /// + public string CleanText(string sourceTxt) + { + if (string.IsNullOrEmpty(sourceTxt)) + { + return string.Empty; + } + + string cleanedText = sourceTxt + .Replace(',', ' ') + .Replace('.', ' ') + .Replace('。', ' ') + .Replace(',', ' ') + .Replace('@', ' ') + .Replace('-', ' ') + .Replace('*', ' ') + .Replace("1", string.Empty) + .Replace("2", string.Empty) + .Replace("3", string.Empty) + .Replace("4", string.Empty) + .Replace("5", string.Empty) + .Replace("6", string.Empty) + .Replace("9", string.Empty) + .Replace("0", string.Empty) + .Replace("_", string.Empty) + .Replace(" ", string.Empty).ToLower(); + return cleanedText; + } + + /// + /// 判断文本中是否包含敏感词 + /// + /// + /// + public bool ContainsSensitiveWord(string text) + { + //过滤字符串 + text = CleanText(text); + for (int i = 0; i < text.Length; i++) + { + TrieNode currentNode = Root; + int j = i; + // 从当前位置开始匹配敏感词 + while (j < text.Length && currentNode.Children != null && currentNode.Children.ContainsKey(text[j])) + { + currentNode = currentNode.Children[text[j]]; + // 如果当前节点是敏感词结尾,返回true + if (currentNode.IsEnd) + { + return true; + } + j++; + } + } + return false; + } + + public bool TextCensor(string text) + { + return ContainsSensitiveWord(text); + } + + public Task TextCensorAsync(string text) + { + return Task.Run(() => + { + return ContainsSensitiveWord(text); + }); + + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/TextCensor/TextCensorExtend.cs b/Utile/HuanMeng.DotNetCore/TextCensor/TextCensorExtend.cs new file mode 100644 index 0000000..f5e2254 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/TextCensor/TextCensorExtend.cs @@ -0,0 +1,122 @@ +using HuanMeng.DotNetCore.TextCensor.SensitiveWord; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Microsoft.Extensions.DependencyInjection; + +namespace HuanMeng.DotNetCore.TextCensor +{ + /// + /// + /// + public static class TextCensorExtend + { + + /// + /// 获取文本检测 + /// + /// + /// + public static ITextCensor GetITextCensor(string _dirPath) + { + + return GetSensitiveWordFilterFrozen(_dirPath) + //GetSensitiveWordFilter(_dirPath) + ; + } + + + /// + /// + /// + /// + /// + public static SensitiveWordFilter GetSensitiveWordFilter(string _dirPath) + { + SensitiveWordFilter sensitiveWordFilter = new SensitiveWordFilter(); + var ckPath = Path.GetFullPath(_dirPath); + var filePath = Directory.EnumerateFiles(ckPath); + foreach (var item in filePath) + { + AddShieldString(item, sensitiveWordFilter); + } + return sensitiveWordFilter; + } + + /// + /// + /// + /// + /// + public static SensitiveWordFilterFrozen GetSensitiveWordFilterFrozen(string _dirPath) + { + SensitiveWordFilterFrozen sensitiveWordFilter = new SensitiveWordFilterFrozen(); + var ckPath = Path.GetFullPath(_dirPath); + var filePath = Directory.EnumerateFiles(ckPath); + foreach (var item in filePath) + { + AddShieldString(item, sensitiveWordFilter); + } + return sensitiveWordFilter; + } + + /// + /// + /// + /// + /// + public static void AddShieldString(string path, SensitiveWordFilterFrozen sensitiveWordFilter) + { + + if (!File.Exists(path)) + { + throw new Exception("文件不存在"); + } + using (StreamReader reader = new StreamReader(path, UnicodeEncoding.UTF8)) + { + + while (reader.Peek() > 0) + { + + var tempStr = (reader.ReadLine() ?? ""); + if (!string.IsNullOrEmpty(tempStr)) + { + sensitiveWordFilter.AddSensitiveWord(tempStr); + + } + } + } + } + /// + /// + /// + /// + /// + public static void AddShieldString(string path, SensitiveWordFilter sensitiveWordFilter) + { + + if (!File.Exists(path)) + { + throw new Exception("文件不存在"); + } + using (StreamReader reader = new StreamReader(path, UnicodeEncoding.UTF8)) + { + + while (reader.Peek() > 0) + { + + var tempStr = (reader.ReadLine() ?? ""); + if (!string.IsNullOrEmpty(tempStr)) + { + sensitiveWordFilter.AddSensitiveWord(tempStr); + + } + } + } + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/Utility/AssemblyHelper/AssemblyInfo.cs b/Utile/HuanMeng.DotNetCore/Utility/AssemblyHelper/AssemblyInfo.cs new file mode 100644 index 0000000..e028cd2 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Utility/AssemblyHelper/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.Json.Serialization; + +namespace HuanMeng.DotNetCore.Utility.AssemblyHelper +{ + /// + /// 保存各种程序集信息属性的类。 + /// + [Serializable] + public class AssemblyInfo + { + /// + /// 获取或设置程序集的版本。 + /// + public string? Version { get; set; } + + /// + /// 获取或设置程序集的文件版本。 + /// + public string? FileVersion { get; set; } + + /// + /// 获取或设置程序集版本。 + /// + public string? AssemblyVersion { get; set; } + + /// + /// 获取或设置程序集的信息性版本。 + /// + public string? InformationalVersion { get; set; } + + ///// + ///// 获取或设置与程序集关联的公司名称。 + ///// + //public string Company { get; set; } + + ///// + ///// 获取或设置与程序集关联的产品名称。 + ///// + //public string Product { get; set; } + + /// + /// 获取或设置与程序集关联的版权信息。 + /// + public string? Copyright { get; set; } + + /// + /// 获取或设置程序集的描述信息。 + /// + public string? Description { get; set; } + } + +} diff --git a/Utile/HuanMeng.DotNetCore/Utility/AssemblyHelper/AssemblyInfoHelper.cs b/Utile/HuanMeng.DotNetCore/Utility/AssemblyHelper/AssemblyInfoHelper.cs new file mode 100644 index 0000000..28355a6 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Utility/AssemblyHelper/AssemblyInfoHelper.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace HuanMeng.DotNetCore.Utility.AssemblyHelper +{ + /// + /// 用于检索程序集信息的辅助类。 + /// + public static class AssemblyInfoHelper + { + /// + /// 从正在执行的程序集检索各种属性,并返回一个 AssemblyInfo 对象。 + /// + /// 包含程序集属性的 AssemblyInfo 对象。 + public static AssemblyInfo GetAssemblyInfo() + { + // 获取正在执行的程序集 + Assembly assembly = Assembly.GetExecutingAssembly(); + + // 创建并填充 AssemblyInfo 对象的相关属性 + var assemblyInfo = new AssemblyInfo + { + Version = assembly.GetName().Version.ToString(), + FileVersion = assembly.GetCustomAttributes().FirstOrDefault()?.Version ?? "", + AssemblyVersion = assembly.GetCustomAttributes().FirstOrDefault()?.Version ?? "", + InformationalVersion = assembly.GetCustomAttributes().FirstOrDefault()?.InformationalVersion ?? "", + //Company = assembly.GetCustomAttributes().FirstOrDefault()?.Company ?? "", + //Product = assembly.GetCustomAttributes().FirstOrDefault()?.Product ?? "", + Copyright = assembly.GetCustomAttributes().FirstOrDefault()?.Copyright ?? "", + Description = assembly.GetCustomAttributes().FirstOrDefault()?.Description ?? "" + }; + + return assemblyInfo; + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/Utility/DateTimeExtensions.cs b/Utile/HuanMeng.DotNetCore/Utility/DateTimeExtensions.cs new file mode 100644 index 0000000..72b700c --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Utility/DateTimeExtensions.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace HuanMeng.DotNetCore.Utility +{ + /// + /// 时间扩展 + /// + public static class DateTimeExtensions + { + /// + /// 获取时间戳,秒 + /// + /// + /// + public static long ToUnixTimestamp(this DateTime dateTime) + { + return (long)(dateTime.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalSeconds; + } + + /// + /// 获取是时间戳,毫秒 + /// + /// + /// + public static long ToUnixTimestampMilliseconds(this DateTime dateTime) + { + return (long)(dateTime.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalMilliseconds; + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/Utility/HttpContextExtensions.cs b/Utile/HuanMeng.DotNetCore/Utility/HttpContextExtensions.cs new file mode 100644 index 0000000..f67c3c6 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Utility/HttpContextExtensions.cs @@ -0,0 +1,64 @@ +using Microsoft.AspNetCore.Http; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.Utility +{ + /// + /// + /// + public static class HttpContextExtensions + { + /// + /// 获取IP地址 + /// + /// + /// + public static string GetClientIpAddress(this HttpContext context) + { + // 尝试从X-Forwarded-For头部中获取IP地址 + var forwardedFor = context.Request.Headers["X-Forwarded-For"].FirstOrDefault(); + if (!string.IsNullOrEmpty(forwardedFor)) + { + // 处理可能的多个IP地址,通常第一个是客户端的真实IP + var ipAddresses = forwardedFor.Split(','); + if (ipAddresses.Length > 0) + { + return ipAddresses[0].Trim(); + } + } + + // 如果X-Forwarded-For头部不存在,使用RemoteIpAddress + return context.Connection.RemoteIpAddress?.ToString(); + } + + /// + /// 从请求头中提取Authorization信息(JWT)。 + /// + /// 请求头字典。 + /// 如果包含有效的Authorization头,则返回JWT Token,否则返回null。 + public static string? GetAuthorization(this IHeaderDictionary headers) + { + // 尝试从请求头中获取Authorization字段 + if (headers.TryGetValue("Authorization", out var authHeaderObj)) + { + // 获取Authorization头的值并移除"Bearer "前缀 + var authHeader = authHeaderObj.ToString(); + + // 如果Authorization以"Bearer "开头,提取JWT Token + if (!string.IsNullOrEmpty(authHeader) && authHeader.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) + { + return authHeader.Substring(7).Trim(); // 直接返回JWT Token + } + } + + // 如果没有Authorization头或格式不正确,返回null + return null; + } + + } +} diff --git a/Utile/HuanMeng.DotNetCore/Utility/HttpRequestMessageExtensions.cs b/Utile/HuanMeng.DotNetCore/Utility/HttpRequestMessageExtensions.cs new file mode 100644 index 0000000..4976da0 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Utility/HttpRequestMessageExtensions.cs @@ -0,0 +1,28 @@ +using Newtonsoft.Json; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.Utility; + +/// +/// +/// +public static class HttpRequestMessageExtensions +{ + public static async Task ToJsonAsync(this HttpRequestMessage request) + { + var requestInfo = new + { + Method = request.Method.Method, + Url = request.RequestUri?.ToString(), + Headers = request.Headers, + Content = request.Content != null ? await request.Content.ReadAsStringAsync() : null + }; + + return JsonConvert.SerializeObject(requestInfo, Formatting.None); + } +} diff --git a/Utile/HuanMeng.DotNetCore/Utility/HttpResponseMessageExtensions.cs b/Utile/HuanMeng.DotNetCore/Utility/HttpResponseMessageExtensions.cs new file mode 100644 index 0000000..0f67a38 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Utility/HttpResponseMessageExtensions.cs @@ -0,0 +1,40 @@ +using Newtonsoft.Json; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.Utility; + +/// +/// +/// +public static class HttpResponseMessageExtensions +{ + /// + /// + /// + /// + /// + public static async Task ToJsonAsync(this HttpResponseMessage response) + { + var responseInfo = new + { + StatusCode = response.StatusCode, + ReasonPhrase = response.ReasonPhrase, + Headers = response.Headers, + Content = response.Content != null ? await response.Content.ReadAsStringAsync() : null, + RequestMessage = response.RequestMessage != null + ? new + { + Method = response.RequestMessage.Method.Method, + Url = response.RequestMessage.RequestUri.ToString() + } + : null + }; + + return JsonConvert.SerializeObject(responseInfo, Formatting.Indented); + } +} diff --git a/Utile/HuanMeng.DotNetCore/Utility/MD5Encryption.cs b/Utile/HuanMeng.DotNetCore/Utility/MD5Encryption.cs new file mode 100644 index 0000000..496aabd --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Utility/MD5Encryption.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.Utility +{ + /// + /// + /// + public static class MD5Encryption + { + /// + /// md5加密 + /// + /// + /// + public static string ComputeMD5Hash(string input) + { + // 创建一个 MD5 哈希算法的实例 + using (MD5 md5 = MD5.Create()) + { + // 将输入字符串转换为字节数组 + byte[] inputBytes = Encoding.UTF8.GetBytes(input); + + // 计算 MD5 哈希值 + byte[] hashBytes = md5.ComputeHash(inputBytes); + + // 将字节数组转换为十六进制字符串 + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < hashBytes.Length; i++) + { + sb.Append(hashBytes[i].ToString("x2")); + } + + // 返回哈希值字符串 + return sb.ToString(); + } + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/Utility/ObjectExtensions.cs b/Utile/HuanMeng.DotNetCore/Utility/ObjectExtensions.cs new file mode 100644 index 0000000..ff84f43 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Utility/ObjectExtensions.cs @@ -0,0 +1,168 @@ +using HuanMeng.DotNetCore.AttributeExtend; + +using System.Collections; +using System.Collections.Concurrent; +using System.Linq.Expressions; +using System.Reflection; + +namespace HuanMeng.DotNetCore.Utility; + + +/// +/// object转数据字典 +/// +public static class ObjectExtensions +{ + /// + /// 用于存储每种类型的属性访问器数组的线程安全缓存。 + /// + private static readonly ConcurrentDictionary PropertyCache = new(); + + /// + /// 缓存每个属性是否具有 ImagesAttribute 特性。 + /// + public static readonly ConcurrentDictionary _PropertyCache = new(); + + /// + /// 判断对象是否为原始类型或字符串类型。 + /// + /// 要检查的对象。 + /// 如果对象是原始类型或字符串,返回 true;否则返回 false。 + public static bool IsPrimitiveType(object obj) => + obj is not null && (obj.GetType().IsPrimitive || obj is string or ValueType); + + /// + /// 判断对象是否为集合类型(不包括字符串)。 + /// + /// 要检查的对象。 + /// 如果对象是集合类型(但不是字符串),返回 true;否则返回 false。 + public static bool IsCollectionType(object obj) => obj is IEnumerable && obj is not string; + + /// + /// 根据对象类型,将对象转换为字典或列表格式,支持可选的路径前缀。 + /// + /// 要转换的对象。 + /// 属性路径的可选前缀。 + /// 对象的字典或列表表示形式。 + public static object ToDictionaryOrList(this object obj, bool isEnumerable, string prefix = "", Func? imageFunc = null, Func? languageFunc = null) + { + if (obj == null) return null; + + return obj switch + { + _ when IsPrimitiveType(obj) => obj, + IEnumerable enumerable => TransformCollection(enumerable, prefix, imageFunc, languageFunc), + _ => TransformObject(obj, isEnumerable, prefix, imageFunc, languageFunc) + }; + } + + /// + /// 将集合对象转换为包含转换项的列表,每个项保留其路径前缀。 + /// + /// 要转换的集合。 + /// 集合中每个属性路径的前缀。 + /// 转换后的项列表。 + private static List TransformCollection(IEnumerable enumerable, string prefix = "", Func? imageFunc = null, Func? languageFunc = null) + { + var list = new List(enumerable is ICollection collection ? collection.Count : 10); + int index = 0; + foreach (var item in enumerable) + { + list.Add(ToDictionaryOrList(item, true, $"{prefix}.[{index}]", imageFunc, languageFunc)); // 为集合中每个项添加路径 + index++; + } + return list; + } + + /// + /// 将对象的属性转换为带有路径前缀的字典,并应用前缀规则。 + /// + /// 要转换的对象。 + /// 每个属性路径的前缀。 + /// 包含属性名和属性值的字典。 + private static Dictionary TransformObject(object obj, bool isEnumerable, string prefix = "", Func? imageFunc = null, Func? languageFunc = null) + { + if (obj == null) + { + return null; + } + var type = obj.GetType(); + var accessors = PropertyCache.GetOrAdd(type, CreatePropertyAccessors); + var keyValuePairs = new Dictionary(accessors.Length); + + foreach (var accessor in accessors) + { + var propertyPath = $"{prefix}.{accessor.PropertyName}"; // 构建完整的属性路径 + + // 使用访问器获取属性值 + var propertyValue = accessor.Getter(obj); + + // 如果属性是字符串,在其值前添加 "test" + if (propertyValue is string stringValue) + { + if (stringValue == null) + { + keyValuePairs[accessor.PropertyName] = ""; + continue; + } + if (!string.IsNullOrEmpty(stringValue) && languageFunc != null) + { + stringValue = languageFunc?.Invoke(stringValue, propertyPath, accessor.PropertyName, isEnumerable) ?? ""; + } + keyValuePairs[accessor.PropertyName] = stringValue; + continue; + } + + // 如果属性具有 ImagesAttribute,在其值前添加 "image" + // 否则,如果是集合类型,则递归转换 + keyValuePairs[accessor.PropertyName] = accessor.HasImagesAttribute + ? imageFunc?.Invoke((int)propertyValue) ?? "" + : ToDictionaryOrList(propertyValue, isEnumerable, propertyPath, imageFunc, languageFunc); // IsCollectionType(propertyValue) ?: propertyValue; + } + + return keyValuePairs; + } + + /// + /// 为给定类型创建属性访问器数组。 + /// + /// 要创建属性访问器的类型。 + /// 属性访问器数组。 + private static PropertyAccessor[] CreatePropertyAccessors(Type type) + { + var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); + return properties.Select(property => + { + // 创建用于访问属性值的委托 + var getter = CreatePropertyGetter(type, property); + // 检查属性是否具有 ImagesAttribute,并将结果存储在缓存中 + var isImagesAttribute = _PropertyCache.GetOrAdd(property, p => p.GetCustomAttribute() != null); + return new PropertyAccessor(property.Name, getter, isImagesAttribute); + }).ToArray(); + } + + + + private static Func CreatePropertyGetter(Type type, PropertyInfo property) + { + var parameter = Expression.Parameter(typeof(object), "obj"); + var castParameter = Expression.Convert(parameter, type); + var propertyAccess = Expression.Property(castParameter, property); + var convertPropertyAccess = Expression.Convert(propertyAccess, typeof(object)); + return Expression.Lambda>(convertPropertyAccess, parameter).Compile(); + } + + private class PropertyAccessor + { + public string PropertyName { get; } + public Func Getter { get; } + public bool HasImagesAttribute { get; } + + public PropertyAccessor(string propertyName, Func getter, bool hasImagesAttribute) + { + PropertyName = propertyName; + Getter = getter; + HasImagesAttribute = hasImagesAttribute; + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/Utility/OtherExtensions.cs b/Utile/HuanMeng.DotNetCore/Utility/OtherExtensions.cs new file mode 100644 index 0000000..06338e4 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Utility/OtherExtensions.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.Utility +{ + /// + /// 其它扩展类 + /// + public static class OtherExtensions + { + /// + /// 验证身份证号是否正确 + /// + /// + /// + + public static bool ValidateIDCard(string idNumber) + { + if (string.IsNullOrEmpty(idNumber)) + { + return false; + } + + // 验证长度 + if (idNumber.Length != 18) + { + return false; + } + + // 验证格式 + Regex regex = new Regex(@"^\d{17}(\d|X)$"); + if (!regex.IsMatch(idNumber)) + { + return false; + } + + // 验证校验码 + return ValidateCheckDigit(idNumber); + } + /// + /// 验证校验码 + /// + /// + /// + + private static bool ValidateCheckDigit(string idNumber) + { + // 加权因子 + int[] weights = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 }; + // 校验码 + char[] checkDigits = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' }; + + int sum = 0; + for (int i = 0; i < 17; i++) + { + sum += (idNumber[i] - '0') * weights[i]; + } + + int mod = sum % 11; + return idNumber[17] == checkDigits[mod]; + } + + /// + /// 根据身份证号计算年龄、性别、生日 + /// + /// 身份证号 + /// + public static (bool verify, int age, string sex, string birthday) GetIDCardBirthdayAgeSex(string identityCard) + { + var birthday = ""; + var age = 0; + var sex = ""; + if (string.IsNullOrEmpty(identityCard)) + { + return (false, 0, "", ""); + } + else + { + if (identityCard.Length != 15 && identityCard.Length != 18)//身份证号码只能为15位或18位其它不合法 + { + return (false, 0, "", ""); + } + } + + birthday = ""; + string strSex = string.Empty; + if (identityCard.Length == 18)//处理18位的身份证号码从号码中得到生日和性别代码 + { + birthday = identityCard.Substring(6, 4) + "-" + identityCard.Substring(10, 2) + "-" + identityCard.Substring(12, 2); + strSex = identityCard.Substring(14, 3); + } + if (identityCard.Length == 15) + { + birthday = "19" + identityCard.Substring(6, 2) + "-" + identityCard.Substring(8, 2) + "-" + identityCard.Substring(10, 2); + strSex = identityCard.Substring(12, 3); + } + + age = CalculateAge(birthday);//根据生日计算年龄 + + if (int.Parse(strSex) % 2 == 0)//性别代码为偶数是女性奇数为男性 + { + sex = "女"; + } + else + { + sex = "男"; + } + return (true, age, sex, birthday); + } + + /// + /// 根据出生日期,计算精确的年龄 + /// + /// 生日 + /// + public static int CalculateAge(string birthDay) + { + DateTime birthDate = DateTime.Parse(birthDay); + DateTime nowDateTime = DateTime.Now; + int age = nowDateTime.Year - birthDate.Year; + //再考虑月、天的因素 + if (nowDateTime.Month < birthDate.Month || (nowDateTime.Month == birthDate.Month && nowDateTime.Day < birthDate.Day)) + { + age--; + } + return age; + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/Utility/PhoneNumberValidator.cs b/Utile/HuanMeng.DotNetCore/Utility/PhoneNumberValidator.cs new file mode 100644 index 0000000..af12a12 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Utility/PhoneNumberValidator.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; + +namespace HuanMeng.DotNetCore.Utility; +/// +/// 手机号 +/// +public class PhoneNumberValidator +{ + // 正则表达式用于匹配手机号码。可以根据需要调整以适应不同的国家或地区。 + private static readonly Regex phoneNumberRegex = new Regex(@"^(1[3-9]\d{9})$"); + + public static bool IsPhoneNumber(string input) + { + if (string.IsNullOrWhiteSpace(input)) + { + return false; + } + + return phoneNumberRegex.IsMatch(input); + } +} + diff --git a/Utile/HuanMeng.DotNetCore/Utility/StringExtend.cs b/Utile/HuanMeng.DotNetCore/Utility/StringExtend.cs new file mode 100644 index 0000000..14782ef --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/Utility/StringExtend.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.Utility; + +/// +/// 字符串扩展 +/// +public static class StringExtend +{ + /// + /// 判断字符串是否包含中文字符(使用字符遍历) + /// + /// 需要检查的字符串 + /// 如果包含中文字符,则返回 true;否则返回 false + public static bool ContainsChineseOptimized(this string input) + { + if (string.IsNullOrEmpty(input)) + { + return false; + } + + foreach (char c in input) + { + if (c >= '\u4e00' && c <= '\u9fa5') + { + return true; + } + } + return false; + } + +} diff --git a/Utile/HuanMeng.DotNetCore/WeChat/MiniProgram.cs b/Utile/HuanMeng.DotNetCore/WeChat/MiniProgram.cs new file mode 100644 index 0000000..a3b5328 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/WeChat/MiniProgram.cs @@ -0,0 +1,148 @@ +using Newtonsoft.Json; + +using StackExchange.Redis; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.WeChat +{ + /// + /// 小程序帮助类 + /// + /// + /// + /// + /// + public class MiniProgram(string appId, string secret, IDatabase database, IHttpClientFactory? _httpClientFactory) + { + public string AppId { get; set; } = appId; + string key = $"WeChat:{appId}"; + // Method to get user's OpenID + public async Task<(string openId, string unionid, string session_key)> GetOpenid(string code) + { + string url = $"https://api.weixin.qq.com/sns/jscode2session?appid={appId}&secret={secret}&js_code={code}&grant_type=authorization_code"; + var resUserInfo = await GetCurlData(url); + + if (resUserInfo.ContainsKey("errcode")) + { + return (null, null, null); + } + + string openid = resUserInfo.GetValueOrDefault("openid")?.ToString() ?? ""; + string unionid = resUserInfo.GetValueOrDefault("unionid")?.ToString() ?? ""; + string session_key = resUserInfo.GetValueOrDefault("session_key")?.ToString() ?? ""; + + return new(openid, unionid, session_key); + + } + + + // Get user info based on access token and openid + public async Task GetUserInfoAsync(string openid) + { + var accessToken = await GetAccessToken(); + string url = $"https://api.weixin.qq.com/sns/userinfo?access_token={accessToken}&openid={openid}&lang=zh_CN"; + var response = await GetCurlData(url); + + return response; + } + + public async Task GetAccessToken() + { + var accessTokenInfo = GetConfig(); + + if (accessTokenInfo != null) + { + return accessTokenInfo?.Access_token; + } + else + { + string url = $"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appId}&secret={secret}"; + var resAccessToken = await GetCurlData(url); + if (resAccessToken.ContainsKey("errcode")) + { + throw new Exception("获取微信token失败"); + } + + string accessToken = resAccessToken["access_token"].ToString(); + int expiresIn = Convert.ToInt32(resAccessToken["expires_in"]); + long accessTokenTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds() + expiresIn; + + var data = new AccessToken(accessToken, accessTokenTime); + SetConfig(data); + return accessToken; + } + } + + // Helper method for GET requests + private async Task> GetCurlData(string url) + { + using HttpClient client = _httpClientFactory.CreateClient(); + var response = await client.GetStringAsync(url); + return JsonConvert.DeserializeObject>(response); + } + + // Helper method for POST requests + private async Task> PostCurlData(string url, object data) + { + using HttpClient client = _httpClientFactory.CreateClient(); + var json = JsonConvert.SerializeObject(data); + var content = new StringContent(json, Encoding.UTF8, "application/json"); + var response = await client.PostAsync(url, content); + var result = await response.Content.ReadAsStringAsync(); + return JsonConvert.DeserializeObject>(result); + } + + // Helper method for HTTP POST data + private async Task HttpPostData(string url, object data) + { + using HttpClient client = _httpClientFactory.CreateClient(); + var json = JsonConvert.SerializeObject(data); + var content = new StringContent(json, Encoding.UTF8, "application/json"); + var response = await client.PostAsync(url, content); + return await response.Content.ReadAsStringAsync(); + } + + private AccessToken? GetConfig() + { + + var json = database.StringGet(key); + if (!string.IsNullOrEmpty(json)) + { + return JsonConvert.DeserializeObject(json); + } + return null; + } + + private void SetConfig(AccessToken access) + { + var outTime = new TimeSpan(0, 0, 7000); + database.StringSet(key, JsonConvert.SerializeObject(access), outTime); + } + + } + + /// + /// + /// + public class AccessToken + { + public string? Access_token { get; } + public long Access_token_time { get; } + + public AccessToken(string? access_token, long access_token_time) + { + Access_token = access_token; + Access_token_time = access_token_time; + } + public AccessToken() + { + + } + } +} diff --git a/Utile/HuanMeng.DotNetCore/WeChat/WXBizDataCrypt.cs b/Utile/HuanMeng.DotNetCore/WeChat/WXBizDataCrypt.cs new file mode 100644 index 0000000..7c21252 --- /dev/null +++ b/Utile/HuanMeng.DotNetCore/WeChat/WXBizDataCrypt.cs @@ -0,0 +1,124 @@ +using System; +using System.IO; +using System.Security.Cryptography; +using System.Text; + +using Newtonsoft.Json.Linq; + +namespace HuanMeng.DotNetCore.WeChat +{ + + /// + /// + /// + public class WXBizDataCrypt + { + private string appId; + private string sessionKey; + + /// + /// 构造函数 + /// + /// 小程序的 appId + /// 用户在小程序登录后获取的会话密钥 + public WXBizDataCrypt(string appId, string sessionKey) + { + this.appId = appId; + this.sessionKey = sessionKey; + } + + /// + /// 检验数据的真实性,并且获取解密后的明文 + /// + /// 加密的用户数据 + /// 与用户数据一同返回的初始向量 + /// 解密后的原文 + /// 成功0,失败返回对应的错误码 + public int DecryptData(string encryptedData, string iv, out string data) + { + data = null; + + // 检查 sessionKey 长度 + if (sessionKey.Length != 24) + { + return ErrorCode.IllegalAesKey; + } + + // 检查 iv 长度 + if (iv.Length != 24) + { + return ErrorCode.IllegalIv; + } + + try + { + byte[] aesKey = Convert.FromBase64String(sessionKey); + byte[] aesIV = Convert.FromBase64String(iv); + byte[] aesCipher = Convert.FromBase64String(encryptedData); + + using (Aes aesAlg = Aes.Create()) + { + aesAlg.Key = aesKey; + aesAlg.IV = aesIV; + aesAlg.Mode = CipherMode.CBC; + aesAlg.Padding = PaddingMode.PKCS7; + + using (ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV)) + { + using (MemoryStream msDecrypt = new MemoryStream(aesCipher)) + { + using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) + { + using (StreamReader srDecrypt = new StreamReader(csDecrypt)) + { + // 解密后的明文 + data = srDecrypt.ReadToEnd(); + } + } + } + } + } + + JObject dataObj = JObject.Parse(data); + + // 检查 appId + if (dataObj["watermark"]["appid"].ToString() != this.appId) + { + return ErrorCode.IllegalBuffer; + } + + return ErrorCode.OK; + } + catch + { + return ErrorCode.IllegalBuffer; + } + } + } + + public static class ErrorCode + { + + public const int OK = 0; + public const int IllegalAesKey = -41001; + public const int IllegalIv = -41002; + public const int IllegalBuffer = -41003; + } + + public class WXBizDataCryptModel + { + public WXBizDataCryptModel() { } + /// + /// + /// + public string? EncryptedData; + /// + /// + /// + public string? Iv; + + + public int UserId { get; set; } + } + +}