熱點出現 Infomodel
This commit is contained in:
parent
5e43d27e2c
commit
faa267ff75
@ -163,12 +163,9 @@ const initForge = async () => {
|
|||||||
viewer.isLoadDone()
|
viewer.isLoadDone()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (viewer.isLoadDone()) {
|
hideAllObjects();
|
||||||
// updateForgeViewer(viewer);
|
createSprites();
|
||||||
hideAllObjects();
|
forgeClickListener();
|
||||||
createSprites();
|
|
||||||
forgeClickListener();
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
};
|
};
|
||||||
|
70
src/hooks/forge/useForgeFloor.js
Normal file
70
src/hooks/forge/useForgeFloor.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
function useForgeFloor() {
|
||||||
|
const findLevels = (viewer) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
viewer.model.search(
|
||||||
|
"layer",
|
||||||
|
(nodeIds) => {
|
||||||
|
let levels = [];
|
||||||
|
const tree = viewer.model.getInstanceTree();
|
||||||
|
for (let i = 0; i < nodeIds.length; i++) {
|
||||||
|
const dbId = nodeIds[i];
|
||||||
|
const name = tree.getNodeName(dbId);
|
||||||
|
if (!name || name.includes("<沒有層級>")) continue;
|
||||||
|
levels.push({
|
||||||
|
guid: dbId,
|
||||||
|
name,
|
||||||
|
dbId,
|
||||||
|
extension: {
|
||||||
|
buildingStory: true,
|
||||||
|
structure: false,
|
||||||
|
computationHeight: 0,
|
||||||
|
groundPlane: false,
|
||||||
|
hasAssociatedViewPlans: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
levels = levels.sort((a, b) => b.elevation - a.elevation);
|
||||||
|
resolve(levels);
|
||||||
|
},
|
||||||
|
(e) => {
|
||||||
|
reject(e);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// function getCutPlaneParam(idx, n, viewer, levels) {
|
||||||
|
// if (idx < 0 || !n) return;
|
||||||
|
|
||||||
|
// const level = levels[idx];
|
||||||
|
// if (!level) return;
|
||||||
|
|
||||||
|
// const model = viewer.model;
|
||||||
|
// const globalOffset = model.getData().globalOffset;
|
||||||
|
// const units = model.getUnitString();
|
||||||
|
// const elevRaw = Autodesk.Viewing.Private.convertUnits(
|
||||||
|
// "ft",
|
||||||
|
// units,
|
||||||
|
// 1,
|
||||||
|
// level.elevation
|
||||||
|
// );
|
||||||
|
// let d = elevRaw - globalOffset.z - 0.5;
|
||||||
|
// if (n == 1) d = -1 * d;
|
||||||
|
|
||||||
|
// return new THREE.Vector4(0, 0, n, d);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// function profile(viewer, levels) {
|
||||||
|
// //const upperIdx = 6;
|
||||||
|
// const upperCutPlaneParam = getCutPlaneParam(2, 1, viewer, levels);
|
||||||
|
// //const lowerIdx = 7;
|
||||||
|
// const lowerCutPlaneParam = getCutPlaneParam(3, -1, viewer, levels);
|
||||||
|
// viewer.setCutPlanes([upperCutPlaneParam, lowerCutPlaneParam]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return { findLevels, profile };
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useForgeFloor;
|
@ -7,6 +7,9 @@ import useSelectedFloor from "@/hooks/useSelectedFloor";
|
|||||||
export default function useForgeSprite() {
|
export default function useForgeSprite() {
|
||||||
const store = useAlarmStore();
|
const store = useAlarmStore();
|
||||||
const { subscribeData } = inject("system_deviceList");
|
const { subscribeData } = inject("system_deviceList");
|
||||||
|
const { getCurrentInfoModalData, clearSelectedDeviceInfo } = inject(
|
||||||
|
"system_selectedDevice"
|
||||||
|
);
|
||||||
const forgeViewer = ref(null);
|
const forgeViewer = ref(null);
|
||||||
const dataVizExtn = ref(null);
|
const dataVizExtn = ref(null);
|
||||||
const updateDataVisualization = async (viewer) => {
|
const updateDataVisualization = async (viewer) => {
|
||||||
@ -20,12 +23,27 @@ export default function useForgeSprite() {
|
|||||||
dataVizExtn.value = markRaw(dataVisualization);
|
dataVizExtn.value = markRaw(dataVisualization);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSpriteClicked = (event) => {
|
function onSpriteClicked(event) {
|
||||||
event.hasStopped = true;
|
event.hasStopped = false;
|
||||||
console.log("onSpriteClicked", event);
|
|
||||||
// const data = deviceList.value.find((d) => d.spriteDbId === event.dbId);
|
if (event.type === Autodesk.DataVisualization.Core.MOUSE_CLICK_OUT) return;
|
||||||
|
|
||||||
|
const data = subscribeData.value.find(
|
||||||
|
(d) =>
|
||||||
|
d.spriteDbId === event.dbId || d.forge_dbid === event.dbIdArray?.[0]
|
||||||
|
);
|
||||||
|
console.log("onSpriteClicked", event.target);
|
||||||
|
console.log("onSpriteClicked", data);
|
||||||
// modalContent.value = data;
|
// modalContent.value = data;
|
||||||
};
|
debugger;
|
||||||
|
if (data) {
|
||||||
|
getCurrentInfoModalData(
|
||||||
|
event,
|
||||||
|
{ left: event.target.startX, top: event.target.startY },
|
||||||
|
data
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const { selectedFloor } = useSelectedFloor();
|
const { selectedFloor } = useSelectedFloor();
|
||||||
const showData = computed(() =>
|
const showData = computed(() =>
|
||||||
@ -90,12 +108,14 @@ export default function useForgeSprite() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const forgeClickListener = () => {
|
const forgeClickListener = () => {
|
||||||
|
console.log("監聽forge");
|
||||||
|
|
||||||
forgeViewer.value.addEventListener(
|
forgeViewer.value.addEventListener(
|
||||||
Autodesk.DataVisualization.Core.MOUSE_CLICK,
|
Autodesk.DataVisualization.Core.MOUSE_CLICK,
|
||||||
onSpriteClicked
|
onSpriteClicked
|
||||||
);
|
);
|
||||||
forgeViewer.value.addEventListener(
|
forgeViewer.value.addEventListener(
|
||||||
Autodesk.Viewing.SELECTION_CHANGED_EVENT,
|
Autodesk.DataVisualization.Core.MOUSE_CLICK_OUT,
|
||||||
onSpriteClicked
|
onSpriteClicked
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -35,6 +35,7 @@ const data = ref([]) // filter data
|
|||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
const getData = async () => {
|
const getData = async () => {
|
||||||
|
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_tag: buildingStore.selectedBuilding?.building_tag,
|
||||||
@ -167,7 +168,8 @@ const getCurrentInfoModalData = (e, position, value) => {
|
|||||||
const selectedDeviceRealtime = computed(() => realtimeData.value?.find(({ device_number }) => device_number === selectedDevice.value?.value?.device_number)?.data)
|
const selectedDeviceRealtime = computed(() => realtimeData.value?.find(({ device_number }) => device_number === selectedDevice.value?.value?.device_number)?.data)
|
||||||
|
|
||||||
const clearSelectedDeviceInfo = () => {
|
const clearSelectedDeviceInfo = () => {
|
||||||
selectedDevice.value.value = null
|
|
||||||
|
selectedDevice.value.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
provide("system_selectedDevice", { selectedDeviceRealtime, selectedDevice, getCurrentInfoModalData, clearSelectedDeviceInfo })
|
provide("system_selectedDevice", { selectedDeviceRealtime, selectedDevice, getCurrentInfoModalData, clearSelectedDeviceInfo })
|
||||||
@ -206,8 +208,10 @@ provide("system_selectedDevice", { selectedDeviceRealtime, selectedDevice, getCu
|
|||||||
<div class="col-span-1 h-full flex flex-col justify-between">
|
<div class="col-span-1 h-full flex flex-col justify-between">
|
||||||
<SystemMode />
|
<SystemMode />
|
||||||
<div class="min-h-[75vh] relative">
|
<div class="min-h-[75vh] relative">
|
||||||
<SystemFloor :class="twMerge('absolute h-full w-full', route.query.mode === '2D' ? 'opacity-100 z-10' : 'opacity-0 z-0')"/>
|
<SystemFloor
|
||||||
<div :class="twMerge('absolute h-full w-full', route.query.mode === '3D' ? 'opacity-100 z-10' : 'opacity-0 z-0')">
|
:class="twMerge('absolute h-full w-full', route.query.mode === '2D' ? 'opacity-100 z-10' : 'opacity-0 z-0')" />
|
||||||
|
<div
|
||||||
|
:class="twMerge('absolute h-full w-full', route.query.mode === '3D' ? 'opacity-100 z-10' : 'opacity-0 z-0')">
|
||||||
<ForgeForSystem :initialData="{}" />
|
<ForgeForSystem :initialData="{}" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -12,7 +12,17 @@ const { getCurrentInfoModalData } = inject("system_selectedDevice")
|
|||||||
const FILE_BASEURL = import.meta.env.VITE_FILE_API_BASEURL;
|
const FILE_BASEURL = import.meta.env.VITE_FILE_API_BASEURL;
|
||||||
|
|
||||||
const asset_floor_chart = ref(null);
|
const asset_floor_chart = ref(null);
|
||||||
const defaultOption = (map, data = []) => ({
|
const sameOption = {
|
||||||
|
type: "effectScatter",
|
||||||
|
coordinateSystem: "geo",
|
||||||
|
geoIndex: 0,
|
||||||
|
symbolSize: 10,
|
||||||
|
encode: {
|
||||||
|
tooltip: 2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const defaultOption = (map, data = []) => {
|
||||||
|
return {
|
||||||
tooltip: {},
|
tooltip: {},
|
||||||
geo: {
|
geo: {
|
||||||
tooltip: {
|
tooltip: {
|
||||||
@ -21,20 +31,24 @@ const defaultOption = (map, data = []) => ({
|
|||||||
map,
|
map,
|
||||||
roam: true, // 一定要关闭拖拽
|
roam: true, // 一定要关闭拖拽
|
||||||
},
|
},
|
||||||
series: {
|
series: [
|
||||||
type: "effectScatter",
|
{
|
||||||
coordinateSystem: "geo",
|
...sameOption,
|
||||||
geoIndex: 0,
|
itemStyle: {
|
||||||
symbolSize: 10,
|
color: data?.[0]?.[2]?.device_normal_color || "#b02a02",
|
||||||
itemStyle: {
|
},
|
||||||
color: "#b02a02",
|
data,
|
||||||
},
|
},
|
||||||
encode: {
|
// {
|
||||||
tooltip: 2,
|
// itemStyle: {
|
||||||
},
|
// color: "#555555",
|
||||||
data,
|
// },
|
||||||
},
|
// data: data?.[1],
|
||||||
});
|
// }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
const { selectedFloor } = useSelectedFloor()
|
const { selectedFloor } = useSelectedFloor()
|
||||||
|
|
||||||
@ -46,7 +60,7 @@ watch([selectedFloor, () => asset_floor_chart,], ([newValue, newChart], [oldValu
|
|||||||
path: `${FILE_BASEURL}/${newValue.map_url}`,
|
path: `${FILE_BASEURL}/${newValue.map_url}`,
|
||||||
},
|
},
|
||||||
|
|
||||||
defaultOption(newValue?.title, subscribeData.value.filter(d => d.device_coordinate && d.floor_guid === route.params.floor_id).map(d => [...d.device_coordinate.split(","), d]))
|
defaultOption(newValue?.title, subscribeData.value?.filter(d => d.device_coordinate && d.floor_guid === route.params.floor_id).map(d => [...d.device_coordinate.split(","), d]) || [])
|
||||||
);
|
);
|
||||||
newChart.value.chart.on("click", function (params) {
|
newChart.value.chart.on("click", function (params) {
|
||||||
console.log(params, params.data[2])
|
console.log(params, params.data[2])
|
||||||
|
@ -25,21 +25,22 @@ watch(selectedFloor, (newValue) => {
|
|||||||
<p class="title">{{ d.full_name }}</p>
|
<p class="title">{{ d.full_name }}</p>
|
||||||
<div class="grid grid-cols-3 gap-5">
|
<div class="grid grid-cols-3 gap-5">
|
||||||
<div class="col-auto relative" v-for="device in d.device_list" :key="device.device_guid">
|
<div class="col-auto relative" v-for="device in d.device_list" :key="device.device_guid">
|
||||||
<div class="item">
|
<div class="item h-36">
|
||||||
<div class="left w-4/5">
|
<div class="left w-4/5 h-full flex flex-wrap justify-center">
|
||||||
<div class="sec02">
|
<div class="sec02 w-full">
|
||||||
<img v-if="device.device_image_url" :src="device.device_image_url" alt="" class="w-8 h-8">
|
<img v-if="device.device_image_url" :src="device.device_image_url" alt="" class="w-8 h-8">
|
||||||
<span class="w-8 h-8" v-else></span>
|
<span class="w-8 h-8" v-else></span>
|
||||||
<span class="w-32 break-all">{{ device.full_name }}</span>
|
<span class="w-32 break-all">{{ device.full_name }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between w-full self-end">
|
||||||
<div class="sec03">
|
<div class="sec03">
|
||||||
<span></span>
|
<span class="w-5 h-5 rounded-full" :style="{ backgroundColor: device.device_normal_color }"></span>
|
||||||
<span>{{$t("system.status")}}:</span>
|
<span class="mx-2">{{ $t("system.status") }}:</span>
|
||||||
<span></span>
|
<span>{{ device.device_status }}</span>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn-text border-0 "
|
<button class="btn-text border-0 "
|
||||||
@click.stop.prevent="(e) => getCurrentInfoModalData(e, { left: e.clientX, top: e.clientY }, device)">{{$t("system.details")}}</button>
|
@click.stop.prevent="(e) => getCurrentInfoModalData(e, { left: e.clientX, top: e.clientY }, device)">{{
|
||||||
|
$t("system.details") }}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -129,11 +130,11 @@ watch(selectedFloor, (newValue) => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.equipment-show .item .sec03 span:nth-child(1) {
|
/* .equipment-show .item .sec03 span:nth-child(1) {
|
||||||
width: 15px;
|
width: 15px;
|
||||||
height: 15px;
|
height: 15px;
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
display: block;
|
display: block;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
} */
|
||||||
</style>
|
</style>
|
@ -14,7 +14,6 @@ const position = ref({
|
|||||||
watch(
|
watch(
|
||||||
data,
|
data,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
console.log(newValue.value)
|
|
||||||
if (!newValue.value) {
|
if (!newValue.value) {
|
||||||
position.value = {
|
position.value = {
|
||||||
display: "none"
|
display: "none"
|
||||||
|
@ -65,7 +65,7 @@ const onCancel = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body px-0">
|
<div class="card-body p-0">
|
||||||
<component :is="tabs[currentTab]"></component>
|
<component :is="tabs[currentTab]"></component>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -8,10 +8,10 @@ const { selectedDevice, selectedDeviceRealtime } = inject("system_selectedDevice
|
|||||||
|
|
||||||
const data = computed(() => {
|
const data = computed(() => {
|
||||||
|
|
||||||
return selectedDeviceRealtime?.value && selectedDevice.value?.value.points.map((d) => ({
|
return selectedDevice.value?.value?.points?.map((d) => ({
|
||||||
...d,
|
...d,
|
||||||
value: selectedDeviceRealtime?.value?.find(({ point }) => point === d.points)?.value || "無資料"
|
value: selectedDeviceRealtime?.value?.find(({ point }) => point === d.points)?.value || "無資料"
|
||||||
}))
|
})) || []
|
||||||
})
|
})
|
||||||
|
|
||||||
const columns = [{
|
const columns = [{
|
||||||
|
Loading…
Reference in New Issue
Block a user