执行任务接口增加
This commit is contained in:
@@ -14,9 +14,9 @@ import {
|
||||
import {
|
||||
Plane, Navigation, Wind, Thermometer, Droplets, Satellite,
|
||||
LayoutGrid, Clock, CheckCircle2, AlertCircle, Zap, Waves,
|
||||
Calendar, User, TrendingUp, Maximize2
|
||||
Calendar, User, TrendingUp, Maximize2, Play, Square, X, MapPin, RotateCw
|
||||
} from 'lucide-react';
|
||||
import { getsinglePlan, getsinglePlanTrack } from '@/api/device';
|
||||
import { getsinglePlan, getsinglePlanTrack, updateFlightTaskStatus, postFlightCommmand } from '@/api/device';
|
||||
import dayjs from 'dayjs';
|
||||
import utils from '@/lib/utils';
|
||||
import CesiumMap from '../Map';
|
||||
@@ -44,6 +44,14 @@ export default function WayLinePage({ planedevices }) {
|
||||
|
||||
const [points, setPoints] = useState([]);
|
||||
|
||||
// 任务控制相关状态
|
||||
const [selectedTask, setSelectedTask] = useState(null);
|
||||
const [taskstatus, setTaskStatus] = useState('suspended');
|
||||
const [isReturningHome, setIsReturningHome] = useState(false);
|
||||
const [isTaskPaused, setIsTaskPaused] = useState(false);
|
||||
const [flightCommandLoading, setFlightCommandLoading] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
// 顶部统计
|
||||
const topCards = [
|
||||
{ title: '今日航线计划', value: '18', unit: '条', trend: '较昨日 +2', trendColor: '#00B42A', icon: <LayoutGrid size={22} />, color: '#165DFF' },
|
||||
@@ -168,6 +176,7 @@ export default function WayLinePage({ planedevices }) {
|
||||
|
||||
// 表格行点击查看轨迹
|
||||
const handleRowClick = async (record) => {
|
||||
setSelectedTask(record); // 记录当前选中的任务
|
||||
try {
|
||||
const res = await getsinglePlanTrack(record);
|
||||
if (res.code === 0 && res.data.track?.points?.length) {
|
||||
@@ -204,6 +213,72 @@ export default function WayLinePage({ planedevices }) {
|
||||
};
|
||||
const { waitList, runList, finishList } = groupBoardData();
|
||||
|
||||
// 指令下发逻辑
|
||||
const sendFlightCommand = async (command: 'return_home' | 'return_home_cancel' | 'flighttask_pause' | 'flighttask_recovery') => {
|
||||
if (!listDrone?.device_sn) {
|
||||
utils.message.warning('未选中无人机或无人机SN不存在');
|
||||
return;
|
||||
}
|
||||
|
||||
setFlightCommandLoading(true);
|
||||
const data = {
|
||||
command,
|
||||
deviceSn: listDrone.device_sn,
|
||||
}
|
||||
try {
|
||||
const res: any = await postFlightCommmand(data);
|
||||
if (res.code === 200 || res.code === 0) {
|
||||
utils.message.success('指令下发成功');
|
||||
// 切换状态
|
||||
if (command === 'return_home') setIsReturningHome(true);
|
||||
if (command === 'return_home_cancel') setIsReturningHome(false);
|
||||
if (command === 'flighttask_pause') setIsTaskPaused(true);
|
||||
if (command === 'flighttask_recovery') setIsTaskPaused(false);
|
||||
} else {
|
||||
utils.message.error(res.msg || '指令下发失败');
|
||||
}
|
||||
} catch (err) {
|
||||
utils.message.error('接口请求异常');
|
||||
} finally {
|
||||
setFlightCommandLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 任务状态更新逻辑
|
||||
const updateTaskStatus = async (taskId: string, status: string) => {
|
||||
if (!taskId) {
|
||||
utils.message.warning('请先选择航线任务');
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
try {
|
||||
const res: any = await updateFlightTaskStatus(taskId, status);
|
||||
if (res.code === 200 || res.code === 0) {
|
||||
const statusText = {
|
||||
executing: '任务执行成功',
|
||||
suspended: '任务已挂起',
|
||||
restored: '任务已继续',
|
||||
return_home: '任务已返航'
|
||||
}[status] || '状态更新成功';
|
||||
|
||||
if (status === "suspended") {
|
||||
setTaskStatus('suspended');
|
||||
} else {
|
||||
setTaskStatus('restored');
|
||||
}
|
||||
utils.message.success(statusText);
|
||||
// 刷新任务列表
|
||||
getListTask();
|
||||
} else {
|
||||
utils.message.error(res.msg || '操作失败');
|
||||
}
|
||||
} catch (err) {
|
||||
utils.message.error('操作接口异常');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="normal-spacing" style={{ background: '#f5f7fa', minHeight: '100vh', padding: '16px', paddingTop: 0 }}>
|
||||
<Row gutter={[16, 16]} style={{ marginBottom: 16 }}>
|
||||
@@ -310,7 +385,7 @@ export default function WayLinePage({ planedevices }) {
|
||||
columns={taskColumns}
|
||||
dataSource={taskList}
|
||||
pagination={false}
|
||||
scroll={{ y: 260 }}
|
||||
scroll={{ y: 'auto', maxHeight: 260 }}
|
||||
style={{ height: '100%' }}
|
||||
onRow={(record) => ({
|
||||
onClick: () => handleRowClick(record),
|
||||
@@ -401,6 +476,62 @@ export default function WayLinePage({ planedevices }) {
|
||||
<Switch size="small" />
|
||||
</Space>
|
||||
</div>
|
||||
<Divider style={{ margin: '16px 0' }} />
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '8px' }}>
|
||||
{/* 执行/挂起/继续 逻辑 */}
|
||||
{selectedTask?.status === 'executing' || selectedTask?.status === 'running' || selectedTask?.status === 'restored' ? (
|
||||
<Button
|
||||
type="primary"
|
||||
danger
|
||||
icon={<Square size={16} />}
|
||||
onClick={() => updateTaskStatus(selectedTask?.uuid, 'suspended')}
|
||||
loading={loading}
|
||||
// 统一样式:高度36 + 圆角18 + 字重600 + 图标文字居中
|
||||
style={{ height: 36, borderRadius: 18, fontWeight: 600, display: 'inline-flex', alignItems: 'center', gap: 4 }}
|
||||
>
|
||||
挂起任务
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<Play size={16} />}
|
||||
onClick={() => {
|
||||
if (selectedTask?.status === 'suspended') {
|
||||
updateTaskStatus(selectedTask?.uuid, 'restored');
|
||||
} else {
|
||||
updateTaskStatus(selectedTask?.uuid, 'executing');
|
||||
}
|
||||
}}
|
||||
loading={loading}
|
||||
// 统一样式:主色#165DFF + 高度36 + 圆角18 + 字重600
|
||||
style={{ background: '#165DFF', height: 36, borderRadius: 18, fontWeight: 600, display: 'inline-flex', alignItems: 'center', gap: 4 }}
|
||||
>
|
||||
{selectedTask?.status === 'suspended' ? '继续任务' : '执行任务'}
|
||||
</Button>
|
||||
)}
|
||||
{/* 返航逻辑 */}
|
||||
<Button
|
||||
type="primary"
|
||||
danger={isReturningHome}
|
||||
icon={isReturningHome ? <X size={16} /> : <MapPin size={16} />}
|
||||
onClick={() => sendFlightCommand(isReturningHome ? 'return_home_cancel' : 'return_home')}
|
||||
loading={flightCommandLoading}
|
||||
style={{ background: '#165DFF', height: 36, borderRadius: 18, fontWeight: 600, display: 'inline-flex', alignItems: 'center', gap: 4 }}
|
||||
>
|
||||
{isReturningHome ? '取消返航' : '返航'}
|
||||
</Button>
|
||||
|
||||
{/* 暂停/恢复逻辑 */}
|
||||
<Button
|
||||
type="default"
|
||||
icon={isTaskPaused ? <RotateCw size={16} /> : <Square size={16} />}
|
||||
onClick={() => sendFlightCommand(isTaskPaused ? 'flighttask_recovery' : 'flighttask_pause')}
|
||||
loading={flightCommandLoading}
|
||||
style={{ height: 36, borderRadius: 18, fontWeight: 600, display: 'inline-flex', alignItems: 'center', gap: 4 }}
|
||||
>
|
||||
{isTaskPaused ? '恢复任务' : '暂停任务'}
|
||||
</Button>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card
|
||||
|
||||
Reference in New Issue
Block a user