用電即時分佈圖表 | 首頁進度小卡 | 系統小卡樣式修改 | 歷史資料新增大類 | 設備管理修改文字
This commit is contained in:
parent
c5345db462
commit
a7054c07b5
@ -1,2 +1,3 @@
|
||||
export const GET_REALTIME_DIST_API = `/api/Energe/GetRealTimeDistribution`;
|
||||
export const GET_ELECUSE_DAY_API = `/api/Energe/GetElecUseDay`;
|
||||
export const GET_TAI_POWER_API = `/api/Energe/GetTaipower`;
|
@ -1,10 +1,20 @@
|
||||
import {
|
||||
GET_REALTIME_DIST_API,
|
||||
GET_ELECUSE_DAY_API,
|
||||
GET_TAI_POWER_API,
|
||||
} from "./api";
|
||||
import instance from "@/util/request";
|
||||
import apihandler from "@/util/apihandler";
|
||||
|
||||
export const getRealTimeDist = async () => {
|
||||
const res = await instance.post(GET_REALTIME_DIST_API);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
};
|
||||
|
||||
export const getElecUseDay = async () => {
|
||||
const res = await instance.post(GET_ELECUSE_DAY_API);
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
"title": "历史资料",
|
||||
"building_name": "厂区",
|
||||
"device_name": "设备名称",
|
||||
"system_category": "系统类别",
|
||||
"device_category": "设备类别",
|
||||
"category": "类别",
|
||||
"value": "数值",
|
||||
@ -243,7 +244,7 @@
|
||||
"phone": "手机",
|
||||
"created_at": "建立时间",
|
||||
"operation": "功能",
|
||||
"name_placeholder": "请输入使用者名称",
|
||||
"name_placeholder": "请输入使用者、帐号名称",
|
||||
"role_placeholder": "请输入角色名称",
|
||||
"change_password": "变更密码",
|
||||
"choose": "选择"
|
||||
|
@ -27,6 +27,7 @@
|
||||
"title": "歷史資料",
|
||||
"building_name": "廠區",
|
||||
"device_name": "設備名稱",
|
||||
"system_category": "系統類別",
|
||||
"device_category": "設備類別",
|
||||
"category": "類別",
|
||||
"value": "數值",
|
||||
@ -243,7 +244,7 @@
|
||||
"phone": "手機",
|
||||
"created_at": "建立時間",
|
||||
"operation": "功能",
|
||||
"name_placeholder": "請輸入使用者名稱",
|
||||
"name_placeholder": "請輸入使用者、帳號名稱",
|
||||
"role_placeholder": "請輸入角色名稱",
|
||||
"change_password": "變更密碼",
|
||||
"choose": "選擇"
|
||||
|
@ -18,6 +18,7 @@
|
||||
"title": "Historical Data",
|
||||
"building_name": "Building",
|
||||
"device_name": "Device Name",
|
||||
"system_category": "System Category",
|
||||
"device_category": "Device Category",
|
||||
"category": "Category",
|
||||
"value": "Value",
|
||||
@ -155,7 +156,7 @@
|
||||
"phone": "Phone",
|
||||
"email": "Email",
|
||||
"created_at": "Creation Date",
|
||||
"maintenance": "Maintenance",
|
||||
"maintenance": "Upkeep",
|
||||
"repair": "Repair",
|
||||
"company_info": "Company Info",
|
||||
"repair_item": "Repair Item",
|
||||
@ -243,8 +244,8 @@
|
||||
"phone": "Phone",
|
||||
"created_at": "Created Time",
|
||||
"operation": "Function",
|
||||
"name_placeholder": "Please enter user name",
|
||||
"role_placeholder": "Please enter the role name",
|
||||
"name_placeholder": "Please enter the user's name / account",
|
||||
"role_placeholder": "Please enter the role's name",
|
||||
"change_password": "Change Password",
|
||||
"choose": "Choose"
|
||||
},
|
||||
@ -261,8 +262,8 @@
|
||||
"submit": "Submit",
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
"deselect_all": "Deselect all",
|
||||
"select_all": "Select all",
|
||||
"deselect_all": "Deselect All",
|
||||
"select_all": "Select All",
|
||||
"phone_format": "Please enter the correct phone number format",
|
||||
"email_format": "Please enter correct email address",
|
||||
"password_format": "The password must be at least 8 characters long and must contain English and numbers.",
|
||||
|
@ -147,7 +147,7 @@ const removeAccount = async (id) => {
|
||||
:placeholder="t('accountManagement.name_placeholder')"
|
||||
name="Full_name"
|
||||
:value="searchData"
|
||||
class="mr-3"
|
||||
class="mr-3 w-96"
|
||||
/>
|
||||
<Input
|
||||
:placeholder="t('accountManagement.role_placeholder')"
|
||||
|
@ -1,93 +1,87 @@
|
||||
<script setup>
|
||||
import { ref, computed } from "vue";
|
||||
|
||||
// Mock data based on the image, grouped data
|
||||
const mockData = ref([
|
||||
{
|
||||
title: "Abnormal state",
|
||||
items: [
|
||||
[
|
||||
{ label: "Abnormal", value: 0 },
|
||||
{ label: "Return", value: 5168 },
|
||||
],
|
||||
[
|
||||
{ label: "Confirmed", value: 182 },
|
||||
{ label: "Unacknowledged", value: 4986 },
|
||||
],
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Progress",
|
||||
items: [
|
||||
[
|
||||
{ label: "Not dispatched", value: 5126 },
|
||||
{ label: "Dispatched", value: 42 },
|
||||
],
|
||||
[
|
||||
{ label: "Completed", value: 28 },
|
||||
{ label: "Unfinished", value: 14 },
|
||||
],
|
||||
],
|
||||
},
|
||||
]);
|
||||
const equipmentData = ref({
|
||||
title: "System Status",
|
||||
items: [
|
||||
{ label: "Auxiliary", online: 6, offline: 0, alarm: 0 },
|
||||
{ label: "Air Detection", online: 31, offline: 0, alarm: 2 },
|
||||
{ label: "Electricity", online: 12, offline: 0, alarm: 1 },
|
||||
{ label: "Lighting", online: 20, offline: 3, alarm: 0 },
|
||||
{ label: "Air Condition", online: 23, offline: 0, alarm: 0 },
|
||||
],
|
||||
});
|
||||
|
||||
// Compute progress value for each group
|
||||
const getProgressValue = (group) => {
|
||||
const total = group.reduce((sum, item) => sum + item.value, 0);
|
||||
return (group[0].value / total) * 100;
|
||||
};
|
||||
const orderData = ref({
|
||||
title: "Work Order",
|
||||
items: [
|
||||
{ label: "Unassigned", value: 2 },
|
||||
{ label: "Assigned", value: 4 },
|
||||
{ label: "Completed", value: 1 },
|
||||
],
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-wrap">
|
||||
<div
|
||||
v-for="(section, index) in mockData"
|
||||
:key="index"
|
||||
class="w-full sm:w-1/2 state-box-col relative px-4"
|
||||
>
|
||||
<div class="w-full sm:w-3/5 state-box-col relative ps-2">
|
||||
<div class="state-box">
|
||||
<div class="title">
|
||||
<img class="state-title01" src="@ASSET/img/state-title01.svg" />
|
||||
<span>{{ section.title }}</span>
|
||||
<span class="">{{ equipmentData.title }}</span>
|
||||
<img class="state-title02" src="@ASSET/img/state-title02.svg" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-for="(group, groupIndex) in section.items"
|
||||
:key="groupIndex"
|
||||
class="item"
|
||||
>
|
||||
<div class="item-title">
|
||||
<div
|
||||
v-for="(item, itemIndex) in group"
|
||||
:key="itemIndex"
|
||||
class="text"
|
||||
<table class="table table-sm text-center">
|
||||
<thead>
|
||||
<tr class="border-cyan-400 text-cyan-100">
|
||||
<th></th>
|
||||
<th>Online</th>
|
||||
<th>Offline</th>
|
||||
<th>Alarm</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(item, index) in equipmentData.items"
|
||||
:key="index"
|
||||
class="border-cyan-400"
|
||||
>
|
||||
<div class="text-position">
|
||||
<span>{{ item.label }}</span>
|
||||
<span>{{ item.value }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="state-ul">
|
||||
<img src="@ASSET/img/state-ul.svg" />
|
||||
<div class="box">
|
||||
<div class="mark">
|
||||
<span class="w-10">{{ group[0].value }}</span>
|
||||
<span
|
||||
><img class="w-[50px]" src="@ASSET/img/state-ul-text.svg" />
|
||||
</span>
|
||||
<span class="w-10">{{ group[1].value }}</span>
|
||||
</div>
|
||||
<progress
|
||||
class="progress [&::-webkit-progress-value]:bg-red-600 [&::-moz-progress-bar]:bg-red-600"
|
||||
:value="getProgressValue(group)"
|
||||
max="100"
|
||||
size=""
|
||||
></progress>
|
||||
</div>
|
||||
</div>
|
||||
<th class="px-0 text-start">{{ item.label }}</th>
|
||||
<td>{{ item.online }}</td>
|
||||
<td>{{ item.offline }}</td>
|
||||
<td>{{ item.alarm }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full sm:w-2/5 state-box-col relative ps-2">
|
||||
<div class="state-box">
|
||||
<div class="title">
|
||||
<img class="state-title01" src="@ASSET/img/state-title01.svg" />
|
||||
<span>{{ orderData.title }}</span>
|
||||
<img class="state-title02" src="@ASSET/img/state-title02.svg" />
|
||||
</div>
|
||||
<table class="table table-sm text-center">
|
||||
<thead>
|
||||
<tr class="border-cyan-400 text-cyan-100">
|
||||
<th></th>
|
||||
<th>value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(item, index) in orderData.items"
|
||||
:key="index"
|
||||
class="border-cyan-400"
|
||||
>
|
||||
<th class="px-0 text-start">
|
||||
<span>{{ item.label }}</span>
|
||||
</th>
|
||||
<td>{{ item.value }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -107,7 +101,7 @@ const getProgressValue = (group) => {
|
||||
}
|
||||
|
||||
.state-box {
|
||||
@apply border-2 border-light-info rounded-sm py-2 px-6 text-white relative;
|
||||
@apply h-80 border-2 border-light-info rounded-sm py-2 px-6 text-white relative;
|
||||
}
|
||||
|
||||
.state-box:after {
|
||||
@ -133,58 +127,4 @@ const getProgressValue = (group) => {
|
||||
.state-box .title .state-title02 {
|
||||
@apply w-5 ml-1.5;
|
||||
}
|
||||
|
||||
.state-box .item-title {
|
||||
@apply flex justify-between items-center m-auto mb-1 relative;
|
||||
}
|
||||
|
||||
.state-box .item-title:after {
|
||||
@apply absolute right-0 -bottom-2.5 w-full h-4 bg-no-repeat bg-center z-10;
|
||||
content: "";
|
||||
background-image: url(@ASSET/img/text-position-line.svg);
|
||||
}
|
||||
|
||||
.state-box .item-title .text {
|
||||
@apply w-1/2 m-0 mb-1.5 flex justify-center items-center relative;
|
||||
}
|
||||
|
||||
.state-box .item-title .text .text-position span {
|
||||
@apply block text-center text-xs;
|
||||
}
|
||||
|
||||
.state-box .item-title .text .text-position span:nth-child(2) {
|
||||
text-shadow: 0px 0px 5px rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.mark {
|
||||
@apply flex justify-between items-center mb-2.5;
|
||||
}
|
||||
|
||||
.state-ul {
|
||||
@apply relative mb-2.5;
|
||||
}
|
||||
|
||||
.state-ul::after {
|
||||
@apply absolute -left-3.5 top-0 w-4 h-16 bg-no-repeat bg-center z-10;
|
||||
content: "";
|
||||
background-image: url(@ASSET/img/state-ul-background01.svg);
|
||||
}
|
||||
|
||||
.state-ul .box {
|
||||
@apply absolute top-1/2 w-4/5 left-0 right-0 m-auto text-center -translate-y-1/2;
|
||||
}
|
||||
|
||||
.progress {
|
||||
@apply w-full h-3 rounded;
|
||||
appearance: none;
|
||||
|
||||
&::-webkit-progress-bar {
|
||||
border: 1px solid #ffffff;
|
||||
background-color: #5eabea;
|
||||
}
|
||||
|
||||
&::-webkit-progress-value {
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,35 +1,29 @@
|
||||
<script setup>
|
||||
import { ref, onMounted, nextTick } from "vue";
|
||||
import { ref, onMounted, nextTick, computed } from "vue";
|
||||
import * as echarts from "echarts";
|
||||
import { getRealTimeDist } from "@/apis/energy";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const chartDiv = ref(null);
|
||||
|
||||
const chartOption = {
|
||||
tooltip: {
|
||||
trigger: "item",
|
||||
formatter: "{b}: {c}kWh",
|
||||
formatter: (p) => {
|
||||
return `${p.name}: ${p.value}kWh (${p.data.percentage}%)`;
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: "sankey",
|
||||
layout: "none",
|
||||
nodeWidth: 20,
|
||||
nodeWidth: 10,
|
||||
nodeGap: 10,
|
||||
data: [
|
||||
{ name: "Total", value: 100 },
|
||||
{ name: "HVAC System", value: 40 },
|
||||
{ name: "Lighting System", value: 25 },
|
||||
{ name: "Elevator System", value: 15 },
|
||||
{ name: "Outlets", value: 10 },
|
||||
{ name: "Others", value: 10 },
|
||||
],
|
||||
links: [
|
||||
{ source: "Total", target: "HVAC System", value: 40 },
|
||||
{ source: "Total", target: "Lighting System", value: 25 },
|
||||
{ source: "Total", target: "Elevator System", value: 15 },
|
||||
{ source: "Total", target: "Outlets", value: 10 },
|
||||
{ source: "Total", target: "Others", value: 10 },
|
||||
],
|
||||
right: 180,
|
||||
data: [],
|
||||
links: [],
|
||||
emphasis: {
|
||||
focus: "adjacency",
|
||||
},
|
||||
@ -37,6 +31,9 @@ const chartOption = {
|
||||
position: "right",
|
||||
fontSize: 14,
|
||||
color: "#fff",
|
||||
formatter: (p) => {
|
||||
return `${p.name} (${p.data.percentage}%)`;
|
||||
},
|
||||
},
|
||||
itemStyle: {
|
||||
borderWidth: 0,
|
||||
@ -50,11 +47,42 @@ const chartOption = {
|
||||
],
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
const loadData = async () => {
|
||||
const res = await getRealTimeDist();
|
||||
if (res.isSuccess) {
|
||||
const rawData = res.data;
|
||||
const totalValue = rawData.reduce((acc, item) => acc + item.value, 0);
|
||||
|
||||
// 構造 data 節點
|
||||
const data = [
|
||||
{ name: "Total", value: totalValue, percentage: 100 },
|
||||
...rawData.map((item) => ({
|
||||
name: item.key,
|
||||
value: item.value,
|
||||
percentage: item.percentage,
|
||||
})),
|
||||
];
|
||||
|
||||
// 構造 links 連結
|
||||
const links = rawData.map((item) => ({
|
||||
source: "Total",
|
||||
target: item.key,
|
||||
value: item.value,
|
||||
percentage: item.percentage,
|
||||
}));
|
||||
|
||||
// 更新 chartOption
|
||||
chartOption.series[0].data = data;
|
||||
chartOption.series[0].links = links;
|
||||
|
||||
// 初始化圖表
|
||||
const myChart = echarts.init(chartDiv.value);
|
||||
myChart.setOption(chartOption);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -64,19 +92,7 @@ onMounted(() => {
|
||||
{{ $t("energy.elec_consumption") }}
|
||||
</h2>
|
||||
<div class="chart-container">
|
||||
<div ref="chartDiv" class="w-full min-h-[190px] h-full"></div>
|
||||
</div>
|
||||
<div class="text-sm mt-3.5">
|
||||
<ul class="flex flex-wrap items-center text-white">
|
||||
<li class="pr-5 relative z-20">
|
||||
<span class="pr-3.5"> {{ $t("energy.total_elec") }} (kWh)</span>
|
||||
<span class="pr-3.5">160.05</span>
|
||||
</li>
|
||||
<li class="pr-5 relative z-20">
|
||||
<span class="pr-3.5">{{ $t("energy.green_elec") }} (kWh)</span>
|
||||
<span class="pr-3.5">39.50</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div ref="chartDiv" class="w-full min-h-[200px] h-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -25,8 +25,15 @@ import dayjs from "dayjs";
|
||||
|
||||
const { searchParams, changeParams } = useSearchParam();
|
||||
|
||||
// 選小類
|
||||
const store = useBuildingStore();
|
||||
// 選大類
|
||||
const {
|
||||
items: sysMainTagItems,
|
||||
changeActiveBtn: changeMainSysActiveBtn,
|
||||
setItems: setMainSysItems,
|
||||
selectedBtn: selectedMainSysItems,
|
||||
} = useActiveBtn();
|
||||
// 選小類
|
||||
const {
|
||||
items: sysTagItems,
|
||||
changeActiveBtn: changeSysActiveBtn,
|
||||
@ -34,6 +41,38 @@ const {
|
||||
selectedBtn: selectedSysItems,
|
||||
} = useActiveBtn();
|
||||
|
||||
watch(
|
||||
() => store.mainSys,
|
||||
() => {
|
||||
setMainSysItems(
|
||||
store.mainSubSys.map(({ full_name, main_system_tag }, index) => ({
|
||||
title: full_name,
|
||||
key: main_system_tag,
|
||||
active: searchParams.value.main_system_tag
|
||||
? searchParams.value.main_system_tag === mian_system_tag
|
||||
: index === 0,
|
||||
}))
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => selectedMainSysItems,
|
||||
(newVal, oldVal) => {
|
||||
setSysItems(
|
||||
store.subSys.filter((s) => s.main_system_tag === newVal.value?.key).map(({ full_name, sub_system_tag }, index) => ({
|
||||
title: full_name,
|
||||
key: sub_system_tag,
|
||||
active: index === 0,
|
||||
}))
|
||||
);
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => selectedSysItems,
|
||||
(newVal, oldVal) => {
|
||||
@ -54,21 +93,6 @@ watch(
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => store.subSys,
|
||||
() => {
|
||||
setSysItems(
|
||||
store.subSys.map(({ full_name, sub_system_tag }, index) => ({
|
||||
title: full_name,
|
||||
key: sub_system_tag,
|
||||
active: searchParams.value.sub_system_tag
|
||||
? searchParams.value.sub_system_tag === sub_system_tag
|
||||
: index === 0,
|
||||
}))
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// 設定點位
|
||||
const {
|
||||
items: points,
|
||||
@ -82,7 +106,7 @@ const getPoint = async (deviceList) => {
|
||||
setPoints(
|
||||
res.data.map((d, index) => ({
|
||||
...d,
|
||||
title: d.points,
|
||||
title: d.item_name,
|
||||
key: d.points,
|
||||
active: index === 0,
|
||||
}))
|
||||
@ -118,10 +142,10 @@ watch(searchParams, (newVal, oldValue) => {
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
setSysItems(
|
||||
store.subSys.map(({ full_name, sub_system_tag }, index) => ({
|
||||
setMainSysItems(
|
||||
store.mainSubSys.map(({ full_name, main_system_tag }, index) => ({
|
||||
title: full_name,
|
||||
key: sub_system_tag,
|
||||
key: main_system_tag,
|
||||
active: index === 0,
|
||||
}))
|
||||
);
|
||||
@ -136,7 +160,23 @@ onBeforeMount(() => {
|
||||
<div class="flex flex-col custom-border p-4 mb-4">
|
||||
<!-- <HistoryFavoriteOption class="mb-4" />-->
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<h2 class="text-lg font-bold ps-2">{{ $t("history.device_category") }} :</h2>
|
||||
<h2 class="text-lg font-bold ps-2">
|
||||
{{ $t("history.system_category") }} :
|
||||
</h2>
|
||||
<ButtonGroup
|
||||
:items="sysMainTagItems"
|
||||
:withLine="true"
|
||||
:onclick="
|
||||
(e, item) => {
|
||||
changeMainSysActiveBtn(item);
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<h2 class="text-lg font-bold ps-2">
|
||||
{{ $t("history.device_category") }} :
|
||||
</h2>
|
||||
<ButtonGroup
|
||||
:items="sysTagItems"
|
||||
:withLine="true"
|
||||
|
@ -65,9 +65,12 @@ watch(searchParams, (newValue, oldValue) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-wrap mt-3">
|
||||
<div class="flex flex-wrap items-center mt-6">
|
||||
<h2 class="text-lg font-bold ps-1 pe-4">
|
||||
{{ $t("history.device_category") }} :
|
||||
</h2>
|
||||
<button
|
||||
class="btn btn-success mr-4"
|
||||
class="btn btn-sm btn-success"
|
||||
@click.stop.prevent="changeCheckedItem"
|
||||
>
|
||||
{{ checkedItem.length === store.subSys.length ? t("button.deselect_all") : t("button.select_all") }}
|
||||
|
@ -216,7 +216,7 @@ provide("system_selectedDevice", { selectedDeviceRealtime, selectedDevice, getCu
|
||||
<SystemInfoModal :data="selectedDevice" />
|
||||
<SystemFloorBar />
|
||||
<div class="grid grid-cols-2 gap-5 mt-8 mb-4">
|
||||
<div class="col-span-1 h-[80vh] flex flex-col justify-start">
|
||||
<div class="col-span-1 h-[79vh] flex flex-col justify-start">
|
||||
<div>
|
||||
<div class="flex mb-4 items-center">
|
||||
<span class="flex items-center mr-3" v-if="statusList?.device_normal_text">
|
||||
@ -237,13 +237,13 @@ provide("system_selectedDevice", { selectedDeviceRealtime, selectedDevice, getCu
|
||||
</div>
|
||||
<SystemSubBar class="mt-2 mb-4" />
|
||||
</div>
|
||||
<div class="h-full max-h-[75vh] pr-2 overflow-y-auto">
|
||||
<div class="h-full pr-2 overflow-y-auto">
|
||||
<RouterView />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-1 h-full flex flex-col justify-between">
|
||||
<SystemMode />
|
||||
<div class="min-h-[75vh] relative">
|
||||
<div class="h-full relative">
|
||||
<SystemFloor
|
||||
:class="twMerge('absolute h-full w-full', route.query.mode === '2D' ? 'opacity-100 z-10' : 'opacity-0 z-0')" />
|
||||
<div
|
||||
|
@ -22,14 +22,14 @@ const fitToView = (forge_dbid) => {
|
||||
<div class="equipment-show" v-for="d in showData" :key="d.full_name">
|
||||
<template v-if="d.device_list.length > 0">
|
||||
<p class="title">{{ d.full_name }}</p>
|
||||
<div class="grid grid-cols-3 gap-5">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-5">
|
||||
<div class="col-auto relative" v-for="device in d.device_list" :key="device.device_guid">
|
||||
<div class="item h-full">
|
||||
<div class="left h-full flex flex-wrap justify-center">
|
||||
<div class="sec02 w-full">
|
||||
<img v-if="device.device_image_url" :src="device.device_image_url" alt="" class="w-8 h-8">
|
||||
<span class="w-8 h-8" v-else></span>
|
||||
<span class="w-32 break-all">{{ device.full_name }}</span>
|
||||
<img v-if="device.device_image_url" :src="device.device_image_url" alt="" >
|
||||
<span v-else></span>
|
||||
<span>{{ device.full_name }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between w-full self-end">
|
||||
<div class="sec03">
|
||||
@ -60,7 +60,7 @@ const fitToView = (forge_dbid) => {
|
||||
}
|
||||
|
||||
.item {
|
||||
@apply flex items-center border border-success py-4 px-5 relative mb-5 after:absolute after:right-0 after:top-3 after:w-6 after:h-10 after:bg-[url(/src/assets/img/equipment/state-background.svg)] after:z-10;
|
||||
@apply flex items-center border border-success rounded shadow-emerald-600 shadow-inner py-4 px-5 relative mb-5 after:absolute after:right-0 after:top-3 after:w-6 after:h-10 after:bg-[url(/src/assets/img/equipment/state-background.svg)] after:z-10;
|
||||
;
|
||||
|
||||
}
|
||||
@ -105,7 +105,7 @@ const fitToView = (forge_dbid) => {
|
||||
background: url(/src/assets/img/equipment/state-title.svg) center center;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: -10px;
|
||||
bottom: -18px;
|
||||
height: 25px;
|
||||
width: 105px;
|
||||
background-repeat: no-repeat;
|
||||
@ -118,10 +118,14 @@ const fitToView = (forge_dbid) => {
|
||||
display: block;
|
||||
border-radius: 5px;
|
||||
margin-right: 10px;
|
||||
width: 2rem !important;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.equipment-show .item .sec02 span:nth-child(2) {
|
||||
font-size: 1.5rem;
|
||||
font-size: 1.4rem;
|
||||
width: calc(100% - 2rem);
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.equipment-show .item .sec03 {
|
||||
|
@ -16,7 +16,7 @@ const data = computed(() => {
|
||||
|
||||
const columns = [{
|
||||
title: t("system.attribute"),
|
||||
key: "points"
|
||||
key: "full_name"
|
||||
},
|
||||
{
|
||||
title: t("system.value"),
|
||||
|
Loading…
Reference in New Issue
Block a user