Files
order_site/apps/frontend/src/pages/claim/H5ClaimEntryPage.tsx
T
yml2213 7e197c9413 fix(frontend): H5 领取前缀整段接管,/h5 裸链接不再跳后台登录
根因:公开路径判定原先只认「带参数」形态(isH5ClaimPath 只认 /h5/<orderNo>),
裸前缀 https://<域名>/h5(后台 claimLinkBase / certLink 的基址)判定不命中,
于是落回主站 HashRouter 被后台路由接管成
https://<域名>/h5/#/admin/dashboard 后台登录页。

- utils/claim-path.ts:isClaimPath / isH5ClaimPath 改为命名空间级判定(含裸前缀与多段路径),
  参数解析仍严格;新增 resolveH5ClaimOrderNoFromInput(纯订单号 / 整条链接 / 缺协议 /
  带后台残留 hash 都能取出订单号,只有前缀时返回空串)
- pages/claim/H5ClaimEntryPage.tsx:新增 /h5 领取入口页,买家输订单号或粘贴完整链接后
  跳 /h5/<订单号>,走与分享链接同一套领取流程
- App.tsx:H5ClaimApplication 接管 /h5 整段前缀(/h5 入口页、/h5/:orderNo 领取页、
  其它子路径回入口页);useClearStrayHash 抹掉历史残留的 #/admin/dashboard
- tests/claim-path.test.ts:补齐裸前缀、相邻前缀 /h5x、粘贴链接解析等回归用例

验证:npm run check 全绿(prettier + eslint + tsc + 143 单测 + vite build)
2026-10-13 13:42:06 +08:00

57 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { SearchOutlined } from '@ant-design/icons'
import { Button, Card, Form, Input, Typography } from 'antd'
import { useNavigate } from 'react-router'
import { showError } from '@/lib/feedback'
import { resolveH5ClaimOrderNoFromInput } from '@/utils/claim-path'
/**
* H5 领取入口页(`https://<域名>/h5`,不带订单号)。
*
* 这条前缀**只允许用来领取**:买家输入订单号后跳到 `/h5/<订单号>`,走与分享链接完全相同的领取流程。
*
* 为什么必须有这个页面:后台配置的 `claimLinkBase` / `certLink` 都是 `https://<域名>/h5`,
* 平台/客服可能直接把基址给买家。历史上这条路径没有命中任何领取判定,于是落回主站 HashRouter
* 被后台路由接管,买家点开看到的是 `https://<域名>/h5/#/admin/dashboard` 后台登录页。
* 现在 `/h5` 整段前缀由领取应用接管,这里给出「补订单号」的入口,把链接救回来。
*/
export default function H5ClaimEntryPage() {
const navigate = useNavigate()
function handleSubmit(values: { orderNo?: string }) {
const orderNo = resolveH5ClaimOrderNoFromInput(values.orderNo)
if (!orderNo) {
showError('没有识别到订单号,请粘贴完整领取链接或直接输入订单号')
return
}
void navigate(`/h5/${encodeURIComponent(orderNo)}`)
}
return (
<main className="claim-page h5-claim-entry">
<Card className="claim-content-card">
<Typography.Title level={3} style={{ margin: 0 }}>
订单领取
</Typography.Title>
<Typography.Paragraph type="secondary" style={{ margin: 0 }}>
输入订单号即可进入领取流程;也可以直接粘贴完整的领取链接(形如 https://…/h5/订单号)。
</Typography.Paragraph>
<Form layout="vertical" onFinish={handleSubmit}>
<Form.Item
name="orderNo"
label="订单号"
rules={[{ required: true, message: '请输入订单号' }]}
>
<Input size="large" placeholder="订单号 / 领取链接" autoComplete="off" allowClear />
</Form.Item>
<Button type="primary" size="large" block htmlType="submit" icon={<SearchOutlined />}>
开始领取
</Button>
</Form>
</Card>
</main>
)
}