Files
Spectral-Insight-Mission-Plan/src/views/PathLineViewer.vue
xin d732580c3e Initial commit: Happa Mission Plan v0.1.0
Task planning and path generation software for automated data collection
equipment (hyperspectral cameras, DSLR, depth cameras).

- Generate mission plans (JSON) with subtasks per device
- Generate scan path binary files (.RecordLine3)
- Multi-rectangle area planning with reference map support
- Device-specific FOV defaults (Pika L 17.6°, Pika NIR 21.7°, etc.)
- Timeline scheduling with constraint validation
- Tauri 2.x + Vue 3 + Naive UI + Pinia
2026-06-17 17:17:39 +08:00

83 lines
2.7 KiB
Vue

<template>
<div class="pathline-viewer">
<n-space style="padding: 8px" align="center">
<n-button size="small" @click="goBack">
<template #icon><n-icon><ArrowBackOutline /></n-icon></template>
返回
</n-button>
<n-button size="small" @click="openFile">
<template #icon><n-icon><FolderOpenOutline /></n-icon></template>
打开航线文件
</n-button>
</n-space>
<n-empty v-if="!records.length" description="请打开一个 .RecordLine3 文件" style="margin-top: 60px" />
<div v-else style="padding: 8px">
<n-statistic label="记录条数" :value="records.length" />
<n-data-table
:columns="columns"
:data="records"
:bordered="true"
:single-line="false"
size="small"
:max-height="600"
virtual-scroll
/>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { useMessage } from 'naive-ui';
import { ArrowBackOutline, FolderOpenOutline } from '@vicons/ionicons5';
import { invoke } from '@tauri-apps/api/core';
import type { DataTableColumn } from 'naive-ui';
import type { PathLineRecord } from '../types/path-line';
const router = useRouter();
const message = useMessage();
const records = ref<PathLineRecord[]>([]);
const columns: DataTableColumn<PathLineRecord>[] = [
{ title: 'Y 位置', key: 'targetYPosition', render: r => r.targetYPosition.toFixed(2) },
{ title: 'Y 速度', key: 'speedTargetYPosition', render: r => r.speedTargetYPosition.toFixed(2) },
{ title: 'X 起始', key: 'targetXMinPosition', render: r => r.targetXMinPosition.toFixed(2) },
{ title: 'X 起始速度', key: 'speedTargetXMinPosition', render: r => r.speedTargetXMinPosition.toFixed(2) },
{ title: 'X 结束', key: 'targetXMaxPosition', render: r => r.targetXMaxPosition.toFixed(2) },
{ title: 'X 扫描速度', key: 'speedTargetXMaxPosition', render: r => r.speedTargetXMaxPosition.toFixed(2) },
{ title: '#', key: 'index', render: (_, i) => i + 1, width: 50 },
];
async function openFile() {
try {
const { open } = await import('@tauri-apps/plugin-dialog');
const selected = await open({
filters: [{ name: 'RecordLine3', extensions: ['RecordLine3'] }],
multiple: false,
});
if (selected) {
const file = await invoke('load_path_line', { path: selected });
records.value = (file as any).records;
message.success(`加载成功: ${(file as any).records.length} 条记录`);
}
} catch (e) {
message.error('打开文件失败: ' + e);
}
}
function goBack() {
router.push('/editor');
}
</script>
<style scoped>
.pathline-viewer {
height: 100vh;
display: flex;
flex-direction: column;
}
</style>