Files
tunnel-cloud-web/src/components/content/tunnelScene/PreviewScene.vue
2023-12-22 13:56:41 +08:00

336 lines
9.5 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="500" :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 } from "vue";
import { ElMessage } from "element-plus";
// 获取html标签跟随组件dom
const content = ref(null);
const info = ref(null);
const edit = ref(null);
let demo; //定义demo全局变量
// const loader = new OBJLoader();
const loader = new OBJLoader();
let hdrLoader = new RGBELoader();
let backColorSet = three.sRGBEncoding;
const params = defineProps(["isedit"]); //接收参数看是不是编辑模式,如果是编辑模式,则需要做一些处理
// alert(params.isedit)
let isedit = ref(params.isedit)
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.gltf");
demo.addOrbitControls(OrbitControls);
demo.addTween(TWEEN);
demo.addCSS3Renderer(CSS3DRenderer, CSS3DSprite, doms);
demo.setDistance(10);
lClickCallback(demo); //绑定左键回调
rClickCallback(demo); //绑定右键回调
//加载HDR背景图片
demo.loadBackground(hdrLoader, backColorSet);
// 初始化设备模型
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);
demo.previewtunnelModeInit();
} catch (err) {
console.log(err);
}
}
// 每个模型加载回调
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;
// 右键点击附着点后调函数
function rClickCallback(demo) {
function editDev(targetPoint = null) {
hasDevice = targetPoint.hasDevice;
targetP = targetPoint;
//点击之后马上调用这个函数变成回调然后进行处理处理在传给preview表单
previewEquInfProcess()
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) {
if (!formInfo.equipmentType) {
ElMessage({
message: "请选择传感器!",
type: "warning",
});
return;
}
//表单信息
//这里利用处理请求
demo.addEquipment(targetP, formInfo);
ElMessage({
message: "添加成功!",
type: "success",
});
}
const centerDialogVisible = ref(false);
// 删除设备
function handleRemoveEqu() {
if (!targetP.hasDevice) {
ElMessage({
message: "该点位不存在设备!",
type: "warning",
});
return;
}
centerDialogVisible.value = true;
}
// 对话框确认删除
function handleConfirmAddEqu() {
demo.removeEquipment(targetP);
centerDialogVisible.value = false;
ElMessage({
message: "删除成功!",
type: "success",
});
}
// 处理取消关闭编辑框事件
function handleCancel() {
if (!demo) return;
// 关闭标签
demo.isControlOrbit(true);
demo._resetState();
demo.clearTagsObj();
}
//我们的数据应该在哪个获取并将其传入进去呢?
//是在demo.js中还是我们这二个PreviewScene或者editDialog呢
//按目前我这写的逻辑,好像是获取了二次??,有没有办法可以把里面的导出到这呢?
// console.log(demo.isControlOrbit());
let equipmentType = ref(0)
let equipmentName = ref(0)
let equipmentValue = ref(0)
function previewEquInfProcess() {
//3个信息都可以完全获取之后我们可以进行信息处理再传进去就可以了
// console.log(demo);
// console.log(targetP.name);
// console.log(demo.ThreeConfig.data.tunnelThreeConfig);
let tunnelThreeConfig = demo.ThreeConfig.data.tunnelThreeConfig
for (const equipment of tunnelThreeConfig) {
if (equipment.pointName == targetP.name) {
equipmentType.value = equipment.equipmentType
equipmentName.value = equipment.equipmentName
equipmentValue.value = equipment.equipmentValue
console.log(equipmentType.value);
console.log(equipmentName.value);
console.log(equipmentValue.value);
}
}
}
// let equipmentType = reactive(previewEquInfProcess().equipmentType)
// let equipmentName = reactive(previewEquInfProcess().equipmentName)
// let equipmentValue = reactive(previewEquInfProcess().equipmentValue)
// console.log(equipmentType);
const ThreeConfig = {
code: 0,
data: {
tunnelThreeConfig: [{
equipmentId: 'fan_01',//传感器id
equipmentName: '01',//设备名称
pointName: 'point_005_tl',//附着点名称(定位)
equipmentType: 'fan',//设备类型(类型可根据后端
equipmentValue: 23, //设备存的值
}, {
equipmentId: 'sensors_01',//传感器id
equipmentName: '01',//设备名称
pointName: 'point_009_bl',//附着点名称(定位)
equipmentType: 'sensors',//设备类型(类型可根据后端
equipmentValue: 67, //设备存的值
}],
},
msg: "dda"
}
</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>