diff --git a/src/actions/resource.ts b/src/actions/resource.ts index 3e53bf7..6b7c10e 100644 --- a/src/actions/resource.ts +++ b/src/actions/resource.ts @@ -40,14 +40,14 @@ export async function createResource(props: { live: number mode: number quota: number - expire: number + expire_at: number daily_limit: number } long?: { live: number mode: number quota: number - expire: number + expire_at: number daily_limit: number } }) { @@ -60,14 +60,14 @@ export async function prepareResource(props: { live: number mode: number quota: number - expire: number + expire_at: number daily_limit: number } long?: { live: number mode: number quota: number - expire: number + expire_at: number daily_limit: number } payment_method: number diff --git a/src/app/(auth)/login/captcha.tsx b/src/app/(auth)/login/captcha.tsx index 808d472..3f3e5ca 100644 --- a/src/app/(auth)/login/captcha.tsx +++ b/src/app/(auth)/login/captcha.tsx @@ -1,3 +1,4 @@ +'use client' import {useEffect, useState} from 'react' import {Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger} from '@/components/ui/dialog' import {Button} from '@/components/ui/button' diff --git a/src/app/(auth)/login/login-card.tsx b/src/app/(auth)/login/login-card.tsx index b2e959b..0ff002b 100644 --- a/src/app/(auth)/login/login-card.tsx +++ b/src/app/(auth)/login/login-card.tsx @@ -16,7 +16,6 @@ import {useRouter} from 'next/navigation' import {login} from '@/actions/auth' import {useProfileStore} from '@/components/stores-provider' import Captcha from './captcha' -import {merge} from '@/lib/utils' const smsSchema = zod.object({ username: zod.string().length(11, '请输入正确的手机号码'), @@ -99,7 +98,7 @@ export default function LoginCard(props: { {...field} id={id} type="tel" - placeholder={mode === 'phone_code' ? '请输入手机号' : '请输入用户名'} + placeholder={mode === 'phone_code' ? '请输入手机号' : '请输入用户名/手机号/邮箱'} autoComplete="tel-national" /> )} @@ -170,9 +169,9 @@ export default function LoginCard(props: {

登录即表示您同意 - 《用户协议》 + 《用户协议》 和 - 《隐私政策》 + 《隐私政策》

diff --git a/src/app/(home)/_components/header/common.tsx b/src/app/(home)/_components/header/common.tsx index 8bfeb0e..169a4c4 100644 --- a/src/app/(home)/_components/header/common.tsx +++ b/src/app/(home)/_components/header/common.tsx @@ -1,3 +1,4 @@ +'use client' import {createContext} from 'react' import Image, {StaticImageData} from 'next/image' diff --git a/src/app/(home)/_components/header/menu-solution.tsx b/src/app/(home)/_components/header/menu-solution.tsx index b597516..9e44f45 100644 --- a/src/app/(home)/_components/header/menu-solution.tsx +++ b/src/app/(home)/_components/header/menu-solution.tsx @@ -1,3 +1,4 @@ +'use client' import Wrap from '@/components/wrap' import s01 from '@/assets/header/solution/01.svg' import s02 from '@/assets/header/solution/02.svg' diff --git a/src/app/admin/channels/page.tsx b/src/app/admin/channels/page.tsx index 926e788..4ca1b03 100644 --- a/src/app/admin/channels/page.tsx +++ b/src/app/admin/channels/page.tsx @@ -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) {
+ name="expired_status" label={状态}> + {({field}) => ( + + )} + + name="auth_type" label={认证方式}> {({field}) => (