增加客户端标识 & 套餐管理重置今日限额字段 &提取IP/IP管理模块新增字段
This commit is contained in:
@@ -7,7 +7,7 @@ import Page from '@/components/page'
|
||||
import DataTable from '@/components/data-table'
|
||||
import {toast} from 'sonner'
|
||||
import {listChannels} from '@/actions/channel'
|
||||
import {format} from 'date-fns'
|
||||
import {format, isBefore} from 'date-fns'
|
||||
import {Form, FormField} from '@/components/ui/form'
|
||||
import {z} from 'zod'
|
||||
import {useForm} from 'react-hook-form'
|
||||
@@ -16,7 +16,7 @@ import DatePicker from '@/components/date-picker'
|
||||
import {Button} from '@/components/ui/button'
|
||||
import {EraserIcon, SearchIcon} from 'lucide-react'
|
||||
import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue} from '@/components/ui/select'
|
||||
|
||||
import {Badge} from '@/components/ui/badge'
|
||||
export type ChannelsPageProps = {}
|
||||
|
||||
export default function ChannelsPage(props: ChannelsPageProps) {
|
||||
@@ -32,6 +32,12 @@ export default function ChannelsPage(props: ChannelsPageProps) {
|
||||
list: [],
|
||||
})
|
||||
|
||||
// 检查是否过期
|
||||
const isExpired = (expiredAt: string | Date) => {
|
||||
const date = typeof expiredAt === 'string' ? new Date(expiredAt) : expiredAt
|
||||
return isBefore(date, new Date())
|
||||
}
|
||||
|
||||
const refresh = async (page: number, size: number) => {
|
||||
try {
|
||||
setStatus('load')
|
||||
@@ -39,6 +45,7 @@ export default function ChannelsPage(props: ChannelsPageProps) {
|
||||
// 筛选条件
|
||||
const filter = filterForm.getValues()
|
||||
const auth_type = filter.auth_type ? parseInt(filter.auth_type) : undefined
|
||||
const expired_status = filter.expired_status
|
||||
|
||||
// 请求数据
|
||||
console.log({
|
||||
@@ -47,12 +54,26 @@ export default function ChannelsPage(props: ChannelsPageProps) {
|
||||
const resp = await listChannels({
|
||||
page, size, ...filter, auth_type,
|
||||
})
|
||||
console.log(resp, 'ip管理的respresprespresp')
|
||||
|
||||
if (!resp.success) {
|
||||
throw new Error(resp.message)
|
||||
}
|
||||
|
||||
let filteredList = resp.data.list
|
||||
if (expired_status !== undefined && expired_status !== 'all') {
|
||||
filteredList = resp.data.list.filter((channel) => {
|
||||
const expired = isExpired(channel.expired_at)
|
||||
return !expired
|
||||
})
|
||||
resp.data.total = filteredList.length
|
||||
}
|
||||
|
||||
// 更新数据
|
||||
setData(resp.data)
|
||||
setData({
|
||||
...resp.data,
|
||||
list: filteredList,
|
||||
})
|
||||
setStatus('done')
|
||||
}
|
||||
catch (e) {
|
||||
@@ -74,6 +95,7 @@ export default function ChannelsPage(props: ChannelsPageProps) {
|
||||
|
||||
const filterSchema = z.object({
|
||||
auth_type: z.enum(['0', '1', '2']),
|
||||
expired_status: z.enum(['all', 'active']).default('all'),
|
||||
expire_after: z.date().optional(),
|
||||
expire_before: z.date().optional(),
|
||||
})
|
||||
@@ -83,12 +105,13 @@ export default function ChannelsPage(props: ChannelsPageProps) {
|
||||
resolver: zodResolver(filterSchema),
|
||||
defaultValues: {
|
||||
auth_type: '0',
|
||||
expired_status: 'all',
|
||||
expire_after: undefined,
|
||||
expire_before: undefined,
|
||||
},
|
||||
})
|
||||
const filterHandler = filterForm.handleSubmit(async (value) => {
|
||||
await refresh(data.page, data.size)
|
||||
await refresh(1, data.size)
|
||||
})
|
||||
|
||||
// ======================
|
||||
@@ -100,6 +123,20 @@ export default function ChannelsPage(props: ChannelsPageProps) {
|
||||
<section className="flex justify-between">
|
||||
<div></div>
|
||||
<Form form={filterForm} handler={filterHandler} className="flex-auto flex flex-wrap gap-4 items-end">
|
||||
<FormField<FilterSchema, 'expired_status'> name="expired_status" label={<span className="text-sm">状态</span>}>
|
||||
{({field}) => (
|
||||
<Select value={field.value} onValueChange={field.onChange}>
|
||||
<SelectTrigger className="h-9 w-32">
|
||||
<SelectValue placeholder="选择状态"/>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">全部</SelectItem>
|
||||
<SelectItem value="active">未过期</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
)}
|
||||
</FormField>
|
||||
|
||||
<FormField<FilterSchema, 'auth_type'> name="auth_type" label={<span className="text-sm">认证方式</span>}>
|
||||
{({field}) => (
|
||||
<Select value={field.value} onValueChange={field.onChange}>
|
||||
@@ -136,7 +173,13 @@ export default function ChannelsPage(props: ChannelsPageProps) {
|
||||
<SearchIcon/>
|
||||
筛选
|
||||
</Button>
|
||||
<Button theme="outline" className="h-9" onClick={() => filterForm.reset()}>
|
||||
<Button
|
||||
theme="outline"
|
||||
className="h-9"
|
||||
onClick={() => {
|
||||
filterForm.reset()
|
||||
refresh(1, data.size)
|
||||
}}>
|
||||
<EraserIcon/>
|
||||
重置
|
||||
</Button>
|
||||
@@ -155,11 +198,35 @@ export default function ChannelsPage(props: ChannelsPageProps) {
|
||||
}}
|
||||
columns={[
|
||||
{
|
||||
header: '代理地址', cell: ({row}) => {
|
||||
header: '批次号',
|
||||
cell: ({row}) => {
|
||||
const channel = row.original
|
||||
const ip = channel.proxy?.ip
|
||||
const expired = isExpired(channel.expired_at)
|
||||
return (
|
||||
<div className={`${expired ? 'text-weak' : ''}`}>
|
||||
<span>{row.original.batch_no}</span>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
header: '代理地址',
|
||||
cell: ({row}) => {
|
||||
const channel = row.original
|
||||
const ip = channel.host
|
||||
const port = channel.port
|
||||
return `${ip}:${port}`
|
||||
const expired = isExpired(channel.expired_at)
|
||||
|
||||
return (
|
||||
<div className={`${expired ? 'text-weak' : ''}`}>
|
||||
<span>{ip}:{port}</span>
|
||||
{expired && (
|
||||
<Badge variant="secondary">
|
||||
已过期
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -176,12 +243,9 @@ export default function ChannelsPage(props: ChannelsPageProps) {
|
||||
<span >白名单</span>
|
||||
<div className="flex flex-wrap gap-1 max-w-[200px]">
|
||||
{channel.whitelists.split(',').map((ip, index) => (
|
||||
<span
|
||||
key={index}
|
||||
className="inline-block px-2 py-0.5 bg-gray-100 rounded text-xs text-gray-700 break-all"
|
||||
>
|
||||
<Badge key={index} variant="secondary">
|
||||
{ip.trim()}
|
||||
</span>
|
||||
</Badge >
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
@@ -200,10 +264,12 @@ export default function ChannelsPage(props: ChannelsPageProps) {
|
||||
},
|
||||
},
|
||||
{
|
||||
header: '过期时间', cell: ({row}) => format(row.original.expired_at, 'yyyy-MM-dd HH:mm:ss'),
|
||||
header: '提取时间',
|
||||
cell: ({row}) => format(row.original.created_at, 'yyyy-MM-dd HH:mm'),
|
||||
},
|
||||
{
|
||||
header: '操作', cell: ({row}) => <span>-</span>,
|
||||
header: '过期时间',
|
||||
cell: ({row}) => format(row.original.expired_at, 'yyyy-MM-dd HH:mm:ss'),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user