增加了代理平台和日志
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import api from './client';
|
||||
import type { ProxyConfig, ProxyTestResult } from './types';
|
||||
import type { ProxyConfig, ProxyTestResult, PlatformInfo } from './types';
|
||||
|
||||
export const proxyApi = {
|
||||
get: () => api.get<ProxyConfig, ProxyConfig>('/proxy'),
|
||||
update: (data: ProxyConfig) => api.put<ProxyConfig, ProxyConfig>('/proxy', data),
|
||||
test: () => api.post<ProxyTestResult, ProxyTestResult>('/proxy/test'),
|
||||
testWhitelist: () => api.post<ProxyTestResult, ProxyTestResult>('/proxy/whitelist/test'),
|
||||
getPlatforms: () => api.get<PlatformInfo[], PlatformInfo[]>('/proxy/platforms'),
|
||||
};
|
||||
|
||||
@@ -112,6 +112,9 @@ export interface ProxyConfig {
|
||||
http: string;
|
||||
https: string;
|
||||
whitelist_enabled: boolean;
|
||||
whitelist_platform: string;
|
||||
whitelist_credentials: Record<string, string> | null;
|
||||
// 旧字段保留(向后兼容)
|
||||
whitelist_uid: string;
|
||||
whitelist_ukey: string;
|
||||
}
|
||||
@@ -121,6 +124,18 @@ export interface ProxyTestResult {
|
||||
success: boolean;
|
||||
}
|
||||
|
||||
export interface PlatformFieldDef {
|
||||
key: string;
|
||||
label: string;
|
||||
placeholder: string;
|
||||
}
|
||||
|
||||
export interface PlatformInfo {
|
||||
name: string;
|
||||
label: string;
|
||||
credential_fields: PlatformFieldDef[];
|
||||
}
|
||||
|
||||
// ==================== Permissions ====================
|
||||
|
||||
export interface PermissionsListResult {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useState, useCallback } from 'react';
|
||||
import { Form, Input, Switch, Button, Card, message, Row, Col } from 'antd';
|
||||
import { proxyApi, type ProxyConfig } from '../api/modules';
|
||||
import { Form, Input, Switch, Button, Card, Select, message, Row, Col } from 'antd';
|
||||
import { proxyApi, type ProxyConfig, type PlatformInfo } from '../api/modules';
|
||||
import RealtimeLogPanel from '../components/RealtimeLogPanel';
|
||||
import { useWebSocketLogs } from '../hooks/useWebSocketLogs';
|
||||
import { getErrorMessage } from '../utils/error';
|
||||
@@ -13,6 +13,19 @@ export default function ProxyPage() {
|
||||
const [configLoaded, setConfigLoaded] = useState(false);
|
||||
const { logs, connect: connectLogs, close: closeLogs } = useWebSocketLogs();
|
||||
|
||||
// 平台相关状态
|
||||
const [platforms, setPlatforms] = useState<PlatformInfo[]>([]);
|
||||
const [selectedPlatform, setSelectedPlatform] = useState<string>('xiequ');
|
||||
const [credentials, setCredentials] = useState<Record<string, string>>({});
|
||||
|
||||
// 加载平台列表
|
||||
useEffect(() => {
|
||||
proxyApi.getPlatforms().then(setPlatforms).catch(() => {});
|
||||
}, []);
|
||||
|
||||
// 当前平台的凭据字段定义
|
||||
const currentPlatformFields = platforms.find(p => p.name === selectedPlatform)?.credential_fields ?? [];
|
||||
|
||||
const loadConfig = useCallback(async () => {
|
||||
try {
|
||||
const data = await proxyApi.get();
|
||||
@@ -22,9 +35,19 @@ export default function ProxyPage() {
|
||||
http: data.http ?? '',
|
||||
https: data.https ?? '',
|
||||
whitelist_enabled: data.whitelist_enabled ?? false,
|
||||
whitelist_uid: data.whitelist_uid ?? '',
|
||||
whitelist_ukey: data.whitelist_ukey ?? '',
|
||||
});
|
||||
|
||||
// 恢复平台和凭据
|
||||
const platform = data.whitelist_platform || 'xiequ';
|
||||
setSelectedPlatform(platform);
|
||||
if (data.whitelist_credentials && Object.keys(data.whitelist_credentials).length > 0) {
|
||||
setCredentials(data.whitelist_credentials);
|
||||
} else if (data.whitelist_uid || data.whitelist_ukey) {
|
||||
// 向后兼容:旧字段迁移到凭据
|
||||
setCredentials({ uid: data.whitelist_uid || '', ukey: data.whitelist_ukey || '' });
|
||||
} else {
|
||||
setCredentials({});
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
message.error(getErrorMessage(e));
|
||||
} finally {
|
||||
@@ -56,7 +79,15 @@ export default function ProxyPage() {
|
||||
setLoading(true);
|
||||
try {
|
||||
const values = await form.validateFields();
|
||||
await proxyApi.update(values as ProxyConfig);
|
||||
const submitData: ProxyConfig = {
|
||||
...values,
|
||||
whitelist_platform: selectedPlatform,
|
||||
whitelist_credentials: credentials,
|
||||
// 旧字段:协固平台双写,其他平台清空
|
||||
whitelist_uid: selectedPlatform === 'xiequ' ? (credentials.uid || '') : '',
|
||||
whitelist_ukey: selectedPlatform === 'xiequ' ? (credentials.ukey || '') : '',
|
||||
};
|
||||
await proxyApi.update(submitData);
|
||||
message.success('已保存');
|
||||
} catch (e: unknown) {
|
||||
message.error(getErrorMessage(e));
|
||||
@@ -87,6 +118,15 @@ export default function ProxyPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const handlePlatformChange = (value: string) => {
|
||||
setSelectedPlatform(value);
|
||||
setCredentials({});
|
||||
};
|
||||
|
||||
const handleCredentialChange = (key: string, value: string) => {
|
||||
setCredentials(prev => ({ ...prev, [key]: value }));
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', height: '100%', gap: 8 }}>
|
||||
@@ -106,8 +146,6 @@ export default function ProxyPage() {
|
||||
api_url: '',
|
||||
http: '',
|
||||
https: '',
|
||||
whitelist_uid: '',
|
||||
whitelist_ukey: '',
|
||||
}}
|
||||
style={{ flexShrink: 0 }}
|
||||
>
|
||||
@@ -118,7 +156,7 @@ export default function ProxyPage() {
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
<Form.Item name="api_url" label="代理API地址" style={{ marginBottom: 8 }}>
|
||||
<Input placeholder="http://op.xiequ.cn/...?act=get" />
|
||||
<Input placeholder="代理提取API地址" />
|
||||
</Form.Item>
|
||||
<Form.Item name="http" label="静态HTTP代理" style={{ marginBottom: 8 }}>
|
||||
<Input placeholder="http://ip:port" />
|
||||
@@ -134,12 +172,30 @@ export default function ProxyPage() {
|
||||
<Form.Item name="whitelist_enabled" label="启用白名单自动管理" valuePropName="checked" style={{ marginBottom: 8 }}>
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
<Form.Item name="whitelist_uid" label="协固UID" style={{ marginBottom: 8 }}>
|
||||
<Input placeholder="如: 99769" />
|
||||
</Form.Item>
|
||||
<Form.Item name="whitelist_ukey" label="协固UKEY" style={{ marginBottom: 8 }}>
|
||||
<Input placeholder="如: C99371082B965B70F46DCAA87A04618B" />
|
||||
</Form.Item>
|
||||
|
||||
{/* 平台选择 */}
|
||||
<div style={{ marginBottom: 8 }}>
|
||||
<div style={{ marginBottom: 4, fontSize: 13, color: 'rgba(0,0,0,0.88)' }}>代理平台</div>
|
||||
<Select
|
||||
value={selectedPlatform}
|
||||
onChange={handlePlatformChange}
|
||||
style={{ width: '100%' }}
|
||||
options={platforms.map(p => ({ value: p.name, label: p.label }))}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 动态凭据字段 */}
|
||||
{currentPlatformFields.map(field => (
|
||||
<div key={field.key} style={{ marginBottom: 8 }}>
|
||||
<div style={{ marginBottom: 4, fontSize: 13, color: 'rgba(0,0,0,0.88)' }}>{field.label}</div>
|
||||
<Input
|
||||
placeholder={field.placeholder}
|
||||
value={credentials[field.key] || ''}
|
||||
onChange={(e) => handleCredentialChange(field.key, e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
|
||||
<Button size="small" onClick={handleTestWhitelist} loading={testingWl}>测试白名单</Button>
|
||||
</Card>
|
||||
</Col>
|
||||
|
||||
Reference in New Issue
Block a user