Files
tunnel-cloud-web/src/components/content/tunnelScene/PreviewScene.vue

445 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div id="scene">
<div id="cvs" ref="content"></div>
<dev-info ref="info" :devInfo="devInfo" />
<pre-dialog ref="edit" @addEquipment="handleAddEqu" @removeEquipment="handleRemoveEqu" @cancel="handleCancel"
:hasDev="hasDevice" :pointNum="pointNum" :pointGap="pointGap" :equipmentType="equipmentType"
:equipmentName="equipmentName" :equipmentValue="equipmentValue" />
<el-dialog v-model="centerDialogVisible" width="30%" destroy-on-close center :show-close="false" style="
margin: 20% auto;
width: 569px;
height: 330px;
background: rgba(7, 35, 72, 0.79);
border-radius: 20px;
border: 2px solid #0f82af;
">
<p id="remove-title">是否确定删除该设备</p>
<div class="btn">
<button @click="centerDialogVisible = false">取消</button>
<button @click="handleConfirmAddEqu">确定</button>
</div>
</el-dialog>
</div>
</template>
<script setup>
import * as three from "three";
import ThreeDScene from "./sceneClass/demo.js";
import DevInfo from "./displayInfoComp/DevInfo.vue";
import PreDialog from "./preEquComp/preDialog.vue"
// 导入模模型加载器
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
// import { DRACOLoader } from "three/examples/jsm/loaders/dracoloader";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import * as TWEEN from "three/examples/jsm/libs/tween.module";
import {
CSS3DRenderer,
CSS3DObject,
CSS3DSprite,
} from "three/addons/renderers/CSS3DRenderer.js";
// 引入CSS2渲染器CSS2DRenderer和CSS2模型对象CSS2DObject
import {
CSS2DRenderer,
CSS2DObject,
} from "three/addons/renderers/CSS2DRenderer.js";
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader";
import { onMounted, reactive, ref, toRaw, getCurrentInstance } from "vue";
import { ElMessage } from "element-plus";
import { editTunnel, getTunnelDetail } from "@/api/tunnelManage";
import { useModelSceneStore } from "@/store/modelSceneStore";
// 获取html标签跟随组件dom
const content = ref(null);
const info = ref(null);
const edit = ref(null);
let modelList = ref(null);
let demo; //定义demo全局变量
// const loader = new OBJLoader();
const form = ref({
tunnelName: "",
serialNumber: "",
totalLength: "",
referenceFrequency: '',
upTime: '',
upFrequency: '',
dropTime: '',
dropFrequency: '',
isDefault: false,
remarks: "",
});
const loader = new OBJLoader();
let hdrLoader = new RGBELoader();
let backColorSet = three.sRGBEncoding;
const modelStore = useModelSceneStore();
const params = defineProps(["isedit", "tunnelId", "tunnelLen", "largeScreen"]); //接收参数看是不是编辑模式,如果是编辑模式,则需要做一些处理
let isedit = ref(params.isedit)
let fanData;
let tunnelAlias = reactive('')
watch(
() => params.largeScreen,
(now) => {
console.log(params.largeScreen);
params.largeScreen = now;
fanData = (toRaw(params.largeScreen.value)).frequencyChangerList;
console.log(fanData);
},
{ deep: true }
);
const getTunnel = () => {
if (params.tunnelId !== 0) {
getTunnelDetail(params.tunnelId).then((res) => {
if (res?.code === 1000) {
form.value = res.data;
console.log(form.value.tunnelAlias);
tunnelAlias = form.value.tunnelAlias
}
});
}
};
getTunnel();
// const form = ref({
// tunnelName: "",
// serialNumber: "",
// totalLength: "",
// isDefault: false,
// remarks: "",
// });
// const getTunnelPreview = () => {
// getTunnelDetail(params.tunnelId).then((res) => {
// if (res?.code === 1000) {
// form.value = res.data;
// }
// });
// };
let pointGap = reactive(params.tunnelLen.value);
watch(
() => params.tunnelLen,
(now) => {
params.tunnelLen = now;
// console.log(params.tunnelLen);
pointGap = params.tunnelLen.value / 20;
},
{ deep: true }
);
watch(
() => params.tunnelId,
(now) => {
params.tunnelId = now
console.log(params.tunnelId);
// getTunnelPreview();
// console.log(form.value);
},
{ deep: true }
)
onMounted(handleMounted);
// 挂载后回调
async function handleMounted() {
const doms = [info.value.$el, edit.value.$el];
demo = new ThreeDScene(three, content.value);
//看是不是预览模式,然后继续相关的操作(会在demo中的初始化中进行)
demo.isedit = params.isedit;
let tunnelasync = await demo.loadModel(GLTFLoader, "./assets/tunnelModel/chanel-have-wall.gltf");
demo.addOrbitControls(OrbitControls);
demo.addTween(TWEEN);
demo.addCSS3Renderer(CSS3DRenderer, CSS3DSprite, doms);
demo.setDistance(10);
lClickCallback(demo); //绑定左键回调
rClickCallback(demo); //绑定右键回调
//加载HDR背景图片
demo.loadBackground(hdrLoader, backColorSet);
//先不加试试???
// watch(
// () => params.tunnelId,
// async () => {
// const text = await initData(params.tunnelId);
// }
// );
// 初始化设备模型
try {
//在这加载隧道
const map = new Map();
map.set("equ_fan", await loadModel("/devicesModel/model2.obj"));
map.set("equ_sensors", await loadModel("/devicesModel/sensors.obj"));
// 给对象初加载设备模型
demo.initDevicesModel(map);
// const equipmentList = await store.getEquipmentList();
modelList.value = await modelStore.initModelDataPreview(params.tunnelId);
// console.log(modelList.value);
// console.log("init", params.tunnelId);
demo.previewtunnelModeInit(toRaw(modelList.value), fanData);
demo.SignsInf(tunnelAlias, String(params.tunnelLen.value))
// watch(
// () => params.tunnelId,
// (now) => {
// params.tunnelId = now
// // console.log(params.tunnelId);
// checkTunnelInit(modelList.value)
// demo.previewtunnelModeInit(modelList.value);
// },
// { deep: true }
// )
// demo.previewtunnelModeInit(equipmentList);
// previewEquInfProcess(modelList.value, targetP.value)
} catch (err) {
if (err == undefined) {
return
} else {
console.log(err);
ElMessage({
message: "场景初始化异常---",
type: "warning",
});
}
}
}
// function checkTunnelInit(equipmentList) {
// equipmentList.forEach((item) => {
// let equipment = toRaw(item)
// console.log("我要清理掉之前的设备!!!");
// console.log(equipment);
// console.log(demo.scene.getObjectByName(equipment.position));
// demo.removeEquipment(demo.scene.getObjectByName(equipment.position));
// });
// }
// 每个模型加载回调
function loadModel(path) {
return new Promise((resolve, reject) => {
loader.load(
path,
(obj) => {
resolve(obj);
},
(xhr) => { },
(err) => {
reject(err);
}
);
});
}
let hasDevice = ref(true);
let devInfo = reactive({
meshId: null,
name: "无",
state: "无",
position: "无",
});
// 对象建构赋值功能
function editDevInfo(
value = {
meshId: null,
name: "无",
state: "无",
position: "无",
}
) {
devInfo.meshId = value.meshId;
devInfo.name = value.name;
devInfo.state = value.state;
devInfo.position = value.position;
}
//左键/双击左键回调函数
function lClickCallback(demo) {
//demo动态添加函数为操作组件内部
function displayDevInfo(targetPoint = null) {
hasDevice.value = targetPoint.hasDevice;
if (!targetPoint.info) {
editDevInfo();
return;
}
editDevInfo(targetPoint.info);
}
// 传给内部使用
demo.addFunction("displayDevInfo", displayDevInfo);
}
let pointNum = ref(0);
let targetP = ref({});
// 右键点击附着点后调函数
function rClickCallback(demo) {
function editDev(targetPoint = null) {
hasDevice.value = targetPoint.hasDevice;
targetP.value = targetPoint;
//这里是初始化必经之路!!!
const equipmentList = modelStore.initModelDataPreview(params.tunnelId)
equipmentList.then((result) => {
previewEquInfProcess(result, targetP.value)
})
pointNum.value = Number(
targetPoint.name.substring(
targetPoint.name.indexOf("_") + 1,
targetPoint.name.lastIndexOf("_")
) - 1
);
if (!targetPoint.info) return;
editDevInfo(targetPoint.info);
}
demo.addFunction("editDev", editDev);
}
// 添加设备
function handleAddEqu(formInfo) {
demo.addEquipment(targetP.value, formInfo);
// //将墙壁设置为可以穿透点击
// for (let line = 1; line <= 20; line++) {
// if (line < 10) {
// let wall = 'wall_' + '0' + line
// this.scene.getObjectByName(wall).layers.set(0)
// } else if (line >= 10) {
// let wall = 'wall_' + line
// this.scene.getObjectByName(wall).layers.set(0)
// }
// }
}
const centerDialogVisible = ref(false);
// 删除设备
function handleRemoveEqu() {
if (!targetP.hasDevice) {
ElMessage({
message: "该点位不存在设备!",
type: "warning",
});
return;
}
centerDialogVisible.value = true;
}
// 对话框确认删除
function handleConfirmAddEqu() {
console.log("target:", targetP.value.info);
modelStore
.deleteEquipment(targetP.value.info.equipmentId, pointGap)
.then((res) => {
demo.removeEquipment(targetP.value);
centerDialogVisible.value = false;
ElMessage({
message: "删除成功!",
type: "success",
});
})
.catch((res) => {
ElMessage({
message: "删除失败!",
type: "warning",
});
});
}
// 处理取消关闭编辑框事件
function handleCancel() {
if (!demo) return;
// 关闭标签
demo.isControlOrbit(true);
demo._resetState();
demo.clearTagsObj();
}
let equipmentType = ref(0)
let equipmentName = ref(0)
let equipmentValue = ref(0)
function previewEquInfProcess(equipmentList, targetP) {
for (const equipment of equipmentList) {
if (equipment.position == targetP.name) {
equipmentType.value = equipment.equipmentType
//需要将获取到的设备列表进行序列化
equipmentName.value = equipment.equipmentName
equipmentValue.value = equipment.threshold
if (equipmentType.value == 'frequency') {
equipmentType.value = '风机'
}
if (equipmentType.value == 'windPressure') {
equipmentType.value = '风压传感器'
}
if (equipmentType.value == 'sensor') {
equipmentType.value = '其他传感器'
}
// console.log(equipmentType.value);
// console.log(equipmentName.value);
// console.log(equipmentValue.value);
}
}
}
</script>
<style lang="scss" scoped>
#scene {
position: relative;
height: 100%;
width: 100%;
#cvs {
height: 100%;
}
}
#remove-title {
height: 42px;
font-size: 32px;
font-family: MicrosoftYaHei, MicrosoftYaHei;
font-weight: bold;
color: #08b7b8;
line-height: 42px;
letter-spacing: 3px;
text-align: center;
margin: 65px 0px 70px 0px;
}
.btn {
display: flex;
justify-content: center;
gap: 80px;
:nth-child(1) {
width: 190px;
height: 60px;
border-radius: 11px;
border: 2px solid #0f82af;
font-size: 28px;
font-family: MicrosoftYaHei;
color: #08b7b8;
line-height: 37px;
background: transparent;
}
:nth-child(2) {
width: 190px;
height: 60px;
background: #08b7b8;
border-radius: 11px;
font-size: 28px;
font-family: MicrosoftYaHei, MicrosoftYaHei;
font-weight: bold;
color: #ffffff;
line-height: 37px;
}
}
</style>