From 62cce4ec0e765b5fd2854be20e2b0feff7c1b76e Mon Sep 17 00:00:00 2001 From: mmc <1556375442@qq.com> Date: Mon, 25 May 2026 13:06:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=A0=E4=BA=BA=E6=9C=BA=20=E7=AE=A1?= =?UTF-8?q?=E7=90=86=20=E7=BB=91=E5=AE=9A=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/device.ts | 20 ++- .../SystemSetting/DeviceManagement.tsx | 160 +++++++++++++++++- 2 files changed, 178 insertions(+), 2 deletions(-) diff --git a/src/api/device.ts b/src/api/device.ts index c7c26f8..28380d5 100644 --- a/src/api/device.ts +++ b/src/api/device.ts @@ -139,7 +139,25 @@ export function changeCameraPlane(data) { }) } -//直播心跳 +// 绑定无人机 +export function bindDrone(data) { + return request({ + url: '/iot/UAV/bind', + method: 'post', + data + }) +} + +// 解绑无人机 +export function unbindDrone(data) { + return request({ + url: '/iot/UAV/unbind', + method: 'post', + data + }) +} + +// 直播心跳 export function postLiveHeartbeat(data) { return request({ diff --git a/src/components/SystemSetting/DeviceManagement.tsx b/src/components/SystemSetting/DeviceManagement.tsx index 327efa2..b15da1e 100644 --- a/src/components/SystemSetting/DeviceManagement.tsx +++ b/src/components/SystemSetting/DeviceManagement.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { Table, Input, @@ -12,6 +12,10 @@ import { Tabs, Card, InputNumber, + Checkbox, + Tooltip, + Row, + Col, } from 'antd'; import { SearchOutlined, @@ -19,8 +23,14 @@ import { PlusOutlined, EditOutlined, DeleteOutlined, + LinkOutlined, + DisconnectOutlined, } from '@ant-design/icons'; import SerialNumGenerate from "./SerialNumGenerate" +import { getPlaneDeviceList, bindDrone, unbindDrone } from '@/api/device'; +import { useSelector } from 'react-redux'; +import { RootState } from '@/src/store'; +import utils from '@/lib/utils'; // 模拟数据 const allDeviceList = [ @@ -54,6 +64,101 @@ export default function DeviceManagementPage() { const [loading, setLoading] = useState(false); const [deviceList, setDeviceList] = useState(allDeviceList); + // 无人机相关状态 + const { userInfo } = useSelector((state: RootState) => state.user); + const [droneList, setDroneList] = useState([]); + const [bindModalVisible, setBindModalVisible] = useState(false); + const [bindForm] = Form.useForm(); + const [selectedDroneKeys, setSelectedDroneKeys] = useState([]); + + const fetchDroneList = async () => { + setLoading(true); + try { + const res: any = await getPlaneDeviceList(); + if (res.code == 200) { + setDroneList(res?.data?.detail || []); + } + } catch (err) { + utils.message.error('获取无人机列表失败'); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + if (activeTab === 'drone') { + fetchDroneList(); + } + }, [activeTab]); + + const handleBind = async (values) => { + try { + const payload = { + siteId: values.siteId, + orgId: values.orgId, + userId: values.userId || userInfo?.userId, + sns: values.sns.split(',').map(s => s.trim()), + }; + const res: any = await bindDrone(payload); + if (res.code === 200) { + utils.message.success('绑定成功'); + setBindModalVisible(false); + bindForm.resetFields(); + fetchDroneList(); + } else { + utils.message.error(res.msg || '绑定失败'); + } + } catch (err) { + utils.message.error('操作异常'); + } + }; + + const handleUnbind = (sns, type) => { + const typeText = { 1: '人员', 2: '场站', 3: '组织' }[type]; + Modal.confirm({ + title: '确认解绑', + content: `确定要为选中的无人机清除${typeText}绑定吗?`, + onOk: async () => { + try { + const res: any = await unbindDrone({ sns, type }); + if (res.code === 200) { + utils.message.success('解绑成功'); + fetchDroneList(); + setSelectedDroneKeys([]); + } else { + utils.message.error(res.msg || '解绑失败'); + } + } catch (err) { + utils.message.error('操作异常'); + } + } + }); + }; + + const droneColumns = [ + { title: '设备名称', dataIndex: 'drone_callsign', key: 'name' }, + { title: 'SN码', dataIndex: 'device_sn', key: 'sn' }, + { title: '网关SN', dataIndex: 'gateway_sn', key: 'gsn' }, + { title: '状态', dataIndex: 'onlineStatus', key: 'status', render: s => {s === 1 ? '在线' : '离线'} }, + { + title: '操作', + key: 'action', + render: (_, record) => ( + + + + + + + + + + + + ), + }, + ]; + // 根据 Tab 过滤数据 const filteredByTab = deviceList.filter(tabs.find(t => t.key === activeTab)?.filter || (() => false)); @@ -149,12 +254,65 @@ export default function DeviceManagementPage() { + {/* ====================== 判断显示内容 ====================== */} {activeTab === 'serialGenerate' ? ( + ) : activeTab === 'drone' ? ( + <> +
+ + + + + + +
+ + `共 ${t} 条` }} + /> + + setBindModalVisible(false)} + onOk={() => bindForm.submit()} + width={500} + > +
+ + + + +
+ + + + + + + + + + + + + + + + ) : ( // 显示原来的设备列表 <>