Files
web-client/src/components/Connection/ConnectDialog.tsx
wdvipa 28040495c8 111
2026-02-09 16:33:52 +08:00

171 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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