- 数据库新增 099_order_claim_status.sql 迁移,扩展 claim_status、claim_status_reason 等字段 - 后端新增 /claims/h5/:orderNo、UID提交、分销提交接口,保留原有 token 接口双轨兼容 - 增加兑换有效性强拦截:暂停/关闭/退款/取消订单精准阻断并返回友好提示 - 后台新增 POST /admin/orders/:orderId/claim-status 接口与审计日志记录 - 前端管理后台(订单列表、详情页)支持 H5 兑换状态展示、一键复制链接及暂停/关闭/启用弹窗 - 前端领取页面适配 /h5/:orderNo 路由及暂停/关闭等状态的异常展示 - 验证方式:运行前后端类型检查、全量单元测试(后端 674、前端 132)及全量构建编译均通过
63 lines
2.6 KiB
TypeScript
63 lines
2.6 KiB
TypeScript
import assert from 'node:assert/strict'
|
||
import test from 'node:test'
|
||
|
||
import {
|
||
isClaimPath,
|
||
isH5ClaimPath,
|
||
resolveClaimToken,
|
||
resolveH5ClaimOrderNo,
|
||
} from '../src/utils/claim-path.ts'
|
||
|
||
test('isClaimPath:只认路径式 /claim/<token>,容忍结尾斜杠', () => {
|
||
assert.equal(isClaimPath('/claim/abc123'), true)
|
||
assert.equal(isClaimPath('/claim/abc123/'), true)
|
||
assert.equal(isClaimPath('/claim/abc123//'), true)
|
||
})
|
||
|
||
test('isClaimPath:/claim、/claim/、多段路径、其它路径都不算', () => {
|
||
assert.equal(isClaimPath('/claim'), false)
|
||
assert.equal(isClaimPath('/claim/'), false)
|
||
assert.equal(isClaimPath('/claim/a/b'), false)
|
||
assert.equal(isClaimPath('/redeem'), false)
|
||
assert.equal(isClaimPath('/admin/claim/abc'), false)
|
||
assert.equal(isClaimPath('/'), false)
|
||
assert.equal(isClaimPath(''), false)
|
||
assert.equal(isClaimPath(null), false)
|
||
assert.equal(isClaimPath(undefined), false)
|
||
})
|
||
|
||
test('isClaimPath:打手页是 hash 路由,pathname 为 / 或 hash 串时不命中', () => {
|
||
// 打手链接形如 https://<域名>/#/claim/<token>:pathname 是 '/',hash 才是路由
|
||
assert.equal(isClaimPath('/'), false)
|
||
assert.equal(isClaimPath('#/claim/abc123'), false)
|
||
// 路径本身带 token 时,多出来的 hash 片段会被忽略
|
||
assert.equal(isClaimPath('/claim/abc123#/claim/other'), true)
|
||
})
|
||
|
||
test('resolveClaimToken:取出并解码 token 片段', () => {
|
||
assert.equal(resolveClaimToken('/claim/abc123'), 'abc123')
|
||
assert.equal(resolveClaimToken('/claim/abc123/?x=1'), 'abc123')
|
||
assert.equal(resolveClaimToken('/claim/a%2Fb'), 'a/b')
|
||
assert.equal(resolveClaimToken('/claim/%E4%B8%AD%E6%96%87'), '中文')
|
||
// 非法百分号编码退回原始片段,交给后端判定
|
||
assert.equal(resolveClaimToken('/claim/100%'), '100%')
|
||
assert.equal(resolveClaimToken('/redeem'), '')
|
||
})
|
||
|
||
test('isH5ClaimPath:只认路径式 /h5/<orderNo>,容忍结尾斜杠', () => {
|
||
assert.equal(isH5ClaimPath('/h5/2623001922675146'), true)
|
||
assert.equal(isH5ClaimPath('/h5/2623001922675146/'), true)
|
||
assert.equal(isH5ClaimPath('/h5'), false)
|
||
assert.equal(isH5ClaimPath('/h5/'), false)
|
||
assert.equal(isH5ClaimPath('/h5/a/b'), false)
|
||
assert.equal(isH5ClaimPath('/claim/123'), false)
|
||
})
|
||
|
||
test('resolveH5ClaimOrderNo:正确解析并解码订单号', () => {
|
||
assert.equal(resolveH5ClaimOrderNo('/h5/2623001922675146'), '2623001922675146')
|
||
assert.equal(resolveH5ClaimOrderNo('/h5/2623001922675146?from=sms'), '2623001922675146')
|
||
assert.equal(resolveH5ClaimOrderNo('/h5/ORDER-001/'), 'ORDER-001')
|
||
assert.equal(resolveH5ClaimOrderNo('/claim/123'), '')
|
||
})
|
||
|