增强地图编辑 CAD 能力与反射对象管理体验。

补充对齐/批量建站 API,并优化反射面板、历史栈与字段管理相关交互。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zhaowei.huang
2026-07-26 11:32:30 +08:00
co-authored by Cursor
parent b1dd4f9005
commit 8299c3dc5c
18 changed files with 609 additions and 231 deletions
@@ -1,17 +1,17 @@
<template>
<div class="car-page">
<el-tabs v-model="tab" type="border-card" class="car-tabs admin-tabs" @tab-change="onTabChange">
<el-tabs v-model="tab" class="car-tabs admin-tabs admin-tabs--ops" @tab-change="onTabChange">
<el-tab-pane label="车辆列表" name="list">
<ReflectionManagerPanel
v-if="tab === 'list'"
kind="car"
kind-label="车辆"
title="车辆管理Car / AbstractCar,含模拟车、插件车型 reflectionApi 实例化)"
title="车辆管理"
empty-text="当前没有车辆点击右上角新建车辆从已加载的 CarType 中选一个实例化"
enable-project-save
/>
</el-tab-pane>
<el-tab-pane label="车型样式 / 报警颜色" name="style">
<el-tab-pane label="车型样式" name="style">
<CarStyleEditor v-if="tab === 'style'" />
</el-tab-pane>
</el-tabs>
@@ -39,10 +39,11 @@ onMounted(() => {
<style scoped>
.car-page {
height: calc(100vh - 56px);
padding: 12px 14px;
padding: 10px 12px;
box-sizing: border-box;
display: flex;
flex-direction: column;
min-height: 0;
}
.car-tabs {
flex: 1;
@@ -3,7 +3,7 @@
<ReflectionManagerPanel
kind="process"
kind-label="进程"
title="进程管理Mission / Process"
title="进程管理"
empty-text="当前没有进程点击右上角新建进程即可基于已加载的 MissionType 实例化一个"
show-status-column
status-label="状态"
@@ -20,7 +20,8 @@ import ReflectionManagerPanel from '@/components/reflection/ReflectionManagerPan
<style scoped>
.process-page {
height: calc(100vh - 56px);
padding: 12px 14px;
padding: 10px 12px;
box-sizing: border-box;
min-height: 0;
}
</style>
@@ -1,12 +1,12 @@
<template>
<div class="scene-mgr-page">
<el-tabs v-model="activeTab" type="border-card" class="scene-tabs admin-tabs" @tab-change="onTabChange">
<div class="scene-mgr-page ops-console-page">
<el-tabs v-model="activeTab" class="scene-tabs admin-tabs admin-tabs--ops" @tab-change="onTabChange">
<el-tab-pane label="站点" name="site">
<ReflectionManagerPanel
ref="sitePanelRef"
kind="site"
kind-label="站点"
title="站点管理Site / UISite,含禁用/启用、必空点等动作)"
title="站点管理"
empty-text="当前没有站点点击右上角新建站点 x/y 坐标添加"
enable-project-save
/>
@@ -16,7 +16,7 @@
ref="trackPanelRef"
kind="track"
kind-label="路径"
title="路径管理Track / UITrack,含方向、冲突、投影、二分等动作)"
title="路径管理"
empty-text="当前没有路径点击右上角新建路径选起止站点添加"
enable-project-save
/>
@@ -26,7 +26,7 @@
ref="specialPanelRef"
kind="special"
kind-label="装饰物"
title="装饰物管理UI_Image / UI_Text / UI_Model"
title="装饰物管理"
empty-text="当前没有装饰物新建图片/文本/模型可用底部按钮或先在地图编辑里上传资产"
enable-project-save
/>
@@ -37,14 +37,8 @@
<script setup lang="ts">
/**
* 场景管理:3 个 ReflectionManagerPanel 实例承载 site/track/special 三个 subKind
*
* 这里之所以用三个独立 panel 而不是单一 panel + 顶部切换:
* - 每个 subKind 列字段、可创建子类型完全不同(site 要 x/y、track 要 siteA/siteB、
* 装饰物要 imagePath/modelPath 等),共享一组 ref 会让创建表单状态错乱;
* - ReflectionManagerPanel 已经把 list/详情/方法/字段/SSE 全部包好,三份实例几乎零边际成本。
*
* SceneManagerView 自己只负责 tab 切换 + 默认走 site tab。
* 场景管理:3 个 ReflectionManagerPanel 分别承载 site/track/special。
* Style A:外层 underline tabs + 紧凑运维控制台壳。
*/
import { ref } from 'vue'
@@ -57,7 +51,6 @@ const trackPanelRef = ref<InstanceType<typeof ReflectionManagerPanel> | null>(nu
const specialPanelRef = ref<InstanceType<typeof ReflectionManagerPanel> | null>(null)
function onTabChange(name: string | number) {
// 切到对应 tab 时主动 refresh 一次,确保 SSE 没接的情况下也能拿到最新列表。
const target =
name === 'site' ? sitePanelRef.value :
name === 'track' ? trackPanelRef.value :
@@ -67,19 +60,19 @@ function onTabChange(name: string | number) {
</script>
<style scoped>
/* 会话 N+2tabs 通用样式提到全局 `.admin-tabs`(见 styles/theme.css),
这里只保留容器布局,避免 scoped 选择器把全局规则压住。 */
.scene-mgr-page {
height: calc(100vh - 56px);
padding: 12px 14px;
padding: 10px 12px;
box-sizing: border-box;
display: flex;
flex-direction: column;
min-height: 0;
}
.scene-tabs {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
min-height: 0;
}
</style>
@@ -11,7 +11,7 @@
<ReflectionManagerPanel
kind="script"
kind-label="脚本"
title="脚本管理CarProgram 运行实例 · 与 SimpleLite 工作台「脚本」页对齐)"
title="脚本管理"
empty-text="当前无 CarProgram 实例CarProgram Mission 运行时编译用户脚本后产生的对象请在 SimpleLite 工作台新建 Mission任务后由调度运行时自动生成"
disable-create
disable-delete
@@ -31,7 +31,8 @@ import ReflectionManagerPanel from '@/components/reflection/ReflectionManagerPan
<style scoped>
.script-page {
height: calc(100vh - 56px);
padding: 12px 14px;
padding: 10px 12px;
box-sizing: border-box;
min-height: 0;
}
</style>
@@ -566,26 +566,37 @@ onMounted(async () => {
<style scoped>
.simple-field-page {
padding: 16px;
height: 100%;
padding: 10px 12px;
height: calc(100vh - 56px);
overflow: auto;
box-sizing: border-box;
}
.page-card {
min-height: calc(100vh - 88px);
border: 1px solid rgba(40, 33, 58, 0.10) !important;
border-radius: 8px !important;
box-shadow: none !important;
background: #fffefd !important;
}
.page-card { min-height: calc(100vh - 88px); }
.page-header {
display: flex;
align-items: flex-start;
align-items: center;
justify-content: space-between;
gap: 16px;
gap: 12px;
}
.page-header h2 { margin: 0 0 4px; font-size: 18px; }
.page-header p { margin: 0; color: var(--el-text-color-secondary); font-size: 13px; }
.header-actions { display: flex; gap: 8px; flex-shrink: 0; }
.page-header h2 { margin: 0 0 2px; font-size: 15px; font-weight: 650; }
.page-header p { margin: 0; color: var(--el-text-color-secondary); font-size: 12px; }
.header-actions { display: flex; gap: 6px; flex-shrink: 0; }
.filters {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 12px;
margin-bottom: 12px;
gap: 10px;
margin-bottom: 10px;
padding: 8px 10px;
border: 1px solid rgba(40, 33, 58, 0.08);
border-radius: 8px;
background: rgba(246, 243, 251, 0.65);
}
.car-type-filter,
.keyword-filter {
@@ -636,7 +647,21 @@ onMounted(async () => {
.bordered-select :deep(.el-select__placeholder) {
line-height: 30px;
}
.field-tabs { margin-top: 4px; }
.field-tabs { margin-top: 2px; }
.field-tabs :deep(.el-tabs__item) {
height: 34px;
line-height: 34px;
font-size: 13px;
}
.field-tabs :deep(.el-tabs__item.is-active) { font-weight: 700; }
.page-card :deep(.el-card__header) {
padding: 10px 14px;
border-bottom: 1px solid rgba(40, 33, 58, 0.08);
}
.page-card :deep(.el-card__body) { padding: 12px 14px; }
.page-card :deep(.el-table .cell) {
font-variant-numeric: tabular-nums;
}
.field-tabs :deep(.search-hit-row > td.el-table__cell) {
background-color: #f5f3ff !important;
}