fix(delivery): 禁用Rock二次生成二维码并治理上游110001频控报错
1. 业务防乱(专属通道锁定):提货页面一旦生成二维码后,直接禁用'重新生成二维码'按钮并锁定游戏UID输入框,杜绝Token浪费与绑定混乱; 2. 频控治理(前端3秒冷却):手动点击'检查扫码状态'增加3秒倒计时防抖冷却,且对'过于频繁/110001'错误进行平滑提示,不再触发大红报错; 3. 频控治理(后端瞬时防抖与软降级):RockService增加800ms内存并发安全防抖缓存,当上游返回110001时自动优雅降级返回等待扫码状态,不抛出HTTP 400错误。
This commit is contained in:
@@ -78,6 +78,15 @@ export default function Delivery() {
|
||||
const [generatingImage, setGeneratingImage] = useState(false)
|
||||
const [copyingImage, setCopyingImage] = useState(false)
|
||||
const [previewModalOpen, setPreviewModalOpen] = useState(false)
|
||||
const [manualCheckCooldown, setManualCheckCooldown] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
if (manualCheckCooldown <= 0) return
|
||||
const timer = setTimeout(() => {
|
||||
setManualCheckCooldown((prev) => Math.max(0, prev - 1))
|
||||
}, 1000)
|
||||
return () => clearTimeout(timer)
|
||||
}, [manualCheckCooldown])
|
||||
|
||||
const decodedOrderNo = useMemo(() => decodeURIComponent(orderNo), [orderNo])
|
||||
const deliveryAuth = useMemo(() => {
|
||||
@@ -225,7 +234,12 @@ export default function Delivery() {
|
||||
}
|
||||
} catch (e) {
|
||||
if (!silent) {
|
||||
message.error(e instanceof Error ? e.message : '检查绑定状态失败')
|
||||
const errStr = e instanceof Error ? e.message : String(e || '')
|
||||
if (errStr.includes('频繁') || errStr.includes('110001')) {
|
||||
message.info('正在同步扫码状态,请稍候...')
|
||||
} else {
|
||||
message.error(errStr || '检查绑定状态失败')
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (!silent) setCheckingBind(false)
|
||||
@@ -234,6 +248,12 @@ export default function Delivery() {
|
||||
[bindResult?.bind_uuid, decodedOrderNo, deliveryAuth]
|
||||
)
|
||||
|
||||
const handleManualCheckBind = () => {
|
||||
if (manualCheckCooldown > 0 || checkingBind) return
|
||||
setManualCheckCooldown(3)
|
||||
checkBindStatus(false)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!bindResult?.bind_uuid || boundInfo?.bound || submitting || submitResult) {
|
||||
return
|
||||
@@ -579,9 +599,13 @@ export default function Delivery() {
|
||||
name="game_account"
|
||||
label="游戏账号(用于接收充值)"
|
||||
rules={[{ required: true, message: '请输入接收道具的游戏账号 UID' }]}
|
||||
extra="请务必核对游戏账号 UID,充值成功后无法撤回"
|
||||
extra={bindResult ? '已锁定专属发货通道,如需修改账号请刷新页面重试' : '请务必核对游戏账号 UID,充值成功后无法撤回'}
|
||||
>
|
||||
<Input placeholder="请输入游戏账号 UID" size="large" />
|
||||
<Input
|
||||
placeholder="请输入游戏账号 UID"
|
||||
size="large"
|
||||
disabled={Boolean(bindResult)}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
|
||||
@@ -591,16 +615,18 @@ export default function Delivery() {
|
||||
icon={<QrcodeOutlined />}
|
||||
loading={binding}
|
||||
onClick={bindAccount}
|
||||
disabled={Boolean(bindResult)}
|
||||
>
|
||||
{bindResult ? '重新生成二维码' : '生成绑定二维码'}
|
||||
{bindResult ? '专属二维码已生成' : '生成绑定二维码'}
|
||||
</Button>
|
||||
{bindResult && !boundInfo?.bound && (
|
||||
<Button
|
||||
icon={<ReloadOutlined />}
|
||||
loading={checkingBind}
|
||||
onClick={() => checkBindStatus(false)}
|
||||
disabled={manualCheckCooldown > 0}
|
||||
onClick={handleManualCheckBind}
|
||||
>
|
||||
检查扫码状态
|
||||
{manualCheckCooldown > 0 ? `检查扫码状态 (${manualCheckCooldown}s)` : '检查扫码状态'}
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
|
||||
Reference in New Issue
Block a user