diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Payment/Alipay/AlipayPayment.cs b/src/0-core/HuanMeng.MiaoYu.Code/Payment/Alipay/AlipayPayment.cs
index 1d41821..b8e49b4 100644
--- a/src/0-core/HuanMeng.MiaoYu.Code/Payment/Alipay/AlipayPayment.cs
+++ b/src/0-core/HuanMeng.MiaoYu.Code/Payment/Alipay/AlipayPayment.cs
@@ -10,13 +10,14 @@ using Alipay.EasySDK.Kernel;
using Alipay.EasySDK.Kernel.Util;
using Alipay.EasySDK.Payment.FaceToFace.Models;
using StackExchange.Redis;
+using HuanMeng.DotNetCore.MultiTenant.Contract;
namespace HuanMeng.MiaoYu.Code.Payment.Alipay
{
///
///
///
- public class AlipayPayment : IPayment
+ public class AlipayPayment(Config config, ITenantInfo tenantInfo) : IPayment
{
public Task<(string orderId, string order)> CreateOrder(string productName, decimal price, params object[] args)
{
@@ -31,12 +32,11 @@ namespace HuanMeng.MiaoYu.Code.Payment.Alipay
}
var orderId = GenerateTimestampIdWithOffset();
//.SetOptions(GetConfig());
- var response = Factory.Payment.App().Optional("passback_params", "PaymentType%3Dzfb").Pay(productName, orderId, priceStr);
- if (ResponseChecker.Success(response))
- {
- Console.WriteLine("调用成功");
- }
- else
+ //AsyncNotify
+ //https://pay.shhuanmeng.com/api/${tenant}/zfb/${orderId}
+ var notifyUrl = config.NotifyUrl.Replace("${pay}", "zfb").Replace("${orderId}", orderId).Replace("${tenant}", tenantInfo.Identifier); ;
+ var response = Factory.Payment.App().AsyncNotify(notifyUrl).Optional("passback_params", "PaymentType%3Dzfb").Pay(productName, orderId, priceStr);
+ if (!ResponseChecker.Success(response))
{
throw new Exception("创建订单失败!" + response.Body);
}
@@ -44,6 +44,10 @@ namespace HuanMeng.MiaoYu.Code.Payment.Alipay
var zfbOrderId = response.Body;
return Task.FromResult((orderId, zfbOrderId));
}
+ ///
+ ///
+ ///
+ ///
private string GenerateTimestampIdWithOffset()
{
var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); // 获取Unix时间戳(毫秒)
diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Payment/PaymentExtend.cs b/src/0-core/HuanMeng.MiaoYu.Code/Payment/PaymentExtend.cs
index 583f070..84c8e07 100644
--- a/src/0-core/HuanMeng.MiaoYu.Code/Payment/PaymentExtend.cs
+++ b/src/0-core/HuanMeng.MiaoYu.Code/Payment/PaymentExtend.cs
@@ -56,7 +56,7 @@ namespace HuanMeng.MiaoYu.Code.Payment
return builder;
}
-
+ public static Config AlipayConfig { get; set; }
///
/// 支付
///
@@ -80,7 +80,9 @@ namespace HuanMeng.MiaoYu.Code.Payment
//可设置异步通知接收服务地址(可选)
NotifyUrl = x.NotifyUrl,
};
+ AlipayConfig = config;
Factory.SetOptions(config);
+
}
else
{
@@ -93,14 +95,14 @@ namespace HuanMeng.MiaoYu.Code.Payment
///
///
///
- public static IPayment GetPayment(string payment)
+ public static IPayment GetPayment(string payment, MiaoYuBase miaoYuBase)
{
if (payment == "zfb")
{
- return new AlipayPayment();
+ return new AlipayPayment(AlipayConfig, miaoYuBase.TenantInfo);
}
- return new WeChatPayment(wxClient, weChatConfig);
+ return new WeChatPayment(wxClient, weChatConfig, miaoYuBase.TenantInfo);
}
///
diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Payment/WeChat/WeChatPayment.cs b/src/0-core/HuanMeng.MiaoYu.Code/Payment/WeChat/WeChatPayment.cs
index 3b98225..e7f34a2 100644
--- a/src/0-core/HuanMeng.MiaoYu.Code/Payment/WeChat/WeChatPayment.cs
+++ b/src/0-core/HuanMeng.MiaoYu.Code/Payment/WeChat/WeChatPayment.cs
@@ -3,26 +3,28 @@ using HuanMeng.MiaoYu.Code.Payment.Contract;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Models;
using SKIT.FlurlHttpClient.Wechat.TenpayV3;
using Newtonsoft.Json;
+using HuanMeng.DotNetCore.MultiTenant.Contract;
namespace HuanMeng.MiaoYu.Code.Payment.WeChat
{
///
/// 微信支付
///
- public class WeChatPayment(WechatTenpayClient client, WeChatConfig weChatConfig) : IPayment
+ public class WeChatPayment(WechatTenpayClient client, WeChatConfig weChatConfig, ITenantInfo tenantInfo) : IPayment
{
public async Task<(string orderId, string order)> CreateOrder(string productName, decimal price, params object[] args)
{
var orderId = GenerateTimestampIdWithOffset();
//var client = new WechatTenpayClient(wechatTenpayClientOptions);
/* 以 JSAPI 统一下单接口为例 */
+ var notifyUrl = weChatConfig.NotifyUrl.Replace("${pay}", "wx").Replace("${orderId}", orderId).Replace("${tenant}", tenantInfo.Identifier);
var request = new CreatePayTransactionAppRequest()
{
OutTradeNumber = orderId,
AppId = weChatConfig.AppId,
Description = productName,
ExpireTime = DateTimeOffset.Now.AddMinutes(20),
- NotifyUrl = weChatConfig.NotifyUrl,
+ NotifyUrl = notifyUrl,
Amount = new CreatePayTransactionJsapiRequest.Types.Amount()
{
Total = (int)(price * 100)
diff --git a/src/0-core/HuanMeng.MiaoYu.Code/SysDictionary/DictionaryNetwork/DictionaryInfoServerNetwork.cs b/src/0-core/HuanMeng.MiaoYu.Code/SysDictionary/DictionaryNetwork/DictionaryInfoServerNetwork.cs
index 49704e8..c9a1ccb 100644
--- a/src/0-core/HuanMeng.MiaoYu.Code/SysDictionary/DictionaryNetwork/DictionaryInfoServerNetwork.cs
+++ b/src/0-core/HuanMeng.MiaoYu.Code/SysDictionary/DictionaryNetwork/DictionaryInfoServerNetwork.cs
@@ -68,7 +68,10 @@ namespace HuanMeng.MiaoYu.Code.SysDictionary.DictionaryNetwork
{
dictionaryUrl = configuration.GetSection("SystemConfig:DictionaryUrl").Get() ?? "";
}
-
+ if (string.IsNullOrEmpty(dictionaryUrl))
+ {
+ return;
+ }
using var client = httpClientFactory.CreateClient();
var request = await client.GetAsync(dictionaryUrl);
if (request.IsSuccessStatusCode)
diff --git a/src/2-api/HuanMeng.MiaoYu.WebPayApi/Controllers/PayController.cs b/src/2-api/HuanMeng.MiaoYu.WebPayApi/Controllers/PayController.cs
new file mode 100644
index 0000000..1ed1031
--- /dev/null
+++ b/src/2-api/HuanMeng.MiaoYu.WebPayApi/Controllers/PayController.cs
@@ -0,0 +1,30 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+
+namespace HuanMeng.MiaoYu.WebPayApi.Controllers
+{
+ [Route("api/[controller]/")]
+ [ApiController]
+ public class PayController : ControllerBase
+ {
+ ///
+ ///
+ ///
+ ///
+ [HttpGet("{tenant?}/{pay?}/{orderId?}")]
+ public string Get(string? tenant, string? pay, string? orderId)
+ {
+ return "ok";
+ }
+
+ ///
+ /// ${tenant}/zfb/${orderId}
+ ///
+ ///
+ [HttpPost("{tenant?}/{pay?}/{orderId?}")]
+ public string Post(string? tenant, string? pay,string? orderId)
+ {
+ return $"ok;{pay},{orderId}";
+ }
+ }
+}
diff --git a/src/2-api/HuanMeng.MiaoYu.WebPayApi/HuanMeng.MiaoYu.WebPayApi.csproj b/src/2-api/HuanMeng.MiaoYu.WebPayApi/HuanMeng.MiaoYu.WebPayApi.csproj
index 3171938..d9ec514 100644
--- a/src/2-api/HuanMeng.MiaoYu.WebPayApi/HuanMeng.MiaoYu.WebPayApi.csproj
+++ b/src/2-api/HuanMeng.MiaoYu.WebPayApi/HuanMeng.MiaoYu.WebPayApi.csproj
@@ -13,7 +13,15 @@
+
+
+
+
+
+
+
+
diff --git a/src/2-api/HuanMeng.MiaoYu.WebPayApi/Program.cs b/src/2-api/HuanMeng.MiaoYu.WebPayApi/Program.cs
index df2434c..ec038d4 100644
--- a/src/2-api/HuanMeng.MiaoYu.WebPayApi/Program.cs
+++ b/src/2-api/HuanMeng.MiaoYu.WebPayApi/Program.cs
@@ -1,23 +1,126 @@
+using AgileConfig.Client;
+
+using HuanMeng.DotNetCore.CustomExtension;
+using HuanMeng.DotNetCore.MiddlewareExtend;
+using HuanMeng.DotNetCore.Utility.AssemblyHelper;
+using HuanMeng.MiaoYu.Code.Base;
+using HuanMeng.MiaoYu.Code.JwtUtil;
+using HuanMeng.MiaoYu.Code.MultiTenantUtil;
+using HuanMeng.MiaoYu.Code.Other;
+using HuanMeng.MiaoYu.Code.Payment;
+using HuanMeng.MiaoYu.Code.SysDictionary;
+using HuanMeng.MiaoYu.Code.TencentUtile;
+using HuanMeng.MiaoYu.Code.Users.UserAccount.VerificationCodeManager;
+using HuanMeng.MiaoYu.Model.Dto;
+using HuanMeng.MiaoYu.Code.AppExtend;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.Extensions.Configuration;
+using Microsoft.OpenApi.Models;
+
+using Newtonsoft.Json.Serialization;
+
+using Serilog;
+
+using System.Diagnostics;
+using System.Reflection;
var builder = WebApplication.CreateBuilder(args);
-
-// Add services to the container.
-
+builder.Host.UseSerilog((context, services, configuration) => configuration
+ .ReadFrom.Configuration(context.Configuration)
+ .ReadFrom.Services(services)
+ .Enrich.FromLogContext());
+builder.AddAppConfigClient();
+builder.Services.AddSingleton(typeof(ILogger), serviceProvider =>
+{
+ var loggerFactory = serviceProvider.GetRequiredService();
+ return loggerFactory.CreateLogger();
+});
+// 检索程序集信息
+AssemblyInfo assemblyInfo = AssemblyInfoHelper.GetAssemblyInfo();
+// Add services to the container.
+builder.Services.AddHttpClient();
+builder.Services.AddHttpContextAccessor(); //添加httpContext注入访问
+#region 添加跨域
+var _myAllowSpecificOrigins = "_myAllowSpecificOrigins";
+builder.Services.AddCustomCors(_myAllowSpecificOrigins);
+#endregion
+#region automap
+var mapperDomain = AppDomain.CurrentDomain.GetAssemblies().Where(it => it.FullName.Contains("HuanMeng") || it.FullName.Contains("XLib.")).ToList();
+Type type = typeof(ResponseUserInfo);
+if (type != null)
+{
+ Assembly assembly = Assembly.GetAssembly(type);
+ if (!mapperDomain.Any(it => it.FullName == assembly.FullName))
+ {
+ mapperDomain.Add(assembly);
+ }
+}
builder.Services.AddControllers();
+builder.Services.AddSwaggerGen();
+builder.Services.AddAutoMapper(mapperDomain);
+#endregion
+
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
-builder.Services.AddSwaggerGen();
+builder.AddDictionaryInfo();
+//配置路由选项,使URL全部小写
+//builder.Services.AddRouting(options => options.LowercaseUrls = true);
+builder.AddPayment();
+//添加多租户
+builder.AddMultiTenantMiaoYu();
var app = builder.Build();
// Configure the HTTP request pipeline.
-if (app.Environment.IsDevelopment())
+//if (app.Environment.IsDevelopment())
+//{
+app.UseSwagger();
+app.UseSwaggerUI(c =>
{
- app.UseSwagger();
- app.UseSwaggerUI();
-}
+ c.EnableDeepLinking();
+ c.DefaultModelsExpandDepth(3);
+ c.DefaultModelExpandDepth(3);
+ c.EnableFilter("true");
+ //c.RoutePrefix = string.Empty;
+ c.SwaggerEndpoint("/swagger/v1/swagger.json", "寰梦支付API V1");
+});
+//}
+app.UseSerilogRequestLogging();
app.UseAuthorization();
-
+//自定义初始化
+//使用跨域
+app.UseCors(_myAllowSpecificOrigins);
app.MapControllers();
+app.UseStaticFiles();//静态文件访问配置
+
+//执行扩展中间件
+app.UseExceptionMiddleware()
+ .UseExecutionTimeMiddleware();
+
+#region 默认请求
+app.MapGet("/", () => "请求成功").WithName("默认请求");
+
+var startDateTime = DateTime.Now;
+var InformationalVersion = Assembly.GetEntryAssembly().GetCustomAttribute().InformationalVersion;
+Console.WriteLine($"version:{InformationalVersion}");
+app.MapGet("/system", () =>
+{
+
+ using Process currentProcess = Process.GetCurrentProcess();
+ // CPU使用率 (一般是一个0-100之间的值,但实际是时间占比,需要转换)
+ double cpuUsage = currentProcess.TotalProcessorTime.TotalMilliseconds / Environment.TickCount * 100;
+ // 已用内存 (字节)
+ long memoryUsage = currentProcess.WorkingSet64;
+ return new
+ {
+ msg = $"系统信息:{assemblyInfo.InformationalVersion},启动时间:{startDateTime.ToString("yyyy-MM-dd HH:mm:ss")},已安全运行时间:{DateTime.Now.Subtract(startDateTime).TotalMinutes.ToString("0.##")}分钟",
+ assemblyInfo,
+ startDateTime,
+ MemoryUsage = $"{memoryUsage / (1024.0 * 1024.0):F2}MB",
+ CPUUsage = $"{cpuUsage:F2}%"
+
+ };
+}).WithName("获取系统数据");
+#endregion
app.Run();
diff --git a/src/2-api/HuanMeng.MiaoYu.WebPayApi/appsettings.Development.json b/src/2-api/HuanMeng.MiaoYu.WebPayApi/appsettings.Development.json
index 0c208ae..a2020fc 100644
--- a/src/2-api/HuanMeng.MiaoYu.WebPayApi/appsettings.Development.json
+++ b/src/2-api/HuanMeng.MiaoYu.WebPayApi/appsettings.Development.json
@@ -4,5 +4,12 @@
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
+ },
+ "AgileConfig": {
+ "appId": "huanmeng",
+ "secret": "dfa47997-fb5c-b644-3770-880f5e7fb403",
+ "nodes": "http://124.220.55.158:94", //多个节点使用逗号分隔
+ "env": "DEV",
+ "name": "PayClient"
}
}
diff --git a/src/2-api/HuanMeng.MiaoYu.WebPayApi/appsettings.json b/src/2-api/HuanMeng.MiaoYu.WebPayApi/appsettings.json
index 10f68b8..e682769 100644
--- a/src/2-api/HuanMeng.MiaoYu.WebPayApi/appsettings.json
+++ b/src/2-api/HuanMeng.MiaoYu.WebPayApi/appsettings.json
@@ -5,5 +5,56 @@
"Microsoft.AspNetCore": "Warning"
}
},
- "AllowedHosts": "*"
+ "AllowedHosts": "*",
+ "Serilog": {
+ "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
+ "MinimumLevel": {
+ "Default": "Information",
+ "Override": {
+ "Microsoft": "Warning",
+ "System": "Warning"
+ }
+ },
+ "WriteTo": [
+ { "Name": "Console" },
+ {
+ "Name": "File",
+ "Args": {
+ "path": "../output/logs/info/log-.txt",
+ "rollingInterval": "Day",
+ "restrictedToMinimumLevel": "Information", //写入日志的级别
+ "shared": true
+ //"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}"
+ }
+ },
+ {
+ "Name": "File",
+ "Args": {
+ "path": "../output/logs/error/log-.txt",
+ "rollingInterval": "Day", //日志文件按天滚动生成。
+ "restrictedToMinimumLevel": "Error", //写入日志的级别 //包括 Verbose、Debug、Information、Warning、Error 和 Fatal
+ "shared": true //不占用文件
+ // "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}"
+ }
+ },
+ {
+ "Name": "File",
+ "Args": {
+ "path": "../output/logs/debug/log-.txt",
+ "rollingInterval": "Day", //日志文件按天滚动生成。
+ "restrictedToMinimumLevel": "Debug", //写入日志的级别 //包括 Verbose、Debug、Information、Warning、Error 和 Fatal
+ "shared": true //不占用文件
+ // "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}"
+ }
+ }
+ ],
+ "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ]
+ },
+ "AgileConfig": {
+ "appId": "huanmeng",
+ "secret": "dfa47997-fb5c-b644-3770-880f5e7fb403",
+ "nodes": "http://10.0.12.5:94", //多个节点使用逗号分隔
+ "env": "PROD",
+ "name": "PayClient"
+ }
}