import { ReloadOutlined, SearchOutlined } from '@ant-design/icons' import { Alert, Button, Card, Col, Form, Input, Row, Skeleton, Space, Statistic, Table, Tag, Typography, } from 'antd' import type { TableColumnsType } from 'antd' import { useQuery } from '@tanstack/react-query' import { useMemo, useState } from 'react' import { AdminRangePicker } from '@/components/admin/AdminDatePicker' import PageHeader from '@/components/admin/PageHeader' import StatusTag from '@/components/admin/StatusTag' import dayjs from '@/lib/dayjs' import { fetchAdminDashboardSummary, fetchAdminLoginLogs } from '@/services/admin' import type { AdminLoginLogItem } from '@/types/admin' import { ADMIN_DEFAULT_PAGE_SIZE, buildAdminTablePagination, } from '@/utils/admin-pagination' import { formatAdminDateTime } from '@/utils/admin-time' const cards = [ { key: 'todayOrders', label: '今日订单' }, { key: 'paidPendingClaim', label: '待领取' }, { key: 'claimingTasks', label: '领取中' }, { key: 'redeemedToday', label: '今日成功' }, { key: 'abnormalTasks', label: '异常任务' }, ] as const type LoginFilterForm = { username?: string dateRange?: unknown } export default function AdminDashboardPage() { const [page, setPage] = useState(1) const [pageSize, setPageSize] = useState(ADMIN_DEFAULT_PAGE_SIZE) const [filters, setFilters] = useState({ username: '', dateFrom: '', dateTo: '', }) const summaryQuery = useQuery({ queryKey: ['admin-dashboard-summary'], queryFn: () => fetchAdminDashboardSummary(), }) const summary = summaryQuery.data?.data const loginQueryParams = useMemo( () => ({ page, pageSize, username: filters.username || undefined, dateFrom: filters.dateFrom || undefined, dateTo: filters.dateTo || undefined, }), [filters.dateFrom, filters.dateTo, filters.username, page, pageSize], ) const loginQuery = useQuery({ queryKey: ['admin-login-logs', loginQueryParams], queryFn: () => fetchAdminLoginLogs(loginQueryParams), }) const loginData = loginQuery.data?.data const columns: TableColumnsType = [ { title: '登录时间', dataIndex: 'createdAt', width: 180, render: (value) => formatAdminDateTime(value), }, { title: '账号', dataIndex: 'username', minWidth: 120, render: (value) => {value || '-'}, }, { title: '角色', dataIndex: 'role', width: 110, render: (value) => , }, { title: '结果', width: 90, render: (_, row) => row.success ? ( 成功 ) : ( 失败 ), }, { title: '登录地点', dataIndex: 'location', minWidth: 140, render: (value) => value || '-', }, { title: '登录 IP', dataIndex: 'ip', width: 150, render: (value) => value || '-', }, { title: '设备信息', dataIndex: 'userAgent', minWidth: 280, render: (value) => ( {value || '-'} ), }, ] function applyLoginFilters(values: LoginFilterForm) { const range = Array.isArray(values.dateRange) ? values.dateRange : [] const dateFrom = range[0] && dayjs(range[0]).isValid() ? dayjs(range[0]).format('YYYY-MM-DD') : '' const dateTo = range[1] && dayjs(range[1]).isValid() ? dayjs(range[1]).format('YYYY-MM-DD') : '' setPage(1) setFilters({ username: String(values.username || '').trim(), dateFrom, dateTo, }) } return (
{summaryQuery.error ? ( ) : null} {summaryQuery.isLoading ? ( ) : ( {cards.map((card) => ( ))} )} 全部后台账号的登录信息 } > layout="inline" className="filter-form" onFinish={applyLoginFilters} initialValues={{ username: filters.username }} style={{ marginBottom: 16 }} > {loginQuery.error ? ( ) : null} rowKey="logId" loading={loginQuery.isLoading || loginQuery.isFetching} columns={columns} dataSource={loginData?.items || []} scroll={{ x: 1100 }} pagination={buildAdminTablePagination({ current: loginData?.pagination.page || page, pageSize: loginData?.pagination.pageSize || pageSize, total: loginData?.pagination.total || 0, onChange: (nextPage, nextPageSize) => { setPage(nextPage) setPageSize(nextPageSize) }, })} locale={{ emptyText: '暂无登录记录(新登录成功后会自动写入)' }} />
) }