新增巡檢任務與巡檢設定初頁面,調整側邊欄與麵包屑組件的路由配置
This commit is contained in:
parent
9bcbad5ee3
commit
0e33a0b64f
@ -8,17 +8,10 @@
|
||||
</el-breadcrumb-item>
|
||||
<el-breadcrumb-item
|
||||
v-for="(item, idx) in breadcrumbs"
|
||||
:key="item.path || idx"
|
||||
:to="
|
||||
item.path && idx !== breadcrumbs.length - 1
|
||||
? { path: item.path }
|
||||
: undefined
|
||||
"
|
||||
:key=" idx"
|
||||
:to="item.name ? { name: item.name } : undefined"
|
||||
>
|
||||
<span v-if="!item.path || idx === breadcrumbs.length - 1">{{
|
||||
item.title || item.name
|
||||
}}</span>
|
||||
<span v-else>{{ item.title || item.name }}</span>
|
||||
<span>{{ item.title }}</span>
|
||||
</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</template>
|
||||
@ -28,84 +21,30 @@ import { computed } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { menuConfig } from "../../constants/menuConfig.js";
|
||||
|
||||
// 更簡潔的選單查找與麵包屑組裝
|
||||
function findMenuItem(route) {
|
||||
for (const menu of menuConfig) {
|
||||
for (const child of menu.children) {
|
||||
// 靜態路由、名稱
|
||||
if (child.routeName === route.name || child.path === route.path) {
|
||||
return { parent: menu, item: child };
|
||||
}
|
||||
// 動態路由(如 /plant/:id)
|
||||
if (
|
||||
child.routeName === "PlantInfo" &&
|
||||
route.path &&
|
||||
route.path.startsWith("/plant/")
|
||||
) {
|
||||
return { parent: menu, item: child };
|
||||
const route = useRoute();
|
||||
|
||||
function findBreadcrumbs(menu, route, path = []) {
|
||||
for (const item of menu) {
|
||||
const currentPath = [...path, { title: item.title, name: item.routeName || null }];
|
||||
if (item.routeName === route.name) {
|
||||
if (item.params) {
|
||||
const paramsMatch = Object.keys(item.params).every(key => item.params[key] == route.params[key]);
|
||||
if (paramsMatch) {
|
||||
return currentPath;
|
||||
}
|
||||
} else {
|
||||
return currentPath;
|
||||
}
|
||||
}
|
||||
if (item.children) {
|
||||
const result = findBreadcrumbs(item.children, route, currentPath);
|
||||
if (result) return result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function buildBreadcrumb(route) {
|
||||
const match = findMenuItem(route);
|
||||
if (!match) return [];
|
||||
const crumbs = [
|
||||
{
|
||||
name: match.parent.title,
|
||||
title: match.parent.title,
|
||||
path: null,
|
||||
meta: { title: match.parent.title },
|
||||
},
|
||||
];
|
||||
let itemTitle = match.item.title;
|
||||
if (route.name === "PlantInfo" && route.params.id) {
|
||||
const plantNames = {
|
||||
"1": "四磺子坪",
|
||||
"2": "宜蘭大清水",
|
||||
"3": "宜蘭小清水",
|
||||
};
|
||||
itemTitle = plantNames[route.params.id] || match.item.title;
|
||||
}
|
||||
crumbs.push({
|
||||
name: itemTitle,
|
||||
title: itemTitle,
|
||||
path: match.item.path,
|
||||
meta: { title: itemTitle },
|
||||
});
|
||||
return crumbs;
|
||||
}
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const breadcrumbs = computed(() => {
|
||||
const menuBreadcrumbs = buildBreadcrumb(route);
|
||||
if (menuBreadcrumbs.length > 0) {
|
||||
return menuBreadcrumbs;
|
||||
}
|
||||
const matchedRoutes = route.matched.filter((r) => r.meta && r.meta.title);
|
||||
if (matchedRoutes.length === 0) {
|
||||
return [];
|
||||
}
|
||||
const currentRoute = matchedRoutes[matchedRoutes.length - 1];
|
||||
if (currentRoute.meta.parentTitle) {
|
||||
return [
|
||||
{
|
||||
title: currentRoute.meta.parentTitle,
|
||||
path: null,
|
||||
},
|
||||
{
|
||||
title: currentRoute.meta.title,
|
||||
path: currentRoute.path,
|
||||
},
|
||||
];
|
||||
}
|
||||
return matchedRoutes.map((r) => ({
|
||||
title: r.meta.title,
|
||||
name: r.name,
|
||||
path: r.path,
|
||||
}));
|
||||
return findBreadcrumbs(menuConfig, route) || [];
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
<span>結元能源</span>
|
||||
</div>
|
||||
|
||||
<el-sub-menu v-for="menu in menuConfig" :key="menu.id" :index="menu.id">
|
||||
<el-sub-menu v-for="menu in menuConfig" :key="menu.title" :index="menu.title">
|
||||
<template #title>
|
||||
<el-icon>
|
||||
<component :is="getIconComponent(menu.icon)" />
|
||||
@ -26,8 +26,8 @@
|
||||
|
||||
<el-menu-item
|
||||
v-for="item in menu.children"
|
||||
:key="item.id"
|
||||
:index="item.path || item.id"
|
||||
:key="item.title"
|
||||
:index="item.title"
|
||||
@click="handleMenuClick(item)"
|
||||
>
|
||||
{{ item.title }}
|
||||
@ -73,12 +73,9 @@ const getIconComponent = (iconName) => {
|
||||
|
||||
// 處理選單點擊
|
||||
const handleMenuClick = (item) => {
|
||||
if (item.path) {
|
||||
if (item.routeName && item.params) {
|
||||
router.push({ name: item.routeName, params: item.params });
|
||||
} else {
|
||||
router.push(item.path);
|
||||
}
|
||||
if (item.routeName) {
|
||||
router.push({ name: item.routeName, params: item.params || {} });
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
@ -87,12 +84,12 @@ const activeMenuIndex = computed(() => {
|
||||
// 嘗試根據當前路由匹配選單項
|
||||
for (const menu of menuConfig) {
|
||||
for (const item of menu.children) {
|
||||
if (item.routeName === route.name || item.path === route.path) {
|
||||
return item.path || item.id;
|
||||
if (item.routeName === route.name) {
|
||||
return item.title;
|
||||
}
|
||||
}
|
||||
}
|
||||
return route.name || route.path;
|
||||
return '';
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@ -1,129 +1,102 @@
|
||||
export const menuConfig = [
|
||||
{
|
||||
id: 'overview',
|
||||
title: '總覽',
|
||||
icon: 'Location',
|
||||
children: [
|
||||
{
|
||||
id: 'PlantsMap',
|
||||
title: '地圖總覽',
|
||||
path: '/plantsMap',
|
||||
routeName: 'PlantsMap'
|
||||
},
|
||||
{
|
||||
id: 'PlantsOverview',
|
||||
title: '電廠總覽',
|
||||
path: '/plants',
|
||||
routeName: 'PlantsOverview'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'factory-info',
|
||||
title: '電廠資訊',
|
||||
icon: 'Postcard',
|
||||
children: [
|
||||
{
|
||||
id: 'plant-1',
|
||||
title: '四磺子坪',
|
||||
path: '/plant/1',
|
||||
routeName: 'PlantInfo',
|
||||
params: { id: 1 }
|
||||
},
|
||||
{
|
||||
id: 'plant-2',
|
||||
title: '宜蘭大清水',
|
||||
path: '/plant/2',
|
||||
routeName: 'PlantInfo',
|
||||
params: { id: 2 }
|
||||
},
|
||||
{
|
||||
id: 'plant-3',
|
||||
title: '宜蘭小清水',
|
||||
path: '/plant/3',
|
||||
routeName: 'PlantInfo',
|
||||
params: { id: 3 }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'inspection',
|
||||
title: '巡檢系統',
|
||||
icon: 'DocumentChecked',
|
||||
children: [
|
||||
{
|
||||
id: 'inspection-task',
|
||||
title: '巡檢任務'
|
||||
title: '巡檢任務',
|
||||
routeName: 'PatrolMission',
|
||||
},
|
||||
{
|
||||
id: 'inspection-setting',
|
||||
title: '巡檢設定'
|
||||
title: '巡檢設定',
|
||||
routeName: 'PatrolSetting',
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'report',
|
||||
title: '報表查詢',
|
||||
icon: 'DataLine',
|
||||
children: [
|
||||
{
|
||||
id: 'PlantsReport',
|
||||
title: '電廠報表',
|
||||
path: '/plantsReport',
|
||||
routeName: 'PlantsReport'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'alert',
|
||||
title: '即時告警',
|
||||
icon: 'Bell',
|
||||
children: [
|
||||
{
|
||||
id: 'alert-event',
|
||||
title: '異常事件查詢'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'material',
|
||||
title: '備料管理',
|
||||
icon: 'MessageBox',
|
||||
children: [
|
||||
{
|
||||
id: 'material-item',
|
||||
title: '備品料件管理'
|
||||
},
|
||||
{
|
||||
id: 'material-location',
|
||||
title: '倉庫櫃位管理'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'security',
|
||||
title: '智慧安防',
|
||||
icon: 'VideoCamera',
|
||||
children: [
|
||||
{
|
||||
id: 'security-system',
|
||||
title: '安防系統'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'system',
|
||||
title: '系統設定',
|
||||
icon: 'Setting',
|
||||
children: [
|
||||
{
|
||||
id: 'system-factory',
|
||||
title: '電廠設定',
|
||||
path: '/plantSetting',
|
||||
routeName: 'PlantSetting'
|
||||
},
|
||||
{
|
||||
id: 'system-account',
|
||||
title: '帳號設定'
|
||||
}
|
||||
]
|
||||
|
||||
@ -1,62 +1,51 @@
|
||||
import { createRouter, createWebHashHistory } from "vue-router";
|
||||
import Home from "../views/Home.vue";
|
||||
import PlantsOverview from "../views/PlantsOverview.vue";
|
||||
import PatrolMission from "../views/PatrolMission.vue";
|
||||
import PatrolSetting from "../views/PatrolSetting.vue";
|
||||
import PlantReport from "../views/PlantReport.vue";
|
||||
import PlantInfo from "../views/PlantInfo.vue";
|
||||
import PlantSetting from "../views/PlantSetting.vue";
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: "/",
|
||||
redirect: "/plantsMap"
|
||||
},
|
||||
{
|
||||
path: "/plantsMap",
|
||||
name: "PlantsMap",
|
||||
component: Home,
|
||||
meta: {
|
||||
title: "地圖總覽",
|
||||
icon: "Location",
|
||||
menuGroup: "overview",
|
||||
parentTitle: "總覽",
|
||||
},
|
||||
component: Home
|
||||
},
|
||||
{
|
||||
path: "/plants",
|
||||
name: "PlantsOverview",
|
||||
component: PlantsOverview,
|
||||
meta: {
|
||||
title: "電廠總覽",
|
||||
icon: "Postcard",
|
||||
menuGroup: "overview",
|
||||
parentTitle: "總覽"
|
||||
},
|
||||
component: PlantsOverview
|
||||
},
|
||||
{
|
||||
path: "/plant/:id",
|
||||
name: "PlantInfo",
|
||||
component: PlantInfo,
|
||||
meta: {
|
||||
title: "電廠詳細",
|
||||
menuGroup: "factory-info",
|
||||
parentTitle: "電廠資訊",
|
||||
},
|
||||
component: PlantInfo
|
||||
},
|
||||
{
|
||||
path: "/patrolMission",
|
||||
name: "PatrolMission",
|
||||
component: PatrolMission
|
||||
},
|
||||
{
|
||||
path: "/patrolSetting",
|
||||
name: "PatrolSetting",
|
||||
component: PatrolSetting
|
||||
},
|
||||
{
|
||||
path: "/plantsReport",
|
||||
name: "PlantsReport",
|
||||
component: PlantReport,
|
||||
meta: {
|
||||
title: "電廠報表",
|
||||
menuGroup: "report",
|
||||
parentTitle: "報表查詢",
|
||||
},
|
||||
component: PlantReport
|
||||
},
|
||||
{
|
||||
path: "/plantSetting",
|
||||
name: "PlantSetting",
|
||||
component: PlantSetting,
|
||||
meta: {
|
||||
title: "電廠設定",
|
||||
menuGroup: "report",
|
||||
parentTitle: "系統設定",
|
||||
},
|
||||
component: PlantSetting
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
9
src/views/PatrolMission.vue
Normal file
9
src/views/PatrolMission.vue
Normal file
@ -0,0 +1,9 @@
|
||||
<template>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from "vue";
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
30
src/views/PatrolSetting.vue
Normal file
30
src/views/PatrolSetting.vue
Normal file
@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<el-row :gutter="20" style="margin-top: 20px">
|
||||
<el-col :xs="24">
|
||||
<el-card shadow="always" class="custom-card">
|
||||
<template #header
|
||||
><el-radio-group v-model="radio" size="large" fill="#409eff">
|
||||
<el-radio-button label="樣板管理" value="template" />
|
||||
<el-radio-button label="任務管理" value="task" /> </el-radio-group
|
||||
></template>
|
||||
<div v-if="radio === 'template'">
|
||||
<!-- 樣板管理內容 -->
|
||||
<p>這裡是樣板管理</p>
|
||||
</div>
|
||||
|
||||
<div v-if="radio === 'task'">
|
||||
<!-- 任務管理內容 -->
|
||||
<p>這裡是任務管理</p>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
|
||||
const radio = ref("template");
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
Loading…
Reference in New Issue
Block a user