Commit 0e54e30f authored by 牛辰龙's avatar 牛辰龙

init

parents
Pipeline #92 failed with stages
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# prog
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "prog",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.8.3",
"echarts": "^5.6.0",
"element-ui": "^2.15.14",
"three": "^0.173.0",
"three-stdlib": "^2.35.13",
"vue": "^2.6.14"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3",
"vue-template-compiler": "^2.6.14"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "@babel/eslint-parser"
},
"rules": {
"vue/multi-word-component-names": "off"
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
<template>
<div id="app">
<Sidebar @navigate="handleNavigate" /> <!-- 监听 navigate 事件 -->
<MainContent ref="mainContent" /> <!-- 使用 MainContent 组件 -->
</div>
</template>
<script>
import Sidebar from './components/Sidebar.vue'
import MainContent from './components/MainContent.vue' // 引入 MainContent 组件
export default {
components: {
Sidebar,
MainContent // 注册 MainContent 组件
},
methods: {
handleNavigate(page) {
this.$refs.mainContent.updateBreadcrumb(page); // 调用 MainContent 的方法更新面包屑
}
}
}
</script>
<style>
#app {
display: flex; /* 使用 flexbox 布局 */
height: 100vh; /* 设置整体高度为当前屏幕高度 */
}
.sidebar {
width: 200px; /* 侧边栏宽度 */
background-color: #ffffff; /* 侧边栏背景色 */
}
</style>
\ No newline at end of file
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
<template>
<div>
<!-- 表格 -->
<el-table :data="tableData" border style="width: 100%">
<el-table-column
prop="time"
label="推演时间"
:show-overflow-tooltip="true"
:label-class-name="'table-header'"
/>
<el-table-column
prop="pointCloudFile"
label="点云文件"
:show-overflow-tooltip="true"
:label-class-name="'table-header'"
/>
<el-table-column
prop="pointCloudCount"
label="点云数量"
:show-overflow-tooltip="true"
:label-class-name="'table-header'"
/>
<el-table-column
prop="model"
label="推演模型"
:show-overflow-tooltip="true"
:label-class-name="'table-header'"
/>
<el-table-column label="操作" :label-class-name="'table-header'">
<template slot-scope="scope">
<el-button @click="view(scope.row)" type="primary">查看</el-button>
<el-button @click="deleteItem(scope.row)" type="danger" >删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: 'LogManagementComponent',
data() {
return {
tableData: [
{ time: '2024-2-6 10:32', pointCloudFile:"bildstein_station1_xyz_intensity_rgb",pointCloudCount: 1078712, model: 'Semantic3D-1-12-30e' },
{ time: '2024-2-6 16:13', pointCloudFile:"domfountain_station2_xyz_intensity_rgb",pointCloudCount: 28019428, model: 'Semantic3D-1-14-60e' },
{ time: '2024-2-14 21:35', pointCloudFile:"watercourse",pointCloudCount: 17349371, model: 'SensatUrban-2-6-60e' },// ... 其他数据
]
};
},
methods: {
view(row) {
// 查看操作
console.log('查看:', row);
},
deleteItem(row) {
// 删除操作
console.log('删除:', row);
}
}
}
</script>
<style scoped>
.table-header {
font-weight: bold;
background-color: #f5f5f5;
}
</style>
\ No newline at end of file
<template>
<div class="main-content">
<div class="header">
<div class="breadcrumb-container">
<el-breadcrumb separator="/">
<el-breadcrumb-item v-for="(item, index) in breadcrumbItems" :key="index">{{ item }}</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="user-avatar">
<img src="@/assets/user.png" alt="User Avatar" class="avatar" />
</div>
</div>
<div class="tabs-container">
<el-tabs
v-model="activeTab"
type="card"
@tab-remove="removeTab"
@tab-click="handleTabClick"
class="tabs"
>
<el-tab-pane
v-for="tab in tabs"
:key="tab.name"
:label="tab.label"
closable
>
<component :is="tab.component" />
</el-tab-pane>
</el-tabs>
</div>
</div>
</template>
<script>
import LogManagementComponent from './LogManagementComponent.vue'; // 导入日志管理组件
import PointCloudManagementComponent from './PointCloudManagementComponent.vue'; // 导入点云管理组件
import SimulationRecordComponent from './SimulationRecordComponent.vue'; // 导入推演记录组件
import ManualAnnotationComponent from './ManualAnnotationComponent.vue';
import SegmentComponent from './SegmentComponent.vue';
export default {
data() {
return {
breadcrumbItems: [],
activeTab: '',
tabs: []
}
},
methods: {
updateBreadcrumb(breadcrumbs) {
console.log("MainContent updateBreadcrumb", breadcrumbs);
this.breadcrumbItems = breadcrumbs; // 更新面包屑内容
},
addTab(tab) {
console.log("MainContent addTab", tab);
const existingTab = this.tabs.find(t => t.name === tab.name);
if (!existingTab) {
this.tabs.push(tab); // 添加新标签
}
this.activeTab = tab.name; // 激活新标签
},
removeTab(targetName) {
console.log("MainContent removeTab", targetName);
this.tabs = this.tabs.filter(tab => tab.name !== targetName);
if (this.tabs.length > 0) {
this.activeTab = this.tabs[this.tabs.length - 1].name; // 激活最后一个标签
} else {
this.activeTab = ''; // 清空激活标签
}
},
handleTabClick(tab) {
console.log("MainContent handleTabClick", tab);
}
},
created() {
this.$parent.$on('navigate', this.updateBreadcrumb); // 监听来自 Sidebar 的事件
},
beforeDestroy() {
this.$parent.$off('navigate', this.updateBreadcrumb); // 清理事件监听
},
components: {
ManualAnnotationComponent,
LogManagementComponent, // 注册日志管理组件
PointCloudManagementComponent, // 注册点云管理组件
SimulationRecordComponent, // 注册推演记录组件
SegmentComponent // 注册语义分割组件
}
}
</script>
<style scoped>
.main-content {
flex: 1; /* 右侧内容区域自适应 */
padding: 20px; /* 右侧内容区域内边距 */
background-color: #f5f5f5; /* 右侧内容区域背景色 */
height: 100%; /* 确保内容区域高度为100% */
display: flex;
flex-direction: column;
}
.header {
display: flex;
justify-content: space-between; /* 左右对齐 */
align-items: center; /* 垂直居中 */
margin-bottom: 20px; /* 与主体内容的间距 */
}
.breadcrumb-container {
flex: 1; /* 面包屑区域自适应 */
}
.user-avatar {
margin-left: 20px; /* 用户头像与面包屑之间的间距 */
}
.avatar {
width: 40px; /* 用户头像宽度 */
height: 40px; /* 用户头像高度 */
border-radius: 50%; /* 圆形头像 */
}
.tabs-container {
background-color: #ffffff; /* 标签页背景色 */
border-radius: 8px; /* 圆角 */
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); /* 阴影效果 */
padding: 20px; /* 标签页内边距 */
flex: 1; /* 使标签页区域占满剩余空间 */
display: flex; /* 使用flex布局 */
flex-direction: column; /* 垂直排列 */
}
.tabs {
height: 100%; /* 确保el-tabs的高度为100% */
}
.el-tabs__content {
height: 100%; /* 确保el-tabs__content的高度为100% */
}
</style>
<template>
<div class="manual-annotation">
<div class="left-panel">
<div v-if="!isBeginTraining" ref="pointCloudContainer" class="point-cloud-container"></div>
<div v-if="isBeginTraining" style="display: flex; justify-content: center;">
<div id="lossChart" style="height: 350px;width: 600px;background-color: #fff;display: flex; justify-content: center;">
</div>
</div>
<div v-if="isBeginTraining" style="margin-top: 20px;"> <!-- 设置上方间距 -->
<span>已完成进度:</span>
<el-progress :percentage="progressPercentage" :text-inside="true" :stroke-width="18"></el-progress>
</div>
</div>
<div class="right-panel">
<!-- <div class="input-group">
<div class="input-label-container">
<el-input
id="budget"
v-model="budget"
:disabled="isBudgetLocked"
placeholder="请输入模型名称"
class="input-field"
/>
</div>
<el-button
type="primary"
@click="startAnnotation"
:disabled="isBudgetLocked"
class="action-button"
>
保存当前模型
</el-button>
</div> -->
<!-- <hr>
<div class="input-group">
<el-button
type="primary"
@click="startAnnotation"
:disabled="isBudgetLocked"
class="action-button"
>
继续标注
</el-button>
</div> -->
<div class="input-group">
<div class="input-label-container">
<label for="budget" class="input-label">标注预算:</label>
<el-input
id="budget"
v-model="budget"
:disabled="isBudgetLocked"
placeholder="请输入标注预算"
class="input-field"
/>
</div>
<el-button
type="primary"
@click="startAnnotation"
:disabled="isBudgetLocked"
class="action-button"
>
开始标注
</el-button>
</div>
<hr>
<div class="input-group">
<div class="input-label-container">
<label for="label" class="input-label">标签:</label>
<el-select v-model="selectedLabel" placeholder="请选择标签" class="input-field">
<el-option label="car" value="car"></el-option>
<el-option label="people" value="people"></el-option>
<el-option label="road" value="road"></el-option>
<el-option label="high-plant" value="high-plant"></el-option>
<el-option label="low-plant" value="low-plant"></el-option>
<el-option label="building" value="building"></el-option>
</el-select>
</div>
<el-button type="primary" @click="goToNext" class="action-button">下一个</el-button>
</div>
<hr>
<div class="input-group">
<div class="input-label-container">
<label for="budget" class="input-label">训练轮次:</label>
<el-input
id="epoch"
v-model="epoch"
:disabled="isBeginTraining"
placeholder="请输入训练轮次"
class="input-field"
/>
</div>
<el-button
type="primary"
@click="startTraining"
class="action-button"
>
开始训练
</el-button>
</div>
</div>
</div>
</template>
<script>
import * as THREE from 'three';
import { PLYLoader } from 'three-stdlib';
import * as echarts from "echarts";
export default {
name: 'ManualAnnotationComponent',
data() {
return {
budget: '',
selectedLabel: '',
isBudgetLocked: false, // 控制标注预算输入框是否可输入
isBeginTraining: false, // 控制开始训练按钮是否可点击
epoch: '', // 训练轮次
trainingData: [], // 存储训练数据
currentEpoch: 0, // 当前训练轮次
totalEpochs: 30, // 总训练轮次
progressPercentage: 33, // 进度条百分比
lossChart: null, // 存储折线图实例
isTraining: false, // 控制训练状态
myChart: {},
xData: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"], // 横轴数据
yData: [1.373, 1.008, 0.988, 0.804, 0.856, 0.634, 0.609, 0.701, 0.599, 0.542], // 纵轴数据
};
},
mounted() {
// this.initThreeJS();
// window.addEventListener('resize', this.onWindowResize);
// this.initEcharts(); // 初始化折线图
},
beforeDestroy() {
window.removeEventListener('resize', this.onWindowResize); // 清理事件监听
},
methods: {
initThreeJS() {
// 创建场景
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, this.$refs.pointCloudContainer.clientWidth / this.$refs.pointCloudContainer.clientHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(this.$refs.pointCloudContainer.clientWidth, this.$refs.pointCloudContainer.clientHeight);
this.$refs.pointCloudContainer.appendChild(renderer.domElement);
// 加载 PLY 文件
const loader = new PLYLoader();
loader.load('/bildstein_station1_xyz_intensity_rgb.ply', (geometry) => { // 更新为相对路径
const material = new THREE.PointsMaterial({ size: 0.05, vertexColors: true });
const points = new THREE.Points(geometry, material);
scene.add(points);
});
// 设置相机位置
camera.position.z = 5;
// 渲染循环
const animate = () => {
requestAnimationFrame(animate);
renderer.render(scene, camera);
};
animate();
},
onWindowResize() {
const container = this.$refs.pointCloudContainer;
const renderer = container.children[0]; // 获取渲染器
if (renderer) {
renderer.setSize(container.clientWidth, container.clientHeight); // 调整渲染器大小
}
},
startAnnotation() {
this.isBudgetLocked = true; // 锁定标注预算输入框
},
goToNext() {
// 清空标签输入框的内容
this.selectedLabel = ''; // 清空标签输入框
if (this.budget > 0) {
this.budget -= 1; // 每次点击减1
}
},
initEcharts() {
console.log("this.initEcharts()1");
const option = {
xAxis: {
data: this.xData,
name: 'Epoch'
},
yAxis: {
name: 'Loss'
},
series: [
{
data: this.yData,
type: "line" // 类型设置为折线图
}
]
};
this.$nextTick(() => {
this.myChart = echarts.init(document.getElementById("lossChart")); // 获取 DOM 元素并初始化图表
this.myChart.setOption(option);
window.addEventListener("resize", () => {
this.myChart.resize();
});
console.log("this.initEcharts()2");
});
// this.myChart = echarts.init(document.getElementById("lossChart"));
// this.myChart.setOption(option);
// //随着屏幕大小调节图表
},
startTraining() {
// 这里可以添加开始训练的逻辑
this.isBeginTraining = true;
this.initEcharts();
// this.currentEpoch = 0; // 重置当前轮次
// this.trainingData = []; // 清空训练数据
// this.progressPercentage = 0; // 重置进度条
// const interval = setInterval(() => {
// if (this.currentEpoch < this.totalEpochs) {
// this.currentEpoch++;
// const loss = Math.random(); // 模拟损失值
// this.trainingData.push({ epoch: this.currentEpoch, loss: loss.toFixed(4) });
// this.updateChart();
// this.progressPercentage = Math.floor((this.currentEpoch / this.totalEpochs) * 100); // 更新进度条
// } else {
// clearInterval(interval); // 训练完成
// }
// }, 1000); // 每秒训练一次
},
initializeChart() {
// const ctx = document.getElementById('lossChart').getContext('2d');
// this.lossChart = new Chart(ctx, {
// type: 'line',
// data: {
// labels: [], // 横轴标签
// datasets: [{
// label: '训练损失',
// data: [], // 数据
// borderColor: 'rgba(75, 192, 192, 1)',
// borderWidth: 2,
// fill: false,
// }]
// },
// options: {
// scales: {
// x: {
// title: {
// display: true,
// text: 'Epoch'
// }
// },
// y: {
// title: {
// display: true,
// text: '损失'
// }
// }
// }
// }
// });
},
updateChart() {
// if (this.lossChart) {
// this.lossChart.data.labels.push(this.currentEpoch); // 添加当前轮次到横轴
// this.lossChart.data.datasets[0].data.push(this.trainingData[this.currentEpoch - 1].loss); // 添加损失值
// this.lossChart.update(); // 更新图表
// }
}
}
}
</script>
<style scoped>
.manual-annotation {
height: 100%; /* 设置高度为100% */
display: flex; /* 使用flex布局 */
}
.left-panel {
flex: 1; /* 左侧占用剩余空间 */
background-color: #f0f0f0; /* 左侧区域背景色 */
padding: 20px; /* 内边距 */
box-sizing: border-box; /* 包含内边距和边框 */
}
.right-panel {
flex: 0 0 20%; /* 右侧占20% */
padding: 20px; /* 内边距 */
box-sizing: border-box; /* 包含内边距和边框 */
}
.input-group {
display: flex; /* 使用flex布局 */
flex-direction: column; /* 垂直排列 */
/* 输入框组之间的间距 */
}
.input-label-container {
display: flex; /* 使用flex布局 */
align-items: center; /* 垂直居中对齐 */
margin-bottom: 5px; /* 标签与输入框之间的间距 */
}
.input-label {
font-weight: bold; /* 加粗标签 */
margin-right: 10px; /* 标签与输入框之间的间距 */
}
.input-field {
flex: 1; /* 输入框占用剩余空间 */
margin-bottom: 10px; /* 输入框与按钮之间的间距 */
}
.button-group {
display: flex; /* 使用flex布局 */
justify-content: flex-start; /* 按钮左对齐 */
}
.action-button {
display: block; /* 按钮块级显示 */
margin: 10px auto; /* 居中显示 */
}
.point-cloud-container {
width: 100%; /* 容器宽度 */
height: 550px; /* 设置容器高度 */
}
</style>
\ No newline at end of file
<template>
<div>
<h3>点云数据管理</h3>
<!-- 这里是管理的具体内容 -->
</div>
</template>
<script>
export default {
name: 'PointCloudManagementComponent'
}
</script>
\ No newline at end of file
<template>
<div class="manual-annotation">
<div class="left-panel">
<div ref="pointCloudContainer" class="point-cloud-container"></div>
</div>
<div class="right-panel">
<div class="input-group">
<div class="input-label-container">
<label for="label" class="input-label">模型库:</label>
<el-select v-model="selectedModel" placeholder="请选择" class="input-field">
<el-option label="Semantic3D-1-12-30e" value="Semantic3D-1-12-30e"></el-option>
<el-option label="Semantic3D-1-14-60e" value="Semantic3D-1-14-60e"></el-option>
<el-option label="SensatUrban-2-6-60e" value="SensatUrban-2-6-60e"></el-option>
</el-select>
</div>
<el-button type="primary" @click="beginSegment" class="action-button">推演完成</el-button>
</div>
<hr>
<!-- <div class="input-group"> -->
<div>
<!-- <div class="input-label-container"> -->
<label style="align-self: center;" for="label" class="input-label">推演结果</label>
<br>
<br>
<span style="margin-top: 50px;">推演时延: s</span>
<br>
<span>结果统计:</span>
<br>
<span> road:%
<br>
building:%
<br>
high-plant:%
<br>
low-plant:%
<br>
car:%
<br>
people:%
<br>
</span>
<!-- </div> -->
</div>
</div>
</div>
</template>
<script>
export default {
name: 'SegmentComponent',
data() {
return {
selectedModel: '',
};
},
mounted() {
},
beforeDestroy() {
},
methods: {
beginSegment(){
},
}
}
</script>
<style scoped>
.manual-annotation {
height: 100%; /* 设置高度为100% */
display: flex; /* 使用flex布局 */
}
.left-panel {
flex: 1; /* 左侧占用剩余空间 */
background-color: #f0f0f0; /* 左侧区域背景色 */
padding: 20px; /* 内边距 */
box-sizing: border-box; /* 包含内边距和边框 */
}
.right-panel {
flex: 0 0 20%; /* 右侧占20% */
padding: 20px; /* 内边距 */
box-sizing: border-box; /* 包含内边距和边框 */
}
.input-group {
display: flex; /* 使用flex布局 */
flex-direction: column; /* 垂直排列 */
/* 输入框组之间的间距 */
}
.input-label-container {
display: flex; /* 使用flex布局 */
align-items: center; /* 垂直居中对齐 */
margin-bottom: 5px; /* 标签与输入框之间的间距 */
}
.input-label {
font-weight: bold; /* 加粗标签 */
margin-right: 10px; /* 标签与输入框之间的间距 */
}
.input-field {
flex: 1; /* 输入框占用剩余空间 */
margin-bottom: 10px; /* 输入框与按钮之间的间距 */
}
.button-group {
display: flex; /* 使用flex布局 */
justify-content: flex-start; /* 按钮左对齐 */
}
.action-button {
display: block; /* 按钮块级显示 */
margin: 10px auto; /* 居中显示 */
}
.point-cloud-container {
width: 100%; /* 容器宽度 */
height: 550px; /* 设置容器高度 */
}
</style>
\ No newline at end of file
<template>
<div class="sidebar">
<div class="logo-container">
<img src="@/assets/logoo.png" alt="Logo" class="logo" /> <!-- 使用本地的 logo -->
<h2 class="platform-title">点云处理</h2>
</div>
<el-menu
default-active="1"
class="menu"
@open="handleOpen"
@close="handleClose"
background-color="#ffffff"
text-color="#333"
active-text-color="#ffd04b"
>
<el-menu-item index="1" @click="navigateTo(['概览'])">
<i class="el-icon-s-data"></i>
概览
</el-menu-item>
<el-submenu index="2">
<template #title>
<i class="el-icon-s-order"></i>
数据管理
</template>
<el-menu-item index="2-1" @click="navigateTo(['数据管理', '推演记录'])">推演记录</el-menu-item>
<el-menu-item index="2-2" @click="navigateTo(['数据管理', '点云管理'])">点云管理</el-menu-item>
<el-menu-item index="2-3" @click="navigateTo(['数据管理', '日志管理'])">日志管理</el-menu-item>
</el-submenu>
<el-menu-item index="3" @click="navigateTo(['模型管理'])"><i class="el-icon-s-tools"></i>模型管理</el-menu-item>
<el-menu-item index="4" @click="navigateTo(['人工标注'])"><i class="el-icon-edit"></i>人工标注</el-menu-item>
<el-menu-item index="5" @click="navigateTo(['语义分割'])"><i class="el-icon-s-promotion"></i>模型推演</el-menu-item>
</el-menu>
</div>
</template>
<script>
export default {
name: 'Sidebar',
data() {
return {
isCollapse: false
}
},
methods: {
handleOpen(key, keyPath) {
console.log(key, keyPath);
},
handleClose(key, keyPath) {
console.log(key, keyPath);
},
navigateTo(breadcrumbs) {
console.log("SideBar navigateTo", breadcrumbs);
this.$emit('navigate', breadcrumbs); // 触发事件,传递当前页面的面包屑路径
// 根据菜单项添加相应的标签页
const tab = this.getTabInfo(breadcrumbs);
if (tab) {
this.$parent.$refs.mainContent.addTab(tab); // 添加标签页
this.$parent.$refs.mainContent.activeTab = tab.name; // 立即激活新标签
}
},
getTabInfo(breadcrumbs) {
// 根据面包屑返回对应的标签信息
const lastItem = breadcrumbs[breadcrumbs.length - 1];
switch (lastItem) {
case '日志管理':
return { name: '日志管理', label: '日志管理', component: 'LogManagementComponent' };
case '点云管理':
return { name: '点云管理', label: '点云管理', component: 'PointCloudManagementComponent' };
case '推演记录':
return { name: '推演记录', label: '推演记录', component: 'LogManagementComponent' };
case '人工标注': // 添加人工标注的处理
return { name: '人工标注', label: '人工标注', component: 'ManualAnnotationComponent' }; // 确保你有这个组件
// 其他菜单项可以继续添加
case '语义分割': // 添加人工标注的处理
return { name: '语义分割', label: '语义分割', component: 'SegmentComponent' }
default:
return null;
}
}
}
}
</script>
<style scoped>
.sidebar {
width: 200px;
background-color: #ffffff; /* 侧边栏背景色 */
display: flex;
flex-direction: column;
}
.logo-container {
display: flex;
align-items: center;
padding: 15px; /* 内边距 */
}
.logo {
width: 40px; /* 调整 logo 宽度 */
height: 40px; /* 调整 logo 高度 */
margin-right: 10px; /* logo 和标题之间的间距 */
}
.platform-title {
font-size: 18px; /* 标题字体大小 */
color: #333; /* 标题颜色 */
margin: 0; /* 去掉默认的 margin */
}
.menu {
flex: 1; /* 使菜单区域自适应剩余空间 */
}
</style>
<template>
<div>
<h3>推演记录</h3>
<!-- 这里是管理的具体内容 -->
</div>
</template>
<script>
export default {
name: 'SimulationRecordComponent'
}
</script>
\ No newline at end of file
import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css'; // 引入 Element UI 样式
Vue.config.productionTip = false
Vue.use(ElementUI)
new Vue({
render: h => h(App),
}).$mount('#app')
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true
})
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment