修复 antd 弃用警告
This commit is contained in:
+33
-29
@@ -1,10 +1,11 @@
|
||||
import { lazy, Suspense, useState, useCallback, type ReactNode } from 'react';
|
||||
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
|
||||
import { ConfigProvider, Spin, theme } from 'antd';
|
||||
import { App as AntdApp, ConfigProvider, Spin, theme } from 'antd';
|
||||
import zhCN from 'antd/locale/zh_CN';
|
||||
import { getUser } from './store/auth';
|
||||
import { ThemeProvider } from './store/theme';
|
||||
import { useTheme } from './store/useTheme';
|
||||
import AntdMessageBridge from './utils/AntdMessageBridge';
|
||||
|
||||
const LoginPage = lazy(() => import('./pages/LoginPage'));
|
||||
const MainLayout = lazy(() => import('./layouts/MainLayout'));
|
||||
@@ -51,34 +52,37 @@ function AppContent() {
|
||||
},
|
||||
}}
|
||||
>
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route path="/login" element={lazyRoute(<LoginPage onLogin={refreshAuth} />)} />
|
||||
<Route
|
||||
path="/"
|
||||
element={
|
||||
isLoggedIn
|
||||
? lazyRoute(<MainLayout key={authVersion} onLogout={refreshAuth} />)
|
||||
: <Navigate to="/login" replace />
|
||||
}
|
||||
>
|
||||
<Route index element={lazyRoute(<DashboardPage />)} />
|
||||
<Route path="accounts" element={lazyRoute(<AccountsPage />)} />
|
||||
<Route path="account-check" element={lazyRoute(<AccountCheckPage />)} />
|
||||
<Route path="assignments" element={lazyRoute(<AssignmentsPage />)} />
|
||||
<Route path="login-tasks" element={lazyRoute(<LoginTasksPage />)} />
|
||||
<Route path="cookies" element={lazyRoute(<CookiePage />)} />
|
||||
<Route path="huya/accounts" element={lazyRoute(<HuyaAccountsPage />)} />
|
||||
<Route path="huya/register" element={lazyRoute(<HuyaRegisterPage />)} />
|
||||
<Route path="huya/assignments" element={lazyRoute(<HuyaAssignmentsPage />)} />
|
||||
<Route path="huya/cookies" element={lazyRoute(<HuyaCookiePage />)} />
|
||||
<Route path="huya/tasks" element={lazyRoute(<HuyaTasksPage />)} />
|
||||
<Route path="proxy" element={lazyRoute(<ProxyPage />)} />
|
||||
<Route path="users" element={lazyRoute(<UsersPage />)} />
|
||||
</Route>
|
||||
<Route path="*" element={<Navigate to="/" replace />} />
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
<AntdApp>
|
||||
<AntdMessageBridge />
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route path="/login" element={lazyRoute(<LoginPage onLogin={refreshAuth} />)} />
|
||||
<Route
|
||||
path="/"
|
||||
element={
|
||||
isLoggedIn
|
||||
? lazyRoute(<MainLayout key={authVersion} onLogout={refreshAuth} />)
|
||||
: <Navigate to="/login" replace />
|
||||
}
|
||||
>
|
||||
<Route index element={lazyRoute(<DashboardPage />)} />
|
||||
<Route path="accounts" element={lazyRoute(<AccountsPage />)} />
|
||||
<Route path="account-check" element={lazyRoute(<AccountCheckPage />)} />
|
||||
<Route path="assignments" element={lazyRoute(<AssignmentsPage />)} />
|
||||
<Route path="login-tasks" element={lazyRoute(<LoginTasksPage />)} />
|
||||
<Route path="cookies" element={lazyRoute(<CookiePage />)} />
|
||||
<Route path="huya/accounts" element={lazyRoute(<HuyaAccountsPage />)} />
|
||||
<Route path="huya/register" element={lazyRoute(<HuyaRegisterPage />)} />
|
||||
<Route path="huya/assignments" element={lazyRoute(<HuyaAssignmentsPage />)} />
|
||||
<Route path="huya/cookies" element={lazyRoute(<HuyaCookiePage />)} />
|
||||
<Route path="huya/tasks" element={lazyRoute(<HuyaTasksPage />)} />
|
||||
<Route path="proxy" element={lazyRoute(<ProxyPage />)} />
|
||||
<Route path="users" element={lazyRoute(<UsersPage />)} />
|
||||
</Route>
|
||||
<Route path="*" element={<Navigate to="/" replace />} />
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
</AntdApp>
|
||||
</ConfigProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ export default function MainLayout({ onLogout }: { onLogout?: () => void }) {
|
||||
)}
|
||||
{collapsed ? (
|
||||
<>
|
||||
<Space direction="vertical" style={{ width: '100%' }}>
|
||||
<Space orientation="vertical" style={{ width: '100%' }}>
|
||||
<Dropdown
|
||||
menu={{ items: THEME_OPTIONS.map(o => ({ key: o.key, label: o.label, icon: o.icon, onClick: () => setMode(o.key) })) }}
|
||||
trigger={['click']}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import {
|
||||
Button, Card, Col, Input, InputNumber, message, Popconfirm, Row, Space, Statistic, Switch, Table, Tag, Typography,
|
||||
Button, Card, Col, Input, InputNumber, Popconfirm, Row, Space, Statistic, Switch, Table, Tag, Typography,
|
||||
} from 'antd';
|
||||
import { message } from '../utils/antdMessage';
|
||||
import type { TableProps } from 'antd';
|
||||
import { DownloadOutlined, PlayCircleOutlined, ReloadOutlined, StopOutlined } from '@ant-design/icons';
|
||||
import { accountCheckApi, type AccountCheckBatch, type AccountCheckItem } from '../api/modules';
|
||||
@@ -163,7 +164,7 @@ export default function AccountCheckPage() {
|
||||
return () => window.clearInterval(timer);
|
||||
}, [batchId, isRunning, refreshBatch]);
|
||||
|
||||
const statusCounts = batch?.status_counts || {};
|
||||
const statusCounts = useMemo(() => batch?.status_counts || {}, [batch?.status_counts]);
|
||||
const categoryStats = useMemo(() => [
|
||||
{ title: '已注销', value: statusCounts.account_cancelled || 0 },
|
||||
{ title: '密码错误', value: statusCounts.password_wrong || 0 },
|
||||
@@ -247,11 +248,11 @@ export default function AccountCheckPage() {
|
||||
];
|
||||
|
||||
return (
|
||||
<Space direction="vertical" size={16} style={{ width: '100%' }}>
|
||||
<Space orientation="vertical" size={16} style={{ width: '100%' }}>
|
||||
<Title level={3} style={{ margin: 0 }}>账号检测</Title>
|
||||
|
||||
<Card title="导入账号">
|
||||
<Space direction="vertical" size={12} style={{ width: '100%' }}>
|
||||
<Space orientation="vertical" size={12} style={{ width: '100%' }}>
|
||||
<TextArea
|
||||
rows={9}
|
||||
value={text}
|
||||
@@ -273,28 +274,32 @@ export default function AccountCheckPage() {
|
||||
</Col>
|
||||
<Col xs={8} md={4}>
|
||||
<Text type="secondary">单账号超时</Text>
|
||||
<InputNumber
|
||||
min={0}
|
||||
max={3600}
|
||||
step={30}
|
||||
value={maxTotalTime}
|
||||
onChange={(value) => setMaxTotalTime(Number(value ?? 0))}
|
||||
disabled={isRunning}
|
||||
addonAfter="秒"
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
<Space.Compact style={{ width: '100%' }}>
|
||||
<InputNumber
|
||||
min={0}
|
||||
max={3600}
|
||||
step={30}
|
||||
value={maxTotalTime}
|
||||
onChange={(value) => setMaxTotalTime(Number(value ?? 0))}
|
||||
disabled={isRunning}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
<Button disabled>秒</Button>
|
||||
</Space.Compact>
|
||||
</Col>
|
||||
<Col xs={8} md={4}>
|
||||
<Text type="secondary">重试次数</Text>
|
||||
<InputNumber
|
||||
min={0}
|
||||
max={50}
|
||||
value={maxLoginRetries}
|
||||
onChange={(value) => setMaxLoginRetries(Number(value ?? 0))}
|
||||
disabled={isRunning}
|
||||
addonAfter="次"
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
<Space.Compact style={{ width: '100%' }}>
|
||||
<InputNumber
|
||||
min={0}
|
||||
max={50}
|
||||
value={maxLoginRetries}
|
||||
onChange={(value) => setMaxLoginRetries(Number(value ?? 0))}
|
||||
disabled={isRunning}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
<Button disabled>次</Button>
|
||||
</Space.Compact>
|
||||
</Col>
|
||||
<Col xs={12} md={4}>
|
||||
<Text type="secondary">代理</Text>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { useEffect, useState, useMemo, useCallback } from 'react';
|
||||
import {
|
||||
Table, Button, Modal, Input, Select, message, Popconfirm, Typography, Tag, Space,
|
||||
Table, Button, Modal, Input, Select, Popconfirm, Typography, Tag, Space,
|
||||
Row, Col, Card, Statistic,
|
||||
} from 'antd';
|
||||
import { message } from '../utils/antdMessage';
|
||||
import type { TableProps } from 'antd';
|
||||
import { ImportOutlined, DeleteOutlined, TagOutlined, FilterOutlined } from '@ant-design/icons';
|
||||
import { accountApi, userApi, type AccountItem, type UserInfo } from '../api/modules';
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { useEffect, useState, useMemo } from 'react';
|
||||
import {
|
||||
Card, Table, Button, Select, Input, Tag, Row, Col, Statistic,
|
||||
message, Space, Tabs, Typography, Badge, theme,
|
||||
Space, Tabs, Typography, Badge, theme,
|
||||
} from 'antd';
|
||||
import { message } from '../utils/antdMessage';
|
||||
import {
|
||||
UserOutlined, CheckCircleOutlined, TeamOutlined,
|
||||
SwapOutlined, ClearOutlined, UsergroupAddOutlined,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useEffect, useState, useCallback } from 'react';
|
||||
import { Table, Button, Card, Row, Col, Statistic, message, Tag, Popconfirm, Space, Typography, Input, theme, Dropdown } from 'antd';
|
||||
import { Table, Button, Card, Row, Col, Statistic, Tag, Popconfirm, Space, Typography, Input, theme, Dropdown } from 'antd';
|
||||
import { message } from '../utils/antdMessage';
|
||||
import { DownloadOutlined, DeleteOutlined, CopyOutlined, SearchOutlined } from '@ant-design/icons';
|
||||
import { cookieApi, type CookieItem } from '../api/modules';
|
||||
import { usePermissions } from '../hooks/usePermissions';
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import {
|
||||
Button, Card, Col, Input, message, Modal, Popconfirm, Row, Select, Space, Statistic, Table, Tag, Typography,
|
||||
Button, Card, Col, Input, Modal, Popconfirm, Row, Select, Space, Statistic, Table, Tag, Typography,
|
||||
} from 'antd';
|
||||
import { message } from '../utils/antdMessage';
|
||||
import type { TableProps } from 'antd';
|
||||
import { DeleteOutlined, FilterOutlined, ImportOutlined, LoginOutlined, MobileOutlined, ReloadOutlined, SearchOutlined, TagOutlined } from '@ant-design/icons';
|
||||
import {
|
||||
@@ -376,7 +377,7 @@ export default function HuyaAccountsPage() {
|
||||
title: '虎牙账号',
|
||||
width: 180,
|
||||
render: (_: unknown, record) => (
|
||||
<Space direction="vertical" size={0}>
|
||||
<Space orientation="vertical" size={0}>
|
||||
<Text strong>{record.nickname || record.username || record.uid || '-'}</Text>
|
||||
<Text type="secondary" style={{ fontSize: 12 }}>
|
||||
UID {record.uid || record.yyuid || '-'}
|
||||
@@ -440,7 +441,7 @@ export default function HuyaAccountsPage() {
|
||||
width: 160,
|
||||
ellipsis: true,
|
||||
render: (value: string, record) => value ? (
|
||||
<Space direction="vertical" size={0}>
|
||||
<Space orientation="vertical" size={0}>
|
||||
<Text>{value}</Text>
|
||||
{record.game_channel ? (
|
||||
<Text type="secondary" style={{ fontSize: 12 }}>{record.game_channel}</Text>
|
||||
@@ -659,7 +660,7 @@ export default function HuyaAccountsPage() {
|
||||
confirmLoading={importing}
|
||||
width={720}
|
||||
>
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={12}>
|
||||
<Space orientation="vertical" style={{ width: '100%' }} size={12}>
|
||||
<Input
|
||||
placeholder="标签,可选"
|
||||
value={importTag}
|
||||
@@ -711,7 +712,7 @@ export default function HuyaAccountsPage() {
|
||||
closable={!passwordImporting}
|
||||
width={720}
|
||||
>
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={12}>
|
||||
<Space orientation="vertical" style={{ width: '100%' }} size={12}>
|
||||
<TextArea
|
||||
rows={10}
|
||||
value={passwordImportText}
|
||||
@@ -757,7 +758,7 @@ export default function HuyaAccountsPage() {
|
||||
closable={!(smsSending || smsLogging)}
|
||||
width={520}
|
||||
>
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={12}>
|
||||
<Space orientation="vertical" style={{ width: '100%' }} size={12}>
|
||||
<Input
|
||||
value={smsPhone}
|
||||
onChange={(e) => setSmsPhone(e.target.value)}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import {
|
||||
Badge, Button, Card, Col, Input, message, Row, Select, Space, Statistic, Table, Tabs, Tag, theme, Typography,
|
||||
Badge, Button, Card, Col, Input, Row, Select, Space, Statistic, Table, Tabs, Tag, theme, Typography,
|
||||
} from 'antd';
|
||||
import { message } from '../utils/antdMessage';
|
||||
import {
|
||||
CheckCircleOutlined, ClearOutlined, SwapOutlined, TeamOutlined, UsergroupAddOutlined, UserOutlined,
|
||||
} from '@ant-design/icons';
|
||||
@@ -178,7 +179,7 @@ export default function HuyaAssignmentsPage() {
|
||||
{
|
||||
title: '虎牙账号',
|
||||
render: (_: unknown, record: HuyaAccountItem) => (
|
||||
<Space direction="vertical" size={0}>
|
||||
<Space orientation="vertical" size={0}>
|
||||
<Text strong>{accountName(record)}</Text>
|
||||
<Text type="secondary" style={{ fontSize: 12 }}>UID {record.uid || record.yyuid || '-'}</Text>
|
||||
</Space>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import {
|
||||
Button, Card, Col, Dropdown, Input, message, Popconfirm, Row, Space, Statistic, Table, Tag, theme, Typography,
|
||||
Button, Card, Col, Dropdown, Input, Popconfirm, Row, Space, Statistic, Table, Tag, theme, Typography,
|
||||
} from 'antd';
|
||||
import { message } from '../utils/antdMessage';
|
||||
import { CopyOutlined, DeleteOutlined, DownloadOutlined, SearchOutlined } from '@ant-design/icons';
|
||||
import { huyaApi, type HuyaCookieItem } from '../api/modules';
|
||||
import { usePermissions } from '../hooks/usePermissions';
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import {
|
||||
Button, Card, Col, Input, InputNumber, message, Row, Segmented, Space, Statistic, Switch, Table, Tag, Typography,
|
||||
Button, Card, Col, Input, InputNumber, Row, Segmented, Space, Statistic, Switch, Table, Tag, Typography,
|
||||
} from 'antd';
|
||||
import { message } from '../utils/antdMessage';
|
||||
import type { TableProps } from 'antd';
|
||||
import {
|
||||
DownloadOutlined, PlayCircleOutlined, RedoOutlined, ReloadOutlined, StopOutlined,
|
||||
@@ -584,11 +585,11 @@ export default function HuyaRegisterPage() {
|
||||
];
|
||||
|
||||
return (
|
||||
<Space direction="vertical" size={16} style={{ width: '100%' }}>
|
||||
<Space orientation="vertical" size={16} style={{ width: '100%' }}>
|
||||
<Title level={3} style={{ margin: 0 }}>虎牙自动注册</Title>
|
||||
|
||||
<Card title="手机号池">
|
||||
<Space direction="vertical" size={12} style={{ width: '100%' }}>
|
||||
<Space orientation="vertical" size={12} style={{ width: '100%' }}>
|
||||
<TextArea
|
||||
rows={9}
|
||||
value={text}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import {
|
||||
Button, Card, Col, DatePicker, Dropdown, Form, Input, InputNumber, message, Modal, QRCode, Radio, Row, Select, Space, Table, Tag, Tooltip, Typography, theme,
|
||||
Button, Card, Col, DatePicker, Dropdown, Form, Input, InputNumber, Modal, QRCode, Radio, Row, Select, Space, Table, Tag, Tooltip, Typography, theme,
|
||||
} from 'antd';
|
||||
import { message } from '../utils/antdMessage';
|
||||
import type { MenuProps, TableProps } from 'antd';
|
||||
import type { Dayjs } from 'dayjs';
|
||||
import type { MouseEvent as ReactMouseEvent } from 'react';
|
||||
@@ -1164,7 +1165,7 @@ export default function HuyaTasksPage() {
|
||||
title: '虎牙 CK',
|
||||
width: 250,
|
||||
render: (_: unknown, record) => (
|
||||
<Space direction="vertical" size={1} style={{ width: '100%' }}>
|
||||
<Space orientation="vertical" size={1} style={{ width: '100%' }}>
|
||||
<Space size={6} wrap>
|
||||
<Text strong>{accountDisplayName(record)}</Text>
|
||||
{record.tag ? <Tag color={tagColorMap[record.tag]}>{record.tag}</Tag> : null}
|
||||
@@ -1191,7 +1192,7 @@ export default function HuyaTasksPage() {
|
||||
width: 170,
|
||||
ellipsis: true,
|
||||
render: (value: string, record) => value ? (
|
||||
<Space direction="vertical" size={0}>
|
||||
<Space orientation="vertical" size={0}>
|
||||
<Text>{value}</Text>
|
||||
{record.game_channel ? <Text type="secondary" style={{ fontSize: 12 }}>{record.game_channel}</Text> : null}
|
||||
</Space>
|
||||
@@ -1214,7 +1215,7 @@ export default function HuyaTasksPage() {
|
||||
const product = taskProductText(task);
|
||||
if (!task || !product) return <Text type="secondary">-</Text>;
|
||||
return (
|
||||
<Space direction="vertical" size={1}>
|
||||
<Space orientation="vertical" size={1}>
|
||||
<Text ellipsis style={{ maxWidth: 170 }}>{product}</Text>
|
||||
<Tag color={STATUS_COLORS[task.status] || 'default'} style={{ width: 'fit-content' }}>
|
||||
{taskTypes[task.task_type] || task.task_type}
|
||||
@@ -1250,7 +1251,7 @@ export default function HuyaTasksPage() {
|
||||
const latest = latestTaskByAccount.get(record.id);
|
||||
if (!latest) return <Text type="secondary">暂无任务</Text>;
|
||||
return (
|
||||
<Space direction="vertical" size={2} style={{ width: '100%' }}>
|
||||
<Space orientation="vertical" size={2} style={{ width: '100%' }}>
|
||||
<Text ellipsis style={{ maxWidth: 238 }}>
|
||||
{taskTypes[latest.task_type] || latest.task_type}:{latest.message || '-'}
|
||||
</Text>
|
||||
@@ -1294,7 +1295,7 @@ export default function HuyaTasksPage() {
|
||||
title: '虎牙 CK',
|
||||
width: 230,
|
||||
render: (_: unknown, record) => (
|
||||
<Space direction="vertical" size={1}>
|
||||
<Space orientation="vertical" size={1}>
|
||||
<Space size={6} wrap>
|
||||
<Text strong>{accountDisplayName(record)}</Text>
|
||||
{record.tag ? <Tag color={tagColorMap[record.tag]}>{record.tag}</Tag> : null}
|
||||
@@ -1315,7 +1316,7 @@ export default function HuyaTasksPage() {
|
||||
dataIndex: 'game_name',
|
||||
ellipsis: true,
|
||||
render: (value: string, record) => value ? (
|
||||
<Space direction="vertical" size={0}>
|
||||
<Space orientation="vertical" size={0}>
|
||||
<Text>{value}</Text>
|
||||
{record.game_channel ? <Text type="secondary" style={{ fontSize: 12 }}>{record.game_channel}</Text> : null}
|
||||
</Space>
|
||||
@@ -1482,7 +1483,7 @@ export default function HuyaTasksPage() {
|
||||
{accountContextMenu.accountIds.length > 1 ? '右键批量动作' : '右键账号动作'}
|
||||
</Text>
|
||||
</div>
|
||||
<Space direction="vertical" size={2} style={{ width: '100%' }}>
|
||||
<Space orientation="vertical" size={2} style={{ width: '100%' }}>
|
||||
{QUICK_ACTIONS.map((item) => (
|
||||
<Button
|
||||
key={item.key}
|
||||
@@ -1626,17 +1627,19 @@ export default function HuyaTasksPage() {
|
||||
</div>
|
||||
|
||||
<div style={{ minHeight: 0, overflowY: 'auto', overflowX: 'hidden' }}>
|
||||
<Space direction="vertical" size={12} style={{ width: '100%' }}>
|
||||
<Space orientation="vertical" size={12} style={{ width: '100%' }}>
|
||||
<Card size="small" title="批量动作" extra={<Tag color={selectedIds.length ? 'blue' : 'default'}>{selectedAccountText}</Tag>}>
|
||||
<Space direction="vertical" size={10} style={{ width: '100%' }}>
|
||||
<InputNumber
|
||||
min={1}
|
||||
max={10}
|
||||
value={concurrency}
|
||||
onChange={(value) => setConcurrency(value || 1)}
|
||||
addonBefore="并发"
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
<Space orientation="vertical" size={10} style={{ width: '100%' }}>
|
||||
<Space.Compact style={{ width: '100%' }}>
|
||||
<Button disabled>并发</Button>
|
||||
<InputNumber
|
||||
min={1}
|
||||
max={10}
|
||||
value={concurrency}
|
||||
onChange={(value) => setConcurrency(value || 1)}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
</Space.Compact>
|
||||
<Select
|
||||
value={selectedTaskType}
|
||||
onChange={setSelectedTaskType}
|
||||
@@ -1685,7 +1688,7 @@ export default function HuyaTasksPage() {
|
||||
</Button>
|
||||
)}
|
||||
>
|
||||
<Space direction="vertical" size={10} style={{ width: '100%' }}>
|
||||
<Space orientation="vertical" size={10} style={{ width: '100%' }}>
|
||||
{goodsCategories.length > 0 ? (
|
||||
<Select
|
||||
value={selectedGoodsCategory}
|
||||
@@ -1707,12 +1710,14 @@ export default function HuyaTasksPage() {
|
||||
style={{ width: '100%' }}
|
||||
filterOption={(input, option) => String(option?.label || '').toLowerCase().includes(input.toLowerCase())}
|
||||
/>
|
||||
<Input
|
||||
addonBefore="PID"
|
||||
value={selectedExchangeGoodsId}
|
||||
onChange={(event) => setSelectedExchangeGoodsId(event.target.value.trim())}
|
||||
placeholder="商品 PID"
|
||||
/>
|
||||
<Space.Compact style={{ width: '100%' }}>
|
||||
<Button disabled>PID</Button>
|
||||
<Input
|
||||
value={selectedExchangeGoodsId}
|
||||
onChange={(event) => setSelectedExchangeGoodsId(event.target.value.trim())}
|
||||
placeholder="商品 PID"
|
||||
/>
|
||||
</Space.Compact>
|
||||
<DatePicker
|
||||
showTime
|
||||
allowClear
|
||||
@@ -1747,7 +1752,7 @@ export default function HuyaTasksPage() {
|
||||
</Button>
|
||||
)}
|
||||
>
|
||||
<Space direction="vertical" size={10} style={{ width: '100%' }}>
|
||||
<Space orientation="vertical" size={10} style={{ width: '100%' }}>
|
||||
<Select
|
||||
showSearch
|
||||
allowClear
|
||||
@@ -1758,14 +1763,16 @@ export default function HuyaTasksPage() {
|
||||
style={{ width: '100%' }}
|
||||
filterOption={(input, option) => String(option?.label || '').toLowerCase().includes(input.toLowerCase())}
|
||||
/>
|
||||
<InputNumber
|
||||
min={1}
|
||||
max={999}
|
||||
value={rechargeCount}
|
||||
onChange={(value) => setRechargeCount(value || 1)}
|
||||
addonAfter="份"
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
<Space.Compact style={{ width: '100%' }}>
|
||||
<InputNumber
|
||||
min={1}
|
||||
max={999}
|
||||
value={rechargeCount}
|
||||
onChange={(value) => setRechargeCount(value || 1)}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
<Button disabled>份</Button>
|
||||
</Space.Compact>
|
||||
<Radio.Group value={rechargePayChannel} onChange={(event) => setRechargePayChannel(event.target.value)}>
|
||||
<Radio value="Weixin">微信</Radio>
|
||||
<Radio value="Zfb">支付宝</Radio>
|
||||
@@ -1862,7 +1869,7 @@ export default function HuyaTasksPage() {
|
||||
]}
|
||||
width={860}
|
||||
>
|
||||
<Space direction="vertical" size={10} style={{ width: '100%' }}>
|
||||
<Space orientation="vertical" size={10} style={{ width: '100%' }}>
|
||||
<div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center' }}>
|
||||
<Input.Search
|
||||
allowClear
|
||||
@@ -1919,7 +1926,7 @@ export default function HuyaTasksPage() {
|
||||
footer={null}
|
||||
width={760}
|
||||
>
|
||||
<Space direction="vertical" size={10} style={{ width: '100%' }}>
|
||||
<Space orientation="vertical" size={10} style={{ width: '100%' }}>
|
||||
<Text type="secondary">
|
||||
{exchangeRecordsAccountName}{exchangeRecordsResult?.sid ? ` / SID ${String(exchangeRecordsResult.sid)}` : ''}
|
||||
</Text>
|
||||
@@ -1944,7 +1951,7 @@ export default function HuyaTasksPage() {
|
||||
>
|
||||
{qrTask && (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 12, padding: '8px 0 12px' }}>
|
||||
<Space direction="vertical" size={4} style={{ width: '100%', textAlign: 'center' }}>
|
||||
<Space orientation="vertical" size={4} style={{ width: '100%', textAlign: 'center' }}>
|
||||
<Text strong>{qrAccountName}</Text>
|
||||
<Tag
|
||||
color={qrBindReady ? 'gold' : qrBindPhase === 'role_timeout' || qrQueryFinished ? 'orange' : 'processing'}
|
||||
@@ -1979,7 +1986,7 @@ export default function HuyaTasksPage() {
|
||||
<Text type="secondary">暂无二维码</Text>
|
||||
)}
|
||||
{qrRoleLine ? (
|
||||
<Space direction="vertical" size={2} style={{ width: '100%', textAlign: 'center' }}>
|
||||
<Space orientation="vertical" size={2} style={{ width: '100%', textAlign: 'center' }}>
|
||||
{qrGameTitle ? <Text type="secondary">{qrGameTitle}</Text> : null}
|
||||
<Text strong>{qrRoleLine}</Text>
|
||||
</Space>
|
||||
@@ -2017,7 +2024,7 @@ export default function HuyaTasksPage() {
|
||||
>
|
||||
{payTask && (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 12, padding: '8px 0 12px' }}>
|
||||
<Space direction="vertical" size={2} style={{ width: '100%', textAlign: 'center' }}>
|
||||
<Space orientation="vertical" size={2} style={{ width: '100%', textAlign: 'center' }}>
|
||||
<Text strong>{payProductName || '充值商品'}</Text>
|
||||
<Text type="secondary">
|
||||
{payChannelLabel || '支付'}{payAmountText ? ` / ${payAmountText}` : ''}{payAccountName ? ` / ${payAccountName}` : ''}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useState } from 'react';
|
||||
import { Card, Form, Input, Button, message, Typography } from 'antd';
|
||||
import { Card, Form, Input, Button, Typography } from 'antd';
|
||||
import { message } from '../utils/antdMessage';
|
||||
import { LockOutlined, UserOutlined } from '@ant-design/icons';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { authApi } from '../api/modules';
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { useEffect, useState, useMemo, useCallback } from 'react';
|
||||
import {
|
||||
Table, Button, Select, message, Tag, Space, InputNumber, Tooltip, Popconfirm, theme, Modal, Form,
|
||||
Table, Button, Select, Tag, Space, InputNumber, Tooltip, Popconfirm, theme, Modal, Form,
|
||||
} from 'antd';
|
||||
import { message } from '../utils/antdMessage';
|
||||
import {
|
||||
PlayCircleOutlined, StopOutlined, FilterOutlined, ReloadOutlined, DeleteOutlined,
|
||||
SettingOutlined, SafetyCertificateOutlined,
|
||||
@@ -503,43 +504,49 @@ export default function LoginTasksPage() {
|
||||
label="并发数"
|
||||
tooltip="同时登录的账号数。1 为顺序执行,最多 10。"
|
||||
>
|
||||
<InputNumber
|
||||
min={1}
|
||||
max={10}
|
||||
value={concurrency}
|
||||
onChange={(v) => setConcurrency(v || 1)}
|
||||
style={{ width: 120 }}
|
||||
addonAfter="个"
|
||||
/>
|
||||
<Space.Compact>
|
||||
<InputNumber
|
||||
min={1}
|
||||
max={10}
|
||||
value={concurrency}
|
||||
onChange={(v) => setConcurrency(v || 1)}
|
||||
style={{ width: 120 }}
|
||||
/>
|
||||
<Button disabled>个</Button>
|
||||
</Space.Compact>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="单账号超时"
|
||||
tooltip="单个账号登录的总时长上限,超时则放弃。0 表示不限。"
|
||||
>
|
||||
<InputNumber
|
||||
min={0}
|
||||
max={3600}
|
||||
step={30}
|
||||
value={maxTotalTime}
|
||||
onChange={(v) => setMaxTotalTime(v ?? 0)}
|
||||
style={{ width: 120 }}
|
||||
addonAfter="秒"
|
||||
placeholder="0=不限"
|
||||
/>
|
||||
<Space.Compact>
|
||||
<InputNumber
|
||||
min={0}
|
||||
max={3600}
|
||||
step={30}
|
||||
value={maxTotalTime}
|
||||
onChange={(v) => setMaxTotalTime(v ?? 0)}
|
||||
style={{ width: 120 }}
|
||||
placeholder="0=不限"
|
||||
/>
|
||||
<Button disabled>秒</Button>
|
||||
</Space.Compact>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="登录整体重试次数"
|
||||
tooltip="单个账号最多重试多少轮(每轮换新代理)。0 表示无限重试直到成功或超时。"
|
||||
>
|
||||
<InputNumber
|
||||
min={0}
|
||||
max={50}
|
||||
value={maxLoginRetries}
|
||||
onChange={(v) => setMaxLoginRetries(v ?? 0)}
|
||||
style={{ width: 120 }}
|
||||
addonAfter="次"
|
||||
placeholder="0=无限"
|
||||
/>
|
||||
<Space.Compact>
|
||||
<InputNumber
|
||||
min={0}
|
||||
max={50}
|
||||
value={maxLoginRetries}
|
||||
onChange={(v) => setMaxLoginRetries(v ?? 0)}
|
||||
style={{ width: 120 }}
|
||||
placeholder="0=无限"
|
||||
/>
|
||||
<Button disabled>次</Button>
|
||||
</Space.Compact>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useEffect, useState, useCallback } from 'react';
|
||||
import { Form, Input, Switch, Button, Card, Select, message, Row, Col } from 'antd';
|
||||
import { Form, Input, Switch, Button, Card, Select, Row, Col } from 'antd';
|
||||
import { message } from '../utils/antdMessage';
|
||||
import { proxyApi, type ProxyConfig, type PlatformInfo } from '../api/modules';
|
||||
import RealtimeLogPanel from '../components/RealtimeLogPanel';
|
||||
import { useWebSocketLogs } from '../hooks/useWebSocketLogs';
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { useEffect, useState, useCallback } from 'react';
|
||||
import {
|
||||
Table, Button, Modal, Form, Input, Select, Tag, Popconfirm, message, Space,
|
||||
Table, Button, Modal, Form, Input, Select, Tag, Popconfirm, Space,
|
||||
Checkbox, Divider, Alert, Tooltip,
|
||||
} from 'antd';
|
||||
import { message } from '../utils/antdMessage';
|
||||
import { PlusOutlined, EditOutlined, DeleteOutlined, SafetyOutlined } from '@ant-design/icons';
|
||||
import { userApi, type UserInfo } from '../api/modules';
|
||||
import { usePermissions } from '../hooks/usePermissions';
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { useEffect } from 'react';
|
||||
import { App as AntdApp } from 'antd';
|
||||
import { setAntdMessageApi } from './antdMessage';
|
||||
|
||||
export default function AntdMessageBridge() {
|
||||
const { message } = AntdApp.useApp();
|
||||
|
||||
useEffect(() => {
|
||||
setAntdMessageApi(message);
|
||||
return () => {
|
||||
setAntdMessageApi(null);
|
||||
};
|
||||
}, [message]);
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import type { Key } from 'react';
|
||||
import type {
|
||||
ArgsProps,
|
||||
JointContent,
|
||||
MessageInstance,
|
||||
MessageType,
|
||||
TypeOpen,
|
||||
} from 'antd/es/message/interface';
|
||||
|
||||
let messageApi: MessageInstance | null = null;
|
||||
|
||||
const noopMessage = Object.assign(() => undefined, {
|
||||
then: (
|
||||
onfulfilled?: ((value: boolean) => unknown) | null,
|
||||
onrejected?: ((reason: unknown) => unknown) | null,
|
||||
) => Promise.resolve(true).then(onfulfilled ?? undefined, onrejected ?? undefined),
|
||||
}) as MessageType;
|
||||
|
||||
function createTypeOpen(type: 'info' | 'success' | 'error' | 'warning' | 'loading'): TypeOpen {
|
||||
return (content: JointContent, duration?: number | VoidFunction, onClose?: VoidFunction) => {
|
||||
if (!messageApi) return noopMessage;
|
||||
return messageApi[type](content, duration, onClose);
|
||||
};
|
||||
}
|
||||
|
||||
export function setAntdMessageApi(api: MessageInstance | null) {
|
||||
messageApi = api;
|
||||
}
|
||||
|
||||
export const message = {
|
||||
info: createTypeOpen('info'),
|
||||
success: createTypeOpen('success'),
|
||||
error: createTypeOpen('error'),
|
||||
warning: createTypeOpen('warning'),
|
||||
loading: createTypeOpen('loading'),
|
||||
open: (args: ArgsProps) => messageApi?.open(args) ?? noopMessage,
|
||||
destroy: (key?: Key) => messageApi?.destroy(key),
|
||||
} satisfies MessageInstance;
|
||||
Reference in New Issue
Block a user