171 lines
4.4 KiB
TypeScript
171 lines
4.4 KiB
TypeScript
|
|
import React, { useState, useEffect } from 'react'
|
|||
|
|
import { Modal, Form, Input, Button, Alert, Space } from 'antd'
|
|||
|
|
import { useSelector } from 'react-redux'
|
|||
|
|
import type { RootState } from '../../store/store'
|
|||
|
|
|
|||
|
|
interface ConnectDialogProps {
|
|||
|
|
visible: boolean
|
|||
|
|
onConnect: (url: string) => void
|
|||
|
|
onCancel: () => void
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 连接服务器对话框
|
|||
|
|
*/
|
|||
|
|
const ConnectDialog: React.FC<ConnectDialogProps> = ({
|
|||
|
|
visible,
|
|||
|
|
onConnect,
|
|||
|
|
onCancel
|
|||
|
|
}) => {
|
|||
|
|
const [form] = Form.useForm()
|
|||
|
|
const [loading, setLoading] = useState(false)
|
|||
|
|
const { status: connectionStatus, serverUrl } = useSelector((state: RootState) => state.connection)
|
|||
|
|
|
|||
|
|
// 预设服务器地址选项
|
|||
|
|
const presetServers = [
|
|||
|
|
'ws://localhost:3001',
|
|||
|
|
'ws://127.0.0.1:3001',
|
|||
|
|
'ws://192.168.1.100:3001', // 示例局域网地址
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
useEffect(() => {
|
|||
|
|
if (visible) {
|
|||
|
|
// 如果已有服务器地址,使用它作为默认值
|
|||
|
|
if (serverUrl) {
|
|||
|
|
form.setFieldValue('serverUrl', serverUrl)
|
|||
|
|
} else {
|
|||
|
|
form.setFieldValue('serverUrl', 'ws://localhost:3001')
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}, [visible, serverUrl, form])
|
|||
|
|
|
|||
|
|
useEffect(() => {
|
|||
|
|
if (connectionStatus === 'connected') {
|
|||
|
|
setLoading(false)
|
|||
|
|
} else if (connectionStatus === 'error') {
|
|||
|
|
setLoading(false)
|
|||
|
|
}
|
|||
|
|
}, [connectionStatus])
|
|||
|
|
|
|||
|
|
const handleConnect = async () => {
|
|||
|
|
try {
|
|||
|
|
const values = await form.validateFields()
|
|||
|
|
setLoading(true)
|
|||
|
|
onConnect(values.serverUrl)
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('表单验证失败:', error)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const handlePresetSelect = (url: string) => {
|
|||
|
|
form.setFieldValue('serverUrl', url)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const validateWebSocketUrl = (_: any, value: string) => {
|
|||
|
|
if (!value) {
|
|||
|
|
return Promise.reject(new Error('请输入服务器地址'))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!value.startsWith('ws://') && !value.startsWith('wss://')) {
|
|||
|
|
return Promise.reject(new Error('地址必须以 ws:// 或 wss:// 开头'))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
new URL(value)
|
|||
|
|
return Promise.resolve()
|
|||
|
|
} catch {
|
|||
|
|
return Promise.reject(new Error('请输入有效的WebSocket地址'))
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<Modal
|
|||
|
|
title="连接到远程控制服务器"
|
|||
|
|
open={visible}
|
|||
|
|
onCancel={onCancel}
|
|||
|
|
width={500}
|
|||
|
|
footer={[
|
|||
|
|
<Button key="cancel" onClick={onCancel}>
|
|||
|
|
取消
|
|||
|
|
</Button>,
|
|||
|
|
<Button
|
|||
|
|
key="connect"
|
|||
|
|
type="primary"
|
|||
|
|
loading={loading}
|
|||
|
|
onClick={handleConnect}
|
|||
|
|
>
|
|||
|
|
{loading ? '连接中...' : '连接'}
|
|||
|
|
</Button>,
|
|||
|
|
]}
|
|||
|
|
maskClosable={false}
|
|||
|
|
>
|
|||
|
|
<Form
|
|||
|
|
form={form}
|
|||
|
|
layout="vertical"
|
|||
|
|
initialValues={{
|
|||
|
|
serverUrl: 'ws://localhost:3001'
|
|||
|
|
}}
|
|||
|
|
>
|
|||
|
|
<Form.Item
|
|||
|
|
label="服务器地址"
|
|||
|
|
name="serverUrl"
|
|||
|
|
rules={[
|
|||
|
|
{ validator: validateWebSocketUrl }
|
|||
|
|
]}
|
|||
|
|
help="输入WebSocket服务器地址,例如: ws://localhost:3001"
|
|||
|
|
>
|
|||
|
|
<Input
|
|||
|
|
placeholder="ws://localhost:3001"
|
|||
|
|
size="large"
|
|||
|
|
autoFocus
|
|||
|
|
onPressEnter={handleConnect}
|
|||
|
|
/>
|
|||
|
|
</Form.Item>
|
|||
|
|
|
|||
|
|
<div style={{ marginBottom: '16px' }}>
|
|||
|
|
<div style={{ marginBottom: '8px', color: '#666', fontSize: '14px' }}>
|
|||
|
|
常用地址:
|
|||
|
|
</div>
|
|||
|
|
<Space wrap>
|
|||
|
|
{presetServers.map((url) => (
|
|||
|
|
<Button
|
|||
|
|
key={url}
|
|||
|
|
size="small"
|
|||
|
|
type="dashed"
|
|||
|
|
onClick={() => handlePresetSelect(url)}
|
|||
|
|
>
|
|||
|
|
{url}
|
|||
|
|
</Button>
|
|||
|
|
))}
|
|||
|
|
</Space>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
{connectionStatus === 'error' && (
|
|||
|
|
<Alert
|
|||
|
|
message="连接失败"
|
|||
|
|
description="无法连接到服务器,请检查地址是否正确,服务器是否运行正常"
|
|||
|
|
type="error"
|
|||
|
|
showIcon
|
|||
|
|
style={{ marginBottom: '16px' }}
|
|||
|
|
/>
|
|||
|
|
)}
|
|||
|
|
|
|||
|
|
<Alert
|
|||
|
|
message="使用说明"
|
|||
|
|
description={
|
|||
|
|
<div>
|
|||
|
|
<p>1. 确保远程控制服务器已启动</p>
|
|||
|
|
<p>2. 如果服务器在本机,使用 localhost 或 127.0.0.1</p>
|
|||
|
|
<p>3. 如果服务器在局域网,使用服务器的IP地址</p>
|
|||
|
|
<p>4. 确保防火墙已开放相应端口</p>
|
|||
|
|
</div>
|
|||
|
|
}
|
|||
|
|
type="info"
|
|||
|
|
showIcon
|
|||
|
|
/>
|
|||
|
|
</Form>
|
|||
|
|
</Modal>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export default ConnectDialog
|