提取IP页面地区筛选数据更新为调用后端接口返回

This commit is contained in:
Eamon-meng
2026-06-12 16:42:05 +08:00
parent 7947fc48a2
commit 49725fd38e
6 changed files with 103 additions and 1697 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -11,13 +11,12 @@ import {Alert, AlertTitle} from '@/components/ui/alert'
import {ArrowRight, Box, CircleAlert, CopyIcon, ExternalLinkIcon, LinkIcon, Loader, Plus, Timer} from 'lucide-react'
import {memo, ReactNode, Suspense, use, useEffect, useRef, useState} from 'react'
import {useStatus} from '@/lib/states'
import {allResource} from '@/actions/resource'
import {allResource, getAreaList} from '@/actions/resource'
import {Resource} from '@/lib/models'
import {format, intlFormatDistance} from 'date-fns'
import {toast} from 'sonner'
import {merge} from '@/lib/utils'
import {Combobox} from '@/components/ui/combobox'
import cities from './_assets/cities.json'
import ExtractDocs from '@/app/(home)/docs/(product)/api-docs/page.md'
import Link from 'next/link'
import {useProfileStore} from '@/components/stores/profile'
@@ -497,11 +496,62 @@ function SelectResource() {
)
}
type AreaItem = {
id: number
parent_id: number
level: number
name: string
created_at: string
updated_at: string
}
function AreaTree(flatList: AreaItem[]) {
const provinces = flatList.filter(item => item.level === 1)
const cities = flatList.filter(item => item.level === 2)
return provinces.map(prov => ({
value: String(prov.id),
label: prov.name,
children: cities
.filter(city => city.parent_id === prov.id)
.map(city => ({
value: String(city.id),
label: city.name,
})),
}))
}
function SelectRegion() {
const {control, setValue} = useFormContext<Schema>()
const regionType = useWatch({control, name: 'regionType'})
const prov = useWatch({control, name: 'prov'})
const city = useWatch({control, name: 'city'})
const [options, setOptions] = useState<ReturnType<typeof AreaTree>>([])
const [loading, setLoading] = useState(false)
useEffect(() => {
if (regionType === 'specific') {
const fetchData = async () => {
setLoading(true)
try {
const req = await getAreaList({})
console.log(req, 'req')
if (req.success && req.data) {
setOptions(AreaTree(req.data))
}
}
catch (error) {
toast.error('无法选择区域')
}
finally {
setLoading(false)
}
}
fetchData()
}
}, [regionType])
return (
<div className="flex flex-col gap-4 md:max-w-[calc(160px*2+1rem)]">
@@ -531,15 +581,22 @@ function SelectRegion() {
</FormField>
{regionType === 'specific' && (
<Combobox
placeholder="请选择地区"
options={cities.options}
value={[prov || '', city || '']}
onChange={(value) => {
setValue('prov', value[0])
setValue('city', value[1])
}}
/>
loading ? (
<div className="flex gap-2 items-center">
<Loader className="animate-spin" size={16}/>
<span className="text-sm text-weak">...</span>
</div>
) : (
<Combobox
placeholder="请选择地区"
options={options}
value={[prov || '', city || '']}
onChange={(value) => {
setValue('prov', value[0] || '')
setValue('city', value[1] || '')
}}
/>
)
)}
</div>
)
@@ -655,12 +712,13 @@ function ApplyLink() {
function link(values: Schema) {
const {resource, prov, city, isp, proto, authType, distinct, format: formatType, hostFormat, separator, breaker, count} = values
console.log(values, 'values')
const sp = new URLSearchParams()
if (resource) sp.set('i', String(resource))
if (authType) sp.set('t', authType)
if (proto != 'all') sp.set('x', proto)
if (prov) sp.set('a', prov)
if (prov) sp.set('b', prov)
if (city) sp.set('b', city)
if (isp != 'all') sp.set('s', isp)