添加虎牙短信登录
This commit is contained in:
@@ -11,6 +11,10 @@ import type {
|
||||
HuyaPasswordLoginResult,
|
||||
HuyaPasswordLoginSelectedRequest,
|
||||
HuyaRechargeGoodsItem,
|
||||
HuyaSmsCodeRequest,
|
||||
HuyaSmsCodeResult,
|
||||
HuyaSmsLoginRequest,
|
||||
HuyaSmsLoginResult,
|
||||
HuyaTaskBatchRequest,
|
||||
HuyaTaskBatchResult,
|
||||
HuyaTaskItem,
|
||||
@@ -31,6 +35,10 @@ export const huyaApi = {
|
||||
api.post<HuyaPasswordLoginResult, HuyaPasswordLoginResult>('/huya/accounts/password-login', data),
|
||||
passwordLoginSelected: (data: HuyaPasswordLoginSelectedRequest) =>
|
||||
api.post<HuyaPasswordLoginBatchResult, HuyaPasswordLoginBatchResult>('/huya/accounts/password-login/selected', data),
|
||||
smsCode: (data: HuyaSmsCodeRequest) =>
|
||||
api.post<HuyaSmsCodeResult, HuyaSmsCodeResult>('/huya/accounts/sms-code', data, { timeout: 120000 }),
|
||||
smsLogin: (data: HuyaSmsLoginRequest) =>
|
||||
api.post<HuyaSmsLoginResult, HuyaSmsLoginResult>('/huya/accounts/sms-login', data, { timeout: 120000 }),
|
||||
assign: (id: number, assigned_to: number | null) =>
|
||||
api.put<MessageResponse, MessageResponse>(`/huya/accounts/${id}/assign`, { assigned_to }),
|
||||
batchAssign: (account_ids: number[], assigned_to: number | null) =>
|
||||
|
||||
@@ -149,6 +149,30 @@ export interface HuyaPasswordLoginResult extends MessageResponse {
|
||||
sdid: string;
|
||||
}
|
||||
|
||||
export interface HuyaSmsCodeRequest {
|
||||
phone: string;
|
||||
cookie?: string;
|
||||
}
|
||||
|
||||
export interface HuyaSmsCodeResult extends MessageResponse {
|
||||
state: string;
|
||||
sdid: string;
|
||||
context: string;
|
||||
request_id: string;
|
||||
}
|
||||
|
||||
export interface HuyaSmsLoginRequest {
|
||||
authcode: string;
|
||||
state: string;
|
||||
phone?: string;
|
||||
tag?: string;
|
||||
}
|
||||
|
||||
export interface HuyaSmsLoginResult extends MessageResponse {
|
||||
account: HuyaAccountItem;
|
||||
sdid: string;
|
||||
}
|
||||
|
||||
export interface HuyaPasswordLoginBatchItem {
|
||||
line: number;
|
||||
username: string;
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
Button, Card, Col, Input, message, Modal, Popconfirm, Row, Select, Space, Statistic, Table, Tag, Typography,
|
||||
} from 'antd';
|
||||
import type { TableProps } from 'antd';
|
||||
import { DeleteOutlined, FilterOutlined, ImportOutlined, LoginOutlined, ReloadOutlined, SearchOutlined, TagOutlined } from '@ant-design/icons';
|
||||
import { DeleteOutlined, FilterOutlined, ImportOutlined, LoginOutlined, MobileOutlined, ReloadOutlined, SearchOutlined, TagOutlined } from '@ant-design/icons';
|
||||
import {
|
||||
huyaApi,
|
||||
type HuyaAccountItem,
|
||||
@@ -53,6 +53,13 @@ export default function HuyaAccountsPage() {
|
||||
const [passwordLoginResultOpen, setPasswordLoginResultOpen] = useState(false);
|
||||
const [passwordLogging, setPasswordLogging] = useState(false);
|
||||
const [passwordLoginResults, setPasswordLoginResults] = useState<HuyaPasswordLoginBatchItem[]>([]);
|
||||
const [smsLoginOpen, setSmsLoginOpen] = useState(false);
|
||||
const [smsPhone, setSmsPhone] = useState('');
|
||||
const [smsCode, setSmsCode] = useState('');
|
||||
const [smsTag, setSmsTag] = useState<string[]>([]);
|
||||
const [smsState, setSmsState] = useState('');
|
||||
const [smsSending, setSmsSending] = useState(false);
|
||||
const [smsLogging, setSmsLogging] = useState(false);
|
||||
const [searchText, setSearchText] = useState('');
|
||||
const [tagFilter, setTagFilter] = useState('');
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
|
||||
@@ -159,6 +166,67 @@ export default function HuyaAccountsPage() {
|
||||
setPasswordImportOpen(true);
|
||||
};
|
||||
|
||||
const openSmsLogin = () => {
|
||||
setSmsPhone('');
|
||||
setSmsCode('');
|
||||
setSmsTag([]);
|
||||
setSmsState('');
|
||||
setSmsLoginOpen(true);
|
||||
};
|
||||
|
||||
const handleSendSmsCode = async () => {
|
||||
const phone = smsPhone.trim();
|
||||
if (!phone) {
|
||||
message.warning('请先输入手机号');
|
||||
return;
|
||||
}
|
||||
setSmsSending(true);
|
||||
try {
|
||||
const result = await huyaApi.smsCode({ phone });
|
||||
setSmsState(result.state);
|
||||
message.success(result.message || '短信已发送');
|
||||
} catch (e: unknown) {
|
||||
message.error(getErrorMessage(e));
|
||||
} finally {
|
||||
setSmsSending(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSmsLogin = async () => {
|
||||
const phone = smsPhone.trim();
|
||||
const authcode = smsCode.trim();
|
||||
if (!smsState) {
|
||||
message.warning('请先发送短信验证码');
|
||||
return;
|
||||
}
|
||||
if (!authcode) {
|
||||
message.warning('请先输入短信验证码');
|
||||
return;
|
||||
}
|
||||
setSmsLogging(true);
|
||||
try {
|
||||
const tag = smsTag.length > 0 ? smsTag[smsTag.length - 1].trim() : '';
|
||||
const result = await huyaApi.smsLogin({
|
||||
phone,
|
||||
authcode,
|
||||
state: smsState,
|
||||
tag,
|
||||
});
|
||||
message.success(result.message || '登录成功,Cookie 已保存');
|
||||
setSmsLoginOpen(false);
|
||||
setSmsPhone('');
|
||||
setSmsCode('');
|
||||
setSmsTag([]);
|
||||
setSmsState('');
|
||||
loadAccounts();
|
||||
loadTags();
|
||||
} catch (e: unknown) {
|
||||
message.error(getErrorMessage(e));
|
||||
} finally {
|
||||
setSmsLogging(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleImportPasswordAccounts = async () => {
|
||||
if (!passwordImportText.trim()) {
|
||||
message.warning('请先粘贴虎牙账号密码');
|
||||
@@ -491,6 +559,15 @@ export default function HuyaAccountsPage() {
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
)}
|
||||
{canImport && (
|
||||
<Button
|
||||
icon={<MobileOutlined />}
|
||||
loading={smsSending || smsLogging}
|
||||
onClick={openSmsLogin}
|
||||
>
|
||||
短信登录
|
||||
</Button>
|
||||
)}
|
||||
{canImport && (
|
||||
<Button icon={<ImportOutlined />} onClick={openPasswordImport}>
|
||||
导入账号密码
|
||||
@@ -656,6 +733,62 @@ export default function HuyaAccountsPage() {
|
||||
</Space>
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
title="虎牙短信登录"
|
||||
open={smsLoginOpen}
|
||||
onCancel={() => {
|
||||
if (smsSending || smsLogging) return;
|
||||
setSmsLoginOpen(false);
|
||||
}}
|
||||
footer={[
|
||||
<Button key="cancel" disabled={smsSending || smsLogging} onClick={() => setSmsLoginOpen(false)}>
|
||||
取消
|
||||
</Button>,
|
||||
<Button key="send" icon={<MobileOutlined />} loading={smsSending} disabled={smsLogging} onClick={handleSendSmsCode}>
|
||||
{smsState ? '重新发码' : '发送短信'}
|
||||
</Button>,
|
||||
<Button key="login" type="primary" icon={<LoginOutlined />} loading={smsLogging} disabled={!smsState || smsSending} onClick={handleSmsLogin}>
|
||||
登录并保存
|
||||
</Button>,
|
||||
]}
|
||||
maskClosable={!(smsSending || smsLogging)}
|
||||
closable={!(smsSending || smsLogging)}
|
||||
width={520}
|
||||
>
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={12}>
|
||||
<Input
|
||||
value={smsPhone}
|
||||
onChange={(e) => setSmsPhone(e.target.value)}
|
||||
placeholder="手机号"
|
||||
disabled={smsSending || smsLogging || Boolean(smsState)}
|
||||
prefix={<MobileOutlined />}
|
||||
/>
|
||||
<Input
|
||||
value={smsCode}
|
||||
onChange={(e) => setSmsCode(e.target.value.replace(/\D/g, '').slice(0, 8))}
|
||||
placeholder="短信验证码"
|
||||
maxLength={8}
|
||||
disabled={!smsState || smsSending || smsLogging}
|
||||
onPressEnter={handleSmsLogin}
|
||||
/>
|
||||
<Select
|
||||
mode="tags"
|
||||
style={{ width: '100%' }}
|
||||
placeholder="可选,保存到账号标签"
|
||||
maxCount={1}
|
||||
value={smsTag}
|
||||
onChange={setSmsTag}
|
||||
options={tags.map((tag) => ({ value: tag, label: tag }))}
|
||||
disabled={smsSending || smsLogging}
|
||||
/>
|
||||
{smsState ? (
|
||||
<Text type="secondary">短信已发送,输入验证码后提交登录。</Text>
|
||||
) : (
|
||||
<Text type="secondary">发码时会自动处理滑块验证,完成后继续输入短信验证码。</Text>
|
||||
)}
|
||||
</Space>
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
title="虎牙登录结果"
|
||||
open={passwordLoginResultOpen}
|
||||
|
||||
Reference in New Issue
Block a user