fix: 以 systemConfig 判斷 Dashboard 左上生產指標顯示

This commit is contained in:
MJM_2025_05\polly 2025-08-11 11:22:25 +08:00
parent 94568c3f86
commit d88dfe3c85
5 changed files with 191 additions and 79 deletions

View File

@ -15,19 +15,22 @@ import useBuildingStore from "@/stores/useBuildingStore";
import { getSystemDevices, getSystemRealTime } from "@/apis/system";
import DashboardRefrig from "./components/DashboardRefrig.vue";
const FILE_BASEURL = import.meta.env.VITE_FILE_API_BASEURL;
const buildingStore = useBuildingStore()
const buildingStore = useBuildingStore();
const subscribeData = ref([]);
const systemData = ref({});
let intervalId = null;
const productVisible = ref(false); //
const productCompleteVisible = ref(false); //
//
const startInterval = () => {
//
if (intervalId) {
clearInterval(intervalId);
}
// 5 getData
intervalId = setInterval(() => {
getData();
@ -37,29 +40,32 @@ const startInterval = () => {
const getData = async () => {
const res = await getSystemDevices({
building_guid: buildingStore.selectedBuilding?.building_guid,
})
});
subscribeData.value = res.data;
console.log("devices", subscribeData.value);
subscribeData.value = res.data
console.log("devices", subscribeData.value)
//
const transformedData = {};
subscribeData.value.forEach(floor => {
subscribeData.value.forEach((floor) => {
if (floor.device_list && floor.device_list.length > 0) {
const fullUrl = floor.floor_map_name;
const uuid = fullUrl ? fullUrl.replace(/\.svg$/, "") : "";
transformedData[uuid] = floor.device_list.map(device => {
transformedData[uuid] = floor.device_list.map((device) => {
//
const coordinates = JSON.parse(device.device_coordinate || '[0,0]');
const coordinates = JSON.parse(device.device_coordinate || "[0,0]");
const x = coordinates[0];
const y = coordinates[1];
//
let state = "Online";
let bgColor = device.device_normal_color;
if (device.device_status === "Offline" || device.device_status === null) {
if (
device.device_status === "Offline" ||
device.device_status === null
) {
state = "Offline";
bgColor = device.device_close_color;
}
@ -80,7 +86,9 @@ const getData = async () => {
points: device.points || [],
floor: floor.full_name,
state: state,
icon: device.device_image ? `${FILE_BASEURL}/upload/device_icon/${device.device_image}` : '',
icon: device.device_image
? `${FILE_BASEURL}/upload/device_icon/${device.device_image}`
: "",
bgColor: bgColor,
Online_color: device.device_normal_color,
Offline_color: device.device_close_color,
@ -92,15 +100,15 @@ const getData = async () => {
buying_date: device.buying_date,
created_at: device.created_at,
bgSize: 50,
}
},
];
});
}
});
console.log("transformedData", transformedData);
systemData.value = transformedData;
}
};
watch(
() => buildingStore.selectedBuilding,
@ -111,7 +119,7 @@ watch(
}
},
{
immediate: true
immediate: true,
}
);
@ -126,29 +134,38 @@ onUnmounted(() => {
<template>
<div class="flex flex-wrap justify-between">
<div
class="order-3 lg:order-1 w-full lg:w-1/4 h-full flex flex-col justify-start z-10 border-dashboard gap-5"
class="order-3 lg:order-1 w-full lg:w-1/4 min-h-screen flex flex-col justify-start z-10 border-dashboard gap-5"
>
<div>
<DashboardProduct />
<!-- 無資料時完整隱藏區塊不留空白 -->
<div class="mb-6">
<DashboardProduct
@visible-change="(v) => (productVisible = v)"
v-show="productVisible"
/>
</div>
<div class="mt-6">
<DashboardProductComplete />
<div class="mb-6">
<DashboardProductComplete
@visible-change="(v) => (productCompleteVisible = v)"
v-show="productVisible"
/>
</div>
<div class="mt-6">
<div class="mb-6">
<DashboardIndoor />
</div>
<div class="mt-10">
<div class="mb-10">
<DashboardRefrig />
</div>
</div>
<div
class="order-1 lg:order-2 w-full lg:w-2/4 relative lg:static min-h-[300px] lg:h-full"
>
<DashboardFloorBar />
<DashboardEffectScatter :data="systemData"/>
<DashboardEffectScatter :data="systemData" />
</div>
<div class="order-2 w-full lg:hidden my-3">
<DashboardSysCard :data="systemData"/>
<div class="order-2 w-full lg:hidden my-3">
<DashboardSysCard :data="systemData" />
</div>
<div
class="order-last w-full lg:w-1/4 flex flex-col justify-start border-dashboard z-20 gap-5"

View File

@ -216,6 +216,7 @@ onUnmounted(() => {
{{ $t("dashboard.no_data") }}
</div>
<LineChart
v-if="!noData"
id="dashboard_other_real_temp"
class="min-h-[260px] max-h-fit"
:option="defaultChartOption"

View File

@ -1,8 +1,54 @@
<script setup>
import { ref, onMounted } from "vue";
import { ref, onMounted, watch } from "vue";
import GaugeChart from "@/components/chart/GaugeChart.vue";
import { CHART_COLOR, SECOND_CHART_COLOR } from "@/constant";
import useBuildingStore from "@/stores/useBuildingStore";
const buildingStore = useBuildingStore();
const visible = ref(false); // /
const emit = defineEmits(["visible-change"]);
// guid sysConfig
watch(
() => buildingStore.selectedBuilding?.building_guid,
async (guid) => {
if (!guid) {
visible.value = false;
return;
}
await buildingStore.getSysConfig(guid);
// .value .value ref/reactive
const cfg = buildingStore.sysConfig?.value ?? buildingStore.sysConfig;
const showIndicator = !!cfg?.show_production_indicator;
console.log("[DashboardProduct] guid:", guid);
console.log("[DashboardProduct] sysConfig:", cfg);
console.log("[DashboardProduct] show_production_indicator:", showIndicator);
if (showIndicator === false) {
visible.value = false; //
return;
}
//
visible.value = true;
},
{ immediate: true }
);
// visible
watch(
visible,
(v) => {
emit("visible-change", v);
},
{ immediate: true }
);
//
const sameOptionAttr = {
type: "gauge",
center: ["50%", "60%"],
@ -119,10 +165,12 @@ onMounted(() => {
});
</script>
<template>
<div>
<!-- 僅在 show_production_indicator === true 時渲染整個元件 -->
<div v-if="visible">
<h3 class="text-info text-xl text-center mb-3">
{{ $t("dashboard.production_quantity") }}
</h3>
<div class="w-full grid grid-cols-3">
<div>
<GaugeChart
@ -150,6 +198,7 @@ onMounted(() => {
</div>
</div>
</div>
<!-- shouldShow null false 時都不顯示任何東西避免閃動與空白框 -->
</template>
<style lang="scss" scoped></style>

View File

@ -1,7 +1,48 @@
<script setup>
import useActiveBtn from "@/hooks/useActiveBtn";
import { ref, onMounted } from "vue";
import { ref, onMounted, watch } from "vue";
import DashboardProductCompleteModal from "./DashboardProductCompleteModal.vue";
import useBuildingStore from "@/stores/useBuildingStore";
const buildingStore = useBuildingStore();
const visible = ref(false); // /
const emit = defineEmits(["visible-change"]);
// guid sysConfig show_production_indicator
watch(
() => buildingStore.selectedBuilding?.building_guid,
async (guid) => {
if (!guid) {
visible.value = false;
return;
}
await buildingStore.getSysConfig(guid);
// ref/reactive .value
const cfg = buildingStore.sysConfig?.value ?? buildingStore.sysConfig;
const flag = !!cfg?.show_production_indicator;
//
// console.log("[DashboardProductRate] guid:", guid);
// console.log("[DashboardProductRate] sysConfig:", cfg);
// console.log("[DashboardProductRate] show_production_indicator:", flag);
visible.value = flag;
},
{ immediate: true }
);
// visible
watch(
visible,
(v) => {
emit("visible-change", v);
},
{ immediate: true }
);
const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn();
@ -44,54 +85,57 @@ onMounted(() => {
</script>
<template>
<DashboardProductCompleteModal />
<div class="mb-3 relative">
<h3 class="text-info text-xl text-center">
{{ $t("dashboard.today_production_rate") }} ()
</h3>
<button
type="button"
class="btn btn-xs btn-success absolute top-0 right-0"
@click.stop="openModal"
>
{{ $t("button.edit") }}
</button>
</div>
<div className="my-3 w-full flex justify-center relative">
<ButtonConnectedGroup
:items="items"
:onclick="
(e, item) => {
changeActiveBtn(item);
}
"
/>
</div>
<template
v-if="progress_data && selectedBtn && progress_data[selectedBtn.key - 1]"
>
<div
class="grid grid-cols-6 gap-3 justify-items-end items-center"
v-for="{ pac, value, target, percentage } in progress_data[
selectedBtn.key - 1
].data"
:key="pac"
>
<span class="col-span-1 text-lg">{{ pac }}</span>
<progress
v-if="target !== 0"
class="progress progress-info col-span-4"
:value="value"
:max="target"
></progress>
<span class="col-span-1 text-lg justify-self-start"
>{{ percentage }} %</span
<!-- show_production_indicator 控制整個元件顯示 -->
<div v-if="visible">
<DashboardProductCompleteModal />
<div class="mb-3 relative">
<h3 class="text-info text-xl text-center">
{{ $t("dashboard.today_production_rate") }} ()
</h3>
<button
type="button"
class="btn btn-xs btn-success absolute top-0 right-0"
@click.stop="openModal"
>
{{ $t("button.edit") }}
</button>
</div>
</template>
<template v-else>
<p class="text-center mt-8 text-lg">尚未設定目標值</p>
</template>
<div className="my-3 w-full flex justify-center relative">
<ButtonConnectedGroup
:items="items"
:onclick="
(e, item) => {
changeActiveBtn(item);
}
"
/>
</div>
<template
v-if="progress_data && selectedBtn && progress_data[selectedBtn.key - 1]"
>
<div
class="grid grid-cols-6 gap-3 justify-items-end items-center"
v-for="{ pac, value, target, percentage } in progress_data[
selectedBtn.key - 1
].data"
:key="pac"
>
<span class="col-span-1 text-lg">{{ pac }}</span>
<progress
v-if="target !== 0"
class="progress progress-info col-span-4"
:value="value"
:max="target"
></progress>
<span class="col-span-1 text-lg justify-self-start"
>{{ percentage }} %</span
>
</div>
</template>
<template v-else>
<p class="text-center mt-8 text-lg">尚未設定目標值</p>
</template>
</div>
</template>
<style lang="css" scoped></style>

View File

@ -218,10 +218,11 @@ onUnmounted(() => {
{{ $t("dashboard.no_data") }}
</div>
<LineChart
id="dashboard_refrigeration"
v-if="!noData"
id="dashboard_other_real_temp"
class="min-h-[260px] max-h-fit"
:option="defaultChartOption"
ref="other_real_temp_chart"
ref="indoorChartRef"
/>
</template>