**面板新增三项(抖音码速达接入配置)**
- 领取链接基址 (claimLinkBase):带实时预览「皮肤订单最终链接」,并拦截两类误配 ——
带 `#`(`#/claim` 是打手领取页,会把买家带进绑定 UID 流程)、缺 http(s) 协议
- 发消息模板 (messageTemplate):提示可用占位符;模板里没有 `{link}` 直接报错提示
- 付款后发领取消息开关 (claimMessageEnabled)
- 顺带把默认出网超时的展示值对齐后端(10s → 20s)
**后台可见买家提交的账号(运营发货依据)**
- `getAdminTaskDetail` 新增 `claimSubmission`,按 `canViewSensitiveTaskData` 门禁下发
(与 claimToken 明文同一门禁);任务详情新增「买家提交信息」卡片(可一键复制账号)
**修正:皮肤任务的领取链接**
- 详情接口原来用全局 `buildClaimUrl`(默认 hash 形式 `…/#/claim/…`),那是**打手**领取页;
皮肤任务改用 `claimLinkBase + '/' + token`,运营复制给买家的链接才是买家页
- 顺带把「履约渠道」筛选项加上「皮肤自动发货」、任务详情执行器标签加上它、
「来源渠道」加上「抖音码速达」(此前筛不出来抖音订单)
129 lines
4.6 KiB
TypeScript
129 lines
4.6 KiB
TypeScript
import assert from 'node:assert/strict'
|
||
import test from 'node:test'
|
||
|
||
import {
|
||
buildDouyinMashidaClaimLinkPreview,
|
||
describeClaimLinkBaseWarning,
|
||
describeMessageTemplateWarning,
|
||
buildDouyinMashidaMessageUrl,
|
||
describeMissingConfigFields,
|
||
isLocalDevBaseUrl,
|
||
} from '../src/utils/douyin-mashida.ts'
|
||
|
||
/** 固定顺序:接入开关 / 商户uid / 用户秘钥 / 兑换链接 */
|
||
const ALL_MISSING = ['接入开关', '商户uid', '用户秘钥', '兑换链接']
|
||
|
||
test('isLocalDevBaseUrl:127.0.0.1 / localhost / host.docker.internal(含端口与结尾斜杠)判为 true', () => {
|
||
assert.equal(isLocalDevBaseUrl('http://127.0.0.1:3000'), true)
|
||
assert.equal(isLocalDevBaseUrl('http://127.0.0.1:3000/'), true)
|
||
assert.equal(isLocalDevBaseUrl('http://127.0.0.1'), true)
|
||
assert.equal(isLocalDevBaseUrl('http://localhost:8080/'), true)
|
||
assert.equal(isLocalDevBaseUrl('http://localhost'), true)
|
||
assert.equal(isLocalDevBaseUrl('http://host.docker.internal:3000/'), true)
|
||
assert.equal(isLocalDevBaseUrl(' http://localhost:5173// '), true)
|
||
})
|
||
|
||
test('isLocalDevBaseUrl:线上地址 / 空串 / 非本地域名判为 false', () => {
|
||
assert.equal(isLocalDevBaseUrl('https://dy-openplatform-api.wanmahui.com'), false)
|
||
assert.equal(isLocalDevBaseUrl('https://dy-openplatform-api.wanmahui.com/'), false)
|
||
assert.equal(isLocalDevBaseUrl(''), false)
|
||
assert.equal(isLocalDevBaseUrl(' '), false)
|
||
assert.equal(isLocalDevBaseUrl('http://example.com'), false)
|
||
assert.equal(isLocalDevBaseUrl('http://notlocalhost:3000'), false)
|
||
})
|
||
|
||
test('buildDouyinMashidaMessageUrl:拼接推送地址并容忍结尾斜杠', () => {
|
||
const suffix = '/api/v1/open/douyin-mashida/message'
|
||
assert.equal(
|
||
buildDouyinMashidaMessageUrl('https://ks.khhao.com'),
|
||
`https://ks.khhao.com${suffix}`,
|
||
)
|
||
assert.equal(
|
||
buildDouyinMashidaMessageUrl('https://ks.khhao.com/'),
|
||
`https://ks.khhao.com${suffix}`,
|
||
)
|
||
assert.equal(
|
||
buildDouyinMashidaMessageUrl('http://127.0.0.1:3000//'),
|
||
`http://127.0.0.1:3000${suffix}`,
|
||
)
|
||
})
|
||
|
||
test('describeMissingConfigFields:四项齐全返回空数组', () => {
|
||
assert.deepEqual(
|
||
describeMissingConfigFields({
|
||
enabled: true,
|
||
uid: 'uid_123',
|
||
hasSecret: true,
|
||
certLink: 'https://ks.khhao.com/redeem',
|
||
}),
|
||
[],
|
||
)
|
||
})
|
||
|
||
test('describeMissingConfigFields:缺多项按固定顺序返回中文名', () => {
|
||
assert.deepEqual(
|
||
describeMissingConfigFields({ enabled: false, uid: '', hasSecret: false, certLink: '' }),
|
||
ALL_MISSING,
|
||
)
|
||
})
|
||
|
||
test('describeMissingConfigFields:缺单项只返回对应中文名', () => {
|
||
assert.deepEqual(
|
||
describeMissingConfigFields({
|
||
enabled: true,
|
||
uid: 'uid_123',
|
||
hasSecret: false,
|
||
certLink: 'https://ks.khhao.com/redeem',
|
||
}),
|
||
['用户秘钥'],
|
||
)
|
||
assert.deepEqual(
|
||
describeMissingConfigFields({
|
||
enabled: false,
|
||
uid: 'uid_123',
|
||
hasSecret: true,
|
||
certLink: ' ',
|
||
}),
|
||
['接入开关', '兑换链接'],
|
||
)
|
||
})
|
||
|
||
test('领取链接预览 = 基址去尾斜杠 + token', () => {
|
||
assert.equal(
|
||
buildDouyinMashidaClaimLinkPreview('https://x.ngrok-free.app/claim', 'tok123'),
|
||
'https://x.ngrok-free.app/claim/tok123',
|
||
)
|
||
// 尾斜杠与前后空格要容忍
|
||
assert.equal(
|
||
buildDouyinMashidaClaimLinkPreview(' https://x.example.com/claim/ ', 'tok123'),
|
||
'https://x.example.com/claim/tok123',
|
||
)
|
||
// 裸域名也允许(后端统一补 /token)
|
||
assert.equal(
|
||
buildDouyinMashidaClaimLinkPreview('https://x.example.com', 'tok123'),
|
||
'https://x.example.com/tok123',
|
||
)
|
||
// 留空 → 不生成链接(后端回退到通用兑换链接)
|
||
assert.equal(buildDouyinMashidaClaimLinkPreview(''), '')
|
||
assert.equal(buildDouyinMashidaClaimLinkPreview(' '), '')
|
||
})
|
||
|
||
test('领取链接基址误配提示:拦 # 与缺协议', () => {
|
||
assert.equal(describeClaimLinkBaseWarning('https://x.example.com/claim'), '')
|
||
assert.equal(describeClaimLinkBaseWarning(''), '')
|
||
|
||
// # 是打手领取页,必须拦(真实踩坑点)
|
||
const hashWarning = describeClaimLinkBaseWarning('https://x.example.com/#/claim')
|
||
assert.match(hashWarning, /#/)
|
||
assert.match(hashWarning, /打手/)
|
||
|
||
const protocolWarning = describeClaimLinkBaseWarning('x.example.com/claim')
|
||
assert.match(protocolWarning, /https:\/\//)
|
||
})
|
||
|
||
test('发消息模板提示:没有 {link} 就等于没给买家链接', () => {
|
||
assert.equal(describeMessageTemplateWarning('您的订单已发货,请点击领取:{link}'), '')
|
||
assert.equal(describeMessageTemplateWarning(''), '')
|
||
assert.match(describeMessageTemplateWarning('您的订单已发货'), /\{link\}/)
|
||
})
|