Merge branch 'feature/system'

This commit is contained in:
WIN-VB61HI6M32L\Administrator 2024-10-23 17:07:27 +08:00
commit 364ac7b730
9 changed files with 163 additions and 45 deletions

View File

@ -33,7 +33,7 @@ const updateHeatBarIsShow = (isShow) => {
heat_bar_isShow.value = isShow;
};
const { updateDataVisualization, createSprites, hideAllObjects, forgeClickListener } = useForgeSprite()
const { updateDataVisualization, createSprites, hideAllObjects, forgeClickListener, clear } = useForgeSprite()
const forgeDom = ref(null);
@ -163,12 +163,9 @@ const initForge = async () => {
viewer.isLoadDone()
);
if (viewer.isLoadDone()) {
// updateForgeViewer(viewer);
hideAllObjects();
createSprites();
forgeClickListener();
}
hideAllObjects();
createSprites();
forgeClickListener();
})
};
@ -197,7 +194,7 @@ const getCurrentInfoModalData = (e, position, value) => {
onUnmounted(() => {
console.log("Forge 銷毀");
NOP_VIEWER.tearDown();
clear();
});
</script>

View 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;

View File

@ -7,6 +7,9 @@ import useSelectedFloor from "@/hooks/useSelectedFloor";
export default function useForgeSprite() {
const store = useAlarmStore();
const { subscribeData } = inject("system_deviceList");
const { getCurrentInfoModalData, clearSelectedDeviceInfo } = inject(
"system_selectedDevice"
);
const forgeViewer = ref(null);
const dataVizExtn = ref(null);
const updateDataVisualization = async (viewer) => {
@ -20,12 +23,27 @@ export default function useForgeSprite() {
dataVizExtn.value = markRaw(dataVisualization);
};
const onSpriteClicked = (event) => {
function onSpriteClicked(event) {
event.hasStopped = true;
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;
};
debugger;
if (data) {
getCurrentInfoModalData(
event,
{ left: event.target.startX, top: event.target.startY },
data
);
}
}
const { selectedFloor } = useSelectedFloor();
const showData = computed(() =>
@ -90,12 +108,14 @@ export default function useForgeSprite() {
);
const forgeClickListener = () => {
console.log("監聽forge");
forgeViewer.value.addEventListener(
Autodesk.DataVisualization.Core.MOUSE_CLICK,
onSpriteClicked
);
forgeViewer.value.addEventListener(
Autodesk.Viewing.SELECTION_CHANGED_EVENT,
Autodesk.DataVisualization.Core.MOUSE_CLICK_OUT,
onSpriteClicked
);
};
@ -134,10 +154,23 @@ export default function useForgeSprite() {
forgeViewer.value.impl.invalidate(true);
};
const clear = () => {
forgeViewer.value.removeEventListener(
Autodesk.DataVisualization.Core.MOUSE_CLICK,
onSpriteClicked
);
forgeViewer.value.removeEventListener(
Autodesk.DataVisualization.Core.MOUSE_CLICK_OUT,
onSpriteClicked
);
forgeViewer.value.tearDown();
};
return {
createSprites,
updateDataVisualization,
hideAllObjects,
forgeClickListener,
clear
};
}

View File

@ -35,6 +35,7 @@ const data = ref([]) // filter data
const route = useRoute()
const getData = async () => {
if (!route.params.sub_system_id) return
const res = await getSystemDevices({
sub_system_tag: route.params.sub_system_id,
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 clearSelectedDeviceInfo = () => {
selectedDevice.value.value = null
selectedDevice.value.value = null;
}
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">
<SystemMode />
<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')"/>
<div :class="twMerge('absolute h-full w-full', route.query.mode === '3D' ? 'opacity-100 z-10' : 'opacity-0 z-0')">
<SystemFloor
: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="{}" />
</div>
</div>

View File

@ -12,7 +12,17 @@ const { getCurrentInfoModalData } = inject("system_selectedDevice")
const FILE_BASEURL = import.meta.env.VITE_FILE_API_BASEURL;
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: {},
geo: {
tooltip: {
@ -21,20 +31,24 @@ const defaultOption = (map, data = []) => ({
map,
roam: true, //
},
series: {
type: "effectScatter",
coordinateSystem: "geo",
geoIndex: 0,
symbolSize: 10,
itemStyle: {
color: "#b02a02",
series: [
{
...sameOption,
itemStyle: {
color: data?.[0]?.[2]?.device_normal_color || "#b02a02",
},
data,
},
encode: {
tooltip: 2,
},
data,
},
});
// {
// itemStyle: {
// color: "#555555",
// },
// data: data?.[1],
// }
],
}
};
const { selectedFloor } = useSelectedFloor()
@ -46,7 +60,7 @@ watch([selectedFloor, () => asset_floor_chart,], ([newValue, newChart], [oldValu
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) {
console.log(params, params.data[2])

View File

@ -25,21 +25,22 @@ watch(selectedFloor, (newValue) => {
<p class="title">{{ d.full_name }}</p>
<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="item">
<div class="left w-4/5">
<div class="sec02">
<div class="item h-36">
<div class="left w-4/5 h-full flex flex-wrap justify-center">
<div class="sec02 w-full">
<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-32 break-all">{{ device.full_name }}</span>
</div>
<div class="flex justify-between">
<div class="flex justify-between w-full self-end">
<div class="sec03">
<span></span>
<span>{{$t("system.status")}}</span>
<span></span>
<span class="w-5 h-5 rounded-full" :style="{ backgroundColor: device.device_normal_color }"></span>
<span class="mx-2">{{ $t("system.status") }}</span>
<span>{{ device.device_status }}</span>
</div>
<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>
@ -129,11 +130,11 @@ watch(selectedFloor, (newValue) => {
align-items: center;
}
.equipment-show .item .sec03 span:nth-child(1) {
/* .equipment-show .item .sec03 span:nth-child(1) {
width: 15px;
height: 15px;
border-radius: 100%;
display: block;
margin-right: 10px;
}
} */
</style>

View File

@ -14,7 +14,6 @@ const position = ref({
watch(
data,
(newValue) => {
console.log(newValue.value)
if (!newValue.value) {
position.value = {
display: "none"

View File

@ -65,7 +65,7 @@ const onCancel = () => {
</Button>
</div>
</div>
<div class="card-body px-0">
<div class="card-body p-0">
<component :is="tabs[currentTab]"></component>
</div>
</div>

View File

@ -8,10 +8,10 @@ const { selectedDevice, selectedDeviceRealtime } = inject("system_selectedDevice
const data = computed(() => {
return selectedDeviceRealtime?.value && selectedDevice.value?.value.points.map((d) => ({
return selectedDevice.value?.value?.points?.map((d) => ({
...d,
value: selectedDeviceRealtime?.value?.find(({ point }) => point === d.points)?.value || "無資料"
}))
})) || []
})
const columns = [{