首頁與能源管理語言包 | 設備管理的2d位置debug | 設備管理的圖資與iot先隱藏
This commit is contained in:
parent
bc51a9db1f
commit
6e346af685
@ -9,7 +9,7 @@ const props = defineProps({
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
value: String,
|
||||
value: Object || String,
|
||||
isTopLabelExist: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
|
@ -21,7 +21,7 @@ const route = useRoute();
|
||||
|
||||
const authPages = ref([]); // 儲存從 API 獲取的 authPages
|
||||
const menu_array = ref([]);
|
||||
const isDrawerOpen = ref(false);
|
||||
const isDrawerOpen = ref(false);
|
||||
|
||||
const iniFroList = async () => {
|
||||
try {
|
||||
@ -69,7 +69,12 @@ watch(locale, () => {
|
||||
|
||||
<template>
|
||||
<header class="navbar w-full relative z-50 p-0">
|
||||
<input id="nav-drawer" type="checkbox" class="drawer-toggle" v-model="isDrawerOpen" />
|
||||
<input
|
||||
id="nav-drawer"
|
||||
type="checkbox"
|
||||
class="drawer-toggle"
|
||||
v-model="isDrawerOpen"
|
||||
/>
|
||||
<!-- Navbar -->
|
||||
<div class="navbar bg-base-300 w-full justify-between">
|
||||
<div class="flex-none lg:hidden">
|
||||
@ -101,18 +106,16 @@ watch(locale, () => {
|
||||
<img src="/logo.svg" alt="logo" class="w-6 lg:w-8 me-1" />
|
||||
新創賦能
|
||||
</router-link>
|
||||
<NavbarBuilding class="hidden lg:block ms-8" />
|
||||
</div>
|
||||
<div class="hidden flex-1 lg:block">
|
||||
<div class="flex items-center justify-around">
|
||||
<NavbarBuilding />
|
||||
<NavbarItem
|
||||
:authPages="authPages"
|
||||
:menu_array="menu_array"
|
||||
@show-drawer="getSubMonitorPage"
|
||||
@getSubPage="getSubPage"
|
||||
@close-drawer="closeDrawer"
|
||||
/>
|
||||
</div>
|
||||
<NavbarItem
|
||||
:authPages="authPages"
|
||||
:menu_array="menu_array"
|
||||
@show-drawer="getSubMonitorPage"
|
||||
@getSubPage="getSubPage"
|
||||
@close-drawer="closeDrawer"
|
||||
/>
|
||||
</div>
|
||||
<ul class="left-menu flex-none">
|
||||
<li>
|
||||
@ -142,7 +145,7 @@ watch(locale, () => {
|
||||
:menu_array="menu_array"
|
||||
@show-drawer="getSubMonitorPage"
|
||||
@getSubPage="getSubPage"
|
||||
@close-drawer="closeDrawer"
|
||||
@close-drawer="closeDrawer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -44,7 +44,10 @@
|
||||
"this_month": "本月",
|
||||
"last_month": "上月",
|
||||
"this_year": "今年",
|
||||
"last_year": "去年"
|
||||
"last_year": "去年",
|
||||
"refrig_temp": "冷藏温度",
|
||||
"indoor_temp": "室内温度",
|
||||
"alerts_data": "异常资料"
|
||||
},
|
||||
"history": {
|
||||
"title": "历史资料",
|
||||
@ -148,7 +151,12 @@
|
||||
"off_peak_contract": "离峰契约",
|
||||
"variable_electricity_charge": "流动电费",
|
||||
"saturday": "周六",
|
||||
"sunday_and_off_peak_days": "周日及离峰日"
|
||||
"sunday_and_off_peak_days": "周日及离峰日",
|
||||
"latest_elec_consumption": "最新用电度数",
|
||||
"daily_elec": "每日用电度数",
|
||||
"line_voltage": "线电压",
|
||||
"electric_current": "电流",
|
||||
"monthly_elec_bill": "每月电费分析"
|
||||
},
|
||||
"alarm": {
|
||||
"title": "显示警告",
|
||||
@ -174,7 +182,7 @@
|
||||
"alarmClass": "告警条件",
|
||||
"device_name": "设备名称",
|
||||
"device_number": "设备编号",
|
||||
"device_point_name":"点位名称",
|
||||
"device_point_name": "点位名称",
|
||||
"date": "发生日期",
|
||||
"time": "发生时间",
|
||||
"error_msg": "异常原因",
|
||||
@ -270,6 +278,7 @@
|
||||
"tax_id_number": "统一编号",
|
||||
"remark": "备注",
|
||||
"date": "日期",
|
||||
"time": "时间",
|
||||
"serial": "单号",
|
||||
"today": "今天",
|
||||
"yesterday": "昨天",
|
||||
@ -387,7 +396,7 @@
|
||||
"sure_to_delete_permanent": "是否确认永久删除该项目?",
|
||||
"delete_success": "删除成功",
|
||||
"delete_failed": "删除失败",
|
||||
"mqtt_refresh":"重新设定成功"
|
||||
"mqtt_refresh": "重新设定成功"
|
||||
},
|
||||
"setting": {
|
||||
"MQTT_parse": "MQTT 解析",
|
||||
|
@ -44,7 +44,10 @@
|
||||
"this_month": "本月",
|
||||
"last_month": "上月",
|
||||
"this_year": "今年",
|
||||
"last_year": "去年"
|
||||
"last_year": "去年",
|
||||
"refrig_temp":"冷藏溫度",
|
||||
"indoor_temp":"室內溫度",
|
||||
"alerts_data":"異常資料"
|
||||
},
|
||||
"history": {
|
||||
"title": "歷史資料",
|
||||
@ -148,7 +151,12 @@
|
||||
"off_peak_contract": "離峰契約",
|
||||
"variable_electricity_charge": "流動電費",
|
||||
"saturday": "週六",
|
||||
"sunday_and_off_peak_days": "週日及離峰日"
|
||||
"sunday_and_off_peak_days": "週日及離峰日",
|
||||
"latest_elec_consumption": "最新用電度數",
|
||||
"daily_elec": "每日用電度數",
|
||||
"line_voltage": "線電壓",
|
||||
"electric_current" : "電流",
|
||||
"monthly_elec_bill":"每月電費分析"
|
||||
},
|
||||
"alarm": {
|
||||
"title": "顯示警告",
|
||||
@ -270,6 +278,7 @@
|
||||
"tax_id_number": "統一編號",
|
||||
"remark": "備注",
|
||||
"date": "日期",
|
||||
"time": "時間",
|
||||
"serial": "單號",
|
||||
"today": "今天",
|
||||
"yesterday": "昨天",
|
||||
|
@ -44,7 +44,10 @@
|
||||
"this_month": "This month",
|
||||
"last_month": "Last month",
|
||||
"this_year": "This year",
|
||||
"last_year": "Last year"
|
||||
"last_year": "Last year",
|
||||
"refrig_temp": "Refrigeration temperature",
|
||||
"indoor_temp": "Indoor temperature",
|
||||
"alerts_data": "Abnormal data"
|
||||
},
|
||||
"history": {
|
||||
"title": "Historical Data",
|
||||
@ -148,7 +151,12 @@
|
||||
"off_peak_contract": "Off-Peak Demand Charge",
|
||||
"variable_electricity_charge": "Variable Electricity Charge",
|
||||
"saturday": "Saturday",
|
||||
"sunday_and_off_peak_days": "Sunday and Off-Peak Days"
|
||||
"sunday_and_off_peak_days": "Sunday and Off-Peak Days",
|
||||
"latest_elec_consumption": "Latest electricity consumption",
|
||||
"daily_elec": "Daily electricity consumption",
|
||||
"line_voltage": "Line voltage",
|
||||
"electric_current": "electric current",
|
||||
"monthly_elec_bill": "Monthly electricity bill analysis"
|
||||
},
|
||||
"alarm": {
|
||||
"title": "Warning",
|
||||
@ -174,7 +182,7 @@
|
||||
"alarmClass": "Alarm Conditions",
|
||||
"device_name": "Device Name",
|
||||
"device_number": "Device Number",
|
||||
"device_point_name":"Point Name",
|
||||
"device_point_name": "Point Name",
|
||||
"date": "Occurrence Date",
|
||||
"time": "Occurrence Time",
|
||||
"error_msg": "Abnormal Cause",
|
||||
@ -270,6 +278,7 @@
|
||||
"tax_id_number": "Tax ID Number",
|
||||
"remark": "Remark",
|
||||
"date": "Date",
|
||||
"time": "Time",
|
||||
"serial": "Order Number",
|
||||
"today": "Today",
|
||||
"yesterday": "Yesterday",
|
||||
@ -387,7 +396,7 @@
|
||||
"sure_to_delete_permanent": "Are you sure you want to permanently delete this item?",
|
||||
"delete_success": "Delete successfully",
|
||||
"delete_failed": "Delete failed",
|
||||
"mqtt_refresh":"MQTT reset successful"
|
||||
"mqtt_refresh": "MQTT reset successful"
|
||||
},
|
||||
"setting": {
|
||||
"MQTT_parse": "MQTT Parse",
|
||||
|
@ -75,7 +75,7 @@ const router = createRouter({
|
||||
component: AlertManagement,
|
||||
},
|
||||
{
|
||||
path: "/energyManagement/:main_system_id/:sub_system_id/:type",
|
||||
path: "/energyManagement",
|
||||
name: "energyManagement",
|
||||
component: EnergyManagement,
|
||||
},
|
||||
|
@ -76,11 +76,11 @@ const onOk = async () => {
|
||||
formData.append("Device_image", props.formState.Device_image);
|
||||
}
|
||||
|
||||
const res = await postAssetSubList(formData);
|
||||
if (res.isSuccess) {
|
||||
props.getData(parseInt(searchParams.value.mainSys_id));
|
||||
onCancel();
|
||||
}
|
||||
// const res = await postAssetSubList(formData);
|
||||
// if (res.isSuccess) {
|
||||
// props.getData(parseInt(searchParams.value.mainSys_id));
|
||||
// onCancel();
|
||||
// }
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -209,8 +209,8 @@ watch(
|
||||
</Select>
|
||||
</div>
|
||||
<AssetTableModalLeftInfoMQTT />
|
||||
<AssetTableModalLeftInfoGraph />
|
||||
<AssetTableModalLeftInfoIoT />
|
||||
<!-- <AssetTableModalLeftInfoGraph /> -->
|
||||
<!-- <AssetTableModalLeftInfoIoT /> -->
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
@ -34,14 +34,25 @@ const defaultOption = (map, data = []) => {
|
||||
// 生成坐標數據,根據坐標值的不同設置不同顏色
|
||||
const formattedData = data.map((coordinate) => {
|
||||
const coordString = JSON.stringify(coordinate);
|
||||
|
||||
// 解析 device_coordinate 為數值陣列進行比對
|
||||
let isSelected = false;
|
||||
if (formState.value.device_coordinate) {
|
||||
try {
|
||||
const deviceCoord = JSON.parse(formState.value.device_coordinate);
|
||||
// 比對數值而非字串,避免精度問題
|
||||
isSelected = coordinate.length === deviceCoord.length &&
|
||||
coordinate.every((val, index) => Math.abs(val - deviceCoord[index]) < 0.001);
|
||||
} catch (e) {
|
||||
console.warn('解析 device_coordinate 失敗:', e);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
name: coordString,
|
||||
value: coordinate,
|
||||
itemStyle: {
|
||||
color:
|
||||
coordString === formState.value.device_coordinate
|
||||
? "#0000FF"
|
||||
: "#b02a02",
|
||||
color: isSelected ? "#0000FF" : "#b02a02",
|
||||
},
|
||||
};
|
||||
});
|
||||
|
@ -2,7 +2,9 @@
|
||||
import dayjs from "dayjs";
|
||||
import { computed, ref, onMounted } from "vue";
|
||||
import { faker } from "@faker-js/faker"; // 引入 faker.js
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
// 假資料
|
||||
const fakeAlarmData = ref([]);
|
||||
|
||||
@ -36,15 +38,15 @@ const alarms = computed(() =>
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h3 class="text-info font-bold text-xl text-center">異常資料 Top 5</h3>
|
||||
<h3 class="text-info text-xl text-center">{{$t("dashboard.alerts_data")}} Top 5</h3>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr class="border-b-2 border-info text-base">
|
||||
<th>日期</th>
|
||||
<th>時間</th>
|
||||
<th>設備名稱</th>
|
||||
<th>備註</th>
|
||||
<th>{{$t("operation.date")}}</th>
|
||||
<th>{{$t("operation.time")}}</th>
|
||||
<th>{{$t("operation.device_name")}}</th>
|
||||
<th>{{$t("operation.remark")}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-base">
|
||||
|
@ -4,7 +4,9 @@ import EffectScatter from "@/components/chart/EffectScatter.vue";
|
||||
import useSearchParam from "@/hooks/useSearchParam";
|
||||
import { computed, inject, ref, watch } from "vue";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const { searchParams, changeParams } = useSearchParam();
|
||||
const FILE_BASEURL = import.meta.env.VITE_FILE_API_BASEURL;
|
||||
@ -28,9 +30,9 @@ const defaultOption = (map, data = []) => {
|
||||
formatter: function (params) {
|
||||
return params.data[2]?.full_name
|
||||
? `
|
||||
<div class="p-2 w-24">
|
||||
<div class="p-2 w-auto min-w-24">
|
||||
<div class="text-lg">${params.data[2].full_name}</div>
|
||||
<div class="text-sm text-gray-500">狀態: ${
|
||||
<div class="text-sm text-gray-500">${t("operation.status")} : ${
|
||||
params.data[2].state || ""
|
||||
}</div>`
|
||||
: "";
|
||||
@ -99,6 +101,7 @@ watch(
|
||||
[searchParams, () => asset_floor_chart.value, () => props.data],
|
||||
([newValue, newChart, newData], [oldValue]) => {
|
||||
if (newValue.floor_id && newChart && Object.keys(newData || {}).length > 0) {
|
||||
console.log("Updating chart with new data", newValue, newChart, newData);
|
||||
newChart.updateSvg(
|
||||
{
|
||||
full_name: newValue.floor_id,
|
||||
|
@ -81,7 +81,7 @@ const onCancel = () => {
|
||||
id="immediate_demand_add_item"
|
||||
:title="t('energy.edit_automatic_demand')"
|
||||
:onCancel="closeModal"
|
||||
width="400"
|
||||
:width="400"
|
||||
>
|
||||
<template #modalContent>
|
||||
<form ref="form" class="mt-5 flex flex-col items-center">
|
||||
|
@ -74,7 +74,7 @@ const closeModal = () => {
|
||||
id="carbon_emission_item"
|
||||
:title="t('energy.edit_carbon_emission')"
|
||||
:onCancel="closeModal"
|
||||
width="400"
|
||||
:width="400"
|
||||
>
|
||||
<template #modalContent>
|
||||
<form ref="form" class="mt-5 flex flex-col items-center">
|
||||
|
@ -6,7 +6,9 @@ import { ref, inject, onMounted, onUnmounted, watch } from "vue";
|
||||
import { getDashboardTemp } from "@/apis/dashboard";
|
||||
import useSearchParams from "@/hooks/useSearchParam";
|
||||
import useBuildingStore from "@/stores/useBuildingStore";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
const { searchParams } = useSearchParams();
|
||||
const buildingStore = useBuildingStore();
|
||||
const intervalType = "indoor";
|
||||
@ -38,7 +40,6 @@ const defaultChartOption = ref({
|
||||
axisLabel: {
|
||||
color: "#ffffff",
|
||||
},
|
||||
|
||||
data: [],
|
||||
},
|
||||
yAxis: {
|
||||
@ -49,14 +50,14 @@ const defaultChartOption = ref({
|
||||
axisLabel: {
|
||||
color: "#ffffff",
|
||||
},
|
||||
// 移除固定的 min/max,讓 ECharts 自動計算範圍
|
||||
},
|
||||
series: [],
|
||||
});
|
||||
|
||||
const timeoutTimer = ref("");
|
||||
const indoor_temp_chart = ref(null);
|
||||
|
||||
const data = ref([]);
|
||||
|
||||
const getData = async (timeInterval) => {
|
||||
const res = await getDashboardTemp({
|
||||
building_guid: buildingStore.selectedBuilding.building_guid,
|
||||
@ -64,16 +65,15 @@ const getData = async (timeInterval) => {
|
||||
tempOption: 1, // 1:室溫 2:冷藏
|
||||
});
|
||||
if (res.isSuccess) {
|
||||
console.log('室內溫度資料:', res.data['室溫']);
|
||||
|
||||
data.value = res.data['室溫'];
|
||||
console.log("室內溫度資料:", res.data["室溫"]);
|
||||
|
||||
data.value = res.data["室溫"];
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
data,
|
||||
(newValue) => {
|
||||
|
||||
newValue.length > 0 &&
|
||||
indoor_temp_chart.value.chart.setOption({
|
||||
legend: {
|
||||
@ -82,6 +82,22 @@ watch(
|
||||
xAxis: {
|
||||
data: newValue[0]?.data.map(({ time }) => time), // 使用 time
|
||||
},
|
||||
yAxis: {
|
||||
min: Math.floor(
|
||||
Math.min(
|
||||
...newValue[0]?.data
|
||||
.filter((data) => data.value !== null)
|
||||
.map(({ value }) => value)
|
||||
)
|
||||
),
|
||||
max: Math.ceil(
|
||||
Math.max(
|
||||
...newValue[0]?.data
|
||||
.filter((data) => data.value !== null)
|
||||
.map(({ value }) => value)
|
||||
)
|
||||
),
|
||||
},
|
||||
series: newValue.map(({ full_name, data }, index) => ({
|
||||
name: full_name,
|
||||
type: "line",
|
||||
@ -111,9 +127,11 @@ watch(
|
||||
clearInterval(timeoutTimer.value);
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
const timeoutTimer = ref("");
|
||||
|
||||
onUnmounted(() => {
|
||||
// 清除定時器
|
||||
@ -125,7 +143,7 @@ onUnmounted(() => {
|
||||
|
||||
<template>
|
||||
<h3 class="text-info font-bold text-xl text-center mb-3 relative">
|
||||
<span>室內溫度</span>
|
||||
<span>{{ $t("dashboard.indoor_temp") }}</span>
|
||||
</h3>
|
||||
|
||||
<LineChart
|
||||
|
@ -6,7 +6,10 @@ import { ref, inject, onMounted, onUnmounted, watch } from "vue";
|
||||
import { getDashboardTemp } from "@/apis/dashboard";
|
||||
import useSearchParams from "@/hooks/useSearchParam";
|
||||
import useBuildingStore from "@/stores/useBuildingStore";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { max, min } from "date-fns";
|
||||
|
||||
const { t } = useI18n();
|
||||
const { searchParams } = useSearchParams();
|
||||
const buildingStore = useBuildingStore();
|
||||
|
||||
@ -53,8 +56,8 @@ const defaultChartOption = ref({
|
||||
series: [],
|
||||
});
|
||||
|
||||
const timeoutTimer = ref("");
|
||||
const frozen_temp_chart = ref(null);
|
||||
|
||||
const data = ref([]);
|
||||
const getData = async (timeInterval) => {
|
||||
const res = await getDashboardTemp({
|
||||
@ -63,9 +66,9 @@ const getData = async (timeInterval) => {
|
||||
tempOption: 2, // 1:室溫 2:冷藏
|
||||
});
|
||||
if (res.isSuccess) {
|
||||
console.log('冷藏溫度資料:', res.data['冷藏溫度']);
|
||||
|
||||
data.value = res.data['冷藏溫度'];
|
||||
console.log("冷藏溫度資料:", res.data["冷藏溫度"]);
|
||||
|
||||
data.value = res.data["冷藏溫度"];
|
||||
}
|
||||
};
|
||||
|
||||
@ -80,6 +83,24 @@ watch(
|
||||
xAxis: {
|
||||
data: newValue[0]?.data.map(({ time }) => time), // 使用 time
|
||||
},
|
||||
yAxis: {
|
||||
min:
|
||||
Math.floor(
|
||||
Math.min(
|
||||
...newValue[0]?.data
|
||||
.filter((data) => data.value !== null)
|
||||
.map(({ value }) => value)
|
||||
)
|
||||
),
|
||||
max:
|
||||
Math.ceil(
|
||||
Math.max(
|
||||
...newValue[0]?.data
|
||||
.filter((data) => data.value !== null)
|
||||
.map(({ value }) => value)
|
||||
)
|
||||
),
|
||||
},
|
||||
series: newValue.map(({ full_name, data }, index) => ({
|
||||
name: full_name,
|
||||
type: "line",
|
||||
@ -109,9 +130,11 @@ watch(
|
||||
clearInterval(timeoutTimer.value);
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
const timeoutTimer = ref("");
|
||||
|
||||
onUnmounted(() => {
|
||||
// 清除定時器
|
||||
@ -123,7 +146,7 @@ onUnmounted(() => {
|
||||
|
||||
<template>
|
||||
<h3 class="text-info font-bold text-xl text-center mb-3 relative">
|
||||
<span>冷藏溫度</span>
|
||||
<span>{{ $t("dashboard.refrig_temp") }}</span>
|
||||
</h3>
|
||||
|
||||
<LineChart
|
||||
|
@ -51,15 +51,15 @@ provide("energy_data", { realTime_data, elecMonth_data, elecDay_data });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="grid gap-4 grid-cols-5 h-[47%] mb-4">
|
||||
<div class="col-span-3">
|
||||
<div class="grid gap-4 md:grid-cols-5 grid-cols-1 h-[47%] my-4">
|
||||
<div class="md:col-span-3 col-span-1">
|
||||
<ImmediateDemandChart />
|
||||
</div>
|
||||
<div class="col-span-2">
|
||||
<div class="md:col-span-2 col-span-1">
|
||||
<CurrentInformation />
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid gap-4 grid-cols-3 h-[47%]">
|
||||
<div class="grid gap-4 md:grid-cols-3 grid-cols-1 h-[47%]">
|
||||
<div class="col-span-1">
|
||||
<UsageInformation />
|
||||
</div>
|
||||
|
@ -1,6 +1,9 @@
|
||||
<script setup>
|
||||
import BarChart from "@/components/chart/BarChart.vue";
|
||||
import { ref, watch, inject } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
const { elecMonth_data } = inject("energy_data");
|
||||
|
||||
const defaultChartOption = ref({
|
||||
@ -11,7 +14,7 @@ const defaultChartOption = ref({
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
data: ["尖峰", "半尖峰", "離峰度數"],
|
||||
data: [t("energy.peak"), t("energy.semi_peak"), t("energy.off_peak")],
|
||||
textStyle: {
|
||||
color: "#ffffff",
|
||||
fontSize: 16,
|
||||
@ -35,41 +38,41 @@ const defaultChartOption = ref({
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
max:15,
|
||||
// max: 15,
|
||||
axisLabel: {
|
||||
color: "#ffffff",
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: "尖峰",
|
||||
name: t("energy.peak"),
|
||||
type: "bar",
|
||||
stack: "total",
|
||||
data: [],
|
||||
itemStyle: {
|
||||
color: "#3c50e0",
|
||||
},
|
||||
barWidth: '20px',
|
||||
// barWidth: "20px",
|
||||
},
|
||||
{
|
||||
name: "半尖峰",
|
||||
name: t("energy.semi_peak"),
|
||||
type: "bar",
|
||||
stack: "total",
|
||||
data: [],
|
||||
itemStyle: {
|
||||
color: "#6577f3",
|
||||
},
|
||||
barWidth: '20px',
|
||||
// barWidth: "20px",
|
||||
},
|
||||
{
|
||||
name: "離峰度數",
|
||||
name: t("energy.off_peak"),
|
||||
type: "bar",
|
||||
stack: "total",
|
||||
data: [],
|
||||
itemStyle: {
|
||||
color: "#8fd0ef",
|
||||
},
|
||||
barWidth: '20px',
|
||||
// barWidth: "20px",
|
||||
},
|
||||
],
|
||||
});
|
||||
@ -96,10 +99,10 @@ watch(
|
||||
class="card bg-normal w-full h-full border border-cyan-300/50 rounded-md"
|
||||
>
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">每月計費度數 (kWh)</h2>
|
||||
<h2 class="card-title">{{ $t("energy.monthly_bill_power")}}</h2>
|
||||
<BarChart
|
||||
id="billing_degree_chart"
|
||||
class="h-full w-full"
|
||||
class="min-h-[250px] max-h-fit"
|
||||
:option="defaultChartOption"
|
||||
ref="degree_chart"
|
||||
/>
|
||||
@ -107,4 +110,5 @@ watch(
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
|
@ -1,17 +1,20 @@
|
||||
<script setup>
|
||||
import { ref, watch, inject } from "vue";
|
||||
import dayjs from "dayjs";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
const { realTime_data } = inject("energy_data");
|
||||
|
||||
const voltage = ref([
|
||||
{ point: "線電壓 V12", value: 0 },
|
||||
{ point: "線電壓 V23", value: 0 },
|
||||
{ point: "線電壓 V31", value: 0 },
|
||||
{ point: `${t("energy.line_voltage")} V12`, value: 0 },
|
||||
{ point: `${t("energy.line_voltage")} V23`, value: 0 },
|
||||
{ point: `${t("energy.line_voltage")} V31`, value: 0 },
|
||||
]);
|
||||
const current = ref([
|
||||
{ point: "電流 1", value: 0 },
|
||||
{ point: "電流 2", value: 0 },
|
||||
{ point: "電流 3", value: 0 },
|
||||
{ point: `${t("energy.electric_current")} 1`, value: 0 },
|
||||
{ point: `${t("energy.electric_current")} 2`, value: 0 },
|
||||
{ point: `${t("energy.electric_current")} 3`, value: 0 },
|
||||
]);
|
||||
const lastUpdated = ref("");
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
<script setup>
|
||||
import BarChart from "@/components/chart/BarChart.vue";
|
||||
import { ref, onMounted, inject, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
const { elecMonth_data } = inject("energy_data");
|
||||
const defaultChartOption = ref({
|
||||
tooltip: {
|
||||
@ -10,7 +13,7 @@ const defaultChartOption = ref({
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
data: ["基本電費", "流動電費"],
|
||||
data: [t("energy.fixed_elec_cost"), t("energy.var_elec_cost")],
|
||||
textStyle: {
|
||||
color: "#ffffff",
|
||||
fontSize: 16,
|
||||
@ -34,7 +37,7 @@ const defaultChartOption = ref({
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
max: 500,
|
||||
// max: 500,
|
||||
min: 0,
|
||||
axisLabel: {
|
||||
color: "#ffffff",
|
||||
@ -42,24 +45,24 @@ const defaultChartOption = ref({
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: "基本電費",
|
||||
name: t("energy.fixed_elec_cost"),
|
||||
type: "bar",
|
||||
stack: "total",
|
||||
data: [],
|
||||
itemStyle: {
|
||||
color: "#37c640",
|
||||
},
|
||||
barWidth: '20px',
|
||||
// barWidth: "20px",
|
||||
},
|
||||
{
|
||||
name: "流動電費",
|
||||
name: t("energy.var_elec_cost"),
|
||||
type: "bar",
|
||||
stack: "total",
|
||||
data: [],
|
||||
itemStyle: {
|
||||
color: "#8ee894",
|
||||
},
|
||||
barWidth: '20px',
|
||||
// barWidth: "20px",
|
||||
},
|
||||
],
|
||||
});
|
||||
@ -69,8 +72,8 @@ watch(
|
||||
(newData) => {
|
||||
const times = newData.map((item) => item.time);
|
||||
const costBase = newData.map((item) => item.costBase);
|
||||
const costDemand = newData.map(
|
||||
(item) => (item.costPeak + item.costHalfPeak + item.costOffPeak).toFixed(2)
|
||||
const costDemand = newData.map((item) =>
|
||||
(item.costPeak + item.costHalfPeak + item.costOffPeak).toFixed(2)
|
||||
);
|
||||
|
||||
defaultChartOption.value.xAxis.data = times;
|
||||
@ -86,10 +89,10 @@ watch(
|
||||
class="card bg-normal w-full h-full border border-cyan-300/50 rounded-md"
|
||||
>
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">每月電費分析</h2>
|
||||
<h2 class="card-title">{{ $t("energy.monthly_elec_bill") }}</h2>
|
||||
<BarChart
|
||||
id="electricity_bill_chart"
|
||||
class="h-full w-full"
|
||||
class="min-h-[250px] max-h-fit"
|
||||
:option="defaultChartOption"
|
||||
ref="bill_chart"
|
||||
/>
|
||||
|
@ -1,6 +1,9 @@
|
||||
<script setup>
|
||||
import LineChart from "@/components/chart/LineChart.vue";
|
||||
import { ref, onMounted, watch, inject } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
const { elecDay_data } = inject("energy_data");
|
||||
const todayUsage = ref(0);
|
||||
const demand_chart = ref(null);
|
||||
@ -9,7 +12,7 @@ const defaultChartOption = ref({
|
||||
trigger: "axis",
|
||||
},
|
||||
legend: {
|
||||
data: ["每日用電度數"],
|
||||
data: [t("energy.daily_elec")],
|
||||
textStyle: {
|
||||
color: "#ffffff",
|
||||
fontSize: 16,
|
||||
@ -45,7 +48,7 @@ const defaultChartOption = ref({
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: "每日用電度數",
|
||||
name: t("energy.daily_elec"),
|
||||
type: "line",
|
||||
data: [],
|
||||
smooth: true,
|
||||
@ -95,12 +98,12 @@ watch(
|
||||
>
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">
|
||||
最新用電度數
|
||||
{{$t("energy.latest_elec_consumption")}}
|
||||
<p>{{ todayUsage }} kWh</p>
|
||||
</h2>
|
||||
<LineChart
|
||||
id="immediate_demand_chart"
|
||||
class="h-full w-full"
|
||||
class="min-h-[250px] max-h-fit w-full"
|
||||
:option="defaultChartOption"
|
||||
ref="demand_chart"
|
||||
/>
|
||||
@ -115,7 +118,7 @@ watch(
|
||||
}
|
||||
|
||||
.bg-normal::before {
|
||||
@apply absolute -top-3 -right-[10px] h-8 w-8 bg-no-repeat z-10 bg-[url('@/assets/img/table/content-box-background02.svg')] bg-center;
|
||||
@apply absolute -top-[9px] -left-[11px] -rotate-90 h-8 w-8 bg-no-repeat z-10 bg-[url('@/assets/img/table/content-box-background02.svg')] bg-center;
|
||||
content: "";
|
||||
}
|
||||
</style>
|
||||
|
@ -65,7 +65,7 @@ watch(
|
||||
<!-- 電壓資訊 -->
|
||||
<div class="stat place-items-start">
|
||||
<div class="stat-title text-gray-200 3xl:text-[2rem]">
|
||||
今年電費總計 (元)
|
||||
{{ $t("energy.elec_bills") }}
|
||||
</div>
|
||||
<div class="stat-value text-success text-5xl 3xl:text-[6rem]">
|
||||
{{ totalElecBills }}
|
||||
@ -76,7 +76,7 @@ watch(
|
||||
</div>
|
||||
<div class="stat place-items-start">
|
||||
<div class="stat-title text-gray-200 3xl:text-[2rem]">
|
||||
區間電費總計 (元)
|
||||
{{ $t("energy.interval_elec_charges") }}
|
||||
</div>
|
||||
<div class="stat-value text-success text-5xl 3xl:text-[6rem]">
|
||||
{{ IntervalElecBills }}
|
||||
@ -93,7 +93,7 @@ watch(
|
||||
<!-- 電流資訊 -->
|
||||
<div class="stat place-items-start">
|
||||
<div class="stat-title text-gray-200 3xl:text-[2rem]">
|
||||
今年用電度數 (kWh)
|
||||
{{ $t("energy.year_elec_consumption") }}
|
||||
</div>
|
||||
<div class="stat-value text-success text-5xl 3xl:text-[6rem]">
|
||||
{{ totalElecDegree }}
|
||||
@ -104,7 +104,7 @@ watch(
|
||||
</div>
|
||||
<div class="stat place-items-start">
|
||||
<div class="stat-title text-gray-200 3xl:text-[2rem]">
|
||||
區間用電度數 (kWh)
|
||||
{{ $t("energy.interval_elec_consumption") }}
|
||||
</div>
|
||||
<div class="stat-value text-success text-5xl 3xl:text-[6rem]">
|
||||
{{ IntervalElecDegree }}
|
||||
|
Loading…
Reference in New Issue
Block a user