完善自动注册代理和状态恢复
This commit is contained in:
@@ -181,6 +181,7 @@ export interface HuyaAutoRegisterRequest {
|
||||
poll_interval?: number;
|
||||
password_prefix?: string;
|
||||
fixed_password?: string;
|
||||
use_proxy?: boolean;
|
||||
}
|
||||
|
||||
export interface HuyaAutoRegisterItem {
|
||||
@@ -215,6 +216,7 @@ export interface HuyaAutoRegisterBatch {
|
||||
wait_seconds: number;
|
||||
poll_interval: number;
|
||||
password_prefix: string;
|
||||
use_proxy: boolean;
|
||||
total: number;
|
||||
success_count: number;
|
||||
failed_count: number;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import {
|
||||
Button, Card, Col, Input, InputNumber, message, Row, Segmented, Space, Statistic, Table, Tag, Typography,
|
||||
Button, Card, Col, Input, InputNumber, message, Row, Segmented, Space, Statistic, Switch, Table, Tag, Typography,
|
||||
} from 'antd';
|
||||
import type { TableProps } from 'antd';
|
||||
import { DownloadOutlined, PlayCircleOutlined, ReloadOutlined, StopOutlined } from '@ant-design/icons';
|
||||
@@ -11,6 +11,34 @@ import { getErrorMessage } from '../utils/error';
|
||||
const { TextArea } = Input;
|
||||
const { Text, Title } = Typography;
|
||||
|
||||
type PasswordMode = 'random' | 'fixed';
|
||||
|
||||
interface StoredRegisterForm {
|
||||
text: string;
|
||||
tag: string;
|
||||
concurrency: number;
|
||||
waitSeconds: number;
|
||||
pollInterval: number;
|
||||
passwordMode: PasswordMode;
|
||||
passwordPrefix: string;
|
||||
fixedPassword: string;
|
||||
useProxy: boolean;
|
||||
}
|
||||
|
||||
const FORM_STORAGE_KEY = 'huya_auto_register_form';
|
||||
const BATCH_STORAGE_KEY = 'huya_auto_register_batch_id';
|
||||
const DEFAULT_FORM: StoredRegisterForm = {
|
||||
text: '',
|
||||
tag: '',
|
||||
concurrency: 1,
|
||||
waitSeconds: 180,
|
||||
pollInterval: 5,
|
||||
passwordMode: 'random',
|
||||
passwordPrefix: 'hy',
|
||||
fixedPassword: '',
|
||||
useProxy: false,
|
||||
};
|
||||
|
||||
const STATUS_LABELS: Record<string, string> = {
|
||||
pending: '等待',
|
||||
sending: '发码',
|
||||
@@ -35,35 +63,118 @@ const STATUS_COLORS: Record<string, string> = {
|
||||
|
||||
const RUNNING_STATUS = new Set(['pending', 'running']);
|
||||
|
||||
function safeNumber(value: unknown, fallback: number) {
|
||||
const n = Number(value);
|
||||
return Number.isFinite(n) ? n : fallback;
|
||||
}
|
||||
|
||||
function readStoredForm(): StoredRegisterForm {
|
||||
try {
|
||||
const raw = localStorage.getItem(FORM_STORAGE_KEY);
|
||||
if (!raw) return DEFAULT_FORM;
|
||||
const parsed = JSON.parse(raw) as Partial<StoredRegisterForm>;
|
||||
const passwordMode = parsed.passwordMode === 'fixed' ? 'fixed' : 'random';
|
||||
return {
|
||||
...DEFAULT_FORM,
|
||||
...parsed,
|
||||
concurrency: safeNumber(parsed.concurrency, DEFAULT_FORM.concurrency),
|
||||
waitSeconds: safeNumber(parsed.waitSeconds, DEFAULT_FORM.waitSeconds),
|
||||
pollInterval: safeNumber(parsed.pollInterval, DEFAULT_FORM.pollInterval),
|
||||
passwordMode,
|
||||
useProxy: Boolean(parsed.useProxy),
|
||||
};
|
||||
} catch {
|
||||
return DEFAULT_FORM;
|
||||
}
|
||||
}
|
||||
|
||||
function readStoredBatchId() {
|
||||
try {
|
||||
return localStorage.getItem(BATCH_STORAGE_KEY) || '';
|
||||
} catch {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
export default function HuyaRegisterPage() {
|
||||
const [text, setText] = useState('');
|
||||
const [tag, setTag] = useState('');
|
||||
const [concurrency, setConcurrency] = useState(1);
|
||||
const [waitSeconds, setWaitSeconds] = useState(180);
|
||||
const [pollInterval, setPollInterval] = useState(5);
|
||||
const [passwordMode, setPasswordMode] = useState<'random' | 'fixed'>('random');
|
||||
const [passwordPrefix, setPasswordPrefix] = useState('hy');
|
||||
const [fixedPassword, setFixedPassword] = useState('');
|
||||
const initialFormRef = useRef<StoredRegisterForm | null>(null);
|
||||
if (initialFormRef.current === null) {
|
||||
initialFormRef.current = readStoredForm();
|
||||
}
|
||||
const initialForm = initialFormRef.current;
|
||||
|
||||
const [text, setText] = useState(initialForm.text);
|
||||
const [tag, setTag] = useState(initialForm.tag);
|
||||
const [concurrency, setConcurrency] = useState(initialForm.concurrency);
|
||||
const [waitSeconds, setWaitSeconds] = useState(initialForm.waitSeconds);
|
||||
const [pollInterval, setPollInterval] = useState(initialForm.pollInterval);
|
||||
const [passwordMode, setPasswordMode] = useState<PasswordMode>(initialForm.passwordMode);
|
||||
const [passwordPrefix, setPasswordPrefix] = useState(initialForm.passwordPrefix);
|
||||
const [fixedPassword, setFixedPassword] = useState(initialForm.fixedPassword);
|
||||
const [useProxy, setUseProxy] = useState(initialForm.useProxy);
|
||||
const [batch, setBatch] = useState<HuyaAutoRegisterBatch | null>(null);
|
||||
const [starting, setStarting] = useState(false);
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
const [stopping, setStopping] = useState(false);
|
||||
const restoredBatchRef = useRef(false);
|
||||
|
||||
const batchId = batch?.batch_id || '';
|
||||
const isRunning = !!batch && RUNNING_STATUS.has(batch.status);
|
||||
|
||||
const refreshBatch = useCallback(async () => {
|
||||
if (!batchId) return;
|
||||
const loadBatchById = useCallback(async (id: string) => {
|
||||
if (!id) return;
|
||||
setRefreshing(true);
|
||||
try {
|
||||
const data = await huyaApi.getAutoRegisterBatch(batchId);
|
||||
const data = await huyaApi.getAutoRegisterBatch(id);
|
||||
setBatch(data);
|
||||
localStorage.setItem(BATCH_STORAGE_KEY, data.batch_id);
|
||||
} catch (e: unknown) {
|
||||
message.error(getErrorMessage(e));
|
||||
const err = getErrorMessage(e);
|
||||
if (err.includes('批次不存在') || err.includes('服务已重启')) {
|
||||
localStorage.removeItem(BATCH_STORAGE_KEY);
|
||||
setBatch(null);
|
||||
message.warning('上次自动注册批次已不存在,已清除恢复记录');
|
||||
} else {
|
||||
message.error(err);
|
||||
}
|
||||
} finally {
|
||||
setRefreshing(false);
|
||||
}
|
||||
}, [batchId]);
|
||||
}, []);
|
||||
|
||||
const refreshBatch = useCallback(async () => {
|
||||
if (!batchId) return;
|
||||
await loadBatchById(batchId);
|
||||
}, [batchId, loadBatchById]);
|
||||
|
||||
useEffect(() => {
|
||||
localStorage.setItem(FORM_STORAGE_KEY, JSON.stringify({
|
||||
text,
|
||||
tag,
|
||||
concurrency,
|
||||
waitSeconds,
|
||||
pollInterval,
|
||||
passwordMode,
|
||||
passwordPrefix,
|
||||
fixedPassword,
|
||||
useProxy,
|
||||
}));
|
||||
}, [text, tag, concurrency, waitSeconds, pollInterval, passwordMode, passwordPrefix, fixedPassword, useProxy]);
|
||||
|
||||
useEffect(() => {
|
||||
if (restoredBatchRef.current) return;
|
||||
restoredBatchRef.current = true;
|
||||
const storedBatchId = readStoredBatchId();
|
||||
if (storedBatchId) {
|
||||
loadBatchById(storedBatchId);
|
||||
}
|
||||
}, [loadBatchById]);
|
||||
|
||||
useEffect(() => {
|
||||
if (batch?.batch_id) {
|
||||
localStorage.setItem(BATCH_STORAGE_KEY, batch.batch_id);
|
||||
}
|
||||
}, [batch?.batch_id]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isRunning || !batchId) return undefined;
|
||||
@@ -97,6 +208,7 @@ export default function HuyaRegisterPage() {
|
||||
poll_interval: pollInterval,
|
||||
password_prefix: passwordMode === 'random' ? (passwordPrefix.trim() || 'hy') : 'hy',
|
||||
fixed_password: passwordMode === 'fixed' ? fixedPassword.trim() : '',
|
||||
use_proxy: useProxy,
|
||||
});
|
||||
setBatch(data);
|
||||
message.success('自动注册批次已启动');
|
||||
@@ -274,6 +386,18 @@ export default function HuyaRegisterPage() {
|
||||
)}
|
||||
</Space.Compact>
|
||||
</Col>
|
||||
<Col xs={12} md={4}>
|
||||
<Text type="secondary">代理</Text>
|
||||
<div style={{ height: 32, display: 'flex', alignItems: 'center' }}>
|
||||
<Switch
|
||||
checked={useProxy}
|
||||
checkedChildren="开"
|
||||
unCheckedChildren="关"
|
||||
onChange={setUseProxy}
|
||||
disabled={isRunning}
|
||||
/>
|
||||
</div>
|
||||
</Col>
|
||||
<Col xs={24} md={4}>
|
||||
<Space style={{ width: '100%', paddingTop: 22 }}>
|
||||
<Button
|
||||
|
||||
Reference in New Issue
Block a user