From e62153289fd13c5588518a5ee7cfc05c799df6b9 Mon Sep 17 00:00:00 2001 From: tk Date: Fri, 27 Jun 2025 19:19:35 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E2=9C=A8=20=E8=87=AA=E5=8A=A9=E5=85=85?= =?UTF-8?q?=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/res/NetAdmin.Fields.ln | 12 +- assets/res/NetAdmin.Statements.ln | 1 + assets/seed-data/Sys_Config.json | 5 +- assets/seed-data/Sys_Job.json | 25 +- assets/seed-data/Sys_Menu.json | 11 + assets/seed-data/Sys_RoleApi.json | 24 ++ assets/seed-data/Sys_RoleMenu.json | 4 + assets/seed-data/Sys_User.json | 8 + assets/seed-data/Sys_UserProfile.json | 4 + assets/seed-data/Sys_UserRole.json | 4 + assets/seed-data/Sys_UserWallet.json | 5 + .../DbMaps/Dependency/Fields/IFieldOwner.cs | 6 +- .../NetAdmin.Domain/DbMaps/Sys/Sys_Config.cs | 24 ++ .../DbMaps/Sys/Sys_DepositOrder.cs | 115 ++++++ .../DbMaps/Sys/Sys_DocCatalog.cs | 6 +- .../DbMaps/Sys/Sys_DocContent.cs | 6 +- .../DbMaps/Sys/Sys_JobRecord.cs | 2 +- .../DbMaps/Sys/Sys_LoginLog.cs | 6 +- .../DbMaps/Sys/Sys_RequestLog.cs | 6 +- .../NetAdmin.Domain/DbMaps/Sys/Sys_User.cs | 4 +- .../DbMaps/Sys/Sys_UserWallet.cs | 6 +- .../DbMaps/Sys/Sys_WalletTrade.cs | 6 +- .../Dto/Sys/Config/CreateConfigReq.cs | 15 + .../Dto/Sys/Config/QueryConfigRsp.cs | 12 + .../Sys/DepositOrder/CreateDepositOrderReq.cs | 36 ++ .../Sys/DepositOrder/EditDepositOrderReq.cs | 15 + .../Sys/DepositOrder/GetDepositConfigRsp.cs | 19 + .../Dto/Sys/DepositOrder/PayConfirmReq.cs | 11 + .../Sys/DepositOrder/QueryDepositOrderReq.cs | 11 + .../Sys/DepositOrder/QueryDepositOrderRsp.cs | 73 ++++ .../DepositOrder/ReceivedConfirmationReq.cs | 12 + .../Dto/Sys/User/ExportUserRsp.cs | 8 +- .../Dependency/ApiClientOptions.cs | 5 + .../Configuration/Options/TronScanOptions.cs | 8 + .../NetAdmin.Infrastructure/Constant/Chars.cs | 2 + .../Constant/Numbers.cs | 1 + .../Enums/DepositOrderStatues.cs | 38 ++ .../Enums/PaymentModes.cs | 30 ++ .../Enums/TradeDirections.cs | 4 +- .../Rpc/TronScan/ITronScanClient.cs | 43 +++ .../Rpc/TronScan/NormalAddressInfo.cs | 15 + .../Rpc/TronScan/TokenInfo.cs | 57 +++ .../Rpc/TronScan/TokenTransferInfo.cs | 116 ++++++ .../Rpc/TronScan/TransfersRsp.cs | 28 ++ .../Rpc/TronScan/TriggerInfo.cs | 34 ++ .../Modules/Sys/IDepositOrderModule.cs | 28 ++ .../Sys/Dependency/IDepositOrderService.cs | 6 + .../Services/Sys/DepositOrderService.cs | 235 ++++++++++++ .../Sys/Dependency/IDepositOrderCache.cs | 6 + .../Sys/DepositOrderCache.cs | 86 +++++ .../Controllers/Sys/DepositOrderController.cs | 122 ++++++ .../Extensions/ServiceCollectionExtensions.cs | 26 ++ .../Utils/SqlAuditor.cs | 2 +- .../Filters/JwtHandler.cs | 2 +- .../YourSolution.AdmServer.Host/Startup.cs | 1 + .../AdmSettings.json | 5 + src/frontend/admin/package.json | 1 + .../admin/src/api/sys/depositorder.js | 117 ++++++ .../admin/src/components/scTable/index.vue | 2 +- src/frontend/admin/src/config/table.js | 2 + src/frontend/admin/src/locales/lang/en.js | 30 +- src/frontend/admin/src/locales/lang/zh-cn.js | 30 +- .../admin/src/views/sys/config/index.vue | 7 +- .../admin/src/views/sys/config/save.vue | 15 +- .../admin/src/views/sys/dept/save.vue | 2 +- .../admin/src/views/sys/dic/list/save.vue | 6 +- src/frontend/admin/src/views/sys/dic/save.vue | 2 +- .../admin/src/views/sys/doc/list/save.vue | 6 +- src/frontend/admin/src/views/sys/doc/save.vue | 2 +- .../admin/src/views/sys/job/all/save.vue | 2 +- .../admin/src/views/sys/job/record/save.vue | 2 +- .../admin/src/views/sys/menu/save.vue | 2 +- src/frontend/admin/src/views/sys/msg/save.vue | 2 +- .../admin/src/views/sys/order/index.vue | 351 ++++++++++++++++++ .../admin/src/views/sys/order/save.vue | 197 ++++++++++ .../admin/src/views/sys/role/save.vue | 2 +- .../admin/src/views/sys/trade/index.vue | 2 +- .../admin/src/views/sys/trade/save.vue | 8 +- .../admin/src/views/sys/user/index.vue | 6 +- .../admin/src/views/sys/user/save.vue | 10 +- .../admin/src/views/sys/wallet/index.vue | 6 +- .../admin/src/views/sys/wallet/save.vue | 6 +- .../admin/src/views/sys/wallet/trade.vue | 2 +- 83 files changed, 2112 insertions(+), 110 deletions(-) create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DepositOrder.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/CreateDepositOrderReq.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/EditDepositOrderReq.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/GetDepositConfigRsp.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/PayConfirmReq.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/QueryDepositOrderReq.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/QueryDepositOrderRsp.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/ReceivedConfirmationReq.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Infrastructure/Configuration/Options/TronScanOptions.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Infrastructure/Enums/DepositOrderStatues.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Infrastructure/Enums/PaymentModes.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/ITronScanClient.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/NormalAddressInfo.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/TokenInfo.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/TokenTransferInfo.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/TransfersRsp.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/TriggerInfo.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Application/Modules/Sys/IDepositOrderModule.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IDepositOrderService.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DepositOrderService.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/Dependency/IDepositOrderCache.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/DepositOrderCache.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Host/Controllers/Sys/DepositOrderController.cs create mode 100644 src/frontend/admin/src/api/sys/depositorder.js create mode 100644 src/frontend/admin/src/views/sys/order/index.vue create mode 100644 src/frontend/admin/src/views/sys/order/save.vue diff --git a/assets/res/NetAdmin.Fields.ln b/assets/res/NetAdmin.Fields.ln index ada9421b..76111069 100644 --- a/assets/res/NetAdmin.Fields.ln +++ b/assets/res/NetAdmin.Fields.ln @@ -1,3 +1,4 @@ +USDT 上次执行时间 上次执行状态 上次执行耗时 @@ -19,6 +20,8 @@ 作业状态 信息 倒序排序 +充值成功 +充值订单导出 全部数据 公告 共青团员 @@ -26,6 +29,7 @@ 创建时间 初中 删除 +到账确认中 包含 博士 博士后 @@ -53,10 +57,11 @@ 已校验 已读 并且 +微信支付 成功 或者 -所属角色 -所属部门 +归属角色 +归属部门 手机 手机号 执行耗时 @@ -71,6 +76,8 @@ 接口路径 插入种子数据 操作系统 +支付宝 +支付超时 支出 收入 数据范围 @@ -114,6 +121,7 @@ 站内信导出 等于 等待发送 +等待支付 管理员充值 管理员扣费 管理模块 diff --git a/assets/res/NetAdmin.Statements.ln b/assets/res/NetAdmin.Statements.ln index 295cd5b2..fa0a078f 100644 --- a/assets/res/NetAdmin.Statements.ln +++ b/assets/res/NetAdmin.Statements.ln @@ -33,6 +33,7 @@ XML注释文件不存在 手机号码不能为空 接口编码不存在 支付宝账号 +支付方式不正确 政治面貌不正确 数据库同步开始 数据库服务器时钟偏移 diff --git a/assets/seed-data/Sys_Config.json b/assets/seed-data/Sys_Config.json index 68a2abd8..e5cbb0d0 100644 --- a/assets/seed-data/Sys_Config.json +++ b/assets/seed-data/Sys_Config.json @@ -1,8 +1,11 @@ [ { + "CnyToPointRate": 100, "Enabled": true, + "Trc20ReceiptAddress": "TMTByCrcZkY7o8YMax1pXiYV5SUQBZEnCu", + "UsdToPointRate": 700, "UserRegisterConfirm": false, "UserRegisterDeptId": 372119301627909, - "UserRegisterRoleId": 371729946431493 + "UserRegisterRoleId": 371729946431493, } ] \ No newline at end of file diff --git a/assets/seed-data/Sys_Job.json b/assets/seed-data/Sys_Job.json index 6458c34c..084e1285 100644 --- a/assets/seed-data/Sys_Job.json +++ b/assets/seed-data/Sys_Job.json @@ -2,12 +2,21 @@ { "Enabled": true, "ExecutionCron": "0 * * * * ?", - "HttpMethod": 3, - "JobName": "HTTP 请求测试", - "NextExecTime": "2020-09-13 12:26:40", - "NextTimeId": 1600000000, - "RequestUrl": "https://httpbin.org/ip", - "Status": 1, - "UserId": 370942943322181, - } + "HttpMethod": 7, + "JobName": "用户收入支出统计", + "RequestBody": "{\"Sql\":\"UPDATE Sys_UserWallet SET TotalIncome = (SELECT COALESCE(SUM(Amount), 0) FROM Sys_WalletTrade WHERE Sys_WalletTrade.OwnerId = Sys_UserWallet.Id AND Sys_WalletTrade.TradeDirection = 1);UPDATE Sys_UserWallet SET TotalExpenditure = (SELECT COALESCE(SUM(Amount), 0) FROM Sys_WalletTrade WHERE Sys_WalletTrade.OwnerId = Sys_UserWallet.Id AND Sys_WalletTrade.TradeDirection = 2);\",\"TimeoutSecs\":60}", + "RequestHeader": "{\"Content-Type\":\"application/json\"}", + "RequestUrl": "https://na.tools92.top/api/sys/tools/execute.sql", + "UserId": 664362432344581, + }, + { + "Enabled": true, + "ExecutionCron": "0 * * * * ?", + "HttpMethod": 7, + "JobName": "充值到账确认", + "RequestBody": "{\"readRecordCount\":100}", + "RequestHeader": "{\"Content-Type\":\"application/json\"}", + "RequestUrl": "https://na.tools92.top/api/sys/deposit.order/received.confirmation", + "UserId": 664362432344581, + }, ] \ No newline at end of file diff --git a/assets/seed-data/Sys_Menu.json b/assets/seed-data/Sys_Menu.json index 4842d640..a1ed29a5 100644 --- a/assets/seed-data/Sys_Menu.json +++ b/assets/seed-data/Sys_Menu.json @@ -96,6 +96,17 @@ "Title": "交易流水", "Type": 1 }, + { + "Component": "sys/order", + "Icon": "el-icon-shopping-cart", + "Id": 690907673255944, + "Name": "sys/order", + "ParentId": 690906994118665, + "Path": "/finance/order", + "Sort": 98, + "Title": "充值订单", + "Type": 1 + }, // ------------------------------ 系统管理 ------------------------------ { "Icon": "sc-icon-App", diff --git a/assets/seed-data/Sys_RoleApi.json b/assets/seed-data/Sys_RoleApi.json index f4aa37b0..f6f25acf 100644 --- a/assets/seed-data/Sys_RoleApi.json +++ b/assets/seed-data/Sys_RoleApi.json @@ -78,5 +78,29 @@ { "ApiId": "api/sys/wallet.trade/get", "RoleId": 371729946431493, + }, + { + "ApiId": "api/sys/deposit.order/paged.query", + "RoleId": 371729946431493, + }, + { + "ApiId": "api/sys/deposit.order/count.by", + "RoleId": 371729946431493, + }, + { + "ApiId": "api/sys/deposit.order/create", + "RoleId": 371729946431493, + }, + { + "ApiId": "api/sys/deposit.order/get", + "RoleId": 371729946431493, + }, + { + "ApiId": "api/sys/deposit.order/get.deposit.config", + "RoleId": 371729946431493, + }, + { + "ApiId": "api/sys/deposit.order/pay.confirm", + "RoleId": 371729946431493, } ] \ No newline at end of file diff --git a/assets/seed-data/Sys_RoleMenu.json b/assets/seed-data/Sys_RoleMenu.json index 5e22653e..46b55e0f 100644 --- a/assets/seed-data/Sys_RoleMenu.json +++ b/assets/seed-data/Sys_RoleMenu.json @@ -26,5 +26,9 @@ { "MenuId": 690907673255943, "RoleId": 371729946431493 + }, + { + "MenuId": 690907673255944, + "RoleId": 371729946431493 } ] \ No newline at end of file diff --git a/assets/seed-data/Sys_User.json b/assets/seed-data/Sys_User.json index 9e5850b2..65706084 100644 --- a/assets/seed-data/Sys_User.json +++ b/assets/seed-data/Sys_User.json @@ -14,5 +14,13 @@ "Password": "A8E87D23-49BC-25A1-1C7C-59186BEF5D15", "Token": "4208EA97-B32F-4E39-A290-4C0D27B61EBF", "UserName": "user" + }, + { + "DeptId": 372119301627909, + "Enabled": true, + "Id": 664362432344581, + "Password": "A8E87D23-49BC-25A1-1C7C-59186BEF5D15", + "Token": "751D599B-2B8C-417C-9565-CCF2363F5F6F", + "UserName": "jobs" } ] \ No newline at end of file diff --git a/assets/seed-data/Sys_UserProfile.json b/assets/seed-data/Sys_UserProfile.json index 9159fbe7..03ef72fa 100644 --- a/assets/seed-data/Sys_UserProfile.json +++ b/assets/seed-data/Sys_UserProfile.json @@ -3,6 +3,10 @@ "Id": 370942943322181, "AppConfig": "[]" }, + { + "Id": 664362432344581, + "AppConfig": "[]" + }, { "Id": 560217289236492, "AppConfig": "[]" diff --git a/assets/seed-data/Sys_UserRole.json b/assets/seed-data/Sys_UserRole.json index fad24415..45ceaae6 100644 --- a/assets/seed-data/Sys_UserRole.json +++ b/assets/seed-data/Sys_UserRole.json @@ -3,6 +3,10 @@ "RoleId": 370943613149253, "UserId": 370942943322181 }, + { + "RoleId": 370943613149253, + "UserId": 664362432344581 + }, { "RoleId": 371729946431493, "UserId": 560217289236492 diff --git a/assets/seed-data/Sys_UserWallet.json b/assets/seed-data/Sys_UserWallet.json index b09a7a58..cd32870f 100644 --- a/assets/seed-data/Sys_UserWallet.json +++ b/assets/seed-data/Sys_UserWallet.json @@ -4,6 +4,11 @@ "OwnerDeptId": 372119301627909, "OwnerId": 370942943322181, }, + { + "Id": 664362432344581, + "OwnerDeptId": 372119301627909, + "OwnerId": 664362432344581, + }, { "Id": 560217289236492, "OwnerDeptId": 372119301627909, diff --git a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Dependency/Fields/IFieldOwner.cs b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Dependency/Fields/IFieldOwner.cs index 8431a54c..96ddf472 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Dependency/Fields/IFieldOwner.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Dependency/Fields/IFieldOwner.cs @@ -1,17 +1,17 @@ namespace NetAdmin.Domain.DbMaps.Dependency.Fields; /// -/// 所有者字段接口 +/// 归属字段接口 /// public interface IFieldOwner { /// - /// 所有者部门编号 + /// 归属部门编号 /// long? OwnerDeptId { get; init; } /// - /// 所有者用户编号 + /// 归属用户编号 /// long? OwnerId { get; init; } } \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_Config.cs b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_Config.cs index ebf34ba2..fae8534d 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_Config.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_Config.cs @@ -6,6 +6,14 @@ namespace NetAdmin.Domain.DbMaps.Sys; [Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_Config))] public record Sys_Config : VersionEntity, IFieldEnabled { + /// + /// 人民币兑点数比率 + /// + [Column] + [CsvIgnore] + [JsonIgnore] + public virtual int CnyToPointRate { get; init; } + /// /// 是否启用 /// @@ -14,6 +22,22 @@ public record Sys_Config : VersionEntity, IFieldEnabled [JsonIgnore] public virtual bool Enabled { get; init; } + /// + /// Trc20收款地址 + /// + [Column(DbType = Chars.FLG_DB_FIELD_TYPE_CHAR_34)] + [CsvIgnore] + [JsonIgnore] + public virtual string Trc20ReceiptAddress { get; init; } + + /// + /// 美元兑点数比率 + /// + [Column] + [CsvIgnore] + [JsonIgnore] + public virtual int UsdToPointRate { get; init; } + /// /// 用户注册是否需要人工确认 /// diff --git a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DepositOrder.cs b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DepositOrder.cs new file mode 100644 index 00000000..6e90e6d0 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DepositOrder.cs @@ -0,0 +1,115 @@ +namespace NetAdmin.Domain.DbMaps.Sys; + +/// +/// 充值订单表 +/// +[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_DepositOrder))] +[SqlIndex( // + $"{Chars.FLG_DB_INDEX_PREFIX}{nameof(ActualPayAmount)}_{nameof(FinishTimestamp)}", $"{nameof(ActualPayAmount)},{nameof(FinishTimestamp)}", true)] +[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(PaymentFinger), nameof(PaymentFinger), true, WhenNotNull = true)] +public record Sys_DepositOrder : LiteVersionEntity, IFieldOwner +{ + /// + /// 实际支付金额 + /// + [Column] + [CsvIgnore] + [JsonIgnore] + public virtual long ActualPayAmount { get; init; } + + /// + /// 订单状态 + /// + [Column] + [CsvIgnore] + [JsonIgnore] + public virtual DepositOrderStatues DepositOrderStatus { get; init; } + + /// + /// 充值点数 + /// + [Column] + [CsvIgnore] + [JsonIgnore] + public virtual long DepositPoint { get; init; } + + /// + /// 完成时间戳 + /// + [Column] + [CsvIgnore] + [JsonIgnore] + public virtual long FinishTimestamp { get; init; } + + /// + /// 归属用户 + /// + [CsvIgnore] + [JsonIgnore] + [Navigate(nameof(OwnerId))] + public Sys_User Owner { get; init; } + + /// + /// 归属部门编号 + /// + [Column] + [CsvIgnore] + [JsonIgnore] + public virtual long? OwnerDeptId { get; init; } + + /// + /// 归属用户编号 + /// + [Column] + [CsvIgnore] + [JsonIgnore] + public virtual long? OwnerId { get; init; } + + /// + /// 付款账号 + /// + [Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_127)] + [CsvIgnore] + [JsonIgnore] + public virtual string PaidAccount { get; init; } + + /// + /// 付款时间 + /// + [Column] + [CsvIgnore] + [JsonIgnore] + public virtual DateTime? PaidTime { get; init; } + + /// + /// 付款指纹 + /// + [Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)] + [CsvIgnore] + [JsonIgnore] + public virtual string PaymentFinger { get; init; } + + /// + /// 支付方式 + /// + [Column] + [CsvIgnore] + [JsonIgnore] + public virtual PaymentModes PaymentMode { get; init; } + + /// + /// 收款账号 + /// + [Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_127)] + [CsvIgnore] + [JsonIgnore] + public virtual string ReceiptAccount { get; init; } + + /// + /// 兑点数比率 + /// + [Column] + [CsvIgnore] + [JsonIgnore] + public virtual int ToPointRate { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DocCatalog.cs b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DocCatalog.cs index 774283cf..deded387 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DocCatalog.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DocCatalog.cs @@ -40,7 +40,7 @@ public record Sys_DocCatalog : VersionEntity, IFieldOwner public virtual string Name { get; init; } /// - /// 所有者 + /// 归属用户 /// [CsvIgnore] [JsonIgnore] @@ -48,7 +48,7 @@ public record Sys_DocCatalog : VersionEntity, IFieldOwner public Sys_User Owner { get; init; } /// - /// 所有者部门编号 + /// 归属部门编号 /// [Column] [CsvIgnore] @@ -56,7 +56,7 @@ public record Sys_DocCatalog : VersionEntity, IFieldOwner public virtual long? OwnerDeptId { get; init; } /// - /// 所有者用户编号 + /// 归属用户编号 /// [Column] [CsvIgnore] diff --git a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DocContent.cs b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DocContent.cs index e25e8f87..88d9fda0 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DocContent.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DocContent.cs @@ -41,7 +41,7 @@ public record Sys_DocContent : VersionEntity, IFieldEnabled, IFieldOwner public virtual bool Enabled { get; init; } /// - /// 所有者 + /// 归属用户 /// [CsvIgnore] [JsonIgnore] @@ -49,7 +49,7 @@ public record Sys_DocContent : VersionEntity, IFieldEnabled, IFieldOwner public Sys_User Owner { get; init; } /// - /// 所有者部门编号 + /// 归属部门编号 /// [Column] [CsvIgnore] @@ -57,7 +57,7 @@ public record Sys_DocContent : VersionEntity, IFieldEnabled, IFieldOwner public virtual long? OwnerDeptId { get; init; } /// - /// 所有者用户编号 + /// 归属用户编号 /// [Column] [CsvIgnore] diff --git a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_JobRecord.cs b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_JobRecord.cs index 7d3d702b..36f77b0b 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_JobRecord.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_JobRecord.cs @@ -35,7 +35,7 @@ public record Sys_JobRecord : LiteImmutableEntity public int HttpStatusCode { get; init; } /// - /// 所有者信息 + /// 归属信息 /// [CsvIgnore] [JsonIgnore] diff --git a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_LoginLog.cs b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_LoginLog.cs index b1ae265a..a8f20277 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_LoginLog.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_LoginLog.cs @@ -66,7 +66,7 @@ public record Sys_LoginLog : SimpleEntity, IFieldCreatedTime, IFieldOwner, IFiel public virtual string LoginUserName { get; protected init; } /// - /// 所有者 + /// 归属用户 /// [CsvIgnore] [JsonIgnore] @@ -74,7 +74,7 @@ public record Sys_LoginLog : SimpleEntity, IFieldCreatedTime, IFieldOwner, IFiel public Sys_User Owner { get; init; } /// - /// 所有者部门编号 + /// 归属部门编号 /// [Column] [CsvIgnore] @@ -82,7 +82,7 @@ public record Sys_LoginLog : SimpleEntity, IFieldCreatedTime, IFieldOwner, IFiel public virtual long? OwnerDeptId { get; init; } /// - /// 所有者用户编号 + /// 归属用户编号 /// [Column] [CsvIgnore] diff --git a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_RequestLog.cs b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_RequestLog.cs index db36a8d4..fa8db917 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_RequestLog.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_RequestLog.cs @@ -76,7 +76,7 @@ public record Sys_RequestLog : SimpleEntity, IFieldCreatedTime, IFieldOwner, IFi public virtual int HttpStatusCode { get; init; } /// - /// 所有者 + /// 归属用户 /// [CsvIgnore] [JsonIgnore] @@ -84,7 +84,7 @@ public record Sys_RequestLog : SimpleEntity, IFieldCreatedTime, IFieldOwner, IFi public Sys_User Owner { get; init; } /// - /// 所有者部门编号 + /// 归属部门编号 /// [Column] [CsvIgnore] @@ -92,7 +92,7 @@ public record Sys_RequestLog : SimpleEntity, IFieldCreatedTime, IFieldOwner, IFi public virtual long? OwnerDeptId { get; init; } /// - /// 所有者用户编号 + /// 归属用户编号 /// [Column] [CsvIgnore] diff --git a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_User.cs b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_User.cs index 6436625b..fb6d3450 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_User.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_User.cs @@ -20,7 +20,7 @@ public record Sys_User : VersionEntity, IFieldSummary, IFieldEnabled, IRegister public virtual string Avatar { get; init; } /// - /// 所属部门 + /// 归属部门 /// [CsvIgnore] [JsonIgnore] @@ -84,7 +84,7 @@ public record Sys_User : VersionEntity, IFieldSummary, IFieldEnabled, IRegister public Sys_UserProfile Profile { get; init; } /// - /// 所属角色 + /// 归属角色 /// [CsvIgnore] [JsonIgnore] diff --git a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_UserWallet.cs b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_UserWallet.cs index 98ba6729..ecfc6bf8 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_UserWallet.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_UserWallet.cs @@ -23,7 +23,7 @@ public record Sys_UserWallet : LiteVersionEntity, IFieldOwner public virtual long FrozenBalance { get; init; } /// - /// 所有者 + /// 归属用户 /// [CsvIgnore] [JsonIgnore] @@ -31,7 +31,7 @@ public record Sys_UserWallet : LiteVersionEntity, IFieldOwner public Sys_User Owner { get; init; } /// - /// 所有者部门编号 + /// 归属部门编号 /// [Column] [CsvIgnore] @@ -39,7 +39,7 @@ public record Sys_UserWallet : LiteVersionEntity, IFieldOwner public virtual long? OwnerDeptId { get; init; } /// - /// 所有者用户编号 + /// 归属用户编号 /// [Column] [CsvIgnore] diff --git a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_WalletTrade.cs b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_WalletTrade.cs index fa28739e..e2e29cd1 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_WalletTrade.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_WalletTrade.cs @@ -31,7 +31,7 @@ public record Sys_WalletTrade : ImmutableEntity, IFieldOwner, IFieldSummary public virtual long? BusinessOrderNumber { get; init; } /// - /// 所有者 + /// 归属用户 /// [CsvIgnore] [JsonIgnore] @@ -39,7 +39,7 @@ public record Sys_WalletTrade : ImmutableEntity, IFieldOwner, IFieldSummary public Sys_User Owner { get; init; } /// - /// 所有者部门编号 + /// 归属部门编号 /// [Column] [CsvIgnore] @@ -47,7 +47,7 @@ public record Sys_WalletTrade : ImmutableEntity, IFieldOwner, IFieldSummary public virtual long? OwnerDeptId { get; init; } /// - /// 所有者用户编号 + /// 归属用户编号 /// [Column] [CsvIgnore] diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Config/CreateConfigReq.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Config/CreateConfigReq.cs index 134a6d3a..2b89683d 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Config/CreateConfigReq.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Config/CreateConfigReq.cs @@ -5,10 +5,25 @@ namespace NetAdmin.Domain.Dto.Sys.Config; /// public record CreateConfigReq : Sys_Config { + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + [Range(1, int.MaxValue)] + public override int CnyToPointRate { get; init; } + /// [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public override bool Enabled { get; init; } + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [Length(34, 34)] + public override string Trc20ReceiptAddress { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + [Range(1, int.MaxValue)] + public override int UsdToPointRate { get; init; } + /// [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public override bool UserRegisterConfirm { get; init; } diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Config/QueryConfigRsp.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Config/QueryConfigRsp.cs index 4224a6c0..2ba1d9ad 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Config/QueryConfigRsp.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Config/QueryConfigRsp.cs @@ -8,6 +8,10 @@ namespace NetAdmin.Domain.Dto.Sys.Config; /// public record QueryConfigRsp : Sys_Config { + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override int CnyToPointRate { get; init; } + /// [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public override DateTime CreatedTime { get; init; } @@ -20,6 +24,14 @@ public record QueryConfigRsp : Sys_Config [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public override long Id { get; init; } + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string Trc20ReceiptAddress { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override int UsdToPointRate { get; init; } + /// [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public override bool UserRegisterConfirm { get; init; } diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/CreateDepositOrderReq.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/CreateDepositOrderReq.cs new file mode 100644 index 00000000..e2d8ed6a --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/CreateDepositOrderReq.cs @@ -0,0 +1,36 @@ +namespace NetAdmin.Domain.Dto.Sys.DepositOrder; + +/// +/// 请求:创建充值订单 +/// +public record CreateDepositOrderReq : Sys_DepositOrder, IValidatableObject +{ + /// + public override long ActualPayAmount { get; init; } + + /// + public override DepositOrderStatues DepositOrderStatus { get; init; } = DepositOrderStatues.WaitingForPayment; + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + [Range(100, long.MaxValue)] + public override long DepositPoint { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + [EnumDataType(typeof(PaymentModes))] + public override PaymentModes PaymentMode { get; init; } + + /// + public override int ToPointRate { get; init; } + + /// + public IEnumerable Validate(ValidationContext validationContext) + { + if (PaymentMode != PaymentModes.USDT) { + yield return new ValidationResult(Ln.支付方式不正确, [nameof(PaymentMode)]); + } + + yield return ValidationResult.Success; + } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/EditDepositOrderReq.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/EditDepositOrderReq.cs new file mode 100644 index 00000000..d5845b0d --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/EditDepositOrderReq.cs @@ -0,0 +1,15 @@ +namespace NetAdmin.Domain.Dto.Sys.DepositOrder; + +/// +/// 请求:编辑充值订单 +/// +public record EditDepositOrderReq : CreateDepositOrderReq +{ + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override long Id { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override long Version { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/GetDepositConfigRsp.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/GetDepositConfigRsp.cs new file mode 100644 index 00000000..0cb110e9 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/GetDepositConfigRsp.cs @@ -0,0 +1,19 @@ +namespace NetAdmin.Domain.Dto.Sys.DepositOrder; + +/// +/// 响应:查询充值订单 +/// +public sealed record GetDepositConfigRsp : Sys_Config +{ + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override int CnyToPointRate { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string Trc20ReceiptAddress { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override int UsdToPointRate { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/PayConfirmReq.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/PayConfirmReq.cs new file mode 100644 index 00000000..f9b91a14 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/PayConfirmReq.cs @@ -0,0 +1,11 @@ +namespace NetAdmin.Domain.Dto.Sys.DepositOrder; + +/// +/// 请求:支付确认 +/// +public record PayConfirmReq : Sys_DepositOrder +{ + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override long Id { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/QueryDepositOrderReq.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/QueryDepositOrderReq.cs new file mode 100644 index 00000000..73151795 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/QueryDepositOrderReq.cs @@ -0,0 +1,11 @@ +namespace NetAdmin.Domain.Dto.Sys.DepositOrder; + +/// +/// 请求:查询充值订单 +/// +public sealed record QueryDepositOrderReq : Sys_DepositOrder +{ + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override long Id { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/QueryDepositOrderRsp.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/QueryDepositOrderRsp.cs new file mode 100644 index 00000000..5a9501b3 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/QueryDepositOrderRsp.cs @@ -0,0 +1,73 @@ +using NetAdmin.Domain.Dto.Sys.User; + +namespace NetAdmin.Domain.Dto.Sys.DepositOrder; + +/// +/// 响应:查询充值订单 +/// +public record QueryDepositOrderRsp : Sys_DepositOrder +{ + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override long ActualPayAmount { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override DateTime CreatedTime { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override DepositOrderStatues DepositOrderStatus { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override long DepositPoint { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override long Id { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override DateTime? ModifiedTime { get; init; } + + /// + [CsvIgnore] + public new virtual QueryUserRsp Owner { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override long? OwnerDeptId { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override long? OwnerId { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string PaidAccount { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override DateTime? PaidTime { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string PaymentFinger { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override PaymentModes PaymentMode { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string ReceiptAccount { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override int ToPointRate { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override long Version { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/ReceivedConfirmationReq.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/ReceivedConfirmationReq.cs new file mode 100644 index 00000000..418fb6ad --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/DepositOrder/ReceivedConfirmationReq.cs @@ -0,0 +1,12 @@ +namespace NetAdmin.Domain.Dto.Sys.DepositOrder; + +/// +/// 请求:到账确认 +/// +public record ReceivedConfirmationReq : DataAbstraction +{ + /// + /// 读取前n条记录 + /// + public int ReadRecordCount { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/User/ExportUserRsp.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/User/ExportUserRsp.cs index 5e4f00c6..90804fbd 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/User/ExportUserRsp.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/User/ExportUserRsp.cs @@ -19,10 +19,10 @@ public sealed record ExportUserRsp : QueryUserRsp public override QueryDeptRsp Dept { get; init; } /// - /// 所属部门 + /// 归属部门 /// [CsvIndex(5)] - [CsvName(nameof(Ln.所属部门))] + [CsvName(nameof(Ln.归属部门))] public string DeptName { get; init; } /// @@ -56,10 +56,10 @@ public sealed record ExportUserRsp : QueryUserRsp public override string Mobile { get; init; } /// - /// 所属角色 + /// 归属角色 /// [CsvIndex(4)] - [CsvName(nameof(Ln.所属角色))] + [CsvName(nameof(Ln.归属角色))] public string RoleNames { get; init; } /// diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/Configuration/Dependency/ApiClientOptions.cs b/src/backend/NetAdmin/NetAdmin.Infrastructure/Configuration/Dependency/ApiClientOptions.cs index e2294468..fa03c19b 100644 --- a/src/backend/NetAdmin/NetAdmin.Infrastructure/Configuration/Dependency/ApiClientOptions.cs +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/Configuration/Dependency/ApiClientOptions.cs @@ -10,6 +10,11 @@ public abstract record ApiClientOptions : OptionAbstraction /// public string Gateway { get; set; } + /// + /// 超时时间 + /// + public int TimeoutSecs { get; set; } + /// /// 密钥 /// diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/Configuration/Options/TronScanOptions.cs b/src/backend/NetAdmin/NetAdmin.Infrastructure/Configuration/Options/TronScanOptions.cs new file mode 100644 index 00000000..0b09d7f0 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/Configuration/Options/TronScanOptions.cs @@ -0,0 +1,8 @@ +using NetAdmin.Infrastructure.Configuration.Dependency; + +namespace NetAdmin.Infrastructure.Configuration.Options; + +/// +/// TronScan 配置 +/// +public sealed record TronScanOptions : ApiClientOptions; \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/Constant/Chars.cs b/src/backend/NetAdmin/NetAdmin.Infrastructure/Constant/Chars.cs index 2bcd6ad6..23206685 100644 --- a/src/backend/NetAdmin/NetAdmin.Infrastructure/Constant/Chars.cs +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/Constant/Chars.cs @@ -18,6 +18,7 @@ public static class Chars public const string FLG_DB_EXCEPTION_IDX = "idx_"; public const string FLG_DB_EXCEPTION_PRIMARY_KEY_CONFLICT = "PRIMARY KEY"; public const string FLG_DB_EXCEPTION_UNIQUE_CONSTRAINT_CONFLICT = "UNIQUE constraint"; + public const string FLG_DB_FIELD_TYPE_CHAR_34 = "char(34)"; public const string FLG_DB_FIELD_TYPE_NVARCHAR = "nvarchar"; public const string FLG_DB_FIELD_TYPE_NVARCHAR_1022 = "nvarchar(1022)"; public const string FLG_DB_FIELD_TYPE_NVARCHAR_127 = "nvarchar(127)"; @@ -53,6 +54,7 @@ public static class Chars public const string FLG_HTTP_HEADER_KEY_ACCESS_TOKEN = "ACCESS-TOKEN"; public const string FLG_HTTP_HEADER_KEY_AUTHORIZATION = "Authorization"; public const string FLG_HTTP_HEADER_KEY_REFERER = "Referer"; + public const string FLG_HTTP_HEADER_KEY_TRON_PRO_API_KEY = "TRON-PRO-API-KEY"; public const string FLG_HTTP_HEADER_KEY_USER_AGENT = "User-Agent"; public const string FLG_HTTP_HEADER_KEY_X_ACCESS_TOKEN = "X-ACCESS-TOKEN"; public const string FLG_HTTP_HEADER_KEY_X_ACCESS_TOKEN_HEADER_KEY = "X-Authorization"; diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/Constant/Numbers.cs b/src/backend/NetAdmin/NetAdmin.Infrastructure/Constant/Numbers.cs index 9c1e6f37..795e7808 100644 --- a/src/backend/NetAdmin/NetAdmin.Infrastructure/Constant/Numbers.cs +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/Constant/Numbers.cs @@ -28,5 +28,6 @@ public static class Numbers public const int SECS_CACHE_LOGIN_BY_USER_ID = 3600 * 24 * 30; // 缓存时间(秒):通过用户编号登录的用户信息 public const int SECS_REDIS_LOCK_EXPIRY = 60; // 秒:Redis锁过期时间 public const int SECS_REDIS_LOCK_RETRY_DELAY = 1; // 秒:Redis锁重试间隔 + public const int SECS_TIMEOUT_HTTP_CLIENT = 15; // 超时时间(秒):HTTP 客户端 public const int SECS_TIMEOUT_JOB = 180; // 超时时间(秒):作业 } \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/Enums/DepositOrderStatues.cs b/src/backend/NetAdmin/NetAdmin.Infrastructure/Enums/DepositOrderStatues.cs new file mode 100644 index 00000000..76b4434f --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/Enums/DepositOrderStatues.cs @@ -0,0 +1,38 @@ +namespace NetAdmin.Infrastructure.Enums; + +/// +/// 充值订单状态 +/// +[Export] +public enum DepositOrderStatues +{ + /// + /// 等待支付 + /// + [ResourceDescription(nameof(Ln.等待支付))] + WaitingForPayment = 1 + + , + + /// + /// 到账确认中 + /// + [ResourceDescription(nameof(Ln.到账确认中))] + PaymentConfirming = 2 + + , + + /// + /// 充值成功 + /// + [ResourceDescription(nameof(Ln.充值成功))] + Succeeded = 3 + + , + + /// + /// 支付超时 + /// + [ResourceDescription(nameof(Ln.支付超时))] + PaymentTimeout = 4 +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/Enums/PaymentModes.cs b/src/backend/NetAdmin/NetAdmin.Infrastructure/Enums/PaymentModes.cs new file mode 100644 index 00000000..5734d9d4 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/Enums/PaymentModes.cs @@ -0,0 +1,30 @@ +namespace NetAdmin.Infrastructure.Enums; + +/// +/// 支付方式 +/// +[Export] +public enum PaymentModes +{ + /// + /// USDT + /// + [ResourceDescription(nameof(Ln.USDT))] + USDT = 1 + + , + + /// + /// 支付宝 + /// + [ResourceDescription(nameof(Ln.支付宝))] + Alipay = 2 + + , + + /// + /// 微信支付 + /// + [ResourceDescription(nameof(Ln.微信支付))] + WeChat = 3 +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/Enums/TradeDirections.cs b/src/backend/NetAdmin/NetAdmin.Infrastructure/Enums/TradeDirections.cs index 07cd833c..5cab76cb 100644 --- a/src/backend/NetAdmin/NetAdmin.Infrastructure/Enums/TradeDirections.cs +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/Enums/TradeDirections.cs @@ -10,7 +10,7 @@ public enum TradeDirections /// 收入 /// [ResourceDescription(nameof(Ln.收入))] - Income = 4 + Income = 1 , @@ -18,5 +18,5 @@ public enum TradeDirections /// 支出 /// [ResourceDescription(nameof(Ln.支出))] - Expense = 5 + Expense = 2 } \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/ITronScanClient.cs b/src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/ITronScanClient.cs new file mode 100644 index 00000000..d2cc3f6e --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/ITronScanClient.cs @@ -0,0 +1,43 @@ +namespace NetAdmin.Infrastructure.Rpc.TronScan; + +/// +/// 云码平台 客户端 +/// +public interface ITronScanClient : IHttpDispatchProxy +{ + private static readonly ILogger _logger = App.GetService>(); + + /// + /// 异常拦截 + /// + [Interceptor(InterceptorTypes.Exception)] + static Task OnExceptionAsync(HttpClient _, HttpResponseMessage rsp, string errors) + { + return rsp.LogExceptionAsync(errors, _logger); + } + + /// + /// 请求拦截 + /// + [Interceptor(InterceptorTypes.Request)] + static Task OnRequestAsyncAsync(HttpClient _, HttpRequestMessage req) + { + return req.LogAsync(_logger); + } + + /// + /// 响应拦截 + /// + [Interceptor(InterceptorTypes.Response)] + static Task OnResponsingAsync(HttpClient _, HttpResponseMessage rsp) + { + return rsp.LogAsync(_logger); + } + + /// + /// 获取交易记录 + /// + [Client(nameof(TronScanOptions))] + [Get("api/filter/trc20/transfers?limit={limit}&toAddress={toAddress}")] + Task TransfersAsync([Headers(Chars.FLG_HTTP_HEADER_KEY_TRON_PRO_API_KEY)] string token, int limit, string toAddress); +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/NormalAddressInfo.cs b/src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/NormalAddressInfo.cs new file mode 100644 index 00000000..09212c27 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/NormalAddressInfo.cs @@ -0,0 +1,15 @@ +namespace NetAdmin.Infrastructure.Rpc.TronScan; + +/// +/// 表示一个普通的地址信息记录。 +/// +/// +/// 该记录包含一个布尔值属性,用于指示地址是否存在风险。 +/// +public record NormalAddressInfo +{ + /// + /// 获取或设置地址是否存在风险的标识。 + /// + public bool Risk { get; set; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/TokenInfo.cs b/src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/TokenInfo.cs new file mode 100644 index 00000000..2e930ddb --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/TokenInfo.cs @@ -0,0 +1,57 @@ +namespace NetAdmin.Infrastructure.Rpc.TronScan; + +/// +/// 表示一个令牌的信息,包括发行者地址、令牌缩写、显示属性等详细信息。 +/// +public record TokenInfo +{ + /// + /// 获取或设置发行者的地址。 + /// + public string IssuerAddr { get; set; } + + /// + /// 获取或设置令牌的缩写。 + /// + public string TokenAbbr { get; set; } + + /// + /// 获取或设置令牌可显示的数量。 + /// + public int TokenCanShow { get; set; } + + /// + /// 获取或设置令牌的小数位数。 + /// + public int TokenDecimal { get; set; } + + /// + /// 获取或设置令牌的唯一标识符。 + /// + public string TokenId { get; set; } + + /// + /// 获取或设置令牌的级别。 + /// + public string TokenLevel { get; set; } + + /// + /// 获取或设置令牌的Logo URL或路径。 + /// + public string TokenLogo { get; set; } + + /// + /// 获取或设置令牌的名称。 + /// + public string TokenName { get; set; } + + /// + /// 获取或设置令牌的类型。 + /// + public string TokenType { get; set; } + + /// + /// 获取或设置是否为VIP令牌。 + /// + public bool Vip { get; set; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/TokenTransferInfo.cs b/src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/TokenTransferInfo.cs new file mode 100644 index 00000000..08bdf38e --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/TokenTransferInfo.cs @@ -0,0 +1,116 @@ +namespace NetAdmin.Infrastructure.Rpc.TronScan; + +/// +/// 表示一个代币转账事件。 +/// +public record TokenTransferInfo +{ + /// + /// 获取或设置批准的转账金额。 + /// + [JsonPropertyName("approval_amount")] + public string ApprovalAmount { get; set; } + + /// + /// 获取或设置发生转账事件的区块编号。 + /// + public int Block { get; set; } + + /// + /// 获取或设置发生转账事件的区块的时间戳。 + /// + [JsonPropertyName("block_ts")] + public long BlockTs { get; set; } + + /// + /// 获取或设置一个值,指示转账是否已确认。 + /// + public bool Confirmed { get; set; } + + /// + /// 获取或设置代币的合约地址。 + /// + [JsonPropertyName("contract_address")] + public string ContractAddress { get; set; } + + /// + /// 获取或设置合约执行的返回结果。 + /// + public string ContractRet { get; set; } + + /// + /// 获取或设置合约类型。 + /// + [JsonPropertyName("contract_type")] + public string ContractType { get; set; } + + /// + /// 获取或设置事件类型。 + /// + [JsonPropertyName("event_type")] + public string EventType { get; set; } + + /// + /// 获取或设置转账的最终结果。 + /// + public string FinalResult { get; set; } + + /// + /// 获取或设置发送方地址。 + /// + [JsonPropertyName("from_address")] + public string FromAddress { get; set; } + + /// + /// 获取或设置一个值,指示发送方地址是否为合约地址。 + /// + public bool FromAddressIsContract { get; set; } + + /// + /// 获取或设置转账数量。 + /// + public string Quant { get; set; } + + /// + /// 获取或设置一个值,指示转账是否已回滚。 + /// + public bool Revert { get; set; } + + /// + /// 获取或设置一个值,指示转账是否为风险交易。 + /// + public bool RiskTransaction { get; set; } + + /// + /// 获取或设置转账状态。 + /// + public int Status { get; set; } + + /// + /// 获取或设置接收方地址。 + /// + [JsonPropertyName("to_address")] + public string ToAddress { get; set; } + + /// + /// 获取或设置一个值,指示接收方地址是否为合约地址。 + /// + public bool ToAddressIsContract { get; set; } + + /// + /// 获取或设置代币信息。 + /// + public TokenInfo TokenInfo { get; set; } + + /// + /// 获取或设置交易ID。 + /// + [JsonPropertyName("transaction_id")] + public string TransactionId { get; set; } + + /// + /// 获取或设置合约触发信息。 + /// + [JsonPropertyName("trigger_info")] + public TriggerInfo TriggerInfo { get; set; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/TransfersRsp.cs b/src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/TransfersRsp.cs new file mode 100644 index 00000000..c827e4d6 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/TransfersRsp.cs @@ -0,0 +1,28 @@ +namespace NetAdmin.Infrastructure.Rpc.TronScan; + +/// +/// 表示包含合约信息及相关数据的根响应对象。 +/// +public record TransfersRsp +{ + /// + /// 获取或设置按地址键入的正常地址信息字典。 + /// + public Dictionary NormalAddressInfo { get; set; } + + /// + /// 获取或设置范围内的项目总数。 + /// + public int RangeTotal { get; set; } + + /// + /// 获取或设置令牌转账列表。 + /// + [JsonPropertyName("token_transfers")] + public IReadOnlyCollection TokenTransfers { get; set; } + + /// + /// 获取或设置项目的总数。 + /// + public int Total { get; set; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/TriggerInfo.cs b/src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/TriggerInfo.cs new file mode 100644 index 00000000..9cf13b0f --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/Rpc/TronScan/TriggerInfo.cs @@ -0,0 +1,34 @@ +namespace NetAdmin.Infrastructure.Rpc.TronScan; + +/// +/// 表示触发智能合约的信息。 +/// +public record TriggerInfo +{ + /// + /// 获取或设置调用合约时传递的值。 + /// + [JsonPropertyName("call_value")] + public int CallValue { get; set; } + + /// + /// 获取或设置合约的地址。 + /// + [JsonPropertyName("contract_address")] + public string ContractAddress { get; set; } + + /// + /// 获取或设置调用合约方法的数据。 + /// + public string Data { get; set; } + + /// + /// 获取或设置合约方法的标识符。 + /// + public string Method { get; set; } + + /// + /// 获取或设置合约方法的名称。 + /// + public string MethodName { get; set; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Modules/Sys/IDepositOrderModule.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Modules/Sys/IDepositOrderModule.cs new file mode 100644 index 00000000..e88230f7 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Modules/Sys/IDepositOrderModule.cs @@ -0,0 +1,28 @@ +using NetAdmin.Domain.Dto.Sys.DepositOrder; + +namespace NetAdmin.SysComponent.Application.Modules.Sys; + +/// +/// 充值订单模块 +/// +public interface IDepositOrderModule : ICrudModule +{ + /// + /// 获取充值配置 + /// + Task GetDepositConfigAsync(); + + /// + /// 支付确认 + /// + Task PayConfirmAsync(PayConfirmReq req); + + /// + /// 到账确认 + /// + Task ReceivedConfirmationAsync(ReceivedConfirmationReq req); +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IDepositOrderService.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IDepositOrderService.cs new file mode 100644 index 00000000..b76bcde3 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IDepositOrderService.cs @@ -0,0 +1,6 @@ +namespace NetAdmin.SysComponent.Application.Services.Sys.Dependency; + +/// +/// 充值订单服务 +/// +public interface IDepositOrderService : IService, IDepositOrderModule; \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DepositOrderService.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DepositOrderService.cs new file mode 100644 index 00000000..e0bb5602 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DepositOrderService.cs @@ -0,0 +1,235 @@ +using NetAdmin.Application.Extensions; +using NetAdmin.Domain.DbMaps.Sys; +using NetAdmin.Domain.Dto.Sys.DepositOrder; +using NetAdmin.Domain.Dto.Sys.WalletTrade; +using NetAdmin.Domain.Extensions; +using NetAdmin.Infrastructure.Rpc.TronScan; + +namespace NetAdmin.SysComponent.Application.Services.Sys; + +/// +public sealed class DepositOrderService(BasicRepository rpo) // + : RepositoryService(rpo), IDepositOrderService +{ + /// + public async Task BulkDeleteAsync(BulkReq req) + { + req.ThrowIfInvalid(); + var ret = 0; + + // ReSharper disable once LoopCanBeConvertedToQuery + foreach (var item in req.Items) { + ret += await DeleteAsync(item).ConfigureAwait(false); + } + + return ret; + } + + /// + public Task CountAsync(QueryReq req) + { + req.ThrowIfInvalid(); + return QueryInternal(req).WithNoLockNoWait().CountAsync(); + } + + /// + public async Task, int>>> CountByAsync(QueryReq req) + { + req.ThrowIfInvalid(); + var ret = await QueryInternal(req with { Order = Orders.None }) + .WithNoLockNoWait() + .GroupBy(req.GetToListExp()) + .ToDictionaryAsync(a => a.Count()) + .ConfigureAwait(false); + return ret.Select(x => new KeyValuePair, int>( + req.RequiredFields.ToImmutableDictionary( + y => y, y => typeof(Sys_DepositOrder).GetProperty(y)!.GetValue(x.Key)?.ToString()), x.Value)) + .Where(x => x.Key.Any(y => !y.Value.NullOrEmpty())) + .OrderByDescending(x => x.Value); + } + + /// req + /// + public async Task CreateAsync(CreateDepositOrderReq req) + { + req.ThrowIfInvalid(); + + var config = await GetDepositConfigAsync().ConfigureAwait(false); + + var toPointRate = req.PaymentMode switch { + PaymentModes.USDT => config.UsdToPointRate + , PaymentModes.Alipay => config.CnyToPointRate + , PaymentModes.WeChat => config.CnyToPointRate + , _ => throw new ArgumentOutOfRangeException(nameof(req)) + }; + + var ret = await Rpo.InsertAsync(req with { + ActualPayAmount = (long)(((decimal)req.DepositPoint / toPointRate).Round(3) * 1000) + , ToPointRate = toPointRate + , ReceiptAccount = config.Trc20ReceiptAddress + }) + .ConfigureAwait(false); + return ret.Adapt(); + } + + /// + public Task DeleteAsync(DelReq req) + { + req.ThrowIfInvalid(); + return Rpo.DeleteAsync(a => a.Id == req.Id); + } + + /// + public async Task EditAsync(EditDepositOrderReq req) + { + req.ThrowIfInvalid(); + #if DBTYPE_SQLSERVER + return (await UpdateReturnListAsync(req).ConfigureAwait(false)).FirstOrDefault()?.Adapt(); + #else + return await UpdateAsync(req).ConfigureAwait(false) > 0 + ? await GetAsync(new QueryDepositOrderReq { Id = req.Id }).ConfigureAwait(false) + : null; + #endif + } + + /// + public Task ExportAsync(QueryReq req) + { + req.ThrowIfInvalid(); + return ExportAsync(QueryInternal, req, Ln.充值订单导出); + } + + /// + public async Task GetAsync(QueryDepositOrderReq req) + { + req.ThrowIfInvalid(); + var ret = await QueryInternal(new QueryReq { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false); + return ret.Adapt(); + } + + /// + public async Task GetDepositConfigAsync() + { + var ret = await S().GetLatestConfigAsync().ConfigureAwait(false); + return ret.Adapt(); + } + + /// + public async Task> PagedQueryAsync(PagedQueryReq req) + { + req.ThrowIfInvalid(); + var list = await QueryInternal(req) + .Include(a => a.Owner) + .Page(req.Page, req.PageSize) + .WithNoLockNoWait() + .Count(out var total) + .ToListAsync(req) + .ConfigureAwait(false); + + return new PagedQueryRsp(req.Page, req.PageSize, total, list.Adapt>()); + } + + /// + public Task PayConfirmAsync(PayConfirmReq req) + { + req.ThrowIfInvalid(); + return UpdateAsync(req with { DepositOrderStatus = DepositOrderStatues.PaymentConfirming }, [nameof(req.DepositOrderStatus)], null + , a => a.DepositOrderStatus == DepositOrderStatues.WaitingForPayment && a.Id == req.Id, null, true); + } + + /// + public async Task> QueryAsync(QueryReq req) + { + req.ThrowIfInvalid(); + var ret = await QueryInternal(req).WithNoLockNoWait().Take(req.Count).ToListAsync(req).ConfigureAwait(false); + return ret.Adapt>(); + } + + /// + public async Task ReceivedConfirmationAsync(ReceivedConfirmationReq req) + { + req.ThrowIfInvalid(); + var ret = 0; + var config = await S().GetLatestConfigAsync().ConfigureAwait(false); + var waitConfirmList = (await QueryAsync(new QueryReq { + Count = Numbers.MAX_LIMIT_QUERY_PAGE_SIZE + , DynamicFilter + = new DynamicFilterInfo { + Field = nameof( + QueryDepositOrderReq.DepositOrderStatus) + , Operator = DynamicFilterOperators.Eq + , Value = DepositOrderStatues.PaymentConfirming + } + , Order = Orders.Ascending + , Prop = nameof(QueryDepositOrderReq.Id) + }) + .ConfigureAwait(false)).ToList(); + var apiResult = await S() + .TransfersAsync(S>().Value.Token, req.ReadRecordCount, config.Trc20ReceiptAddress) + .ConfigureAwait(false); + foreach (var apiItem in apiResult.TokenTransfers.Where(x => x.TokenInfo.TokenAbbr == "USDT" && x.Confirmed && x.ContractRet == "SUCCESS" && + x.FinalResult == "SUCCESS")) { + var order = waitConfirmList.SingleOrDefault(x => x.ActualPayAmount == apiItem.Quant.Int64() / 1000); + if (order == null || order.CreatedTime > apiItem.BlockTs.Time()) { + continue; + } + + try { + await S() + .AtomicOperateAsync(async () => { + var updated = await UpdateAsync( // + new Sys_DepositOrder { + DepositOrderStatus = DepositOrderStatues.Succeeded + , Version = order.Version + , FinishTimestamp = DateTime.Now.TimeUnixUtcMs() + , PaidAccount = apiItem.FromAddress + , PaidTime = apiItem.BlockTs.Time() + , PaymentFinger = apiItem.TransactionId + }, [nameof(Sys_DepositOrder.DepositOrderStatus), nameof(Sys_DepositOrder.FinishTimestamp), nameof(Sys_DepositOrder.PaidAccount), nameof(Sys_DepositOrder.PaidTime), nameof(Sys_DepositOrder.PaymentFinger)] + , null, a => a.Id == order.Id && a.DepositOrderStatus == DepositOrderStatues.PaymentConfirming) + .ConfigureAwait(false); + if (updated != 1) { + throw new NetAdminUnexpectedException(Ln.结果非预期); + } + + _ = await S() + .CreateAsync(new CreateWalletTradeReq { + Amount = order.DepositPoint + , BusinessOrderNumber = order.Id + , TradeDirection = TradeDirections.Income + , TradeType = TradeTypes.SelfDeposit + , OwnerId = order.OwnerId + }) + .ConfigureAwait(false) ?? throw new NetAdminUnexpectedException(Ln.结果非预期); + }) + .ConfigureAwait(false); + ret++; + } + catch { + // ignore + } + } + + return ret; + } + + private ISelect QueryInternal(QueryReq req) + { + var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); + + // ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault + switch (req.Order) { + case Orders.None: + return ret; + case Orders.Random: + return ret.OrderByRandom(); + } + + ret = ret.OrderByPropertyNameIf(req.Prop?.Length > 0, req.Prop, req.Order == Orders.Ascending); + if (!req.Prop?.Equals(nameof(req.Filter.Id), StringComparison.OrdinalIgnoreCase) ?? true) { + ret = ret.OrderByDescending(a => a.Id); + } + + return ret; + } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/Dependency/IDepositOrderCache.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/Dependency/IDepositOrderCache.cs new file mode 100644 index 00000000..75defb4a --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/Dependency/IDepositOrderCache.cs @@ -0,0 +1,6 @@ +namespace NetAdmin.SysComponent.Cache.Sys.Dependency; + +/// +/// 充值订单缓存 +/// +public interface IDepositOrderCache : ICache, IDepositOrderModule; \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/DepositOrderCache.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/DepositOrderCache.cs new file mode 100644 index 00000000..460713f7 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/DepositOrderCache.cs @@ -0,0 +1,86 @@ +using NetAdmin.Domain.Dto.Sys.DepositOrder; + +namespace NetAdmin.SysComponent.Cache.Sys; + +/// +public sealed class DepositOrderCache(IDistributedCache cache, IDepositOrderService service) + : DistributedCache(cache, service), IScoped, IDepositOrderCache +{ + /// + public Task BulkDeleteAsync(BulkReq req) + { + return Service.BulkDeleteAsync(req); + } + + /// + public Task CountAsync(QueryReq req) + { + return Service.CountAsync(req); + } + + /// + public Task, int>>> CountByAsync(QueryReq req) + { + return Service.CountByAsync(req); + } + + /// + public Task CreateAsync(CreateDepositOrderReq req) + { + return Service.CreateAsync(req); + } + + /// + public Task DeleteAsync(DelReq req) + { + return Service.DeleteAsync(req); + } + + /// + public Task EditAsync(EditDepositOrderReq req) + { + return Service.EditAsync(req); + } + + /// + public Task ExportAsync(QueryReq req) + { + return Service.ExportAsync(req); + } + + /// + public Task GetAsync(QueryDepositOrderReq req) + { + return Service.GetAsync(req); + } + + /// + public Task GetDepositConfigAsync() + { + return Service.GetDepositConfigAsync(); + } + + /// + public Task> PagedQueryAsync(PagedQueryReq req) + { + return Service.PagedQueryAsync(req); + } + + /// + public Task PayConfirmAsync(PayConfirmReq req) + { + return Service.PayConfirmAsync(req); + } + + /// + public Task> QueryAsync(QueryReq req) + { + return Service.QueryAsync(req); + } + + /// + public Task ReceivedConfirmationAsync(ReceivedConfirmationReq req) + { + return Service.ReceivedConfirmationAsync(req); + } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Controllers/Sys/DepositOrderController.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Controllers/Sys/DepositOrderController.cs new file mode 100644 index 00000000..270549d9 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Controllers/Sys/DepositOrderController.cs @@ -0,0 +1,122 @@ +using NetAdmin.Domain.Dto.Sys.DepositOrder; + +namespace NetAdmin.SysComponent.Host.Controllers.Sys; + +/// +/// 充值订单服务 +/// +[ApiDescriptionSettings(nameof(Sys), Module = nameof(Sys))] +[Produces(Chars.FLG_HTTP_HEADER_VALUE_APPLICATION_JSON)] +public sealed class DepositOrderController(IDepositOrderCache cache) + : ControllerBase(cache), IDepositOrderModule +{ + /// + /// 批量删除充值订单 + /// + [Transaction] + public Task BulkDeleteAsync(BulkReq req) + { + return Cache.BulkDeleteAsync(req); + } + + /// + /// 充值订单计数 + /// + public Task CountAsync(QueryReq req) + { + return Cache.CountAsync(req); + } + + /// + /// 充值订单分组计数 + /// + public Task, int>>> CountByAsync(QueryReq req) + { + return Cache.CountByAsync(req); + } + + /// + /// 创建充值订单 + /// + [Transaction] + public Task CreateAsync(CreateDepositOrderReq req) + { + return Cache.CreateAsync(req); + } + + /// + /// 删除充值订单 + /// + [Transaction] + public Task DeleteAsync(DelReq req) + { + return Cache.DeleteAsync(req); + } + + /// + /// 编辑充值订单 + /// + [Transaction] + public Task EditAsync(EditDepositOrderReq req) + { + return Cache.EditAsync(req); + } + + /// + /// 导出充值订单 + /// + [NonAction] + public Task ExportAsync(QueryReq req) + { + return Cache.ExportAsync(req); + } + + /// + /// 获取单个充值订单 + /// + public Task GetAsync(QueryDepositOrderReq req) + { + return Cache.GetAsync(req); + } + + /// + /// 获取充值配置 + /// + public Task GetDepositConfigAsync() + { + return Cache.GetDepositConfigAsync(); + } + + /// + /// 分页查询充值订单 + /// + public Task> PagedQueryAsync(PagedQueryReq req) + { + return Cache.PagedQueryAsync(req); + } + + /// + /// 支付确认 + /// + public Task PayConfirmAsync(PayConfirmReq req) + { + return Cache.PayConfirmAsync(req); + } + + /// + /// 查询充值订单 + /// + [NonAction] + public Task> QueryAsync(QueryReq req) + { + return Cache.QueryAsync(req); + } + + /// + /// 到账确认 + /// + public Task ReceivedConfirmationAsync(ReceivedConfirmationReq req) + { + return Cache.ReceivedConfirmationAsync(req); + } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Extensions/ServiceCollectionExtensions.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Extensions/ServiceCollectionExtensions.cs index fb1b88a3..080ef727 100644 --- a/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Extensions/ServiceCollectionExtensions.cs +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Extensions/ServiceCollectionExtensions.cs @@ -3,6 +3,7 @@ using NetAdmin.Domain.Contexts; using NetAdmin.Domain.Events; using NetAdmin.Host.Filters; using NetAdmin.Host.Middlewares; +using NetAdmin.Infrastructure.Configuration.Dependency; using NetAdmin.Infrastructure.Schedule; using NetAdmin.SysComponent.Host.Utils; using FreeSqlBuilder = NetAdmin.Infrastructure.Utils.FreeSqlBuilder; @@ -104,6 +105,31 @@ public static class ServiceCollectionExtensions } } + /// + /// 添加 TronScan 客户端 + /// + public static IServiceCollection AddTronScanClient(this IServiceCollection me) + { + _ = me.AddHttpClient(nameof(TronScanOptions), ConfigClient); + return me; + } + + private static void ConfigClient(HttpClient client) + where T : ApiClientOptions, new() + { + ConfigClient(client, Numbers.SECS_TIMEOUT_HTTP_CLIENT); + } + + private static void ConfigClient(HttpClient client, int timeoutSecs) + where T : ApiClientOptions, new() + { + var options = App.GetOptions(); + + client.Timeout = TimeSpan.FromSeconds(options.TimeoutSecs > 0 ? options.TimeoutSecs : timeoutSecs); + client.DefaultRequestHeaders.Add("User-Agent", nameof(NetAdmin)); + client.BaseAddress = new Uri($"{options.Gateway}/"); + } + private static void RunJob(IEnumerable> jobTypes) { foreach (var job in jobTypes) { diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Utils/SqlAuditor.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Utils/SqlAuditor.cs index f3c08207..b3f650cd 100644 --- a/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Utils/SqlAuditor.cs +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Utils/SqlAuditor.cs @@ -149,7 +149,7 @@ public sealed class SqlAuditor : ISingleton } /// - /// 设置所有者 + /// 设置归属 /// private static void SetOwner(AuditValueEventArgs e, ContextUserInfo userInfo) { diff --git a/src/backend/YourSolution.AdmServer.Host/Filters/JwtHandler.cs b/src/backend/YourSolution.AdmServer.Host/Filters/JwtHandler.cs index 205abb20..b542e6d5 100644 --- a/src/backend/YourSolution.AdmServer.Host/Filters/JwtHandler.cs +++ b/src/backend/YourSolution.AdmServer.Host/Filters/JwtHandler.cs @@ -37,7 +37,7 @@ public sealed class JwtHandler : AppAuthorizeHandler return true; } - // 获取所属角色接口权限 进行核对 + // 获取归属角色接口权限 进行核对 if (role.ApiIds?.Contains(path) ?? false) { return true; } diff --git a/src/backend/YourSolution.AdmServer.Host/Startup.cs b/src/backend/YourSolution.AdmServer.Host/Startup.cs index 81efa0b0..76e6509a 100644 --- a/src/backend/YourSolution.AdmServer.Host/Startup.cs +++ b/src/backend/YourSolution.AdmServer.Host/Startup.cs @@ -95,6 +95,7 @@ namespace YourSolution.AdmServer.Host .AddContextUserInfo() // 添加上下文用户信息 .AddRedisCache() // 添加 Redis 缓存 .AddSchedules() // 添加计划任务 + .AddTronScanClient() // 添加 TronScan 客户端 // IMvcBuilder .AddControllers() // 添加控制器 diff --git a/src/backend/YourSolution.AdmServer.Infrastructure/AdmSettings.json b/src/backend/YourSolution.AdmServer.Infrastructure/AdmSettings.json index 3792009d..870b73c8 100644 --- a/src/backend/YourSolution.AdmServer.Infrastructure/AdmSettings.json +++ b/src/backend/YourSolution.AdmServer.Infrastructure/AdmSettings.json @@ -94,4 +94,9 @@ "Secure": false } }, + // TronScan 客户端配置 + "TronScan": { + "Gateway": "https://apilist.tronscanapi.com", + "Token": "fc6629dc-0139-4238-bead-8db7c45ec1e2" + }, } \ No newline at end of file diff --git a/src/frontend/admin/package.json b/src/frontend/admin/package.json index bb7996d1..c4b1911d 100644 --- a/src/frontend/admin/package.json +++ b/src/frontend/admin/package.json @@ -21,6 +21,7 @@ "markdown-it": "14.1.0", "markdown-it-emoji": "3.0.0", "nprogress": "0.2.0", + "qrcode-svg": "1.1.0", "sortablejs": "1.15.6", "vkbeautify": "0.99.3", "vue": "3.5.17", diff --git a/src/frontend/admin/src/api/sys/depositorder.js b/src/frontend/admin/src/api/sys/depositorder.js new file mode 100644 index 00000000..7fc897e1 --- /dev/null +++ b/src/frontend/admin/src/api/sys/depositorder.js @@ -0,0 +1,117 @@ +/** + * 充值订单服务 + * @module @/api/sys/deposit.order + */ +import config from '@/config' +import http from '@/utils/request' +export default { + /** + * 批量删除充值订单 + */ + bulkDelete: { + url: `${config.API_URL}/api/sys/deposit.order/bulk.delete`, + name: `批量删除充值订单`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 充值订单计数 + */ + count: { + url: `${config.API_URL}/api/sys/deposit.order/count`, + name: `充值订单计数`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 充值订单分组计数 + */ + countBy: { + url: `${config.API_URL}/api/sys/deposit.order/count.by`, + name: `充值订单分组计数`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 创建充值订单 + */ + create: { + url: `${config.API_URL}/api/sys/deposit.order/create`, + name: `创建充值订单`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 删除充值订单 + */ + delete: { + url: `${config.API_URL}/api/sys/deposit.order/delete`, + name: `删除充值订单`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 编辑充值订单 + */ + edit: { + url: `${config.API_URL}/api/sys/deposit.order/edit`, + name: `编辑充值订单`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 获取单个充值订单 + */ + get: { + url: `${config.API_URL}/api/sys/deposit.order/get`, + name: `获取单个充值订单`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 获取充值配置 + */ + getDepositConfig: { + url: `${config.API_URL}/api/sys/deposit.order/get.deposit.config`, + name: `获取充值配置`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 分页查询充值订单 + */ + pagedQuery: { + url: `${config.API_URL}/api/sys/deposit.order/paged.query`, + name: `分页查询充值订单`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 支付确认 + */ + payConfirm: { + url: `${config.API_URL}/api/sys/deposit.order/pay.confirm`, + name: `支付确认`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, +} \ No newline at end of file diff --git a/src/frontend/admin/src/components/scTable/index.vue b/src/frontend/admin/src/components/scTable/index.vue index ffcae46f..c5807842 100644 --- a/src/frontend/admin/src/components/scTable/index.vue +++ b/src/frontend/admin/src/components/scTable/index.vue @@ -188,7 +188,7 @@ delete item[x]) // Object.assign(item, data) // }) + } else { + table.refresh() } }, } \ No newline at end of file diff --git a/src/frontend/admin/src/locales/lang/en.js b/src/frontend/admin/src/locales/lang/en.js index c86937b9..3905f5b1 100644 --- a/src/frontend/admin/src/locales/lang/en.js +++ b/src/frontend/admin/src/locales/lang/en.js @@ -99,9 +99,9 @@ export default { 性别: 'Gender', 成功: 'Successful', 我的消息: 'My messages', - 所属字典: 'Dictionary', - 所属角色: 'Role', - 所属部门: 'Department', + 归属字典: 'Dictionary', + 归属角色: 'Role', + 归属部门: 'Department', 手机号: 'Mobile', 手机号码: 'Mobile phone number', 手风琴菜单: 'Accordion menu', @@ -131,13 +131,13 @@ export default { 整页路由: 'Full page routing', 文化程度: 'Educational level', 斑马纹: 'Zebra pattern', - 新增作业: 'Add job', - 新增字典项: 'Add Dictionary Item', - 新增消息: 'Add Message', - 新增用户: 'Add User', - 新增角色: 'Add Role', - 新增部门: 'Add Department', - 新增配置: 'Add Configuration', + 新建作业: 'Add job', + 新建字典项: 'Add Dictionary Item', + 新建消息: 'Add Message', + 新建用户: 'Add User', + 新建角色: 'Add Role', + 新建部门: 'Add Department', + 新建配置: 'Add Configuration', 新密码: 'New password', 新手机号码: 'New mobile phone number', 新手机验证码: 'New mobile verification code', @@ -379,7 +379,7 @@ export default { 响应体: 'Response body', 响应头: 'Response header', 执行时间编号: 'Execution time ID', - 新增字典目录: 'Add dictionary catalog', + 新建字典目录: 'Add dictionary catalog', 字典名称: 'Dictionary name', 字典编码: 'Dictionary code', 父路径: 'Parent path', @@ -579,7 +579,7 @@ export default { '结束值(毫秒)': 'End Value (ms)', '起始值(毫秒)': 'Starting Value (ms)', 复制: 'Copy', - 新增: 'New', + 新建: 'New', '数据已导出(上限 {n} 条)': 'Data exported (Maximum {n} entries)', 同步成功: 'Synchronization succeeded', 缓存详情: 'Cache details', @@ -587,11 +587,11 @@ export default { 数据权限: 'Data Permissions', 首页视图: 'Home view', 删除配置: 'Delete the configuration', - 所属字典目录: 'Dictionary catalog', + 归属字典目录: 'Dictionary catalog', 删除字典项: 'Delete dictionary entries', 接口总数: 'Total number of apis', - 所属文档分类: 'Document catalog', - 请选择所属文档分类: 'Please select the document category', + 归属文档分类: 'Document catalog', + 请选择归属文档分类: 'Please select the document category', 请输入文档标题: 'Please enter a title for the document', 请输入文档内容: 'Please enter the content of the document', 请选择档案可见性: 'Please select profile visibility', diff --git a/src/frontend/admin/src/locales/lang/zh-cn.js b/src/frontend/admin/src/locales/lang/zh-cn.js index 77e39679..79580683 100644 --- a/src/frontend/admin/src/locales/lang/zh-cn.js +++ b/src/frontend/admin/src/locales/lang/zh-cn.js @@ -99,9 +99,9 @@ export default { 性别: '性别', 成功: '成功', 我的消息: '我的消息', - 所属字典: '所属字典', - 所属角色: '所属角色', - 所属部门: '所属部门', + 归属字典: '归属字典', + 归属角色: '归属角色', + 归属部门: '归属部门', 手机号: '手机号', 手机号码: '手机号码', 手风琴菜单: '手风琴菜单', @@ -131,13 +131,13 @@ export default { 整页路由: '整页路由', 文化程度: '文化程度', 斑马纹: '斑马纹', - 新增作业: '新增作业', - 新增字典项: '新增字典项', - 新增消息: '新增消息', - 新增用户: '新增用户', - 新增角色: '新增角色', - 新增部门: '新增部门', - 新增配置: '新增配置', + 新建作业: '新建作业', + 新建字典项: '新建字典项', + 新建消息: '新建消息', + 新建用户: '新建用户', + 新建角色: '新建角色', + 新建部门: '新建部门', + 新建配置: '新建配置', 新密码: '新密码', 新手机号码: '新手机号码', 新手机验证码: '新手机验证码', @@ -378,7 +378,7 @@ export default { 响应体: '响应体', 响应头: '响应头', 执行时间编号: '执行时间编号', - 新增字典目录: '新增字典目录', + 新建字典目录: '新建字典目录', 字典名称: '字典名称', 字典编码: '字典编码', 父路径: '父路径', @@ -577,7 +577,7 @@ export default { '结束值(毫秒)': '结束值(毫秒)', '起始值(毫秒)': '起始值(毫秒)', 复制: '复制', - 新增: '新增', + 新建: '新建', '数据已导出(上限 {n} 条)': '数据已导出(上限 {n} 条)', 同步成功: '同步成功', 缓存详情: '缓存详情', @@ -585,11 +585,11 @@ export default { 数据权限: '数据权限', 首页视图: '首页视图', 删除配置: '删除配置', - 所属字典目录: '所属字典目录', + 归属字典目录: '归属字典目录', 删除字典项: '删除字典项', 接口总数: '接口总数', - 所属文档分类: '所属文档分类', - 请选择所属文档分类: '请选择所属文档分类', + 归属文档分类: '归属文档分类', + 请选择归属文档分类: '请选择归属文档分类', 请输入文档标题: '请输入文档标题', 请输入文档内容: '请输入文档内容', 请选择档案可见性: '请选择档案可见性', diff --git a/src/frontend/admin/src/views/sys/config/index.vue b/src/frontend/admin/src/views/sys/config/index.vue index c8210237..df7407fd 100644 --- a/src/frontend/admin/src/views/sys/config/index.vue +++ b/src/frontend/admin/src/views/sys/config/index.vue @@ -85,6 +85,11 @@ + + + + +