navbar、告警設定、資產管理、運維管理、mqtt 加上building_guid | 資產管理小類能上傳圖片 | 首頁顯示小類icon | 能源管理 : 即時需量串接api 、 圖表初始化設定、新增日期與時間區間 | 系統監控加上部門

This commit is contained in:
koko 2025-04-01 10:22:13 +08:00
parent 8b85e2d67c
commit c8e00421b2
22 changed files with 345 additions and 210 deletions

View File

@ -65,8 +65,12 @@ export const postOperationRecord = async (formData) => {
}); });
}; };
export const getAlertSubList = async () => { export const getAlertSubList = async (
const res = await instance.post(GET_ALERT_SUB_LIST_API, {}); building_guid
) => {
const res = await instance.post(GET_ALERT_SUB_LIST_API, {
building_guid
});
return apihandler(res.code, res.data, { return apihandler(res.code, res.data, {
msg: res.msg, msg: res.msg,

View File

@ -31,8 +31,8 @@ import instance from "@/util/request";
import apihandler from "@/util/apihandler"; import apihandler from "@/util/apihandler";
import { object } from "yup"; import { object } from "yup";
export const getAssetMainList = async () => { export const getAssetMainList = async (building_guid) => {
const res = await instance.post(GET_ASSET_MAIN_LIST_API); const res = await instance.post(GET_ASSET_MAIN_LIST_API,{building_guid});
return apihandler(res.code, res.data, { return apihandler(res.code, res.data, {
msg: res.msg, msg: res.msg,
@ -49,11 +49,12 @@ export const deleteAssetMainItem = async (id) => {
}); });
}; };
export const postAssetMainList = async ({ id, system_key, system_value }) => { export const postAssetMainList = async ({ id, system_key, system_value, building_guid }) => {
const res = await instance.post(POST_ASSET_MAIN_LIST_API, { const res = await instance.post(POST_ASSET_MAIN_LIST_API, {
id, id,
system_key, system_key,
system_value, system_value,
building_guid
}); });
return apihandler(res.code, res.data, { return apihandler(res.code, res.data, {
@ -71,18 +72,8 @@ export const getAssetSubList = async (id) => {
}); });
}; };
export const postAssetSubList = async ({ export const postAssetSubList = async (formData) => {
system_key, const res = await instance.post(POST_ASSET_SUB_LIST_API, formData);
system_value,
system_parent_id,
id,
}) => {
const res = await instance.post(POST_ASSET_SUB_LIST_API, {
system_key,
system_value,
system_parent_id,
id,
});
return apihandler(res.code, res.data, { return apihandler(res.code, res.data, {
msg: res.msg, msg: res.msg,

View File

@ -49,10 +49,8 @@ export const getAuth = async (lang) => {
}); });
}; };
export const getAllSysSidebar = async () => { export const getAllSysSidebar = async (building_guid) => {
const res = await instance.post(GET_SUBAUTHPAGE_API, { const res = await instance.post(GET_SUBAUTHPAGE_API, {building_guid});
building_tag: "",
});
return apihandler(res.code, res.data, { return apihandler(res.code, res.data, {
msg: res.msg, msg: res.msg,
code: res.code, code: res.code,

View File

@ -12,6 +12,7 @@ export const GET_Excel_API = `/api/Energe/GetReportExcel`;
export const GET_DEMAND_API = `/api/Energe/SearchDemandValue`; export const GET_DEMAND_API = `/api/Energe/SearchDemandValue`;
export const POST_ADD_DEMAND_API = `/api/Energe/AddDemandValue`; export const POST_ADD_DEMAND_API = `/api/Energe/AddDemandValue`;
export const POST_EDIT_DEMAND_API = `/api/Energe/UpdateDemandValue`; export const POST_EDIT_DEMAND_API = `/api/Energe/UpdateDemandValue`;
export const GET_REALTIME_DEMAND_API = `/api/Energe/GetRealTimeDemand`;
// 碳排係數 // 碳排係數
export const GET_CARBON_API = `/api/Energe/SearchCarbonValue`; export const GET_CARBON_API = `/api/Energe/SearchCarbonValue`;

View File

@ -8,6 +8,7 @@ import {
GET_Excel_API, GET_Excel_API,
GET_DEMAND_API, GET_DEMAND_API,
POST_EDIT_DEMAND_API, POST_EDIT_DEMAND_API,
GET_REALTIME_DEMAND_API,
GET_CARBON_API, GET_CARBON_API,
POST_EDIT_CARBON_API, POST_EDIT_CARBON_API,
GET_TIME_ELEC_API, GET_TIME_ELEC_API,
@ -199,6 +200,15 @@ export const postEditCarbonValue = async ({
}); });
}; };
export const getRealTimeDemand = async (building_guid) => {
const res = await instance.post(GET_REALTIME_DEMAND_API, { building_guid });
return apihandler(res.code, res.data, {
msg: res.msg,
code: res.code,
});
};
export const getTimeElec = async (building_guid) => { export const getTimeElec = async (building_guid) => {
const res = await instance.post(GET_TIME_ELEC_API, { building_guid }); const res = await instance.post(GET_TIME_ELEC_API, { building_guid });

View File

@ -20,13 +20,13 @@ export const getSystemFloors = async (building_tag, sub_system_tag) => {
export const getSystemDevices = async ({ export const getSystemDevices = async ({
sub_system_tag, sub_system_tag,
building_tag, building_guid,
floor_tag, department_id_list,
}) => { }) => {
const res = await instance.post(GET_SYSTEM_DEVICE_LIST_API, { const res = await instance.post(GET_SYSTEM_DEVICE_LIST_API, {
sub_system_tag, sub_system_tag,
building_tag, building_guid,
floor_tag, department_id_list,
}); });
return apihandler(res.code, res.data, { return apihandler(res.code, res.data, {

View File

@ -37,8 +37,8 @@ const authPages = computed(() =>
); );
const open = ref(false); const open = ref(false);
const getSubMonitorPage = async (building) => { const getSubMonitorPage = async (building_guid) => {
const res = await getAllSysSidebar(); const res = await getAllSysSidebar(building_guid);
buildingStore.mainSubSys = res.data.history_Main_Systems; buildingStore.mainSubSys = res.data.history_Main_Systems;
menu_array.value = res.data.history_Main_Systems; menu_array.value = res.data.history_Main_Systems;
}; };
@ -48,7 +48,7 @@ const getSubPage = async (system_type) => {
}; };
const showDrawer = async (authCode) => { const showDrawer = async (authCode) => {
if (authCode === "PF1") { if (authCode === "PF1") {
await getSubMonitorPage(); await getSubMonitorPage(buildingStore.selectedBuilding.building_guid);
} else if (authCode === "PF2" || authCode === "PF11") { } else if (authCode === "PF2" || authCode === "PF11") {
await getSubPage(authCode === "PF2" ? "Energy" : "Setting"); await getSubPage(authCode === "PF2" ? "Energy" : "Setting");
} }
@ -71,7 +71,7 @@ watch(
() => buildingStore.selectedBuilding, () => buildingStore.selectedBuilding,
(newVal) => { (newVal) => {
if (newVal !== null) { if (newVal !== null) {
getSubMonitorPage(newVal.building_tag); getSubMonitorPage(newVal.building_guid);
} }
} }
); );

View File

@ -5,6 +5,8 @@ import { ref, onMounted, watch, inject } from "vue";
import useSearchParam from "@/hooks/useSearchParam"; import useSearchParam from "@/hooks/useSearchParam";
import useActiveBtn from "@/hooks/useActiveBtn"; import useActiveBtn from "@/hooks/useActiveBtn";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import useBuildingStore from "@/stores/useBuildingStore";
const store = useBuildingStore();
const { t } = useI18n(); const { t } = useI18n();
const { searchParams, changeParams } = useSearchParam(); const { searchParams, changeParams } = useSearchParam();
const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn(); const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn();
@ -17,7 +19,7 @@ const formState = ref({
}); });
const getMainSystems = async () => { const getMainSystems = async () => {
const res = await getAssetMainList(); const res = await getAssetMainList(store.selectedBuilding.building_guid);
const cate = res.data.map((d, index) => ({ const cate = res.data.map((d, index) => ({
...d, ...d,
title: d.system_key, title: d.system_key,
@ -60,9 +62,15 @@ const deleteItem = async (id) => {
}); });
}; };
onMounted(() => { watch(
() => store.selectedBuilding,
(newBuilding) => {
if (newBuilding) {
getMainSystems(); getMainSystems();
}); }
},
{ immediate: true }
);
watch(selectedBtn, (newValue) => { watch(selectedBtn, (newValue) => {
changeParams({ changeParams({

View File

@ -3,8 +3,11 @@ import { ref, defineProps, inject } from "vue";
import * as yup from "yup"; import * as yup from "yup";
import useFormErrorMessage from "@/hooks/useFormErrorMessage"; import useFormErrorMessage from "@/hooks/useFormErrorMessage";
import { postAssetMainList } from "@/apis/asset"; import { postAssetMainList } from "@/apis/asset";
import useBuildingStore from "@/stores/useBuildingStore";
import useSearchParam from "@/hooks/useSearchParam"; import useSearchParam from "@/hooks/useSearchParam";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
const storeBuild = useBuildingStore();
const { t } = useI18n(); const { t } = useI18n();
const { openToast } = inject("app_toast"); const { openToast } = inject("app_toast");
const { searchParams, changeParams } = useSearchParam(); const { searchParams, changeParams } = useSearchParam();
@ -30,6 +33,7 @@ const onOk = async () => {
const res = await postAssetMainList({ const res = await postAssetMainList({
...props.formState, ...props.formState,
id: props.formState ? props.formState.id : 0, id: props.formState ? props.formState.id : 0,
building_guid:storeBuild.selectedBuilding?.building_guid || null,
}); });
if (res.isSuccess) { if (res.isSuccess) {

View File

@ -45,21 +45,41 @@ watch(
deep: true, deep: true,
} }
); );
const formState = ref({
id: 0,
system_key: "",
system_value: "",
system_parent_id: 0,
file: [],
});
const editRecord = ref(null);
// modal
const openModal = () => { const openModal = (item) => {
if (item.id) {
formState.value = { ...item };
if (item.device_image) {
const subFile = item
? {
name: item.device_image,
src: item.device_image,
ext: item.device_image?.split(".")[1],
}
: {};
formState.value.file = [subFile];
}
} else {
formState.value = {
id: 0,
system_key: "",
system_value: "",
system_parent_id: 0,
file: [],
};
}
asset_add_sub_item.showModal(); asset_add_sub_item.showModal();
}; };
const onCancel = () => {
editRecord.value = null;
asset_add_sub_item.close();
};
const edit = (item) => {
editRecord.value = item;
openModal();
};
const deleteItem = async (id) => { const deleteItem = async (id) => {
openToast("warning", t("msg.sure_to_delete"), "body", async () => { openToast("warning", t("msg.sure_to_delete"), "body", async () => {
@ -83,9 +103,8 @@ const deleteItem = async (id) => {
</h2> </h2>
<AssetSubListAddModal <AssetSubListAddModal
:openModal="openModal" :openModal="openModal"
:onCancel="onCancel"
:getData="getSubSystems" :getData="getSubSystems"
:editRecord="editRecord" :formState="formState"
/> />
<button <button
@click.stop.prevent="isEditMode = !isEditMode" @click.stop.prevent="isEditMode = !isEditMode"
@ -112,7 +131,7 @@ const deleteItem = async (id) => {
<template v-if="isEditMode"> <template v-if="isEditMode">
<span <span
class="ml-2 text-base text-warning" class="ml-2 text-base text-warning"
@click.stop.prevent="() => edit(item)" @click.stop.prevent="() => openModal(item)"
> >
<FontAwesomeIcon :icon="['fas', 'pencil-alt']"></FontAwesomeIcon> <FontAwesomeIcon :icon="['fas', 'pencil-alt']"></FontAwesomeIcon>
</span> </span>

View File

@ -5,21 +5,25 @@ import useFormErrorMessage from "@/hooks/useFormErrorMessage";
import useSearchParam from "@/hooks/useSearchParam"; import useSearchParam from "@/hooks/useSearchParam";
import { getAssetMainList, postAssetSubList } from "@/apis/asset"; import { getAssetMainList, postAssetSubList } from "@/apis/asset";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import useBuildingStore from "@/stores/useBuildingStore";
const store = useBuildingStore();
const { t } = useI18n(); const { t } = useI18n();
const { searchParams, changeParams } = useSearchParam(); const { searchParams, changeParams } = useSearchParam();
const props = defineProps({ const props = defineProps({
openModal: Function, openModal: Function,
onCancel: Function,
getData: Function, getData: Function,
editRecord: Object, formState: Object,
}); });
const form = ref(null);
const mainSystem = ref([]); const mainSystem = ref([]);
const updateFileList = (files) => { const updateFileList = (files) => {
formState.value.icon = files; console.log("file", files);
props.formState.file = files;
}; };
const getMainSystems = async () => { const getMainSystems = async () => {
const res = await getAssetMainList(); const res = await getAssetMainList(store.selectedBuilding.building_guid);
mainSystem.value = res.data.map((d) => ({ ...d, key: d.id })); mainSystem.value = res.data.map((d) => ({ ...d, key: d.id }));
}; };
@ -27,53 +31,55 @@ let subSysSchema = yup.object({
system_key: yup.string().required(t("button.required")), // system_key: yup.string().required(t("button.required")), //
system_value: yup.string().required(t("button.required")), // system_value: yup.string().required(t("button.required")), //
system_parent_id: yup.number().required(t("button.required")), // id system_parent_id: yup.number().required(t("button.required")), // id
file: yup.array(),
}); });
const { formErrorMsg, handleSubmit, handleErrorReset } = const { formErrorMsg, handleSubmit, handleErrorReset } =
useFormErrorMessage(subSysSchema); useFormErrorMessage(subSysSchema);
const formState = ref({ const onCancel = () => {
props.formState = {
id: 0,
system_key: "", system_key: "",
system_value: "", system_value: "",
system_parent_id: 0, system_parent_id: 0,
icon: [], file: [],
});
const resetForm = () => {
formState.value = {
system_key: "",
system_value: "",
system_parent_id: 0,
icon: [],
}; };
asset_add_sub_item.close();
updateFileList([]);
handleErrorReset();
}; };
onMounted(() => {
getMainSystems();
});
watch( watch(
() => props.editRecord, () => store.selectedBuilding,
(newValue) => { (newBuilding) => {
if (newValue) { if (newBuilding) {
formState.value = newValue; getMainSystems();
} else {
resetForm();
}
} }
},
{ immediate: true }
); );
const onOk = async () => { const onOk = async () => {
// //
const value = await handleSubmit(subSysSchema, formState.value); const value = await handleSubmit(subSysSchema, props.formState);
const res = await postAssetSubList({ console.log("props.formState", props.formState);
...formState.value,
id: props.editRecord ? props.editRecord.id : 0,
});
const formData = new FormData(form.value);
formData.delete("file");
formData.append("id", props.formState.id);
if (props.formState.file[0]) {
formData.append("file", props.formState.file[0]);
}
if (props.formState.Device_image) {
formData.append("Device_image", props.formState.Device_image);
}
const res = await postAssetSubList(formData);
if (res.isSuccess) { if (res.isSuccess) {
props.getData(parseInt(searchParams.value.mainSys_id)); props.getData(parseInt(searchParams.value.mainSys_id));
props.onCancel(); onCancel();
} }
}; };
</script> </script>
@ -84,7 +90,11 @@ const onOk = async () => {
</button> </button>
<Modal <Modal
id="asset_add_sub_item" id="asset_add_sub_item"
:title="props.editRecord?.id ? t('assetManagement.edit_device_category') : t('assetManagement.add_device_category')" :title="
props.formState?.id
? t('assetManagement.edit_device_category')
: t('assetManagement.add_device_category')
"
:open="open" :open="open"
:onCancel="onCancel" :onCancel="onCancel"
width="300" width="300"
@ -99,7 +109,11 @@ const onOk = async () => {
</span></template </span></template
> >
</Input> </Input>
<Input name="system_value" :value="formState" :readonly="props.editRecord?.id"> <Input
name="system_value"
:value="formState"
:readonly="props.formState?.id"
>
<template #topLeft>{{ $t("assetManagement.system_value") }}</template> <template #topLeft>{{ $t("assetManagement.system_value") }}</template>
<template #bottomLeft <template #bottomLeft
><span class="text-error text-base"> ><span class="text-error text-base">
@ -114,7 +128,7 @@ const onOk = async () => {
name="system_parent_id" name="system_parent_id"
:value="formState" :value="formState"
selectClass="border-info focus-within:border-info" selectClass="border-info focus-within:border-info"
:disabled="props.editRecord?.id" :disabled="props.formState?.id"
> >
<template #topLeft>{{ <template #topLeft>{{
$t("assetManagement.system_parent") $t("assetManagement.system_parent")
@ -126,11 +140,10 @@ const onOk = async () => {
> >
</Select> </Select>
<Upload <Upload
name="icon" name="file"
:fileList="formState.icon" :fileList="formState.file || []"
:getFileList="updateFileList" :getFileList="updateFileList"
:multiple="false" :multiple="false"
:baseUrl="`${BASEURL}/upload/graph_manage`"
> >
<template #topLeft>{{ $t("operation.upload_file") }}</template> <template #topLeft>{{ $t("operation.upload_file") }}</template>
</Upload> </Upload>

View File

@ -3,12 +3,13 @@ import { ref, onMounted, watch } from "vue";
import useSearchParam from "@/hooks/useSearchParam"; import useSearchParam from "@/hooks/useSearchParam";
import useActiveBtn from "@/hooks/useActiveBtn"; import useActiveBtn from "@/hooks/useActiveBtn";
import { getAlertSubList } from "@/apis/alert"; import { getAlertSubList } from "@/apis/alert";
import useBuildingStore from "@/stores/useBuildingStore";
const store = useBuildingStore();
const { searchParams, changeParams } = useSearchParam(); const { searchParams, changeParams } = useSearchParam();
const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn(); const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn();
const getSubSystems = async () => { const getSubSystems = async () => {
const res = await getAlertSubList(); const res = await getAlertSubList(store.selectedBuilding.building_guid);
const history_Sub_systems = res.data.history_Main_Systems.flatMap( const history_Sub_systems = res.data.history_Main_Systems.flatMap(
(mainSystem) => { (mainSystem) => {
return mainSystem.history_Sub_systems; return mainSystem.history_Sub_systems;
@ -24,9 +25,15 @@ const getSubSystems = async () => {
setItems(subSystems); setItems(subSystems);
}; };
onMounted(() => { watch(
() => store.selectedBuilding,
(newBuilding) => {
if (newBuilding) {
getSubSystems(); getSubSystems();
}); }
},
{ immediate: true }
);
watch(selectedBtn, watch(selectedBtn,
(newValue) => { (newValue) => {

View File

@ -5,7 +5,7 @@ import { twMerge } from "tailwind-merge";
import useBuildingStore from "@/stores/useBuildingStore"; import useBuildingStore from "@/stores/useBuildingStore";
const store = useBuildingStore(); const store = useBuildingStore();
const router = useRouter(); const router = useRouter();
const FILE_BASEURL = import.meta.env.VITE_FILE_API_BASEURL;
const navigateToSubSystem = (mainSystemId, subSystemId) => { const navigateToSubSystem = (mainSystemId, subSystemId) => {
router.push({ router.push({
name: "sub_system", name: "sub_system",
@ -17,7 +17,7 @@ const navigateToSubSystem = (mainSystemId, subSystemId) => {
}); });
}; };
console.log("subSys",store.subSys) // console.log("subSys", store.subSys);
</script> </script>
<template> <template>
@ -43,11 +43,16 @@ console.log("subSys",store.subSys)
<div class="equipment-item"> <div class="equipment-item">
<div class="w-16"> <div class="w-16">
<!-- <FontAwesomeIcon <img
v-if="item.device_image_url"
class="w-7 m-auto"
:src="`${FILE_BASEURL}/${item.device_image_url}`"
/>
<FontAwesomeIcon
v-else
class="text-2xl mt-1 m-auto" class="text-2xl mt-1 m-auto"
:icon="['fas', 'tv']" :icon="['fas', 'tv']"
></FontAwesomeIcon> --> ></FontAwesomeIcon>
<img class="w-7 m-auto" src="https://cgems.cvilux-group.com:8088/upload/device_icon/3454f5e0-3afa-4ace-ae54-a68bf7183e7d.png">
</div> </div>
<div class="icon-text"> <div class="icon-text">
<div class=""> <div class="">

View File

@ -1,92 +1,29 @@
<script setup> <script setup>
import LineChart from "@/components/chart/LineChart.vue"; import LineChart from "@/components/chart/LineChart.vue";
import { ref, onMounted,watch } from "vue"; import { ref, onMounted, watch, onUnmounted } from "vue";
import ImmediateDemandModal from "./ImmediateDemandModal.vue"; import ImmediateDemandModal from "./ImmediateDemandModal.vue";
import { getDemand } from "@/apis/energy"; import { getDemand, getRealTimeDemand } from "@/apis/energy";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import useBuildingStore from "@/stores/useBuildingStore"; import useBuildingStore from "@/stores/useBuildingStore";
import dayjs from "dayjs";
const store = useBuildingStore(); const store = useBuildingStore();
const { t } = useI18n(); const { t } = useI18n();
const demandData = ref(null); const demandData = ref(null);
// const realTimeDemand = ref([]);
const data = {
categories: [
"16:22:29",
"16:22:37",
"16:22:47",
"16:23:00",
"16:23:08",
"16:23:18",
],
series: [
{
name: t("energy.real_time_Trend"), //
type: "line",
data: [320, 310, 300, 305, 310, 300],
smooth: true,
lineStyle: {
width: 3,
},
itemStyle: {
color: "#17CEE3",
},
},
{
name: t("energy.contract_capacity"), //
type: "line",
data: [400, 400, 400, 400, 400, 400],
smooth: true,
lineStyle: {
width: 3,
},
itemStyle: {
color: "#E4EA00",
},
},
{
name: t("energy.alert_capacity"), //
type: "line",
data: [350, 350, 350, 350, 350, 350],
smooth: true,
lineStyle: {
width: 3,
},
itemStyle: {
color: "#62E39A",
},
},
{
name: t("energy.reset_value"), //
type: "line",
data: [280, 300, 290, 295, 300, 290],
smooth: true,
lineStyle: {
width: 3,
},
itemStyle: {
color: "#E9971F",
},
},
],
};
const demand_chart = ref(null); const demand_chart = ref(null);
const intervalId = ref(null);
// `null` `ECharts`
const defaultChartOption = ref({ const defaultChartOption = ref({
tooltip: { tooltip: { trigger: "axis" },
trigger: "axis",
},
legend: { legend: {
data: data.series.map((s) => s.name), data: [],
textStyle: { textStyle: { color: "#ffffff", fontSize: 16 },
color: "#ffffff",
fontSize: 16,
},
orient: "horizontal",
bottom: "0%", bottom: "0%",
}, },
grid: { grid: {
top: "10%", top: "3%",
left: "0%", left: "0%",
right: "0%", right: "0%",
bottom: "15%", bottom: "15%",
@ -94,42 +31,126 @@ const defaultChartOption = ref({
}, },
xAxis: { xAxis: {
type: "category", type: "category",
splitLine: { splitLine: { show: false },
show: false, axisLabel: { color: "#ffffff" },
}, data: [], // undefined
axisLabel: {
color: "#ffffff",
},
data: data.categories,
}, },
yAxis: { yAxis: {
type: "value", type: "value",
splitLine: { splitLine: { show: false },
show: false, axisLabel: { color: "#ffffff" },
}, },
axisLabel: { series: [],
color: "#ffffff",
},
},
series: data.series,
}); });
//
const getData = async () => { const getData = async () => {
if (store.selectedBuilding.building_guid) { if (store.selectedBuilding.building_guid) {
const res = await getDemand(store.selectedBuilding.building_guid); const res = await getDemand(store.selectedBuilding.building_guid);
demandData.value = res.data[0]; demandData.value = res.data[0];
updateChart();
} }
}; };
//
const getRealTime = async () => {
if (store.selectedBuilding.building_guid) {
const res = await getRealTimeDemand(store.selectedBuilding.building_guid);
realTimeDemand.value = res.data.reverse();
updateChart();
}
};
//
const updateChart = () => {
if (!demandData.value || !realTimeDemand.value.length) return;
defaultChartOption.value = {
...defaultChartOption.value,
legend: {
...defaultChartOption.value.legend,
data: [
t("energy.real_time_Trend"),
t("energy.contract_capacity"),
t("energy.alert_capacity"),
t("energy.reset_value"),
],
},
xAxis: {
...defaultChartOption.value.xAxis,
data: realTimeDemand.value.map(({ time }) =>
dayjs(time).format("HH:mm:ss")
),
},
series: [
{
name: t("energy.real_time_Trend"),
type: "line",
data: realTimeDemand.value.map((d) => d.value),
smooth: true,
lineStyle: { width: 3 },
itemStyle: { color: "#17CEE3" },
},
{
name: t("energy.contract_capacity"),
type: "line",
data: Array(realTimeDemand.value.length).fill(
demandData.value.contract
),
smooth: true,
lineStyle: { width: 3 },
itemStyle: { color: "#E4EA00" },
},
{
name: t("energy.alert_capacity"),
type: "line",
data: Array(realTimeDemand.value.length).fill(demandData.value.alert),
smooth: true,
lineStyle: { width: 3 },
itemStyle: { color: "#62E39A" },
},
{
name: t("energy.reset_value"),
type: "line",
data: Array(realTimeDemand.value.length).fill(demandData.value.reset),
smooth: true,
lineStyle: { width: 3 },
itemStyle: { color: "#E9971F" },
},
],
};
// `chart`
if (demand_chart.value?.chart) {
// demand_chart.value.chart.clear();
demand_chart.value.chart.setOption(defaultChartOption.value);
}
};
//
watch( watch(
() => store.selectedBuilding, () => store.selectedBuilding,
(newBuilding) => { (newBuilding) => {
if (newBuilding) { if (newBuilding) {
getData(); getData();
getRealTime();
// 30
if (intervalId.value) {
clearInterval(intervalId.value);
}
//
intervalId.value = setInterval(getRealTime, 30000);
} }
}, },
{ immediate: true } { immediate: true }
); );
onUnmounted(() => {
//
clearInterval(intervalId.value); // 使 intervalId.value
intervalId.value = null; // intervalId
console.log("Interval cleared!");
});
</script> </script>
<template> <template>
@ -137,11 +158,14 @@ watch(
<div class="flex items-center text-white mb-5"> <div class="flex items-center text-white mb-5">
<div class="flex items-end text-base relative text mr-32"> <div class="flex items-end text-base relative text mr-32">
{{ $t("energy.immediate_demand") }} {{ $t("energy.immediate_demand") }}
<span class="text-2xl px-2.5">245.48 kw</span> <span class="text-2xl px-2.5"
</div> >{{
<div class="flex items-end text-base"> realTimeDemand.length > 0
{{ $t("energy.average_demand") }} ? realTimeDemand[realTimeDemand.length - 1].value
<span class="text-2xl px-2.5">230.8 kw</span> : "---"
}}
kw</span
>
</div> </div>
<ImmediateDemandModal :demandData="demandData" :getData="getData" /> <ImmediateDemandModal :demandData="demandData" :getData="getData" />
</div> </div>

View File

@ -109,7 +109,7 @@ const chartOption = computed(() => {
const loadData = async (value) => { const loadData = async (value) => {
const res = await getElecUseDay(value); const res = await getElecUseDay(value);
if (res.isSuccess) { if (res.isSuccess && res.data) {
dataSource.value = res.data dataSource.value = res.data
.sort((a, b) => a.time.localeCompare(b.time)) .sort((a, b) => a.time.localeCompare(b.time))
.map((d) => ({ ...d, key: d.id })); .map((d) => ({ ...d, key: d.id }));
@ -119,6 +119,10 @@ const loadData = async (value) => {
min: dates[0], min: dates[0],
max: dates[dates.length - 1], max: dates[dates.length - 1],
}; };
} else {
//
dataSource.value = [];
dateRange.value = { min: null, max: null };
} }
}; };

View File

@ -3,8 +3,10 @@ import { inject, computed, ref, watch } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import LineChart from "@/components/chart/LineChart.vue"; import LineChart from "@/components/chart/LineChart.vue";
import { SECOND_CHART_COLOR } from "@/constant"; import { SECOND_CHART_COLOR } from "@/constant";
import useSearchParam from "@/hooks/useSearchParam";
import dayjs from "dayjs"; import dayjs from "dayjs";
const { searchParams } = useSearchParam();
const { t } = useI18n(); const { t } = useI18n();
const { tableData } = inject("energy_table_data"); const { tableData } = inject("energy_table_data");
const history_chart = ref(null); const history_chart = ref(null);
@ -46,7 +48,10 @@ const defaultChartOption = {
splitLine: { show: false }, splitLine: { show: false },
axisLabel: { axisLabel: {
color: "#ffffff", color: "#ffffff",
formatter: (value) => dayjs(value).format("HH:mm"), // formatter: (value) =>
searchParams.value.Type == 2
? dayjs(value).format("HH:mm")
: dayjs(value).format("MM-DD"), //
}, },
data: [], data: [],
}, },
@ -54,6 +59,10 @@ const defaultChartOption = {
type: "value", type: "value",
splitLine: { show: false }, splitLine: { show: false },
axisLabel: { color: "#ffffff" }, axisLabel: { color: "#ffffff" },
// interval: 100, //Y
min: "dataMin",
max: "dataMax",
// splitArea: { show: false },
}, },
series: [], series: [],
}; };

View File

@ -1,11 +1,13 @@
<script setup> <script setup>
import Checkbox from "@/components/customUI/Checkbox.vue"; import Checkbox from "@/components/customUI/Checkbox.vue";
import { computed, ref, watch, inject } from "vue"; import { computed, ref, watch, inject } from "vue";
import { useRoute } from "vue-router";
import useBuildingStore from "@/stores/useBuildingStore"; import useBuildingStore from "@/stores/useBuildingStore";
import useSearchParam from "@/hooks/useSearchParam"; import useSearchParam from "@/hooks/useSearchParam";
import { getHistorySideBar } from "@/apis/history"; import { getHistorySideBar } from "@/apis/history";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
const { t } = useI18n(); const { t } = useI18n();
const route = useRoute();
const storeBuild = useBuildingStore(); const storeBuild = useBuildingStore();
const buildingGuid = computed(() => storeBuild.selectedBuilding?.building_guid); const buildingGuid = computed(() => storeBuild.selectedBuilding?.building_guid);
const { searchParams, changeParams } = useSearchParam(); const { searchParams, changeParams } = useSearchParam();
@ -22,7 +24,7 @@ const getDeviceData = async ({
const res = await getHistorySideBar({ const res = await getHistorySideBar({
sub_system_tag, sub_system_tag,
department_id, department_id,
elec_type_id, elec_type_id: route.params.type == 3 ? elec_type_id : [],
building_guid: buildingGuid.value, building_guid: buildingGuid.value,
}); });
deviceData.value = (res.data || []).map((building) => ({ deviceData.value = (res.data || []).map((building) => ({

View File

@ -22,12 +22,12 @@ const itemsForEndTime = ref();
const initializeItems = () => { const initializeItems = () => {
setItems([ setItems([
{ {
title: t("history.date_range"), title: t("history.time_range"),
key: "dateRange", key: "dateRange",
active: searchParams.value.Type active: searchParams.value.Type
? parseInt(searchParams.value.Type) === 1 ? parseInt(searchParams.value.Type) === 2
: true, : true,
Type: 1, Type: 2,
}, },
// { // {
// title: t("history.time_range"), // title: t("history.time_range"),

View File

@ -4,6 +4,8 @@ import { computed, onMounted, ref, watch,inject } from "vue";
import useSearchParam from "@/hooks/useSearchParam"; import useSearchParam from "@/hooks/useSearchParam";
import useActiveBtn from "@/hooks/useActiveBtn"; import useActiveBtn from "@/hooks/useActiveBtn";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import useBuildingStore from "@/stores/useBuildingStore";
const store = useBuildingStore();
const { t } = useI18n(); const { t } = useI18n();
const { searchParams, changeParams } = useSearchParam(); const { searchParams, changeParams } = useSearchParam();
const { search } = inject("operation_table"); const { search } = inject("operation_table");
@ -23,7 +25,7 @@ const {
} = useActiveBtn("multiple"); } = useActiveBtn("multiple");
const getMainSystems = async () => { const getMainSystems = async () => {
const res = await getAssetMainList(); const res = await getAssetMainList(store.selectedBuilding.building_guid);
const cate = res.data.map((d, index) => ({ const cate = res.data.map((d, index) => ({
...d, ...d,
title: d.system_key, title: d.system_key,
@ -48,9 +50,15 @@ const getSubSystems = async (id) => {
setSysItems(sub); setSysItems(sub);
}; };
onMounted(() => { watch(
() => store.selectedBuilding,
(newBuilding) => {
if (newBuilding) {
getMainSystems(); getMainSystems();
}); }
},
{ immediate: true }
);
watch(selectedMainSysItems, (newValue) => { watch(selectedMainSysItems, (newValue) => {
changeParams({ changeParams({

View File

@ -11,6 +11,8 @@ import useActiveBtn from "@/hooks/useActiveBtn";
import MQTTListAddModal from "./MQTTListAddModal.vue"; import MQTTListAddModal from "./MQTTListAddModal.vue";
import PointListAddModal from "./PointListAddModal.vue"; import PointListAddModal from "./PointListAddModal.vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import useBuildingStore from "@/stores/useBuildingStore";
const store = useBuildingStore();
const { t } = useI18n(); const { t } = useI18n();
const { openToast, cancelToastOpen } = inject("app_toast"); const { openToast, cancelToastOpen } = inject("app_toast");
const MQTTDataSource = ref([]); const MQTTDataSource = ref([]);
@ -35,7 +37,7 @@ const {
} = useActiveBtn(); } = useActiveBtn();
const getMainSystems = async () => { const getMainSystems = async () => {
const res = await getAssetMainList(); const res = await getAssetMainList(store.selectedBuilding.building_guid);
const cate = res.data.map((d, index) => ({ const cate = res.data.map((d, index) => ({
...d, ...d,
title: d.system_key, title: d.system_key,
@ -179,9 +181,15 @@ watch(
} }
); );
onMounted(() => { watch(
() => store.selectedBuilding,
(newBuilding) => {
if (newBuilding) {
getMainSystems(); getMainSystems();
}); }
},
{ immediate: true }
);
</script> </script>
<template> <template>

View File

@ -38,6 +38,7 @@ const raw_data = ref([]);
const data = ref([]); // filter data const data = ref([]); // filter data
const route = useRoute(); const route = useRoute();
const floors = ref([]); const floors = ref([]);
const deptData = ref([]);
const companyOptions = ref([]); const companyOptions = ref([]);
const selected_dbid = ref([]); const selected_dbid = ref([]);
@ -55,7 +56,8 @@ const getData = async () => {
if (!route.params.sub_system_id) return if (!route.params.sub_system_id) return
const res = await getSystemDevices({ const res = await getSystemDevices({
sub_system_tag: route.params.sub_system_id, sub_system_tag: route.params.sub_system_id,
building_tag: buildingStore.selectedBuilding?.building_tag, building_guid: buildingStore.selectedBuilding?.building_guid,
department_id_list:deptData.value,
}) })
const devices = res.data.map(d => ({ const devices = res.data.map(d => ({
...d, ...d,
@ -136,6 +138,19 @@ watch(
} }
); );
watch(
() => deptData.value,
(newVal) => {
if (newVal) {
getData();
}
},
{
immediate: true,
deep: true,
}
);
watch( watch(
() => route.params.sub_system_id, () => route.params.sub_system_id,
(newRoute, oldRoute) => { (newRoute, oldRoute) => {
@ -230,7 +245,7 @@ const clearSelectedDeviceInfo = () => {
selectedDevice.value.value = null; selectedDevice.value.value = null;
} }
provide("system_selectedDevice", { selectedDeviceRealtime, selectedDevice, getCurrentInfoModalData, clearSelectedDeviceInfo, selectedDeviceCog, selected_dbid }) provide("system_selectedDevice", { selectedDeviceRealtime, selectedDevice, getCurrentInfoModalData, clearSelectedDeviceInfo, selectedDeviceCog, selected_dbid, deptData })
onBeforeUnmount(() => { onBeforeUnmount(() => {
clearInterval(timeId.value); clearInterval(timeId.value);

View File

@ -4,7 +4,7 @@ import { getDepartmentList } from "@/apis/asset";
import { onMounted, ref, watch, inject } from "vue"; import { onMounted, ref, watch, inject } from "vue";
import useActiveBtn from "@/hooks/useActiveBtn"; import useActiveBtn from "@/hooks/useActiveBtn";
import useBuildingStore from "@/stores/useBuildingStore"; import useBuildingStore from "@/stores/useBuildingStore";
const { deptData } = inject("system_selectedDevice");
const storeBuild = useBuildingStore(); const storeBuild = useBuildingStore();
// //
const { const {
@ -23,6 +23,7 @@ watch(
active: true, active: true,
})); }));
setDeptItems(deptList); setDeptItems(deptList);
deptData.value = deptList.map((d) => d.key);
} }
}, },
{ {
@ -30,6 +31,10 @@ watch(
immediate: true, immediate: true,
} }
); );
watch(selectedDeptItems, (newVal) => {
deptData.value = newVal.map((d) => d.key);
});
</script> </script>
<template> <template>