diff --git a/src/apis/system/api.js b/src/apis/system/api.js index f2e5715..a57d55f 100644 --- a/src/apis/system/api.js +++ b/src/apis/system/api.js @@ -1,2 +1,3 @@ export const GET_SYSTEM_FLOOR_LIST_API = `/api/Device/GetFloor`; -export const GET_SYSTEM_DEVICE_LIST_API = `/api/Device/GetDeviceList`; \ No newline at end of file +export const GET_SYSTEM_DEVICE_LIST_API = `/api/Device/GetDeviceList`; +export const GET_SYSTEM_REALTIME_API = `/api/Device/GetRealTimeData`; \ No newline at end of file diff --git a/src/apis/system/index.js b/src/apis/system/index.js index 4054f3f..4810014 100644 --- a/src/apis/system/index.js +++ b/src/apis/system/index.js @@ -1,4 +1,8 @@ -import { GET_SYSTEM_FLOOR_LIST_API, GET_SYSTEM_DEVICE_LIST_API } from "./api"; +import { + GET_SYSTEM_FLOOR_LIST_API, + GET_SYSTEM_DEVICE_LIST_API, + GET_SYSTEM_REALTIME_API, +} from "./api"; import instance from "@/util/request"; import apihandler from "@/util/apihandler"; @@ -30,3 +34,11 @@ export const getSystemDevices = async ({ code: res.code, }); }; + +export const getSystemRealTime = async (device_list) => { + const res = await instance.post(GET_SYSTEM_REALTIME_API, { device_list }); + return apihandler(res.code, res.data, { + msg: res.msg, + code: res.code, + }); +}; diff --git a/src/components/forge/ForgeForSystem.vue b/src/components/forge/ForgeForSystem.vue index 4e8d7ce..fc539a0 100644 --- a/src/components/forge/ForgeForSystem.vue +++ b/src/components/forge/ForgeForSystem.vue @@ -13,7 +13,7 @@ import { twMerge } from "tailwind-merge"; import hexToRgb from "@/util/hexToRgb"; import getModalPosition from "@/util/getModalPosition"; import useSystemStatusByBaja from "@/hooks/baja/useSystemStatusByBaja"; -import ForgeInfoModal from "./ForgeInfoModal.vue"; +import ForgeInfoModal from "../../views/system/components/SystemInfoModal.vue"; import useAlarmStore from "@/stores/useAlarmStore"; import useForgeSprite from "@/hooks/forge/useForgeSprite"; @@ -64,6 +64,10 @@ const initViewer = (container) => { let viewer = new Autodesk.Viewing.GuiViewer3D(container, config); Autodesk.Viewing.Private.InitParametersSetting.alpha = true; viewer.start(); + viewer.setGroundShadow(false); + viewer.impl.renderer().setClearAlpha(0); + viewer.impl.glrenderer().setClearColor(0xffffff, 0); + viewer.impl.invalidate(true); resolve(viewer); } ); @@ -79,6 +83,7 @@ const loadModel = (viewer, filePath) => { (model) => { viewer.impl.invalidate(true); viewer.fitToView(); + updateDataVisualization(viewer) resolve(model); console.log("模型加載完成"); }, @@ -147,10 +152,21 @@ const initForge = async () => { // }); // }); // }); - const FILE_BASEURL = import.meta.env.VITE_FILE_API_BASEURL; + const FILE_BASEURL = import.meta.env.VITE_FILE_API_BASEURL; const viewer = await initViewer(forgeDom.value) const filePath = `${FILE_BASEURL}/upload/forge/0.svf`; await loadModel(viewer, filePath) + viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, + async function () { + console.log( + "Autodesk.Viewing.GEOMETRY_LOADED_EVENT", + viewer.isLoadDone() + ); + // updateForgeViewer(viewer); + createSprites() + hideAllObjects(); + }) + }; onMounted(() => { diff --git a/src/components/forge/ForgeInfoModal.vue b/src/components/forge/ForgeInfoModal.vue deleted file mode 100644 index 68e0cee..0000000 --- a/src/components/forge/ForgeInfoModal.vue +++ /dev/null @@ -1,118 +0,0 @@ - - - - - diff --git a/src/components/forge/ForgeInfoModalDesktop.vue b/src/components/forge/ForgeInfoModalDesktop.vue deleted file mode 100644 index e706405..0000000 --- a/src/components/forge/ForgeInfoModalDesktop.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - - - diff --git a/src/hooks/forge/useForgeHeatmap.js b/src/hooks/forge/useForgeHeatmap.js index e31c3c2..d540dfb 100644 --- a/src/hooks/forge/useForgeHeatmap.js +++ b/src/hooks/forge/useForgeHeatmap.js @@ -1,4 +1,7 @@ -export default function useForgeHeatmap(){ +import { watch, inject, markRaw, ref } from "vue"; + +export default function useForgeHeatmap(dataVizExtn, forgeViewer){ + const { subscribeData } = inject("system_deviceList"); const createHeatMap = async (heatMapName) => { const { @@ -10,7 +13,7 @@ export default function useForgeHeatmap(){ const shadingGroup = new SurfaceShadingGroup(`iot_heatmap_${heatMapName}`); const rooms = new Map(); - for (const { id, roomDbId, position, sensorTypes } of deviceList.value) { + for (const { id, roomDbId, position, sensorTypes } of subscribeData.value) { if (!id || roomDbId == -1 || !roomDbId) { continue; } @@ -28,20 +31,19 @@ export default function useForgeHeatmap(){ shadingData.addChild(shadingGroup); shadingData.initialize(forgeViewer.value?.model); - await dataVizExtension.value.setupSurfaceShading( + await dataVizExtn.value.setupSurfaceShading( forgeViewer.value.model, shadingData ); - dataVizExtension.value.registerSurfaceShadingColors( - "temperature", + dataVizExtn.value.registerSurfaceShadingColors( + heatMapName, [0x0000ff, 0x00ff00, 0xffff00, 0xff0000] ); - dataVizExtension.value.renderSurfaceShading( + dataVizExtn.value.renderSurfaceShading( `iot_heatmap_${heatMapName}`, - "temperature", + heatMapName, getSensorValue ); - console.log(dataVizExtension.value); }; } \ No newline at end of file diff --git a/src/hooks/forge/useForgeSprite.js b/src/hooks/forge/useForgeSprite.js index e764aea..a75784e 100644 --- a/src/hooks/forge/useForgeSprite.js +++ b/src/hooks/forge/useForgeSprite.js @@ -40,20 +40,22 @@ export default function useForgeSprite() { const viewableData = new DataVizCore.ViewableData(); viewableData.spriteSize = 24; // Sprites as points of size 24 x 24 pixels subscribeData.value?.forEach((d, index) => { - const position = d.device_coordinate_3d; - style.color = new THREE.Color(hexToRgb(d.device_normal_color)); - const viewable = new DataVizCore.SpriteViewable( - position, - style, - d.spriteDbId - ); - viewableData.addViewable(viewable); + if (d.device_coordinate_3d) { + const position = d.device_coordinate_3d; + style.color = new THREE.Color(hexToRgb(d.device_normal_color)); + const viewable = new DataVizCore.SpriteViewable( + position, + style, + d.spriteDbId + ); + viewableData.addViewable(viewable); + } }); await viewableData.finish(); dataVizExtn.value.addViewables(viewableData); - NOP_VIEWER.addEventListener(DataVizCore.MOUSE_CLICK, onSpriteClicked); - NOP_VIEWER.addEventListener( + forgeViewer.value.addEventListener(DataVizCore.MOUSE_CLICK, onSpriteClicked); + forgeViewer.value.addEventListener( Autodesk.Viewing.SELECTION_CHANGED_EVENT, onSpriteClicked ); @@ -80,17 +82,17 @@ export default function useForgeSprite() { }; const hideAllObjects = () => { - const tree = NOP_VIEWER.model?.getData().instanceTree; + const tree = forgeViewer.value.model.getInstanceTree(); const allDbIdsStr = Object.keys(tree.nodeAccess.dbIdToIndex); for (var i = 0; i < allDbIdsStr.length; i++) { - NOP_VIEWER.hide(parseInt(allDbIdsStr[i])); + forgeViewer.value.hide(parseInt(allDbIdsStr[i])); } subscribeData.value.forEach((value, index) => { - NOP_VIEWER.show(value.forge_dbid); + forgeViewer.value.show(value.forge_dbid); }); - NOP_VIEWER.impl.invalidate(true); + forgeViewer.value.impl.invalidate(true); }; return { diff --git a/src/views/system/System.vue b/src/views/system/System.vue index 56f617b..addf5fc 100644 --- a/src/views/system/System.vue +++ b/src/views/system/System.vue @@ -6,6 +6,7 @@ import useBuildingStore from "@/stores/useBuildingStore"; import ForgeForSystem from "@/components/forge/ForgeForSystem.vue"; import { getSystemDevices } from "@/apis/system"; import SystemSubBar from './components/SystemSubBar.vue'; +import SystemInfoModal from './components/SystemInfoModal.vue'; const buildingStore = useBuildingStore() @@ -26,7 +27,7 @@ const statusList = computed(() => { }) const raw_data = ref([]) -const data = ref([]) +const data = ref([]) // filter data const route = useRoute() const getData = async () => { @@ -34,12 +35,26 @@ const getData = async () => { sub_system_tag: route.params.sub_system_id, building_tag: buildingStore.selectedBuilding?.building_tag, }) - const data = res.data.map(d => ({ ...d, key: d.full_name })); + const data = res.data.map(d => ({ + ...d, key: d.full_name, device_list: d.device_list.map((d, index) => ({ + ...d, + forge_dbid: parseInt(d.forge_dbid), + device_coordinate_3d: d.device_coordinate_3d + ? JSON.parse(d.device_coordinate_3d) + : { x: 0, y: 0 }, + alarmMsg: "", + is_show: true, + currentColor: d.device_normal_point_color, + spriteDbId: 10 + index, + sensorTypes: d.points.map(({ points }) => points), + points: d.points.map((p) => ({ ...p, value: "" })) + })), + })); raw_data.value = data data.value = data } -const subscribeData = ref([]); +const subscribeData = ref([]); // flat data const getSubPoint = (normal, close, error, sub_points) => { let points = { @@ -56,23 +71,7 @@ const getSubData = (value) => { value.forEach((device) => { items = [ ...items, - ...device.device_list.map((d, index) => ({ - ...d, - forge_dbid: parseInt(d.forge_dbid), - device_coordinate_3d: d.device_coordinate_3d - ? JSON.parse(d.device_coordinate_3d) - : { x: 0, y: 0 }, - // points: getSubPoint( - // d.device_normal_point_name, - // d.device_close_point_name, - // d.device_error_point_name, - // d.points - // ), - alarmMsg: "", - is_show: true, - currentColor: d.device_normal_point_color, - spriteDbId: 10 + index, - })), + ...device.device_list ]; }); data.value = raw_data.value; @@ -83,6 +82,10 @@ watch(raw_data, (newValue) => { updateDataByGas("all") }); +watch(data, (newValue) => { + console.log(newValue); +}) + const updateDataByGas = (gas) => { console.log(gas) if (gas === "all") { @@ -112,12 +115,40 @@ const updateCurrentFloor = (floor) => { provide("system_deviceList", { data, subscribeData, currentFloor, updateCurrentFloor, updateDataByGas }) + +// 傳遞目前點擊資訊 +const currentInfoModalData = ref(null); +const isMobile = (pointerType) => { + // let flag = + // /phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone/gi.test( + // navigator.userAgent + // ); + // console.log("isMobile", flag); + return pointerType !== "mouse"; // is desktop +}; +const getCurrentInfoModalData = (e, position, value) => { + const mobile = isMobile(e.pointerType); + selectedDevice.value = { + initPos: mobile + ? { left: `50%`, top: `50%` } + : { left: `${position.left}px`, top: `${position.top}px` }, + value, + isMobile: mobile, + };; + document.getElementById('system_info_modal').showModal(); +}; + +const selectedDevice = ref(null); + +provide("system_selectedDevice", { selectedDevice, getCurrentInfoModalData }) + \ No newline at end of file diff --git a/src/views/system/SystemFloor.vue b/src/views/system/SystemFloor.vue index e84b1a0..b641a81 100644 --- a/src/views/system/SystemFloor.vue +++ b/src/views/system/SystemFloor.vue @@ -38,7 +38,7 @@ watch([() => currentFloor, () => asset_floor_chart], ([newValue, newChart]) => { asset_floor_chart.value.updateSvg( { full_name: newValue.value?.title, - path: `${FILE_BASEURL}/upload/floor_map/${newValue.value.map_url}`, + path: `${FILE_BASEURL}/${newValue.value.map_url}`, }, defaultOption(newValue.value?.title, subscribeData.value.filter(d => d.device_coordinate).map(d => JSON.parse(d.device_coordinate))) diff --git a/src/views/system/components/SystemCard.vue b/src/views/system/components/SystemCard.vue index bd5c1aa..1ee8ac5 100644 --- a/src/views/system/components/SystemCard.vue +++ b/src/views/system/components/SystemCard.vue @@ -4,6 +4,7 @@ import { inject } from "vue" const { data } = inject("system_deviceList") +const { getCurrentInfoModalData } = inject("system_selectedDevice") @@ -23,10 +24,14 @@ const { data } = inject("system_deviceList") {{ device.full_name }} -
- - 狀態: - +
+
+ + 狀態: + +
+
@@ -52,6 +57,10 @@ const { data } = inject("system_deviceList") } +.item .btn-text { + @apply hover:bg-transparent focus-within:bg-transparent !important; +} + .equipment-show .item .sec01 span:nth-child(1) { font-size: 1rem; position: relative; diff --git a/src/views/system/components/SystemFloorBar.vue b/src/views/system/components/SystemFloorBar.vue index c5f2f2b..ea541e5 100644 --- a/src/views/system/components/SystemFloorBar.vue +++ b/src/views/system/components/SystemFloorBar.vue @@ -1,6 +1,6 @@ + + + + diff --git a/src/components/forge/ForgeInfoModalCog.vue b/src/views/system/components/SystemInfoModalCog.vue similarity index 100% rename from src/components/forge/ForgeInfoModalCog.vue rename to src/views/system/components/SystemInfoModalCog.vue diff --git a/src/views/system/components/SystemInfoModalContent.vue b/src/views/system/components/SystemInfoModalContent.vue new file mode 100644 index 0000000..89d289d --- /dev/null +++ b/src/views/system/components/SystemInfoModalContent.vue @@ -0,0 +1,73 @@ + + + + + \ No newline at end of file diff --git a/src/views/system/components/SystemInfoModalDesktop.vue b/src/views/system/components/SystemInfoModalDesktop.vue new file mode 100644 index 0000000..0687be5 --- /dev/null +++ b/src/views/system/components/SystemInfoModalDesktop.vue @@ -0,0 +1,22 @@ + + + + + diff --git a/src/views/system/components/SystemSubBar.vue b/src/views/system/components/SystemSubBar.vue index 4471ef5..76c890f 100644 --- a/src/views/system/components/SystemSubBar.vue +++ b/src/views/system/components/SystemSubBar.vue @@ -11,10 +11,11 @@ watch(() => buildingStore, (newValue) => { newValue.selectedSystem?.points?.length > 0 && setItems(newValue.selectedSystem.points.map(d => ({ title: d.full_name, key: d.points, - active: false, + active: d.points === "Temp", }))) }, { deep: true, + immediate: true }) const onClick = (item) => { @@ -25,9 +26,8 @@ const onClick = (item) => {