feat(claim): 支持固定H5订单号领取与订单兑换有效性后台控制
- 数据库新增 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)及全量构建编译均通过
This commit is contained in:
@@ -2,6 +2,10 @@ import { Router } from 'express'
|
||||
|
||||
import { getAdminOrderDetail, getAdminOrders } from '../../services/admin/admin-read-service.js'
|
||||
import { resendAdminOrderKuaishouIndustryVoucherCodes } from '../../services/admin/write/kuaishou-industry-actions.js'
|
||||
import {
|
||||
updateAdminOrderClaimStatus,
|
||||
type UpdateOrderClaimStatusPayload,
|
||||
} from '../../services/admin/write/order-actions.js'
|
||||
import { createJsonHandler, requireAdminRoles } from './session.js'
|
||||
import type { AdminOrderRouteParams, AdminOrderRouteQuery } from '../../types/admin/route-inputs.js'
|
||||
|
||||
@@ -34,6 +38,30 @@ router.get(
|
||||
),
|
||||
)
|
||||
|
||||
router.post(
|
||||
'/orders/:orderId/claim-status',
|
||||
requireAdminRoles(['admin', 'operator', 'support']),
|
||||
createJsonHandler(
|
||||
(req) =>
|
||||
updateAdminOrderClaimStatus(
|
||||
String((req.params as AdminOrderRouteParams).orderId || ''),
|
||||
req.body as UpdateOrderClaimStatusPayload,
|
||||
req.adminSession || null,
|
||||
),
|
||||
{
|
||||
successMessage: '订单兑换状态已更新',
|
||||
errorMessage: '更新订单兑换状态失败',
|
||||
scope: '[admin/orders/:orderId/claim-status]',
|
||||
audit: (req, data) => ({
|
||||
action: 'order_claim_status_update',
|
||||
targetType: 'order',
|
||||
targetId: String((req.params as AdminOrderRouteParams).orderId || ''),
|
||||
data: data && typeof data === 'object' ? (data as Record<string, unknown>) : {},
|
||||
}),
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
router.post(
|
||||
'/orders/:orderId/kuaishou-industry/resend-code',
|
||||
requireAdminRoles(['admin', 'operator', 'support']),
|
||||
@@ -58,3 +86,4 @@ router.post(
|
||||
)
|
||||
|
||||
export default router
|
||||
|
||||
|
||||
@@ -2,9 +2,12 @@ import { Router } from 'express'
|
||||
|
||||
import { createRateLimitMiddleware, getParamRateLimitKey } from '../middleware/rate-limit.js'
|
||||
import {
|
||||
getH5ClaimDetailByOrderNo,
|
||||
getKuaishouCloudClaimDetail,
|
||||
submitAffiliateDashClaim,
|
||||
submitClaimUid,
|
||||
submitH5AffiliateDashClaimByOrderNo,
|
||||
submitH5ClaimUidByOrderNo,
|
||||
} from '../services/claim/kuaishou-cloud-claim-service.js'
|
||||
import { buildNotFoundPayload, createRouteHandler } from '../utils/http.js'
|
||||
|
||||
@@ -22,6 +25,51 @@ const claimWriteRateLimit = createRateLimitMiddleware({
|
||||
key: getParamRateLimitKey('token'),
|
||||
})
|
||||
|
||||
const h5ReadRateLimit = createRateLimitMiddleware({
|
||||
scope: 'claim:h5:read',
|
||||
windowMs: 60_000,
|
||||
max: 120,
|
||||
key: getParamRateLimitKey('orderNo'),
|
||||
})
|
||||
const h5WriteRateLimit = createRateLimitMiddleware({
|
||||
scope: 'claim:h5:write',
|
||||
windowMs: 60_000,
|
||||
max: 30,
|
||||
key: getParamRateLimitKey('orderNo'),
|
||||
})
|
||||
|
||||
router.get(
|
||||
'/h5/:orderNo',
|
||||
h5ReadRateLimit,
|
||||
createRouteHandler((req) => getH5ClaimDetailByOrderNo(req.params.orderNo), {
|
||||
errorMessage: '查询订单领取详情失败',
|
||||
scope: '[claims/h5/:orderNo]',
|
||||
}),
|
||||
)
|
||||
|
||||
router.post(
|
||||
'/h5/:orderNo/uid',
|
||||
h5WriteRateLimit,
|
||||
createRouteHandler((req) => submitH5ClaimUidByOrderNo(req.params.orderNo, req.body || {}), {
|
||||
successMessage: 'UID 已提交',
|
||||
errorMessage: '提交 UID 失败',
|
||||
scope: '[claims/h5/:orderNo/uid]',
|
||||
}),
|
||||
)
|
||||
|
||||
router.post(
|
||||
'/h5/:orderNo/affiliate-dash/submit',
|
||||
h5WriteRateLimit,
|
||||
createRouteHandler(
|
||||
(req) => submitH5AffiliateDashClaimByOrderNo(req.params.orderNo, req.body || {}),
|
||||
{
|
||||
successMessage: '发货已提交',
|
||||
errorMessage: '提交发货失败',
|
||||
scope: '[claims/h5/:orderNo/affiliate-dash/submit]',
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
router.get(
|
||||
'/:token',
|
||||
claimReadRateLimit,
|
||||
|
||||
Reference in New Issue
Block a user