|
|
@ -80,6 +80,42 @@ |
|
|
<span><i class="gray"></i>离线</span> |
|
|
<span><i class="gray"></i>离线</span> |
|
|
</div> |
|
|
</div> |
|
|
<div class="map-scale">{{ mapScaleText }}</div> |
|
|
<div class="map-scale">{{ mapScaleText }}</div> |
|
|
|
|
|
|
|
|
|
|
|
<div |
|
|
|
|
|
v-if="commandProgress.open" |
|
|
|
|
|
class="command-progress-float" |
|
|
|
|
|
role="status" |
|
|
|
|
|
aria-live="polite" |
|
|
|
|
|
> |
|
|
|
|
|
<header> |
|
|
|
|
|
<div> |
|
|
|
|
|
<strong>{{ commandProgress.title }}</strong> |
|
|
|
|
|
<small>{{ commandProgress.deviceName }}</small> |
|
|
|
|
|
</div> |
|
|
|
|
|
<button type="button" class="icon-button" title="关闭" @click="closeCommandProgress"> |
|
|
|
|
|
<svg><use href="#i-x" /></svg> |
|
|
|
|
|
</button> |
|
|
|
|
|
</header> |
|
|
|
|
|
<ol> |
|
|
|
|
|
<li :class="{ done: commandProgress.step > 1, active: commandProgress.step === 1 }"> |
|
|
|
|
|
<i></i><span>确认下发</span><em>已确认</em> |
|
|
|
|
|
</li> |
|
|
|
|
|
<li :class="{ done: commandProgress.step > 2, active: commandProgress.step === 2 }"> |
|
|
|
|
|
<i></i><span>已下发</span><em>{{ commandProgress.step >= 2 ? '等待应答' : '…' }}</em> |
|
|
|
|
|
</li> |
|
|
|
|
|
<li |
|
|
|
|
|
:class="{ |
|
|
|
|
|
done: commandProgress.step >= 3 && !commandProgress.error && commandProgress.status === 'acked', |
|
|
|
|
|
active: commandProgress.step === 3, |
|
|
|
|
|
fail: commandProgress.step >= 3 && (commandProgress.status === 'timeout' || commandProgress.status === 'terminal' || !!commandProgress.error), |
|
|
|
|
|
}" |
|
|
|
|
|
> |
|
|
|
|
|
<i></i> |
|
|
|
|
|
<span>{{ commandProgressTerminalLabel }}</span> |
|
|
|
|
|
<em>{{ commandProgress.error || commandProgress.result || '…' }}</em> |
|
|
|
|
|
</li> |
|
|
|
|
|
</ol> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<aside class="detail-panel" :class="{ 'drone-selected': isDrone }"> |
|
|
<aside class="detail-panel" :class="{ 'drone-selected': isDrone }"> |
|
|
@ -202,21 +238,21 @@ |
|
|
</button> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
<div class="workflow-actions"> |
|
|
<div class="workflow-actions"> |
|
|
<button class="workflow-action takeoff" @click="runCommand('一键起飞', '无人机将从机巢起飞并进入待命状态。')"><svg><use href="#i-plane" /></svg><span><strong>一键起飞</strong><small>状态:待执行</small></span></button> |
|
|
|
|
|
<button class="workflow-action landing" @click="runCommand('一键降落', '无人机将返回机巢并自动降落。')"><svg><use href="#i-home" /></svg><span><strong>一键降落</strong><small>状态:待执行</small></span></button> |
|
|
|
|
|
|
|
|
<button class="workflow-action takeoff" @click="runCommand('一键起飞', '无人机将从机巢起飞并进入待命状态。')"><svg><use href="#i-plane" /></svg><span><strong>一键起飞</strong><small>{{ buttonStatusText('一键起飞') }}</small></span></button> |
|
|
|
|
|
<button class="workflow-action landing" @click="runCommand('一键降落', '无人机将返回机巢并自动降落。')"><svg><use href="#i-home" /></svg><span><strong>一键降落</strong><small>{{ buttonStatusText('一键降落') }}</small></span></button> |
|
|
</div> |
|
|
</div> |
|
|
<div class="stage-actions"> |
|
|
<div class="stage-actions"> |
|
|
<button @click="runCommand('起飞准备', '将执行开舱并解除归中。')"><b>01</b><span>起飞准备<small>状态:待执行</small></span></button> |
|
|
|
|
|
<button @click="runCommand('起飞准备完成', '确认起飞准备已完成。')"><b>02</b><span>起飞准备完成<small>状态:待执行</small></span></button> |
|
|
|
|
|
<button @click="runCommand('降落准备', '将开舱并等待无人机返航。')"><b>03</b><span>降落准备<small>状态:待执行</small></span></button> |
|
|
|
|
|
<button @click="runCommand('降落准备完成', '确认降落准备已完成。')"><b>04</b><span>降落准备完成<small>状态:待执行</small></span></button> |
|
|
|
|
|
|
|
|
<button @click="runCommand('起飞准备', '将执行开舱并解除归中。')"><b>01</b><span>起飞准备<small>{{ buttonStatusText('起飞准备') }}</small></span></button> |
|
|
|
|
|
<button @click="runCommand('起飞准备完成', '确认起飞准备已完成。')"><b>02</b><span>起飞准备完成<small>{{ buttonStatusText('起飞准备完成') }}</small></span></button> |
|
|
|
|
|
<button @click="runCommand('降落准备', '将开舱并等待无人机返航。')"><b>03</b><span>降落准备<small>{{ buttonStatusText('降落准备') }}</small></span></button> |
|
|
|
|
|
<button @click="runCommand('降落准备完成', '确认降落准备已完成。')"><b>04</b><span>降落准备完成<small>{{ buttonStatusText('降落准备完成') }}</small></span></button> |
|
|
</div> |
|
|
</div> |
|
|
<button class="reset-action" @click="runCommand('整机复位', '机巢将恢复待命状态。')"><svg><use href="#i-settings" /></svg><span><strong>整机复位</strong><small>状态:待执行</small></span></button> |
|
|
|
|
|
|
|
|
<button class="reset-action" @click="runCommand('整机复位', '机巢将恢复待命状态。')"><svg><use href="#i-settings" /></svg><span><strong>整机复位</strong><small>{{ buttonStatusText('整机复位') }}</small></span></button> |
|
|
<div v-show="controlExpanded" class="dock-control-extra"> |
|
|
<div v-show="controlExpanded" class="dock-control-extra"> |
|
|
<div class="dock-control-extra-grid"> |
|
|
<div class="dock-control-extra-grid"> |
|
|
<button v-for="cmd in dockExtraCommands" :key="cmd.title" @click="runCommand(cmd.title, cmd.desc)"> |
|
|
<button v-for="cmd in dockExtraCommands" :key="cmd.title" @click="runCommand(cmd.title, cmd.desc)"> |
|
|
<svg><use :href="cmd.icon" /></svg> |
|
|
<svg><use :href="cmd.icon" /></svg> |
|
|
<span><strong>{{ cmd.title }}</strong><small>{{ cmd.hint }}</small></span> |
|
|
|
|
|
|
|
|
<span><strong>{{ cmd.title }}</strong><small>{{ commandProgress.buttonTitle === cmd.title && commandProgress.status ? buttonStatusText(cmd.title) : cmd.hint }}</small></span> |
|
|
</button> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
@ -234,7 +270,7 @@ |
|
|
@click="runCommand('一键返航', '无人机将返回绑定机巢并自动降落。')" |
|
|
@click="runCommand('一键返航', '无人机将返回绑定机巢并自动降落。')" |
|
|
> |
|
|
> |
|
|
<svg><use href="#i-home" /></svg> |
|
|
<svg><use href="#i-home" /></svg> |
|
|
<span><strong>一键返航</strong><small>自动回巢 · 降落</small></span> |
|
|
|
|
|
|
|
|
<span><strong>一键返航</strong><small>{{ buttonStatusText('一键返航') }}</small></span> |
|
|
</button> |
|
|
</button> |
|
|
<button |
|
|
<button |
|
|
v-else |
|
|
v-else |
|
|
@ -242,14 +278,14 @@ |
|
|
@click="runCommand('起飞', '无人机将立即起飞进入待命状态。')" |
|
|
@click="runCommand('起飞', '无人机将立即起飞进入待命状态。')" |
|
|
> |
|
|
> |
|
|
<svg><use href="#i-plane" /></svg> |
|
|
<svg><use href="#i-plane" /></svg> |
|
|
<span><strong>起飞</strong><small>离巢后进入待命</small></span> |
|
|
|
|
|
|
|
|
<span><strong>起飞</strong><small>{{ buttonStatusText('起飞') }}</small></span> |
|
|
</button> |
|
|
</button> |
|
|
<div class="secondary-actions"> |
|
|
<div class="secondary-actions"> |
|
|
<button @click="runCommand('暂停任务', '向绑定机巢下发暂停指令。')"><svg><use href="#i-stop" /></svg>暂停任务</button> |
|
|
<button @click="runCommand('暂停任务', '向绑定机巢下发暂停指令。')"><svg><use href="#i-stop" /></svg>暂停任务</button> |
|
|
<button @click="runCommand('继续任务', '向绑定机巢下发继续指令。')"><svg><use href="#i-play" /></svg>继续任务</button> |
|
|
<button @click="runCommand('继续任务', '向绑定机巢下发继续指令。')"><svg><use href="#i-play" /></svg>继续任务</button> |
|
|
<button @click="runCommand('取消任务', '向绑定机巢下发取消指令。')"><svg><use href="#i-x" /></svg>取消任务</button> |
|
|
<button @click="runCommand('取消任务', '向绑定机巢下发取消指令。')"><svg><use href="#i-x" /></svg>取消任务</button> |
|
|
</div> |
|
|
</div> |
|
|
<button class="reset-action" @click="runCommand('紧急停止', '立即中止飞行,无人机原地悬停待命。')"><svg><use href="#i-stop" /></svg><span><strong>紧急停止</strong><small>中止任务 · 原地悬停</small></span></button> |
|
|
|
|
|
|
|
|
<button class="reset-action" @click="runCommand('紧急停止', '立即中止飞行,无人机原地悬停待命。')"><svg><use href="#i-stop" /></svg><span><strong>紧急停止</strong><small>{{ buttonStatusText('紧急停止') }}</small></span></button> |
|
|
<div v-show="controlExpanded" class="drone-control-all"> |
|
|
<div v-show="controlExpanded" class="drone-control-all"> |
|
|
<button v-for="cmd in droneExtraCommands" :key="cmd.title" :class="{ danger: cmd.danger }" @click="runCommand(cmd.title, cmd.desc)"> |
|
|
<button v-for="cmd in droneExtraCommands" :key="cmd.title" :class="{ danger: cmd.danger }" @click="runCommand(cmd.title, cmd.desc)"> |
|
|
<svg><use :href="cmd.icon" /></svg> |
|
|
<svg><use :href="cmd.icon" /></svg> |
|
|
@ -1399,6 +1435,11 @@ function buttonStatusText(title) { |
|
|
return meta ? `状态:${meta.name}` : '状态:待执行' |
|
|
return meta ? `状态:${meta.name}` : '状态:待执行' |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const commandProgressTerminalLabel = computed(() => { |
|
|
|
|
|
if (commandProgress.status === 'acked') return '已确认' |
|
|
|
|
|
return COMMAND_STATUS[commandProgress.status]?.name || '执行结果' |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
function clearCommandTimers() { |
|
|
function clearCommandTimers() { |
|
|
if (commandPollTimer) { |
|
|
if (commandPollTimer) { |
|
|
clearInterval(commandPollTimer) |
|
|
clearInterval(commandPollTimer) |
|
|
|