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:
yml2213
2026-10-10 18:05:46 +08:00
parent 2d727a6797
commit 412d219cca
21 changed files with 788 additions and 50 deletions
+19 -1
View File
@@ -11,7 +11,7 @@ import {
} from 'react-router'
import { getAdminRole, hasAdminSession } from '@/utils/admin-auth'
import { isClaimPath } from '@/utils/claim-path'
import { isClaimPath, isH5ClaimPath } from '@/utils/claim-path'
import { isRedeemPath } from '@/utils/redeem'
import { isWorkerSite, WORKER_SITE_ORIGIN } from '@/utils/site'
import { hasWorkerSession } from '@/utils/worker-auth'
@@ -100,6 +100,11 @@ export default function App() {
return <ClaimApplication />
}
// 路径式 H5 订单号领取链接(`https://<域名>/h5/<订单号>`,不带 `#`)
if (isH5ClaimPath(window.location.pathname)) {
return <H5ClaimApplication />
}
// 固定兑换链接是路径式(`https://<域名>/redeem`,不带 `#`),必须早于站点判断,
// 用独立的 BrowserRouter 分支承载,主站 HashRouter 不受影响。
if (isRedeemPath(window.location.pathname)) {
@@ -190,6 +195,19 @@ function ClaimApplication() {
)
}
function H5ClaimApplication() {
return (
<BrowserRouter>
<Suspense fallback={<RouteLoading />}>
<Routes>
<Route path="/h5/:orderNo" element={<ClaimPage />} />
<Route path="*" element={<ClaimPage />} />
</Routes>
</Suspense>
</BrowserRouter>
)
}
function WorkerApplication() {
return (
<BrowserRouter>