棟別判斷 | 能源管理匯出功能

This commit is contained in:
koko 2025-07-21 09:51:15 +08:00
parent f0e9d7fda6
commit ac5c88a047
8 changed files with 108 additions and 45 deletions

View File

@ -4,6 +4,10 @@ export const GET_HISTORY_SIDEBAR_API = `/api/History/GetDeviceInfo`;
export const GET_HISTORY_POINT_API = `/api/History/GetAllDevPoi`;
export const GET_HISTORY_DATA_API = `/api/History/GetHistoryData`;
export const GET_HISTORY_EXPORT_API = `/api/ExportHistoryExcel`;
export const GET_HISTORY_EXPORT_REPORT_API = `/api/History/GetHistoryExcelReport`;
export const GET_HISTORY_EXPORT_CURVE_API = `/api/History/GetHistoricalCurveExcelReport`;
export const GET_HISTORY_EXPORT_QUICK_API = `/api/History/GetQuickMeteringExcelReport`;
export const GET_HISTORY_EXPORT_CLASS_API = `/api/History/GetElectricityClassificationExcelReport`;
export const GET_HISTORY_FAVORITE_API = `/api/History/GetHistoryFavorite`;
export const POST_HISTORY_FAVORITE_API = `/api/History/SaveHistoryFavorite`;

View File

