diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml
index 9da703b..9d38b61 100644
--- a/.gitea/workflows/deploy.yml
+++ b/.gitea/workflows/deploy.yml
@@ -1,4 +1,4 @@
-# 复制到 admin .gitea/workflows/deploy.yml
+# 复制到 admin .gitea/workflows/deploy.yml
name: Build and Deploy
on:
diff --git a/src/Oms.Application/Integrations/Itfx/ItfxGatewayOptions.cs b/src/Oms.Application/Integrations/Itfx/ItfxGatewayOptions.cs
index 1ba817e..6cbe9af 100644
--- a/src/Oms.Application/Integrations/Itfx/ItfxGatewayOptions.cs
+++ b/src/Oms.Application/Integrations/Itfx/ItfxGatewayOptions.cs
@@ -8,9 +8,9 @@ public class ItfxGatewayOptions
public const string SectionName = "Oms:Itfx";
///
- /// itfx 服务根地址,如 http://api.nanafa.com/itfx。
+ /// itfx 服务根地址。生产默认 api.ideship.com;测试用 appsettings.Development / Consul 覆盖为 api.nanafa.com。
///
- public string BaseUrl { get; set; } = "http://api.nanafa.com/itfx";
+ public string BaseUrl { get; set; } = "https://api.ideship.com/itfx";
public int TimeoutSeconds { get; set; } = 30;
diff --git a/src/SimpleAdmin.Api.IntegrationTests/WeChatRouteIntegrationTests.cs b/src/SimpleAdmin.Api.IntegrationTests/WeChatRouteIntegrationTests.cs
index 5c4f785..9a412b6 100644
--- a/src/SimpleAdmin.Api.IntegrationTests/WeChatRouteIntegrationTests.cs
+++ b/src/SimpleAdmin.Api.IntegrationTests/WeChatRouteIntegrationTests.cs
@@ -30,8 +30,9 @@ public class WeChatRouteIntegrationTests
await using var host = await SimpleAdminApiTestHost.CreateAsync(configureServices: ConfigureWeChatFallback);
host.RoutePatterns.Should().Contain("apiwechat/verification");
- host.RoutePatterns.Should().Contain("wechat/mp/{appId}");
+ host.RoutePatterns.Should().Contain("wechat/mp/{appId:regex(^wx[A-Za-z0-9]+$)}");
host.RoutePatterns.Should().Contain("wechat/mp/login-qrcode");
+ host.RoutePatterns.Should().Contain("wechat/oauth/config");
host.RoutePatterns.Should().Contain("wechat/mp/follow-qrcode");
host.RoutePatterns.Should().Contain("wechat/oauth/user-info");
host.RoutePatterns.Should().Contain("wechat/customer/register");
diff --git a/src/SimpleAdmin.Api/Auth/AuthService.WeChatMp.cs b/src/SimpleAdmin.Api/Auth/AuthService.WeChatMp.cs
index 05bc350..914cee0 100644
--- a/src/SimpleAdmin.Api/Auth/AuthService.WeChatMp.cs
+++ b/src/SimpleAdmin.Api/Auth/AuthService.WeChatMp.cs
@@ -70,9 +70,10 @@ public partial class AuthService
///
/// 微信服务器接入验签,验签通过后原样返回 echostr。
+ /// appId 仅匹配 wx 开头,避免 login-qrcode / oauth-config 等静态段落入本路由。
///
[AllowAnonymous]
- [HttpGet("/wechat/mp/{appId}")]
+ [HttpGet("/wechat/mp/{appId:regex(^wx[A-Za-z0-9]+$)}")]
[Produces("text/plain")]
[ApiExplorerSettings(GroupName = "WeChat")]
public async Task WeChatValidateAsync(
@@ -120,7 +121,7 @@ public partial class AuthService
/// 微信消息/事件推送(明文,XML/JSON)。
///
[AllowAnonymous]
- [HttpPost("/wechat/mp/{appId}")]
+ [HttpPost("/wechat/mp/{appId:regex(^wx[A-Za-z0-9]+$)}")]
[Consumes("text/xml", "application/xml", "application/json", "text/plain")]
[Produces("text/plain", "application/xml")]
[ApiExplorerSettings(GroupName = "WeChat")]
@@ -159,6 +160,32 @@ public partial class AuthService
cancellationToken);
}
+ ///
+ /// H5 网页授权公开配置:AppId + OAuth 回调根(来自其他配置 wechat_mp)。
+ /// 注意:勿挂在 /wechat/mp/{appId} 下,避免被公众号回调路由吞掉。
+ ///
+ [AllowAnonymous]
+ [HttpGet("/wechat/oauth/config")]
+ [ApiExplorerSettings(GroupName = "WeChat")]
+ public async Task GetWeChatOAuthConfigAsync(
+ CancellationToken cancellationToken = default)
+ {
+ var options = await WeChatMpConfigProvider.GetAsync(cancellationToken);
+ if (string.IsNullOrWhiteSpace(options.AppId))
+ {
+ throw new BusinessException(
+ "未配置微信公众号 AppId。请在「其他配置」维护 wechat_mp,AppKey 填公众号 AppId。");
+ }
+
+ return new WxOAuthConfigOutput
+ {
+ AppId = options.AppId.Trim(),
+ OAuthRedirectBase = string.IsNullOrWhiteSpace(options.OAuthRedirectBase)
+ ? null
+ : options.OAuthRedirectBase.Trim().TrimEnd('/')
+ };
+ }
+
///
/// 获取 PC 扫码登录二维码。
///
diff --git a/src/SimpleAdmin.Api/WeChat/Dtos/WeChatDtos.cs b/src/SimpleAdmin.Api/WeChat/Dtos/WeChatDtos.cs
index f5c09ba..d254466 100644
--- a/src/SimpleAdmin.Api/WeChat/Dtos/WeChatDtos.cs
+++ b/src/SimpleAdmin.Api/WeChat/Dtos/WeChatDtos.cs
@@ -12,6 +12,19 @@ public class WxLoginQrcodeOutput
public int ExpiresIn { get; set; } = 600;
}
+/// H5 网页授权所需公开配置(不含 Secret/Token)。
+public class WxOAuthConfigOutput
+{
+ /// 公众号 AppId(来自其他配置 wechat_mp.AppKey)。
+ public string AppId { get; set; } = string.Empty;
+
+ ///
+ /// OAuth 回调根地址(来自 wechat_mp.BaseUrl),如 https://ideship.com。
+ /// 为空时前端回退到当前页面 origin。
+ ///
+ public string? OAuthRedirectBase { get; set; }
+}
+
/// 引导关注公众号:优先返回可直接跳转的公众号链接。
public class WxFollowQrcodeOutput
{
diff --git a/src/SimpleAdmin.Api/appsettings.Development.json b/src/SimpleAdmin.Api/appsettings.Development.json
index f9647a9..1439c62 100644
--- a/src/SimpleAdmin.Api/appsettings.Development.json
+++ b/src/SimpleAdmin.Api/appsettings.Development.json
@@ -12,7 +12,12 @@
},
"App": {
"Urls": ["http://localhost:5281"],
- "CorsOrigins": ["http://localhost:5173", "http://localhost:5281"],
+ "CorsOrigins": [
+ "http://localhost:5173",
+ "http://localhost:5281",
+ "https://oms.nanafa.com",
+ "http://oms.nanafa.com"
+ ],
"SendStartupNotification": false
},
"Jwt": {
@@ -46,7 +51,7 @@
},
"WeChat": {
"Mp": {
- "AppId": "wxd5141ba46c856e1f",
+ "AppId": "wxfffea62e089ee15f",
"Secret": "379f51a89419dc36fbb9167feef6f89a",
"Token": "c6ca74013df823c0e1da0feaaaf8bf66",
"EncodingAesKey": "",
diff --git a/src/SimpleAdmin.Api/appsettings.Production.json b/src/SimpleAdmin.Api/appsettings.Production.json
new file mode 100644
index 0000000..49f2a98
--- /dev/null
+++ b/src/SimpleAdmin.Api/appsettings.Production.json
@@ -0,0 +1,34 @@
+{
+ "UseLocalConfigs": false,
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "App": {
+ "CorsOrigins": [
+ "https://ideship.com",
+ "https://www.ideship.com"
+ ],
+ "SendStartupNotification": false
+ },
+ "WeChat": {
+ "Mp": {
+ "OAuthRedirectBase": "https://ideship.com",
+ "FollowUrl": ""
+ }
+ },
+ "Oms": {
+ "TrackService": {
+ "Enabled": true,
+ "BaseUrl": "https://api.ideship.com/track"
+ },
+ "Itfx": {
+ "BaseUrl": "https://api.ideship.com/itfx"
+ },
+ "PlatformShop": {
+ "FrontendBaseUrl": "https://ideship.com"
+ }
+ }
+}