Files
web-client/src/components/Connection/ConnectDialog.tsx

171 lines
4.4 KiB
TypeScript
Raw Normal View History

2026-02-09 16:33:52 +08:00
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