@ -7,6 +7,10 @@ import {
DELETE_HISTORY_FAVORITE_API,
UPDATE_HISTORY_FAVORITE_API,
GET_HISTORY_EXPORT_API,
GET_HISTORY_EXPORT_REPORT_API,
GET_HISTORY_EXPORT_CURVE_API,
GET_HISTORY_EXPORT_QUICK_API,
GET_HISTORY_EXPORT_CLASS_API,
} from "./api";
import instance, { fileInstance } from "@/util/request";
import apihandler from "@/util/apiHandler";
@ -81,7 +85,52 @@ export const getHistoryData = async ({
};
export const getHistoryExportData = async ({
Start_date,
End_date,
Start_time,
End_time,
Device_list,
Points,
Type,
table_type,
}) => {
const api =
parseInt(table_type) === 1
? GET_HISTORY_EXPORT_CURVE_API
: parseInt(table_type) === 2
? GET_HISTORY_EXPORT_QUICK_API
: parseInt(table_type) === 3
? GET_HISTORY_EXPORT_CLASS_API
: GET_HISTORY_EXPORT_API;
const res = await fileInstance.post(
api,
{
Start_date: Start_date,
End_date: End_date,
Start_time: Start_time,
End_time: End_time,
Points: Array.isArray(Points) ? Points : [Points],
Device_list: Array.isArray(Device_list) ? Device_list : [Device_list],
Type: parseInt(Type),
Building_tag_list: [...new Set(Device_list.map((d) => d.split("_")[1]))],
table_type: parseInt(table_type),
},
{ responseType: "blob" }
);
return apihandler(
res.code,
res,
{
msg: res.msg,
code: res.code,
},
downloadExcel
);
};
export const getHistoryExportReport = async ({
Start_date,
End_date,
Start_time,
@ -89,19 +138,8 @@ export const getHistoryExportData = async ({
Device_list,
Points,
}) => {
/*
{
Type,
Start_date,
End_date,
Start_time,
End_time,
Device_list,
Points,
}
*/
const res = await fileInstance.post(
GET_HISTORY_EXPORT_API,
GET_HISTORY_EXPORT_REPORT_API,
{
// ...exportContent,
Start_date: Start_date,
@ -110,7 +148,6 @@ export const getHistoryExportData = async ({
End_time: End_time,
Points: Array.isArray(Points) ? Points : [Points],
Device_list: Array.isArray(Device_list) ? Device_list : [Device_list],
Type: parseInt(Type),
Building_tag_list: [...new Set(Device_list.map((d) => d.split("_")[1]))],
},
{ responseType: "blob" }

View File

@ -5,6 +5,8 @@ import NavbarItem from "./NavbarItem.vue";
import NavbarBuilding from "./NavbarBuilding.vue";
import Logo from "@/assets/img/logo.svg";
import useUserInfoStore from "@/stores/useUserInfoStore";
import useBuildingStore from "@/stores/useBuildingStore";
import AlarmDrawer from "@/components/alarm/AlarmDrawer.vue";
import NavbarLang from "./NavbarLang.vue";
import { twMerge } from "tailwind-merge";
@ -14,6 +16,7 @@ const menuShow = ref(true);
const router = useRouter();
const store = useUserInfoStore();
const storeBuilding = useBuildingStore();
onMounted(() => {
const name = store.user.user_name;
if (name) {
@ -32,6 +35,7 @@ const logout = () => {
document.cookie = "user_name=; Max-Age=0";
store.user.token = "";
store.user.user_name = "";
storeBuilding.deleteBuilding();
router.push({ path: "/login" });
};
</script>

View File

@ -14,20 +14,20 @@ onMounted(() => {
</script>
<template>
<div class="dropdown dropdown-bottom">
<div
tabindex="0"
role="button"
class="text-white ml-8 text-lg font-semiLight"
>
{{ store.selectedBuilding?.full_name }}
<font-awesome-icon :icon="['fas', 'angle-down']" class="ml-1" />
</div>
<ul
tabindex="0"
class="dropdown-content w-48 left-8 translate-y-2 z-[1] menu py-3 shadow rounded bg-[#4c625e] border text-center"
>
<template v-if="store.buildings.length > 0">
<template v-if="store.buildings.length > 1">
<div class="dropdown dropdown-bottom">
<div
tabindex="0"
role="button"
class="text-white ml-8 text-lg font-semiLight"
>
{{ store.selectedBuilding?.full_name }}
<font-awesome-icon :icon="['fas', 'angle-down']" class="ml-1" />
</div>
<ul
tabindex="0"
class="dropdown-content w-48 left-8 translate-y-2 z-[1] menu py-3 shadow rounded bg-[#4c625e] border text-center"
>
<li
class="text-white my-1 text-base cursor-pointer"
v-for="bui in store.buildings"
@ -36,9 +36,13 @@ onMounted(() => {
>
{{ bui.full_name }}
</li>
</template>
</ul>
</div>
</ul>
</div>
</template>
<template v-else>
<div class="text-white ml-8 text-lg font-semiLight">
{{ store.selectedBuilding?.full_name }}
</div>
</template>
</template>
<style lang="scss" scoped></style>

View File

@ -77,6 +77,15 @@ const useBuildingStore = defineStore("buildingInfo", () => {
})) || [];
};
// 清除localStorage建築物
const deleteBuilding = () => {
localStorage.removeItem("CviBuildingList");
localStorage.removeItem("CviBuilding");
buildings.value = [];
selectedBuilding.value = null;
}
// 當 selectedBuilding 改變時,更新 floorList 和 deptList
watch(selectedBuilding, async (newBuilding) => {
if (newBuilding) {
@ -102,6 +111,7 @@ const useBuildingStore = defineStore("buildingInfo", () => {
mainSys,
subSys,
selectedSystem,
deleteBuilding,
fetchBuildings,
fetchFloorList,
fetchDepartmentList,

View File

@ -40,9 +40,15 @@ const submit = async (e, type = "") => {
if (type === "export") {
const res = await getHistoryExportData({
type: searchParams.value.selectedType,
...params,
...searchParams.value,
Type:
route.params.type != 1
? 2
: searchParams.value.Type
? searchParams.value.Type
: 1,
table_type: route.params.type,
}).catch((err) => {
isToastOpen.value = {
open: true,

View File

@ -1,6 +1,6 @@
<script setup>
import { computed, defineProps, inject, ref, watch } from "vue";
import { getHistoryData, getHistoryExportData } from "@/apis/history";
import { getHistoryData, getHistoryExportReport } from "@/apis/history";
import useSearchParam from "@/hooks/useSearchParam";
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
@ -39,8 +39,7 @@ const submit = async (e, type = "") => {
}
if (type === "export") {
const res = await getHistoryExportData({
type: searchParams.value.selectedType,
const res = await getHistoryExportReport({
...params,
...searchParams.value,
}).catch((err) => {
@ -84,15 +83,15 @@ const submitBtns = computed(() => [
btn: "btn-search",
disabled: isSearchButtonDisabled.value,
},
// {
// title: t("button.export"),
// key: "export",
// icon: "download",
// btn: "btn-export",
// active: false,
// onClick: (e) => submit(e, "export"),
// disabled: isSearchButtonDisabled.value,
// },
{
title: t("button.export"),
key: "export",
icon: "download",
btn: "btn-export",
active: false,
onClick: (e) => submit(e, "export"),
disabled: isSearchButtonDisabled.value,
},
]);
const once = ref(false);

View File

@ -18,7 +18,6 @@ import useBuildingStore from "@/stores/useBuildingStore";
import {
getHistoryPoints,
getHistoryData,
getHistoryExportData,
} from "@/apis/history";
import useSearchParam from "@/hooks/useSearchParam";
import dayjs from "dayjs";