fix(sid): harden admin assignment flow
This commit is contained in:
@@ -70,6 +70,18 @@ function RulesTab() {
|
||||
}
|
||||
}
|
||||
|
||||
if (rules.isPending) return <p className="text-sm text-muted-foreground">正在加载保留规则…</p>
|
||||
if (rules.isError) {
|
||||
return (
|
||||
<div className="text-sm text-destructive">
|
||||
<p>保留规则加载失败。</p>
|
||||
<Button className="mt-2" variant="outline" size="sm" onClick={() => void rules.refetch()}>
|
||||
重新加载
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="grid gap-3 md:grid-cols-2">
|
||||
{(rules.data?.data ?? []).map((rule) => (
|
||||
@@ -131,6 +143,18 @@ function LuckyTab() {
|
||||
}
|
||||
}
|
||||
|
||||
if (numbers.isPending) return <p className="text-sm text-muted-foreground">正在加载幸运号码…</p>
|
||||
if (numbers.isError) {
|
||||
return (
|
||||
<div className="text-sm text-destructive">
|
||||
<p>幸运号码加载失败。</p>
|
||||
<Button className="mt-2" variant="outline" size="sm" onClick={() => void numbers.refetch()}>
|
||||
重新加载
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex flex-wrap items-end gap-3">
|
||||
@@ -140,8 +164,10 @@ function LuckyTab() {
|
||||
id="lucky-number"
|
||||
className="w-32 font-mono"
|
||||
maxLength={3}
|
||||
inputMode="numeric"
|
||||
pattern="[0-9]{3}"
|
||||
value={draft.number}
|
||||
onChange={(e) => setDraft((d) => ({ ...d, number: e.target.value }))}
|
||||
onChange={(e) => setDraft((d) => ({ ...d, number: e.target.value.replace(/\D/g, '') }))}
|
||||
placeholder="888"
|
||||
/>
|
||||
</div>
|
||||
@@ -198,6 +224,8 @@ function AssignTab() {
|
||||
const [checkResult, setCheckResult] = useState<SidCheckResult | null>(null)
|
||||
const [userUid, setUserUid] = useState('')
|
||||
const [busy, setBusy] = useState(false)
|
||||
const validSid = /^[A-HJ-NPR-Z]{3}-?\d{6}$/i.test(sid)
|
||||
const validUid = /^[0-9A-HJKMNP-TV-Z]{26}$/i.test(userUid)
|
||||
|
||||
const check = async () => {
|
||||
setBusy(true)
|
||||
@@ -238,11 +266,14 @@ function AssignTab() {
|
||||
id="sid-input"
|
||||
className="font-mono"
|
||||
value={sid}
|
||||
onChange={(e) => setSid(e.target.value)}
|
||||
placeholder="668888"
|
||||
onChange={(e) => {
|
||||
setSid(e.target.value.toUpperCase())
|
||||
setCheckResult(null)
|
||||
}}
|
||||
placeholder="ABC-668888"
|
||||
/>
|
||||
</div>
|
||||
<Button variant="outline" onClick={check} disabled={!sid || busy}>
|
||||
<Button variant="outline" onClick={check} disabled={!validSid || busy}>
|
||||
查询
|
||||
</Button>
|
||||
</div>
|
||||
@@ -270,14 +301,21 @@ function AssignTab() {
|
||||
<Input
|
||||
id="assign-uid"
|
||||
className="font-mono"
|
||||
maxLength={26}
|
||||
value={userUid}
|
||||
onChange={(e) => setUserUid(e.target.value)}
|
||||
onChange={(e) => setUserUid(e.target.value.toUpperCase())}
|
||||
placeholder="01JXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
onClick={assign}
|
||||
disabled={!sid || !userUid || busy || (checkResult?.reserved === true && !canOverride)}
|
||||
disabled={
|
||||
!validSid ||
|
||||
!validUid ||
|
||||
!checkResult ||
|
||||
busy ||
|
||||
(checkResult.reserved && !canOverride)
|
||||
}
|
||||
>
|
||||
分配 SID
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user