|
|
|
@ -5,7 +5,7 @@ |
|
|
|
<h1>任务管理</h1> |
|
|
|
<span>今日 {{ todayTaskCount }} 个计划 · {{ runningTaskCount }} 个执行中</span> |
|
|
|
</div> |
|
|
|
<button class="primary-command" @click="openCreateTask"><svg><use href="#i-plus" /></svg>新建任务</button> |
|
|
|
<t-button theme="primary" @click="openCreateTask"><svg><use href="#i-plus" /></svg>新建任务</t-button> |
|
|
|
</header> |
|
|
|
|
|
|
|
<div class="business-metric-band task-metrics"> |
|
|
|
@ -32,7 +32,7 @@ |
|
|
|
</div> |
|
|
|
<div class="toolbar-group"> |
|
|
|
<t-select v-model="planFilter" :options="planFilterOptions" placeholder="全部状态" style="width: 140px" /> |
|
|
|
<button class="plain-command" @click="resetPlanFilter">重置</button> |
|
|
|
<t-button variant="outline" @click="resetPlanFilter">重置</t-button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="business-table-wrap"> |
|
|
|
@ -58,7 +58,7 @@ |
|
|
|
<td><span class="media-policy" :class="t.videoPolicyClass">{{ t.videoPolicy }}</span></td> |
|
|
|
<td><span class="table-status" :class="t.statusClass"><i></i>{{ t.status }}</span></td> |
|
|
|
<td>{{ t.lastResult }}</td> |
|
|
|
<td><div class="row-actions"><button v-if="canExecuteTask(t)" @click="executeTask(t)">立即执行</button><button @click="deleteTask(t)">删除</button></div></td> |
|
|
|
<td><div class="row-actions"><t-button v-if="canExecuteTask(t)" variant="text" theme="primary" @click="executeTask(t)">立即执行</t-button><t-button variant="text" theme="danger" @click="deleteTask(t)">删除</t-button></div></td> |
|
|
|
</tr> |
|
|
|
</tbody> |
|
|
|
</table> |
|
|
|
@ -102,7 +102,7 @@ |
|
|
|
<td>{{ r.duration }}</td> |
|
|
|
<td>{{ r.collect }}</td> |
|
|
|
<td><span class="table-status" :class="r.statusClass"><i></i>{{ r.result }}</span></td> |
|
|
|
<td><div class="row-actions"><button class="table-text-action" :disabled="r.statusClass === 'mission'" @click="goReplay(r)">{{ r.statusClass === 'mission' ? '执行中' : '轨迹回放' }}</button><button v-if="r.rawVideoId" class="table-text-action" :disabled="r.rawVideoStatus !== 'ready'" @click="downloadRawVideo(r)">{{ r.rawVideoStatus === 'ready' ? '下载原视频' : '视频处理中' }}</button></div></td> |
|
|
|
<td><div class="row-actions"><t-button variant="text" theme="primary" :disabled="r.statusClass === 'mission'" @click="goReplay(r)">{{ r.statusClass === 'mission' ? '执行中' : '轨迹回放' }}</t-button><t-button v-if="r.rawVideoId" variant="text" theme="primary" :disabled="r.rawVideoStatus !== 'ready'" @click="downloadRawVideo(r)">{{ r.rawVideoStatus === 'ready' ? '下载原视频' : '视频处理中' }}</t-button></div></td> |
|
|
|
</tr> |
|
|
|
</tbody> |
|
|
|
</table> |
|
|
|
@ -119,7 +119,7 @@ |
|
|
|
<template #prefix-icon><t-icon name="search" /></template> |
|
|
|
</t-input> |
|
|
|
</div> |
|
|
|
<button class="plain-command" @click="openRouteEditor"><svg><use href="#i-plus" /></svg>新建航线</button> |
|
|
|
<t-button variant="outline" @click="openRouteEditor"><svg><use href="#i-plus" /></svg>新建航线</t-button> |
|
|
|
</div> |
|
|
|
<div class="route-grid"> |
|
|
|
<article v-for="r in filteredRoutes" :key="r.id"> |
|
|
|
@ -138,9 +138,9 @@ |
|
|
|
|
|
|
|
<div class="route-editor" :hidden="!routeEditorOpen"> |
|
|
|
<header class="route-editor-header"> |
|
|
|
<button class="back-command" type="button" @click="closeRouteEditor"><svg><use href="#i-chevron" /></svg>返回航线库</button> |
|
|
|
<t-button class="back-command" variant="text" type="button" @click="closeRouteEditor"><svg><use href="#i-chevron" /></svg>返回航线库</t-button> |
|
|
|
<div><strong>新建航线</strong><span>{{ routeSummary }}</span></div> |
|
|
|
<div><button class="plain-command" type="button" :disabled="!routePoints.length" @click="undoRoutePoint"><svg><use href="#i-refresh" /></svg>撤销</button><button class="plain-command" type="button" :disabled="!routePoints.length" @click="clearRoutePoints"><svg><use href="#i-x" /></svg>清空</button><button class="primary-command" type="button" :disabled="routeSaving" @click="submitRoute">{{ routeSaving ? '保存中…' : '保存航线' }}</button></div> |
|
|
|
<div><t-button variant="outline" type="button" :disabled="!routePoints.length" @click="undoRoutePoint"><svg><use href="#i-refresh" /></svg>撤销</t-button><t-button variant="outline" type="button" :disabled="!routePoints.length" @click="clearRoutePoints"><svg><use href="#i-x" /></svg>清空</t-button><t-button theme="primary" type="button" :disabled="routeSaving" @click="submitRoute">{{ routeSaving ? '保存中…' : '保存航线' }}</t-button></div> |
|
|
|
</header> |
|
|
|
<div class="route-editor-body"> |
|
|
|
<aside class="route-config-panel"> |
|
|
|
@ -151,11 +151,11 @@ |
|
|
|
<label><span>速度</span><div class="number-input"><t-input-number v-model="routeForm.speed" theme="normal" :min="1" :max="20" :step="0.1" style="width: 100%" /><em>m/s</em></div></label> |
|
|
|
</div> |
|
|
|
<label><span>转弯方式</span><div class="mode-segment route-turn-segment"><button type="button" :class="{ active: routeForm.turnMode === 'auto' }" @click="routeForm.turnMode = 'auto'">自动转弯</button><button type="button" :class="{ active: routeForm.turnMode === 'stop' }" @click="routeForm.turnMode = 'stop'">定点转弯</button></div></label> |
|
|
|
<button class="apply-all-waypoints" type="button" :disabled="!routePoints.length" @click="applyRouteDefaults"><svg><use href="#i-settings" /></svg>应用到全部航点</button> |
|
|
|
<t-button class="apply-all-waypoints" variant="outline" type="button" :disabled="!routePoints.length" @click="applyRouteDefaults"><svg><use href="#i-settings" /></svg>应用到全部航点</t-button> |
|
|
|
<div class="waypoint-heading"><strong>航点列表</strong><span>{{ routePoints.length }}</span></div> |
|
|
|
<div class="waypoint-list"> |
|
|
|
<div v-if="!routePoints.length" class="waypoint-empty">点击右侧地图添加航点</div> |
|
|
|
<div v-for="(point, index) in routePoints" :key="index" class="waypoint-item" @click="openWaypointEditor(index)"><b>{{ index + 1 }}</b><span><strong>{{ point.longitude.toFixed(6) }}, {{ point.latitude.toFixed(6) }}</strong><small>{{ point.altitude }} m · {{ point.speed }} m/s · {{ point.turnMode === 'auto' ? '自动转弯' : '定点转弯' }}</small></span><div class="waypoint-item-actions"><button type="button" title="删除航点" @click.stop="removeWaypoint(index)"><svg><use href="#i-x" /></svg></button></div></div> |
|
|
|
<div v-for="(point, index) in routePoints" :key="index" class="waypoint-item" @click="openWaypointEditor(index)"><b>{{ index + 1 }}</b><span><strong>{{ point.longitude.toFixed(6) }}, {{ point.latitude.toFixed(6) }}</strong><small>{{ point.altitude }} m · {{ point.speed }} m/s · {{ point.turnMode === 'auto' ? '自动转弯' : '定点转弯' }}</small></span><div class="waypoint-item-actions"><t-button variant="text" shape="square" type="button" title="删除航点" @click.stop="removeWaypoint(index)"><svg><use href="#i-x" /></svg></t-button></div></div> |
|
|
|
</div> |
|
|
|
<div class="route-form-error">{{ routeFormError }}</div> |
|
|
|
</aside> |
|
|
|
@ -206,8 +206,8 @@ |
|
|
|
<div class="form-error">{{ taskFormError }}</div> |
|
|
|
</form> |
|
|
|
<template #footer> |
|
|
|
<button class="plain-command" type="button" @click="createTaskOpen = false">取消</button> |
|
|
|
<button class="primary-command" type="button" :disabled="creatingTask" @click="submitCreateTask">{{ creatingTask ? '创建中…' : '创建任务' }}</button> |
|
|
|
<t-button variant="outline" type="button" @click="createTaskOpen = false">取消</t-button> |
|
|
|
<t-button theme="primary" type="button" :disabled="creatingTask" @click="submitCreateTask">{{ creatingTask ? '创建中…' : '创建任务' }}</t-button> |
|
|
|
</template> |
|
|
|
</t-dialog> |
|
|
|
|
|
|
|
@ -226,8 +226,8 @@ |
|
|
|
<div class="route-form-error">{{ waypointFormError }}</div> |
|
|
|
</form> |
|
|
|
<template #footer> |
|
|
|
<button class="plain-command" type="button" @click="closeWaypointEditor">取消</button> |
|
|
|
<button class="primary-command" type="button" @click="saveWaypoint">保存航点</button> |
|
|
|
<t-button variant="outline" type="button" @click="closeWaypointEditor">取消</t-button> |
|
|
|
<t-button theme="primary" type="button" @click="saveWaypoint">保存航点</t-button> |
|
|
|
</template> |
|
|
|
</t-dialog> |
|
|
|
</section> |
|
|
|
@ -834,7 +834,8 @@ function resetPlanFilter() { |
|
|
|
} |
|
|
|
|
|
|
|
async function deleteTask(task) { |
|
|
|
if (!window.confirm(`确定永久删除任务“${task.name}”吗?此操作不可恢复。`)) return |
|
|
|
const ok = await ui.confirm(`确定永久删除任务“${task.name}”吗?`, '此操作不可恢复。') |
|
|
|
if (!ok) return |
|
|
|
try { |
|
|
|
await request.delete(urls.TASK(task.id)) |
|
|
|
ui.toast('任务已删除') |
|
|
|
|