Compare commits
2 Commits
a91914fb43
...
0e33a0b64f
| Author | SHA1 | Date | |
|---|---|---|---|
| 0e33a0b64f | |||
| 9bcbad5ee3 |
@ -34,7 +34,7 @@ onUnmounted(() => {
|
|||||||
<div class="common-layout">
|
<div class="common-layout">
|
||||||
<el-container>
|
<el-container>
|
||||||
<template v-if="!isMobile">
|
<template v-if="!isMobile">
|
||||||
<el-aside :width="isCollapse ? '0px' : '280px'">
|
<el-aside :width="isCollapse ? '0px' : '240px'">
|
||||||
<Sidebar :isCollapse="isCollapse" />
|
<Sidebar :isCollapse="isCollapse" />
|
||||||
</el-aside>
|
</el-aside>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -3,19 +3,15 @@
|
|||||||
separator="/"
|
separator="/"
|
||||||
style="margin: 15px 10px; font-size: 1.05rem; opacity: 0.9"
|
style="margin: 15px 10px; font-size: 1.05rem; opacity: 0.9"
|
||||||
>
|
>
|
||||||
|
<el-breadcrumb-item>
|
||||||
|
<span class="title">工控運維管理平台</span>
|
||||||
|
</el-breadcrumb-item>
|
||||||
<el-breadcrumb-item
|
<el-breadcrumb-item
|
||||||
v-for="(item, idx) in breadcrumbs"
|
v-for="(item, idx) in breadcrumbs"
|
||||||
:key="item.path || idx"
|
:key=" idx"
|
||||||
:to="
|
:to="item.name ? { name: item.name } : undefined"
|
||||||
item.path && idx !== breadcrumbs.length - 1
|
|
||||||
? { path: item.path }
|
|
||||||
: undefined
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<span v-if="!item.path || idx === breadcrumbs.length - 1">{{
|
<span>{{ item.title }}</span>
|
||||||
item.title || item.name
|
|
||||||
}}</span>
|
|
||||||
<span v-else>{{ item.title || item.name }}</span>
|
|
||||||
</el-breadcrumb-item>
|
</el-breadcrumb-item>
|
||||||
</el-breadcrumb>
|
</el-breadcrumb>
|
||||||
</template>
|
</template>
|
||||||
@ -25,84 +21,30 @@ import { computed } from "vue";
|
|||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
import { menuConfig } from "../../constants/menuConfig.js";
|
import { menuConfig } from "../../constants/menuConfig.js";
|
||||||
|
|
||||||
// 更簡潔的選單查找與麵包屑組裝
|
const route = useRoute();
|
||||||
function findMenuItem(route) {
|
|
||||||
for (const menu of menuConfig) {
|
function findBreadcrumbs(menu, route, path = []) {
|
||||||
for (const child of menu.children) {
|
for (const item of menu) {
|
||||||
// 靜態路由、名稱
|
const currentPath = [...path, { title: item.title, name: item.routeName || null }];
|
||||||
if (child.routeName === route.name || child.path === route.path) {
|
if (item.routeName === route.name) {
|
||||||
return { parent: menu, item: child };
|
if (item.params) {
|
||||||
}
|
const paramsMatch = Object.keys(item.params).every(key => item.params[key] == route.params[key]);
|
||||||
// 動態路由(如 /plant/:id)
|
if (paramsMatch) {
|
||||||
if (
|
return currentPath;
|
||||||
child.routeName === "PlantInfo" &&
|
}
|
||||||
route.path &&
|
} else {
|
||||||
route.path.startsWith("/plant/")
|
return currentPath;
|
||||||
) {
|
|
||||||
return { parent: menu, item: child };
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (item.children) {
|
||||||
|
const result = findBreadcrumbs(item.children, route, currentPath);
|
||||||
|
if (result) return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
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 breadcrumbs = computed(() => {
|
||||||
const menuBreadcrumbs = buildBreadcrumb(route);
|
return findBreadcrumbs(menuConfig, 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,
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
<Breadcrumb />
|
<Breadcrumb />
|
||||||
</div>
|
</div>
|
||||||
<div class="title-area">
|
<div class="title-area">
|
||||||
<span class="title">工控運維管理平台</span>
|
<!-- <span class="title">工控運維管理平台</span> -->
|
||||||
<el-dropdown size="large">
|
<el-dropdown size="large">
|
||||||
<el-button type="text" circle>
|
<el-button type="text" circle>
|
||||||
<el-avatar :icon="UserFilled" />
|
<el-avatar :icon="UserFilled" />
|
||||||
|
|||||||
@ -11,12 +11,12 @@
|
|||||||
<img
|
<img
|
||||||
src="../assets/logo.svg"
|
src="../assets/logo.svg"
|
||||||
alt="logo"
|
alt="logo"
|
||||||
style="width: 40px; height: 40px"
|
style="width: 30px; height: 30px"
|
||||||
/>
|
/>
|
||||||
<span>結元能源</span>
|
<span>結元能源</span>
|
||||||
</div>
|
</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>
|
<template #title>
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<component :is="getIconComponent(menu.icon)" />
|
<component :is="getIconComponent(menu.icon)" />
|
||||||
@ -26,8 +26,8 @@
|
|||||||
|
|
||||||
<el-menu-item
|
<el-menu-item
|
||||||
v-for="item in menu.children"
|
v-for="item in menu.children"
|
||||||
:key="item.id"
|
:key="item.title"
|
||||||
:index="item.path || item.id"
|
:index="item.title"
|
||||||
@click="handleMenuClick(item)"
|
@click="handleMenuClick(item)"
|
||||||
>
|
>
|
||||||
{{ item.title }}
|
{{ item.title }}
|
||||||
@ -73,12 +73,9 @@ const getIconComponent = (iconName) => {
|
|||||||
|
|
||||||
// 處理選單點擊
|
// 處理選單點擊
|
||||||
const handleMenuClick = (item) => {
|
const handleMenuClick = (item) => {
|
||||||
if (item.path) {
|
if (item.routeName) {
|
||||||
if (item.routeName && item.params) {
|
router.push({ name: item.routeName, params: item.params || {} });
|
||||||
router.push({ name: item.routeName, params: item.params });
|
return;
|
||||||
} else {
|
|
||||||
router.push(item.path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -87,12 +84,12 @@ const activeMenuIndex = computed(() => {
|
|||||||
// 嘗試根據當前路由匹配選單項
|
// 嘗試根據當前路由匹配選單項
|
||||||
for (const menu of menuConfig) {
|
for (const menu of menuConfig) {
|
||||||
for (const item of menu.children) {
|
for (const item of menu.children) {
|
||||||
if (item.routeName === route.name || item.path === route.path) {
|
if (item.routeName === route.name) {
|
||||||
return item.path || item.id;
|
return item.title;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return route.name || route.path;
|
return '';
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -111,7 +108,7 @@ const activeMenuIndex = computed(() => {
|
|||||||
.title-area {
|
.title-area {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: start;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
font-size: 1.8rem;
|
font-size: 1.8rem;
|
||||||
|
|||||||
@ -1,129 +1,102 @@
|
|||||||
export const menuConfig = [
|
export const menuConfig = [
|
||||||
{
|
{
|
||||||
id: 'overview',
|
|
||||||
title: '總覽',
|
title: '總覽',
|
||||||
icon: 'Location',
|
icon: 'Location',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: 'PlantsMap',
|
|
||||||
title: '地圖總覽',
|
title: '地圖總覽',
|
||||||
path: '/plantsMap',
|
|
||||||
routeName: 'PlantsMap'
|
routeName: 'PlantsMap'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'PlantsOverview',
|
|
||||||
title: '電廠總覽',
|
title: '電廠總覽',
|
||||||
path: '/plants',
|
|
||||||
routeName: 'PlantsOverview'
|
routeName: 'PlantsOverview'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'factory-info',
|
|
||||||
title: '電廠資訊',
|
title: '電廠資訊',
|
||||||
icon: 'Postcard',
|
icon: 'Postcard',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: 'plant-1',
|
|
||||||
title: '四磺子坪',
|
title: '四磺子坪',
|
||||||
path: '/plant/1',
|
|
||||||
routeName: 'PlantInfo',
|
routeName: 'PlantInfo',
|
||||||
params: { id: 1 }
|
params: { id: 1 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'plant-2',
|
|
||||||
title: '宜蘭大清水',
|
title: '宜蘭大清水',
|
||||||
path: '/plant/2',
|
|
||||||
routeName: 'PlantInfo',
|
routeName: 'PlantInfo',
|
||||||
params: { id: 2 }
|
params: { id: 2 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'plant-3',
|
|
||||||
title: '宜蘭小清水',
|
title: '宜蘭小清水',
|
||||||
path: '/plant/3',
|
|
||||||
routeName: 'PlantInfo',
|
routeName: 'PlantInfo',
|
||||||
params: { id: 3 }
|
params: { id: 3 }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'inspection',
|
|
||||||
title: '巡檢系統',
|
title: '巡檢系統',
|
||||||
icon: 'DocumentChecked',
|
icon: 'DocumentChecked',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: 'inspection-task',
|
title: '巡檢任務',
|
||||||
title: '巡檢任務'
|
routeName: 'PatrolMission',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'inspection-setting',
|
title: '巡檢設定',
|
||||||
title: '巡檢設定'
|
routeName: 'PatrolSetting',
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'report',
|
|
||||||
title: '報表查詢',
|
title: '報表查詢',
|
||||||
icon: 'DataLine',
|
icon: 'DataLine',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: 'PlantsReport',
|
|
||||||
title: '電廠報表',
|
title: '電廠報表',
|
||||||
path: '/plantsReport',
|
|
||||||
routeName: 'PlantsReport'
|
routeName: 'PlantsReport'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'alert',
|
|
||||||
title: '即時告警',
|
title: '即時告警',
|
||||||
icon: 'Bell',
|
icon: 'Bell',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: 'alert-event',
|
|
||||||
title: '異常事件查詢'
|
title: '異常事件查詢'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'material',
|
|
||||||
title: '備料管理',
|
title: '備料管理',
|
||||||
icon: 'MessageBox',
|
icon: 'MessageBox',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: 'material-item',
|
|
||||||
title: '備品料件管理'
|
title: '備品料件管理'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'material-location',
|
|
||||||
title: '倉庫櫃位管理'
|
title: '倉庫櫃位管理'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'security',
|
|
||||||
title: '智慧安防',
|
title: '智慧安防',
|
||||||
icon: 'VideoCamera',
|
icon: 'VideoCamera',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: 'security-system',
|
|
||||||
title: '安防系統'
|
title: '安防系統'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'system',
|
|
||||||
title: '系統設定',
|
title: '系統設定',
|
||||||
icon: 'Setting',
|
icon: 'Setting',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: 'system-factory',
|
|
||||||
title: '電廠設定',
|
title: '電廠設定',
|
||||||
path: '/plantSetting',
|
|
||||||
routeName: 'PlantSetting'
|
routeName: 'PlantSetting'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'system-account',
|
|
||||||
title: '帳號設定'
|
title: '帳號設定'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,62 +1,51 @@
|
|||||||
import { createRouter, createWebHashHistory } from "vue-router";
|
import { createRouter, createWebHashHistory } from "vue-router";
|
||||||
import Home from "../views/Home.vue";
|
import Home from "../views/Home.vue";
|
||||||
import PlantsOverview from "../views/PlantsOverview.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 PlantReport from "../views/PlantReport.vue";
|
||||||
import PlantInfo from "../views/PlantInfo.vue";
|
import PlantInfo from "../views/PlantInfo.vue";
|
||||||
import PlantSetting from "../views/PlantSetting.vue";
|
import PlantSetting from "../views/PlantSetting.vue";
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
|
{
|
||||||
|
path: "/",
|
||||||
|
redirect: "/plantsMap"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/plantsMap",
|
path: "/plantsMap",
|
||||||
name: "PlantsMap",
|
name: "PlantsMap",
|
||||||
component: Home,
|
component: Home
|
||||||
meta: {
|
|
||||||
title: "地圖總覽",
|
|
||||||
icon: "Location",
|
|
||||||
menuGroup: "overview",
|
|
||||||
parentTitle: "總覽",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/plants",
|
path: "/plants",
|
||||||
name: "PlantsOverview",
|
name: "PlantsOverview",
|
||||||
component: PlantsOverview,
|
component: PlantsOverview
|
||||||
meta: {
|
|
||||||
title: "電廠總覽",
|
|
||||||
icon: "Postcard",
|
|
||||||
menuGroup: "overview",
|
|
||||||
parentTitle: "總覽"
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/plant/:id",
|
path: "/plant/:id",
|
||||||
name: "PlantInfo",
|
name: "PlantInfo",
|
||||||
component: PlantInfo,
|
component: PlantInfo
|
||||||
meta: {
|
},
|
||||||
title: "電廠詳細",
|
{
|
||||||
menuGroup: "factory-info",
|
path: "/patrolMission",
|
||||||
parentTitle: "電廠資訊",
|
name: "PatrolMission",
|
||||||
},
|
component: PatrolMission
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/patrolSetting",
|
||||||
|
name: "PatrolSetting",
|
||||||
|
component: PatrolSetting
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/plantsReport",
|
path: "/plantsReport",
|
||||||
name: "PlantsReport",
|
name: "PlantsReport",
|
||||||
component: PlantReport,
|
component: PlantReport
|
||||||
meta: {
|
|
||||||
title: "電廠報表",
|
|
||||||
menuGroup: "report",
|
|
||||||
parentTitle: "報表查詢",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/plantSetting",
|
path: "/plantSetting",
|
||||||
name: "PlantSetting",
|
name: "PlantSetting",
|
||||||
component: PlantSetting,
|
component: PlantSetting
|
||||||
meta: {
|
|
||||||
title: "電廠設定",
|
|
||||||
menuGroup: "report",
|
|
||||||
parentTitle: "系統設定",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
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>
|
||||||
@ -1,333 +0,0 @@
|
|||||||
<template>
|
|
||||||
<Breadcrumb />
|
|
||||||
<el-row :gutter="20" style="margin-top: 20px">
|
|
||||||
<el-col :xs="24">
|
|
||||||
<el-card shadow="always" class="custom-card">
|
|
||||||
<template #header>
|
|
||||||
<span style="">電廠總覽</span>
|
|
||||||
</template>
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :xs="24" style="margin-bottom: 15px">
|
|
||||||
<div class="button-row">
|
|
||||||
<el-button type="info" size="large">全選</el-button>
|
|
||||||
<el-button type="primary" size="large"
|
|
||||||
>新北市
|
|
||||||
<span class="badge">1</span>
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" size="large"
|
|
||||||
>宜蘭縣
|
|
||||||
<span class="badge">2</span>
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" style="margin-bottom: 15px">
|
|
||||||
<div class="button-row" style="display: flex; gap: 12px">
|
|
||||||
<el-button type="info" size="large">全選</el-button>
|
|
||||||
<el-checkbox
|
|
||||||
v-model="checked1"
|
|
||||||
size="large"
|
|
||||||
style="margin: 0"
|
|
||||||
border
|
|
||||||
>
|
|
||||||
<span style="vertical-align: middle; margin-right: 4px"
|
|
||||||
>設備正常</span
|
|
||||||
>
|
|
||||||
<el-icon
|
|
||||||
style="vertical-align: middle"
|
|
||||||
color="#67C23A"
|
|
||||||
size="large"
|
|
||||||
><CircleCheckFilled
|
|
||||||
/></el-icon>
|
|
||||||
</el-checkbox>
|
|
||||||
<el-checkbox
|
|
||||||
v-model="checked2"
|
|
||||||
size="large"
|
|
||||||
style="margin: 0"
|
|
||||||
border
|
|
||||||
>
|
|
||||||
<span style="vertical-align: middle; margin-right: 4px"
|
|
||||||
>設備斷線</span
|
|
||||||
>
|
|
||||||
<el-icon
|
|
||||||
style="vertical-align: middle"
|
|
||||||
color="#E6A23C"
|
|
||||||
size="large"
|
|
||||||
><WarningFilled
|
|
||||||
/></el-icon>
|
|
||||||
</el-checkbox>
|
|
||||||
<el-checkbox v-model="checked3" size="large" border>
|
|
||||||
<span style="vertical-align: middle; margin-right: 4px"
|
|
||||||
>設備斷線</span
|
|
||||||
>
|
|
||||||
<el-icon
|
|
||||||
style="vertical-align: middle"
|
|
||||||
color="#F56C6C"
|
|
||||||
size="large"
|
|
||||||
><RemoveFilled
|
|
||||||
/></el-icon>
|
|
||||||
</el-checkbox>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" style="margin-bottom: 15px">
|
|
||||||
<div
|
|
||||||
class="button-row"
|
|
||||||
style="display: flex; gap: 10px; align-items: center"
|
|
||||||
>
|
|
||||||
<el-button size="large" text>排序條件</el-button>
|
|
||||||
<el-select
|
|
||||||
v-model="value1"
|
|
||||||
placeholder="Select"
|
|
||||||
style="width: 150px"
|
|
||||||
size="large"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in options1"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
<el-select
|
|
||||||
v-model="value2"
|
|
||||||
placeholder="Select"
|
|
||||||
style="width: 150px"
|
|
||||||
size="large"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in options2"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24">
|
|
||||||
<el-row :gutter="40" style="margin-top: 10px">
|
|
||||||
<el-col
|
|
||||||
v-for="plant in plants"
|
|
||||||
:key="plant.name"
|
|
||||||
:xs="24"
|
|
||||||
:sm="12"
|
|
||||||
:md="8"
|
|
||||||
>
|
|
||||||
<el-card class="plants-card">
|
|
||||||
<div class="plant-img-wrap">
|
|
||||||
<img :src="plant.img" class="plant-img" />
|
|
||||||
</div>
|
|
||||||
<div class="plant-info-tilte">
|
|
||||||
<el-icon :color="plant.statusColor" size="25">
|
|
||||||
<component :is="plant.statusIcon" />
|
|
||||||
</el-icon>
|
|
||||||
<h3>{{ plant.name }}</h3>
|
|
||||||
<p>
|
|
||||||
<span>{{ plant.temp }}</span>
|
|
||||||
<el-icon size="25">
|
|
||||||
<Sunny />
|
|
||||||
</el-icon>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<ul class="plant-info-list">
|
|
||||||
<li>
|
|
||||||
<span>發電量</span>
|
|
||||||
<div>
|
|
||||||
<span class="value">{{ plant.power }}</span>
|
|
||||||
<span>kWh</span>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span>PR值</span>
|
|
||||||
<div>
|
|
||||||
<span class="value">{{ plant.pr }}</span>
|
|
||||||
<span>%</span>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<LineChart
|
|
||||||
:data="plant.weekTrend"
|
|
||||||
:minHeight="180"
|
|
||||||
yAxisName="kWh"
|
|
||||||
:smooth="true"
|
|
||||||
/>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref } from "vue";
|
|
||||||
import { ElIcon } from "element-plus";
|
|
||||||
import {
|
|
||||||
CircleCheckFilled,
|
|
||||||
WarningFilled,
|
|
||||||
RemoveFilled,
|
|
||||||
Sunny,
|
|
||||||
} from "@element-plus/icons-vue";
|
|
||||||
|
|
||||||
const checked1 = ref(false);
|
|
||||||
const checked2 = ref(false);
|
|
||||||
const checked3 = ref(false);
|
|
||||||
|
|
||||||
const value1 = ref(1);
|
|
||||||
const value2 = ref(1);
|
|
||||||
const options1 = [
|
|
||||||
{ value: 1, label: "發電量 - 正序" },
|
|
||||||
{ value: 2, label: "發電量 - 倒序" },
|
|
||||||
];
|
|
||||||
const options2 = [
|
|
||||||
{ value: 1, label: "PR值 - 正序" },
|
|
||||||
{ value: 2, label: "PR值 - 倒序" },
|
|
||||||
];
|
|
||||||
|
|
||||||
const plants = [
|
|
||||||
{
|
|
||||||
name: "四磺子坪",
|
|
||||||
power: 185,
|
|
||||||
pr: 90,
|
|
||||||
temp: "25°C",
|
|
||||||
status: "正常",
|
|
||||||
statusColor: "#67C23A",
|
|
||||||
statusIcon: CircleCheckFilled,
|
|
||||||
img: "https://192.168.0.206:8820/file/images/plants/plant01.png",
|
|
||||||
weekTrend: [
|
|
||||||
{ time: "周一", value: 120 },
|
|
||||||
{ time: "周二", value: 132 },
|
|
||||||
{ time: "周三", value: 121 },
|
|
||||||
{ time: "周四", value: 134 },
|
|
||||||
{ time: "周五", value: 180 },
|
|
||||||
{ time: "周六", value: 230 },
|
|
||||||
{ time: "周日", value: 210 },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "大清水",
|
|
||||||
power: 170,
|
|
||||||
pr: 91,
|
|
||||||
temp: "27°C",
|
|
||||||
status: "正常",
|
|
||||||
statusColor: "#67C23A",
|
|
||||||
statusIcon: CircleCheckFilled,
|
|
||||||
img: "https://192.168.0.206:8820/file/images/plants/plant02.png",
|
|
||||||
weekTrend: [
|
|
||||||
{ time: "周一", value: 110 },
|
|
||||||
{ time: "周二", value: 120 },
|
|
||||||
{ time: "周三", value: 95 },
|
|
||||||
{ time: "周四", value: 230 },
|
|
||||||
{ time: "周五", value: 150 },
|
|
||||||
{ time: "周六", value: 200 },
|
|
||||||
{ time: "周日", value: 110 },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "大清水",
|
|
||||||
power: 117,
|
|
||||||
pr: 93,
|
|
||||||
temp: "27°C",
|
|
||||||
status: "正常",
|
|
||||||
statusColor: "#67C23A",
|
|
||||||
statusIcon: CircleCheckFilled,
|
|
||||||
img: "https://192.168.0.206:8820/file/images/plants/plant03.png",
|
|
||||||
weekTrend: [
|
|
||||||
{ time: "周一", value: 100 },
|
|
||||||
{ time: "周二", value: 140 },
|
|
||||||
{ time: "周三", value: 120 },
|
|
||||||
{ time: "周四", value: 180 },
|
|
||||||
{ time: "周五", value: 140 },
|
|
||||||
{ time: "周六", value: 200 },
|
|
||||||
{ time: "周日", value: 120 },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.badge {
|
|
||||||
padding: 0.25em 0.6em;
|
|
||||||
font-size: 75%;
|
|
||||||
line-height: 1.3;
|
|
||||||
text-align: center;
|
|
||||||
white-space: nowrap;
|
|
||||||
vertical-align: baseline;
|
|
||||||
border-radius: 4px;
|
|
||||||
background: var(--el-color-primary-dark-2);
|
|
||||||
margin-left: 0.6em;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-card.plants-card) {
|
|
||||||
border-radius: 6px;
|
|
||||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.08);
|
|
||||||
background: #fff;
|
|
||||||
overflow: hidden;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-card.plants-card) .el-card__body {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.plant-img-wrap {
|
|
||||||
width: 100%;
|
|
||||||
height: 250px;
|
|
||||||
background: #eee;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.plant-img {
|
|
||||||
width: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.plant-info-tilte {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 12px 15px;
|
|
||||||
background: #fff;
|
|
||||||
gap: 10px;
|
|
||||||
border-bottom: 1px solid #f0f0f0;
|
|
||||||
font-size: 1rem;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.plant-info-tilte h3 {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
font-weight: 600;
|
|
||||||
margin: 0;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.plant-info-tilte p {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 4px;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.plant-info-list {
|
|
||||||
list-style: none;
|
|
||||||
padding: 10px 20px;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.plant-info-list li {
|
|
||||||
display: flex;
|
|
||||||
align-items: baseline;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 8px 0;
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.plant-info-list .value {
|
|
||||||
color: #409eff;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
font-weight: bold;
|
|
||||||
margin: 0 8px;
|
|
||||||
width: 60%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -7,6 +7,10 @@ import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
|
|||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
base: "./",
|
base: "./",
|
||||||
|
build: {
|
||||||
|
outDir: "../dist",
|
||||||
|
emptyOutDir: true,
|
||||||
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
vue(),
|
vue(),
|
||||||
AutoImport({
|
AutoImport({
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user