feat(admin): 后台新增「抖音码速达」配置面板
- 新增 Tab:/admin/platform-shops?tab=douyinMashida - 面板字段:enabled / baseUrl / uid / secret / certLink / afterVerifyLink / afterVerifyMessage / messageType / timeoutMs / handledTopics(tags) - 密钥脱敏:出参 secret 永远为空,输入框未编辑时对外 value 恒为 '', 掩码不会污染后端「空串=保留原值」语义 - 顶部展示 ready 状态,未就绪时用 Alert 列出缺哪几项; 始终展示平台侧要配的推送地址(可复制) - baseUrl 命中本地地址时提示「当前指向本地网关桩,不会请求真实码速达」 - 把 AdminPlatformShopsPage 内联的 SecretFieldControl 抽成共享组件 (函数体与原实现逐字节一致,8 处既有调用点参数不变)
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* 抖音码速达后台配置的纯展示 / 校验逻辑。
|
||||
*
|
||||
* 刻意写成纯函数:不依赖 React / antd,也不使用 `@/` 别名,只做 `import type`,
|
||||
* 方便 `node --experimental-strip-types --test` 直接跑单测。
|
||||
*/
|
||||
import type { AdminDouyinMashidaConfig } from '../types/admin/platform-config'
|
||||
|
||||
/** 配置完整度检查所需的配置子集 */
|
||||
type MissingConfigCheck = Pick<
|
||||
AdminDouyinMashidaConfig,
|
||||
'enabled' | 'uid' | 'hasSecret' | 'certLink'
|
||||
>
|
||||
|
||||
/** 配置完整度检查的固定展示顺序 */
|
||||
const MISSING_FIELD_LABELS = ['接入开关', '商户uid', '用户秘钥', '兑换链接'] as const
|
||||
|
||||
/** 本地/内网 host:命中即认为不会请求真实码速达 */
|
||||
const LOCAL_DEV_HOSTS = new Set(['127.0.0.1', 'localhost', 'host.docker.internal'])
|
||||
|
||||
/**
|
||||
* 判断 baseUrl 是否指向本地/内网地址(这类地址平台永远访问不到)。
|
||||
*
|
||||
* 容忍端口、结尾斜杠、大小写与缺失协议(如 `127.0.0.1:3000`)。
|
||||
* 无法解析的地址一律视为非本地。
|
||||
*/
|
||||
export function isLocalDevBaseUrl(baseUrl: string): boolean {
|
||||
const text = String(baseUrl ?? '').trim()
|
||||
if (!text) return false
|
||||
|
||||
try {
|
||||
const url = new URL(text.includes('://') ? text : `http://${text}`)
|
||||
return LOCAL_DEV_HOSTS.has(url.hostname.toLowerCase())
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 拼接平台侧需要配置的消息推送地址(容错结尾斜杠)。
|
||||
* 例:`https://ks.khhao.com/` → `https://ks.khhao.com/api/v1/open/douyin-mashida/message`
|
||||
*/
|
||||
export function buildDouyinMashidaMessageUrl(origin: string): string {
|
||||
const normalized = String(origin ?? '')
|
||||
.trim()
|
||||
.replace(/\/+$/, '')
|
||||
return `${normalized}/api/v1/open/douyin-mashida/message`
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回缺失项的中文名数组,顺序固定为:接入开关 / 商户uid / 用户秘钥 / 兑换链接。
|
||||
* 全齐时返回空数组。
|
||||
*/
|
||||
export function describeMissingConfigFields(config: MissingConfigCheck): string[] {
|
||||
const source = config ?? ({} as MissingConfigCheck)
|
||||
const missing: string[] = []
|
||||
|
||||
if (!source.enabled) missing.push(MISSING_FIELD_LABELS[0])
|
||||
if (!String(source.uid ?? '').trim()) missing.push(MISSING_FIELD_LABELS[1])
|
||||
if (!source.hasSecret) missing.push(MISSING_FIELD_LABELS[2])
|
||||
if (!String(source.certLink ?? '').trim()) missing.push(MISSING_FIELD_LABELS[3])
|
||||
|
||||
return missing
|
||||
}
|
||||
Reference in New Issue
Block a user