优化领取页第一步文案示意与 Mock 表单
- 游戏编号文案与红色提示,底部增加编号位置示意图 - 压缩商品信息卡片,示意图移至最下方 - 开发 Mock 在待填 UID 步骤下 UID 改为可选
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 209 KiB |
@@ -128,82 +128,20 @@ export default function AdminDevMockPage() {
|
|||||||
<Row gutter={[16, 16]}>
|
<Row gutter={[16, 16]}>
|
||||||
<Col xs={24} xl={12}>
|
<Col xs={24} xl={12}>
|
||||||
<Card title="1. lewan 领取(强制 UID)" bordered={false}>
|
<Card title="1. lewan 领取(强制 UID)" bordered={false}>
|
||||||
<Form
|
<LewanMockForm
|
||||||
layout="vertical"
|
defaultUid={status?.defaultUid || '10001'}
|
||||||
initialValues={{
|
loading={lewanMutation.isPending}
|
||||||
step: 'binding',
|
onSubmit={(values) => lewanMutation.mutate(values)}
|
||||||
uid: status?.defaultUid || '10001',
|
|
||||||
productNo: '套餐_1----3676797936',
|
|
||||||
}}
|
|
||||||
onFinish={(values) => lewanMutation.mutate(values)}
|
|
||||||
>
|
|
||||||
<Form.Item
|
|
||||||
label="页面步骤"
|
|
||||||
name="step"
|
|
||||||
tooltip="uid=只到填 UID;binding=已预填 UID 且角色匹配;confirm/result=后续步骤"
|
|
||||||
>
|
|
||||||
<Select
|
|
||||||
options={[
|
|
||||||
{ value: 'uid', label: 'uid · 待填 UID' },
|
|
||||||
{ value: 'binding', label: 'binding · 绑定且 UID 已匹配(推荐)' },
|
|
||||||
{ value: 'confirm', label: 'confirm · 待确认兑换' },
|
|
||||||
{ value: 'result', label: 'result · 已完成' },
|
|
||||||
]}
|
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="游戏 UID" name="uid" rules={[{ required: true, message: '请填 UID' }]}>
|
|
||||||
<Input placeholder="10001" />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="91 商品 productNo" name="productNo">
|
|
||||||
<Input placeholder="套餐_1----3676797936" />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="订单号 orderNo(可空自动生成)" name="orderNo">
|
|
||||||
<Input placeholder="留空自动 MOCK91…" />
|
|
||||||
</Form.Item>
|
|
||||||
<Button type="primary" htmlType="submit" loading={lewanMutation.isPending} block>
|
|
||||||
生成 lewan Mock
|
|
||||||
</Button>
|
|
||||||
</Form>
|
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
<Col xs={24} xl={12}>
|
<Col xs={24} xl={12}>
|
||||||
<Card title="2. feifei 领取(拼 UID 到 H5)" bordered={false}>
|
<Card title="2. feifei 领取(拼 UID 到 H5)" bordered={false}>
|
||||||
<Form
|
<FeifeiMockForm
|
||||||
layout="vertical"
|
loading={feifeiMutation.isPending}
|
||||||
initialValues={{
|
onSubmit={(values) => feifeiMutation.mutate(values)}
|
||||||
step: 'ready',
|
|
||||||
uid: '166909256',
|
|
||||||
productName: '套装-浪漫天命',
|
|
||||||
}}
|
|
||||||
onFinish={(values) => feifeiMutation.mutate(values)}
|
|
||||||
>
|
|
||||||
<Form.Item label="页面步骤" name="step">
|
|
||||||
<Select
|
|
||||||
options={[
|
|
||||||
{ value: 'uid', label: 'uid · 待填 UID' },
|
|
||||||
{ value: 'ready', label: 'ready · 已填 UID,可打开 H5(推荐)' },
|
|
||||||
{ value: 'completed', label: 'completed · 模拟成功' },
|
|
||||||
{ value: 'failed', label: 'failed · 模拟失败' },
|
|
||||||
]}
|
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="游戏 UID" name="uid" rules={[{ required: true, message: '请填 UID' }]}>
|
|
||||||
<Input placeholder="166909256" />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="商品名" name="productName">
|
|
||||||
<Input />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="H5 链接(可空用 mock 地址)" name="h5Url">
|
|
||||||
<Input placeholder="http://skin-exchange.../h5/bind?code=..." />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="订单号 orderNo(可空)" name="orderNo">
|
|
||||||
<Input placeholder="留空自动 MOCKFF…" />
|
|
||||||
</Form.Item>
|
|
||||||
<Button type="primary" htmlType="submit" loading={feifeiMutation.isPending} block>
|
|
||||||
生成 feifei Mock
|
|
||||||
</Button>
|
|
||||||
</Form>
|
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
@@ -357,3 +295,136 @@ export default function AdminDevMockPage() {
|
|||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function LewanMockForm({
|
||||||
|
defaultUid,
|
||||||
|
loading,
|
||||||
|
onSubmit,
|
||||||
|
}: {
|
||||||
|
defaultUid: string
|
||||||
|
loading: boolean
|
||||||
|
onSubmit: (values: Record<string, unknown>) => void
|
||||||
|
}) {
|
||||||
|
const [form] = Form.useForm()
|
||||||
|
const step = Form.useWatch('step', form)
|
||||||
|
const uidRequired = step !== 'uid'
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form
|
||||||
|
form={form}
|
||||||
|
layout="vertical"
|
||||||
|
initialValues={{
|
||||||
|
step: 'uid',
|
||||||
|
uid: defaultUid || '10001',
|
||||||
|
productNo: '套餐_1----3676797936',
|
||||||
|
}}
|
||||||
|
onFinish={onSubmit}
|
||||||
|
>
|
||||||
|
<Form.Item
|
||||||
|
label="页面步骤"
|
||||||
|
name="step"
|
||||||
|
tooltip="uid=只到填编号第一步;binding=已预填编号且角色匹配;confirm/result=后续步骤"
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
options={[
|
||||||
|
{ value: 'uid', label: 'uid · 待填 UID(第一步)' },
|
||||||
|
{ value: 'binding', label: 'binding · 绑定且 UID 已匹配(推荐)' },
|
||||||
|
{ value: 'confirm', label: 'confirm · 待确认兑换' },
|
||||||
|
{ value: 'result', label: 'result · 已完成' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="游戏 UID"
|
||||||
|
name="uid"
|
||||||
|
required={uidRequired}
|
||||||
|
rules={
|
||||||
|
uidRequired
|
||||||
|
? [{ required: true, whitespace: true, message: '后续步骤请填写游戏 UID' }]
|
||||||
|
: []
|
||||||
|
}
|
||||||
|
extra={
|
||||||
|
step === 'uid'
|
||||||
|
? '「待填 UID」步骤可不填,打开领取页会停留在第一步让用户填写'
|
||||||
|
: '后续步骤用于模拟已提交的编号,建议与默认角色一致(如 10001)'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Input allowClear placeholder={defaultUid || '10001'} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="91 商品 productNo" name="productNo">
|
||||||
|
<Input placeholder="套餐_1----3676797936" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="订单号 orderNo(可空自动生成)" name="orderNo">
|
||||||
|
<Input placeholder="留空自动 MOCK91…" />
|
||||||
|
</Form.Item>
|
||||||
|
<Button type="primary" htmlType="submit" loading={loading} block>
|
||||||
|
生成 lewan Mock
|
||||||
|
</Button>
|
||||||
|
</Form>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function FeifeiMockForm({
|
||||||
|
loading,
|
||||||
|
onSubmit,
|
||||||
|
}: {
|
||||||
|
loading: boolean
|
||||||
|
onSubmit: (values: Record<string, unknown>) => void
|
||||||
|
}) {
|
||||||
|
const [form] = Form.useForm()
|
||||||
|
const step = Form.useWatch('step', form)
|
||||||
|
const uidRequired = step !== 'uid'
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form
|
||||||
|
form={form}
|
||||||
|
layout="vertical"
|
||||||
|
initialValues={{
|
||||||
|
step: 'uid',
|
||||||
|
uid: '166909256',
|
||||||
|
productName: '套装-浪漫天命',
|
||||||
|
}}
|
||||||
|
onFinish={onSubmit}
|
||||||
|
>
|
||||||
|
<Form.Item label="页面步骤" name="step">
|
||||||
|
<Select
|
||||||
|
options={[
|
||||||
|
{ value: 'uid', label: 'uid · 待填 UID(第一步)' },
|
||||||
|
{ value: 'ready', label: 'ready · 已填 UID,可打开 H5(推荐)' },
|
||||||
|
{ value: 'completed', label: 'completed · 模拟成功' },
|
||||||
|
{ value: 'failed', label: 'failed · 模拟失败' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="游戏 UID"
|
||||||
|
name="uid"
|
||||||
|
required={uidRequired}
|
||||||
|
rules={
|
||||||
|
uidRequired
|
||||||
|
? [{ required: true, whitespace: true, message: '后续步骤请填写游戏 UID' }]
|
||||||
|
: []
|
||||||
|
}
|
||||||
|
extra={
|
||||||
|
step === 'uid'
|
||||||
|
? '「待填 UID」步骤可不填,打开领取页会停留在第一步让用户填写'
|
||||||
|
: '后续步骤用于模拟已提交的编号'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Input allowClear placeholder="166909256" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="商品名" name="productName">
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="H5 链接(可空用 mock 地址)" name="h5Url">
|
||||||
|
<Input placeholder="http://skin-exchange.../h5/bind?code=..." />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="订单号 orderNo(可空)" name="orderNo">
|
||||||
|
<Input placeholder="留空自动 MOCKFF…" />
|
||||||
|
</Form.Item>
|
||||||
|
<Button type="primary" htmlType="submit" loading={loading} block>
|
||||||
|
生成 feifei Mock
|
||||||
|
</Button>
|
||||||
|
</Form>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Alert, Button, Card, Input, Space, Typography } from 'antd'
|
import { Button, Card, Input, Space, Typography } from 'antd'
|
||||||
import type { ClaimProductInfo } from '@/types/claim'
|
import type { ClaimProductInfo } from '@/types/claim'
|
||||||
import { ClaimProductItems, InfoTile } from './claim-shared'
|
import { ClaimProductItems, InfoTile } from './claim-shared'
|
||||||
|
import gameRoleIdGuide from '@/assets/claim/game-role-id-guide.jpg'
|
||||||
|
|
||||||
export function ClaimUidStep({
|
export function ClaimUidStep({
|
||||||
uidInput,
|
uidInput,
|
||||||
@@ -17,38 +18,45 @@ export function ClaimUidStep({
|
|||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<Card className="claim-content-card">
|
<Card className="claim-content-card">
|
||||||
<Typography.Title level={2}>第 1 步:填写游戏 UID</Typography.Title>
|
<Typography.Title level={2}>第 1 步:填写游戏编号(数字的那个)</Typography.Title>
|
||||||
<p className="claim-muted">
|
<p className="claim-muted">
|
||||||
请填写你要领取的游戏角色 UID。提交后系统会按平台继续绑定或跳转领取。
|
请填写你要领取的游戏角色编号(纯数字)。提交后系统会按平台继续绑定或跳转领取。
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className="claim-info-grid">
|
<div className="claim-info-grid claim-info-grid-compact">
|
||||||
<InfoTile label="领取商品" value={product?.title || '-'} />
|
<InfoTile label="领取商品" value={product?.title || '-'} />
|
||||||
<InfoTile label="商品数量" value={String(product?.quantity || 0)} />
|
<InfoTile label="商品数量" value={String(product?.quantity || 0)} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ClaimProductItems product={product} />
|
<ClaimProductItems product={product} compact />
|
||||||
|
|
||||||
<Space direction="vertical" size={12} style={{ width: '100%' }}>
|
<Space direction="vertical" size={12} style={{ width: '100%' }}>
|
||||||
<Input
|
<Input
|
||||||
size="large"
|
size="large"
|
||||||
placeholder="请输入游戏 UID"
|
placeholder="请输入游戏编号(纯数字)"
|
||||||
value={uidInput}
|
value={uidInput}
|
||||||
maxLength={64}
|
maxLength={64}
|
||||||
|
inputMode="numeric"
|
||||||
onChange={(event) => onChange(event.target.value)}
|
onChange={(event) => onChange(event.target.value)}
|
||||||
onPressEnter={onSubmit}
|
onPressEnter={onSubmit}
|
||||||
/>
|
/>
|
||||||
<Button type="primary" size="large" loading={submitting} onClick={onSubmit} block>
|
<Button type="primary" size="large" loading={submitting} onClick={onSubmit} block>
|
||||||
确认 UID,下一步
|
确认编号,下一步
|
||||||
</Button>
|
</Button>
|
||||||
</Space>
|
</Space>
|
||||||
|
|
||||||
<Alert
|
<p className="claim-uid-warning">
|
||||||
type="info"
|
游戏编号需与游戏内角色编号一致,填错将导致无法发货。
|
||||||
showIcon
|
</p>
|
||||||
style={{ marginTop: 16 }}
|
|
||||||
message="UID 需与游戏内角色 ID 一致,填错将导致无法发货。"
|
<div className="claim-uid-guide">
|
||||||
|
<img
|
||||||
|
src={gameRoleIdGuide}
|
||||||
|
alt="游戏编号位置示意:复制游戏内角色编号提交纯数字"
|
||||||
|
className="claim-uid-guide-image"
|
||||||
/>
|
/>
|
||||||
|
<p className="claim-uid-guide-caption">示意:复制游戏内「编号」处的纯数字提交</p>
|
||||||
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ function resolveProgressText(options: {
|
|||||||
isUidMatched: boolean
|
isUidMatched: boolean
|
||||||
}) {
|
}) {
|
||||||
if (!options.hasExpectedUid) {
|
if (!options.hasExpectedUid) {
|
||||||
return '请填写游戏 UID'
|
return '请填写游戏编号'
|
||||||
}
|
}
|
||||||
if (options.isFeifeiFlow) {
|
if (options.isFeifeiFlow) {
|
||||||
return options.feifei?.rechargeStatusLabel || `UID ${options.expectedUid},请打开领取链接`
|
return options.feifei?.rechargeStatusLabel || `UID ${options.expectedUid},请打开领取链接`
|
||||||
|
|||||||
@@ -757,6 +757,63 @@ select {
|
|||||||
gap: 14px;
|
gap: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.claim-info-grid-compact {
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.claim-info-grid-compact .claim-info-item {
|
||||||
|
padding: 8px 10px;
|
||||||
|
gap: 2px;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.claim-info-grid-compact .claim-info-item span {
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.claim-info-grid-compact .claim-info-item strong {
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.35;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.claim-uid-guide {
|
||||||
|
margin: 14px 0 0;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #f8fafc;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.claim-uid-guide-image {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 420px;
|
||||||
|
margin: 0 auto;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
object-fit: contain;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.claim-uid-guide-caption {
|
||||||
|
margin: 8px 0 0;
|
||||||
|
text-align: center;
|
||||||
|
color: #64748b;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.claim-uid-warning {
|
||||||
|
margin: 14px 0 0;
|
||||||
|
color: #ff4d4f;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
.claim-info-item {
|
.claim-info-item {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
|
|||||||
Reference in New Issue
Block a user