diff --git a/apps/frontend/src/pages/admin/platform/DouyinMashidaPanel.tsx b/apps/frontend/src/pages/admin/platform/DouyinMashidaPanel.tsx
index 39e63995..e0a0c585 100644
--- a/apps/frontend/src/pages/admin/platform/DouyinMashidaPanel.tsx
+++ b/apps/frontend/src/pages/admin/platform/DouyinMashidaPanel.tsx
@@ -53,6 +53,7 @@ import {
describeMessageTemplateWarning,
describeMissingConfigFields,
isLocalDevBaseUrl,
+ resolveDouyinMashidaPublicOrigin,
} from '@/utils/douyin-mashida'
const { Text, Paragraph } = Typography
@@ -155,9 +156,14 @@ export function DouyinMashidaPanel() {
async function handleSubscribe(disable = false) {
setSubscribing(true)
try {
- const targetUrl = buildDouyinMashidaMessageUrl(window.location.origin)
+ const targetOrigin = resolveDouyinMashidaPublicOrigin(
+ config.claimLinkBase,
+ config.certLink,
+ window.location.origin,
+ )
+ const targetUrl = buildDouyinMashidaMessageUrl(targetOrigin)
await subscribeAdminDouyinMashidaPush({
- publicUrl: window.location.origin,
+ publicUrl: targetOrigin,
messageUrl: targetUrl,
topics: config.handledTopics,
disable,
@@ -216,7 +222,13 @@ export function DouyinMashidaPanel() {
certLink: config.certLink,
})
const isLocalDev = isLocalDevBaseUrl(config.baseUrl)
- const messageUrl = buildDouyinMashidaMessageUrl(window.location.origin)
+ const publicOrigin = resolveDouyinMashidaPublicOrigin(
+ config.claimLinkBase,
+ config.certLink,
+ window.location.origin,
+ )
+ const messageUrl = buildDouyinMashidaMessageUrl(publicOrigin)
+ const isMessageUrlLocal = isLocalDevBaseUrl(publicOrigin)
const claimLinkPreview = buildDouyinMashidaClaimLinkPreview(config.claimLinkBase)
const claimLinkWarning = describeClaimLinkBaseWarning(config.claimLinkBase)
const messageTemplateWarning = describeMessageTemplateWarning(config.messageTemplate)
@@ -314,14 +326,28 @@ export function DouyinMashidaPanel() {
{/* 平台推送回调地址展示 */}
-
-
- 平台侧消息推送地址 (message_url):
-
-
- {messageUrl}
-
-
+
+
+
+
+
+ 平台侧消息推送地址 (message_url):
+
+
+
+
+
+
+ {messageUrl}
+
+ {isMessageUrlLocal ? (
+ ⚠️ 当前为本地地址,请在下方配置公网域名后订阅
+ ) : (
+ ✅ 公网推送就绪
+ )}
+
+
+
diff --git a/apps/frontend/src/utils/douyin-mashida.ts b/apps/frontend/src/utils/douyin-mashida.ts
index 39e8d5cb..2b590572 100644
--- a/apps/frontend/src/utils/douyin-mashida.ts
+++ b/apps/frontend/src/utils/douyin-mashida.ts
@@ -47,6 +47,27 @@ export function buildDouyinMashidaMessageUrl(origin: string): string {
return `${normalized}/api/v1/open/douyin-mashida/message`
}
+/**
+ * 从已配置的 claimLinkBase 或 certLink 中提取公网 origin,未配置时回退到 fallbackOrigin。
+ * 例:`https://nonsecretly-posttracheal-amado.ngrok-free.dev/h5` → `https://nonsecretly-posttracheal-amado.ngrok-free.dev`
+ */
+export function resolveDouyinMashidaPublicOrigin(
+ claimLinkBase?: string,
+ certLink?: string,
+ fallbackOrigin = 'http://localhost',
+): string {
+ const candidate = String(claimLinkBase || certLink || '').trim()
+ if (candidate && /^https?:\/\//i.test(candidate)) {
+ try {
+ const url = new URL(candidate)
+ return url.origin
+ } catch {
+ // 容错
+ }
+ }
+ return fallbackOrigin
+}
+
/**
* 返回缺失项的中文名数组,顺序固定为:接入开关 / 商户uid / 用户秘钥 / 兑换链接。
* 全齐时返回空数组。
diff --git a/apps/frontend/tests/douyin-mashida.test.ts b/apps/frontend/tests/douyin-mashida.test.ts
index fbbfae4d..bd5dfcdd 100644
--- a/apps/frontend/tests/douyin-mashida.test.ts
+++ b/apps/frontend/tests/douyin-mashida.test.ts
@@ -8,6 +8,7 @@ import {
buildDouyinMashidaMessageUrl,
describeMissingConfigFields,
isLocalDevBaseUrl,
+ resolveDouyinMashidaPublicOrigin,
} from '../src/utils/douyin-mashida.ts'
/** 固定顺序:接入开关 / 商户uid / 用户秘钥 / 兑换链接 */
@@ -126,3 +127,19 @@ test('发消息模板提示:没有 {link} 就等于没给买家链接', () =>
assert.equal(describeMessageTemplateWarning(''), '')
assert.match(describeMessageTemplateWarning('您的订单已发货'), /\{link\}/)
})
+
+test('resolveDouyinMashidaPublicOrigin:从已配置的 claimLinkBase 或 certLink 提取公网 origin', () => {
+ assert.equal(
+ resolveDouyinMashidaPublicOrigin('https://nonsecretly-posttracheal-amado.ngrok-free.dev/h5'),
+ 'https://nonsecretly-posttracheal-amado.ngrok-free.dev',
+ )
+ assert.equal(
+ resolveDouyinMashidaPublicOrigin('', 'https://my-domain.com/h5'),
+ 'https://my-domain.com',
+ )
+ assert.equal(
+ resolveDouyinMashidaPublicOrigin('', '', 'http://localhost:5173'),
+ 'http://localhost:5173',
+ )
+})
+