购买页面 & IP提取页面样式调整

This commit is contained in:
Eamon-meng
2026-04-27 17:08:41 +08:00
parent 78d916ade1
commit 574ad0e662
7 changed files with 102 additions and 87 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "lanhu-web",
"version": "1.10.0",
"version": "1.11.0",
"private": true,
"scripts": {
"dev": "next dev -H 0.0.0.0 --turbopack",

View File

@@ -71,7 +71,7 @@ export default function Extract(props: ExtractProps) {
)}
>
<CardSection>
<Alert variant="warn" className="flex items-center justify-between">
{/* <Alert variant="warn" className="flex items-center justify-between">
<span className="flex items-center gap-2">
<CircleAlert/>
<AlertTitle className="flex text-gray-900">提取IP前需要将本机IP添加到白名单后才可使用</AlertTitle>
@@ -83,7 +83,7 @@ export default function Extract(props: ExtractProps) {
<span>添加白名单</span>
<ArrowRight className="size-4"/>
</Link>
</Alert>
</Alert> */}
<FormFields/>
</CardSection>
@@ -494,6 +494,8 @@ function SelectRegion() {
const regionType = useWatch({control, name: 'regionType'})
const prov = useWatch({control, name: 'prov'})
const city = useWatch({control, name: 'city'})
console.log(regionType, 'regionType')
console.log(prov, 'prov', city, 'city')
return (
<div className="flex flex-col gap-4 md:max-w-[calc(160px*2+1rem)]">
@@ -604,25 +606,40 @@ function ApplyLink() {
}
return (
<div className={merge(
`flex flex-col gap-4`,
`rounded-lg`,
)}>
<h4>API </h4>
<div className="flex flex-col gap-3 rounded-lg">
<Alert variant="warn" className="flex items-center justify-between">
<div className="flex items-center gap-2">
<CircleAlert className="size-4 shrink-0"/>
<AlertTitle className="text-orange-600">
IP IP 使
</AlertTitle>
</div>
<Link href="/admin/whitelist" className="flex-none text-orange-600 font-medium flex items-center gap-1">
<span></span>
<ArrowRight className="size-4"/>
</Link>
</Alert>
{/* 展示链接地址 */}
<div className="bg-secondary p-4 rounded-md break-all">
<Alert className="flex items-center justify-between">
<div className="flex items-center gap-2">
<CircleAlert className="size-4 shrink-0"/>
<AlertTitle> socks5 http </AlertTitle>
</div>
<div className="w-[88px]"/>
</Alert>
<h4 className="text-base font-medium">API </h4>
<div className="bg-gray-100 rounded-md p-4 break-all font-mono text-sm">
{link(form.getValues())}
</div>
{/* 操作 */}
<div className="flex gap-4">
<Button type="button" onClick={() => submit('copy')}>
<CopyIcon/>
<div className="flex gap-3">
<Button type="button" onClick={() => submit('copy')} className="gap-1">
<CopyIcon className="size-4"/>
<span></span>
</Button>
<Button type="button" onClick={() => submit('open')}>
<ExternalLinkIcon/>
<Button type="button" onClick={() => submit('open')} className="gap-1">
<ExternalLinkIcon className="size-4"/>
<span></span>
</Button>
</div>

View File

@@ -81,6 +81,35 @@ export default function Center({skuData}: {
return (
<Card className="flex-auto p-6 flex flex-col gap-10 relative">
<BillingMethodField modeList={modeList} timeDailyLimit={100}/>
{/* 套餐时效 */}
{type === '1' && (
<FormField name="expire" label="套餐有效时间" description="有效时间内可用于提取 IP">
{({id, field}) => (
<RadioGroup
id={id}
value={field.value}
onValueChange={(value) => {
field.onChange(value)
const nextLiveList = getAvailablePurchaseLives(skuData, {mode: type, expire: value})
if (!nextLiveList.includes(live) && nextLiveList[0]) {
setValue('live', nextLiveList[0])
}
}}
className="flex gap-4 flex-wrap">
{expireList.map(day => (
<FormOption
key={day}
id={`${id}-${day}`}
value={day}
label={`${day}`}
compare={field.value}
/>
))}
</RadioGroup>
)}
</FormField>
)}
{/* IP 时效 */}
<FormField<Schema, 'live'>
@@ -129,36 +158,6 @@ export default function Center({skuData}: {
)}
</FormField>
{/* 套餐时效 */}
{type === '1' && (
<FormField name="expire" label="套餐有效时间" description="有效时间内可用于提取 IP">
{({id, field}) => (
<RadioGroup
id={id}
value={field.value}
onValueChange={(value) => {
field.onChange(value)
const nextLiveList = getAvailablePurchaseLives(skuData, {mode: type, expire: value})
if (!nextLiveList.includes(live) && nextLiveList[0]) {
setValue('live', nextLiveList[0])
}
}}
className="flex gap-4 flex-wrap">
{expireList.map(day => (
<FormOption
key={day}
id={`${id}-${day}`}
value={day}
label={`${day}`}
compare={field.value}
/>
))}
</RadioGroup>
)}
</FormField>
)}
{/* 每日提取上限/购买数量 */}
{type === '1' ? (
<NumberStepperField

View File

@@ -20,7 +20,7 @@ export type Schema = z.infer<typeof schema>
export default function LongForm({skuList}: {skuList: ProductItem['skus']}) {
const skuData = parsePurchaseSkuList('long', skuList)
const defaultMode = skuData.modeList.includes('2') ? '2' : '1'
const defaultMode = skuData.modeList.includes('1') ? '1' : '2'
const defaultLive = getAvailablePurchaseLives(skuData, {mode: defaultMode})[0] || ''
const defaultExpire = defaultMode === '1'
? getAvailablePurchaseExpires(skuData, {mode: defaultMode, live: defaultLive})[0] || '0'

View File

@@ -34,15 +34,6 @@ export function BillingMethodField(props: {
}}
className="flex gap-4 max-md:flex-col"
>
{props.modeList.includes('2') && (
<FormOption
id={`${id}-2`}
value="2"
label="包量套餐"
description="适用于短期或不定期高提取业务场景"
compare={field.value}
/>
)}
{props.modeList.includes('1') && (
<FormOption
@@ -53,6 +44,15 @@ export function BillingMethodField(props: {
compare={field.value}
/>
)}
{props.modeList.includes('2') && (
<FormOption
id={`${id}-2`}
value="2"
label="包量套餐"
description="适用于短期或不定期高提取业务场景"
compare={field.value}
/>
)}
</RadioGroup>
)}
</FormField>

View File

@@ -82,6 +82,35 @@ export default function Center({
return (
<Card className="flex-auto p-6 flex flex-col gap-10 relative">
<BillingMethodField modeList={modeList} timeDailyLimit={2000}/>
{/* 套餐时效 */}
{type === '1' && (
<FormField name="expire" label="套餐有效时间" description="有效时间内可用于提取 IP">
{({id, field}) => (
<RadioGroup
id={id}
value={field.value}
onValueChange={(value) => {
field.onChange(value)
const nextLiveList = getAvailablePurchaseLives(skuData, {mode: type, expire: value})
if (!nextLiveList.includes(live) && nextLiveList[0]) {
setValue('live', nextLiveList[0])
}
}}
className="flex gap-4 flex-wrap">
{expireList.map(day => (
<FormOption
key={day}
id={`${id}-${day}`}
value={day}
label={`${day}`}
compare={field.value}
/>
))}
</RadioGroup>
)}
</FormField>
)}
{/* IP 时效 */}
<FormField<Schema, 'live'>
@@ -133,36 +162,6 @@ export default function Center({
)}
</FormField>
{/* 套餐时效 */}
{type === '1' && (
<FormField name="expire" label="套餐有效时间" description="有效时间内可用于提取 IP">
{({id, field}) => (
<RadioGroup
id={id}
value={field.value}
onValueChange={(value) => {
field.onChange(value)
const nextLiveList = getAvailablePurchaseLives(skuData, {mode: type, expire: value})
if (!nextLiveList.includes(live) && nextLiveList[0]) {
setValue('live', nextLiveList[0])
}
}}
className="flex gap-4 flex-wrap">
{expireList.map(day => (
<FormOption
key={day}
id={`${id}-${day}`}
value={day}
label={`${day}`}
compare={field.value}
/>
))}
</RadioGroup>
)}
</FormField>
)}
{/* 每日提取上限/购买数量 */}
{type === '1' ? (
<NumberStepperField

View File

@@ -20,7 +20,7 @@ export type Schema = z.infer<typeof schema>
export default function ShortForm({skuList}: {skuList: ProductItem['skus']}) {
const skuData = parsePurchaseSkuList('short', skuList)
const defaultMode = skuData.modeList.includes('2') ? '2' : '1'
const defaultMode = skuData.modeList.includes('1') ? '1' : '2'
const defaultLive = getAvailablePurchaseLives(skuData, {mode: defaultMode})[0] || ''
const defaultExpire = defaultMode === '1'
? getAvailablePurchaseExpires(skuData, {mode: defaultMode, live: defaultLive})[0] || '0'