Merge pull request 'LJ' (#96) from LJ into dev

Reviewed-on: http://git.feashow.cn/clay/tunnel-cloud-web/pulls/96
This commit is contained in:
liaojie
2023-12-12 16:25:59 +00:00
17 changed files with 95486 additions and 437319 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

40418
public/devicesModel/fan.obj Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -125,6 +125,13 @@ html, body, #app, .el-container, .el-aside, .el-main {
background-image: url('../images/topAndDown/sp_icon_zyc.png'); background-image: url('../images/topAndDown/sp_icon_zyc.png');
} }
.tunnel-length{
position: absolute;
top: 13%;
left: 36%;
z-index: 9;
}
.shrink-left { .shrink-left {
cursor: pointer; cursor: pointer;
position: absolute; position: absolute;

View File

@@ -20,7 +20,6 @@ import {
CSS3DSprite, CSS3DSprite,
} from "three/addons/renderers/CSS3DRenderer.js"; } from "three/addons/renderers/CSS3DRenderer.js";
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader"; import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader"
import DevInfo from "./childComp/DevInfo.vue"; import DevInfo from "./childComp/DevInfo.vue";
import EditDev from "./childComp/EditDev.vue"; import EditDev from "./childComp/EditDev.vue";
import { onMounted, reactive, ref } from "vue"; import { onMounted, reactive, ref } from "vue";
@@ -33,7 +32,6 @@ const edit = ref(null);
const num = 10000; const num = 10000;
let demo; //定义demo全局变量 let demo; //定义demo全局变量
const loader = new OBJLoader(); const loader = new OBJLoader();
let hdrLoader = new RGBELoader();
let backColorSet = three.sRGBEncoding; let backColorSet = three.sRGBEncoding;
// 模版挂载后 // 模版挂载后
onMounted(handleMounted); onMounted(handleMounted);
@@ -49,18 +47,25 @@ async function handleMounted() {
lClickCallback(demo); //左键回调 lClickCallback(demo); //左键回调
rClickCallback(demo); //右键回调 rClickCallback(demo); //右键回调
//加载HDR背景图片 //加载HDR背景图片
demo.loadBackground(hdrLoader, backColorSet) demo.loadBackground(backColorSet)
// 初始化设备模型 // 初始化设备模型
try { try {
const deviceList = []; const deviceList = [];
let result = await loadModel("/devicesModel/Camera.obj"); let result = await loadModel("/devicesModel/camera.obj");
deviceList.push(result); deviceList.push(result);
result = await loadModel("/devicesModel/box_device.obj"); modelEffectProcess(result);
result = await loadModel("/devicesModel/fan.obj");
deviceList.push(result); deviceList.push(result);
result = await loadModel("/devicesModel/dev2.obj"); modelEffectProcess(result);
result = await loadModel("/devicesModel/sensors.obj");
deviceList.push(result); deviceList.push(result);
result = await loadModel("/devicesModel/dev3.obj"); modelEffectProcess(result);
result = await loadModel("/devicesModel/sensors.obj");
deviceList.push(result); deviceList.push(result);
modelEffectProcess(result);
result = await loadModel("/devicesModel/sensors.obj");
deviceList.push(result);
modelEffectProcess(result);
// 给对象初加载设备模型 // 给对象初加载设备模型
demo.initDevicesModel(deviceList); demo.initDevicesModel(deviceList);
console.info("设备模型加载完毕"); console.info("设备模型加载完毕");
@@ -86,6 +91,15 @@ function loadModel(path) {
}); });
} }
function modelEffectProcess(model) {
model.traverse((v) => {
v.material = new three.MeshBasicMaterial
v.material.color = new three.Color(0xC0C0C0)
})
}
let hasDevice = ref(true); let hasDevice = ref(true);
let devInfo = reactive({ let devInfo = reactive({
meshId: null, meshId: null,

View File

@@ -1,14 +1,10 @@
<template> <template>
<div id="edit-dev"> <div id="edit-dev">
<div class="title">编辑设备</div> <!-- <div class="title">编辑设备</div>
<div class="divice-list"> <div class="divice-list">
<ul> <ul>
<li <li v-for="(item, key) of devicesList" :key="key" @click="checkDev(key)"
v-for="(item, key) of devicesList" :class="{ 'li-active': checkIndex === key }">
:key="key"
@click="checkDev(key)"
:class="{ 'li-active': checkIndex === key }"
>
<img :src="item.devImgUrl" /> <img :src="item.devImgUrl" />
<div>{{ item.devName + key }}</div> <div>{{ item.devName + key }}</div>
</li> </li>
@@ -17,6 +13,48 @@
<div class="option-btn"> <div class="option-btn">
<button @click="removeDev" :disabled="!params.hasDev">移除设备</button> <button @click="removeDev" :disabled="!params.hasDev">移除设备</button>
<button @click="addDev" :disabled="params.hasDev">添加设备</button> <button @click="addDev" :disabled="params.hasDev">添加设备</button>
</div> -->
<div>
<!-- 文字内容框 -->
<div class="edit-dev-hole-distance">
<!-- 每个附着点之间的间隔和被点击之后的第几个都需要动态传入 -->
<!-- 之后还需要看最后的计算结果 -->
<span>当前距离洞口{{ pointeachlen }}*{{ poiotwhich }}={{ pointeachlen * poiotwhich }}</span>
</div>
<!-- 输入框内容 -->
<div class="edit-dev-input">
<span class="edit-dev-input-type-font">传感器类型</span>
<div class="edit-dev-input-type">
<select v-model="typeselected" @change="typehandleChange">
<option v-for="type in equipmentTypes" :key="type.value" :value="type.value">
{{ type.text }}
</option>
</select>
</div>
<span class="edit-dev-input-option-font">设备选择</span>
<div class="edit-dev-input-option">
<select v-model="optionselected" @change="optionhandleChange">
<option v-for="option in equipmentOptions" :key="option.value" :value="option.value">
{{ option.text }}
</option>
</select>
</div>
<span class="edit-dev-input-threshold-font">阈值</span>
<div class="edit-dev-input-threshold">
<input type="text" @change="thresholdChange" v-model="thresholdValue">
</div>
</div>
<!-- 删除和确定框 -->
<div class="edit-dev-button">
<div class="edit-dev-button-del">
<!-- 删除 -->
<button>删除</button>
</div>
<div class="edit-dev-button-sure">
<!-- 确认 -->
<button>确认</button>
</div>
</div>
</div> </div>
</div> </div>
</template> </template>
@@ -24,80 +62,171 @@
<script setup> <script setup>
import { reactive, defineEmits, onMounted, ref, defineProps } from "vue"; import { reactive, defineEmits, onMounted, ref, defineProps } from "vue";
const params = defineProps(["hasDev", "meshId"]); const typeselected = ref("1");
// 定义需要发射的事件 const optionselected = ref("1");
const emit = defineEmits(["addDev", "removeDev"]); const thresholdValue = ref("")
// 挂载后加所有的设备模型
const devItem = {
devName: "传感器",
devImgUrl: "/images/camera.jpg",
devState: "未开启",
};
const list = [devItem, devItem, devItem, devItem];
const devicesList = reactive(list);
const checkIndex = ref(-1);
//选择设备 const allAdate = reactive({
function checkDev(key) { point: {
checkIndex.value = key; pointachlen: 1,
poiotwhich: 2
},
equipmentTypes: [
{ text: "风机", value: "1" },
{ text: "风压传感器", value: "2" },
{ text: "普通传感器", value: "3" },
],
equipmentOptions: [
{
value: "1",
text: "风机",
Options: [
{ text: "1号风机", value: "1", threshold: 2 },
{ text: "2号风机", value: "2", threshold: 2 },
{ text: "3号风机", value: "3", threshold: 2 }
]
},
{
value: "2",
text: "风压传感器",
Options: [
{ text: "1号风压", value: "1", threshold: 2 },
{ text: "2号风压", value: "2", threshold: 2 },
{ text: "3号风压", value: "3", threshold: 2 }
]
},
{
value: "3",
text: "普通传感器",
Options: [
{ text: "1号传感器", value: "1", threshold: 2 },
{ text: "2号传感器", value: "2", threshold: 2 },
{ text: "3号传感器", value: "3", threshold: 2 }
]
}
]
})
const pointeachlen = ref(allAdate.point.pointachlen);
const poiotwhich = ref(allAdate.point.poiotwhich);
const equipmentTypes = ref(allAdate.equipmentTypes);
const equipmentOptions = ref(allAdate.equipmentOptions)
function typehandleChange() {
equipmentOptions.value = allAdate.equipmentOptions[typeselected.value].Options
} }
// 添加设备
function addDev() { function optionhandleChange() {
if (checkIndex.value === -1) {
alert("请选择设备");
return;
}
const devInfo = list[checkIndex.value];
devInfo.checkIndex = checkIndex.value;
emit("addDev", devInfo);
} }
//删除设备
function removeDev() { function thresholdChange() {
emit("removeDev"); allAdate.equipmentOptions[typeselected.value].Options[optionselected.value].threshold = thresholdValue
console.log(allAdate.equipmentOptions[typeselected.value].Options[optionselected.value].threshold);
} }
function clear() {
selected.value = "1";
optionselected = "1"
}
// const params = defineProps(["hasDev", "meshId"]);
// // 定义需要发射的事件
// const emit = defineEmits(["addDev", "removeDev"]);
// // 挂载后加所有的设备模型
// const cameradevItem = {
// devName: "摄像头",
// devImgUrl: "/images/camera.jpg",
// devState: "未开启",
// };
// const fandevItem = {
// devName: "风机",
// devImgUrl: "/images/camera.jpg",
// devState: "未开启",
// };
// const WindsensorsdevItem = {
// devName: "风压传感器",
// devImgUrl: "/images/camera.jpg",
// devState: "未开启",
// };
// const GassensorsdevItem = {
// devName: "气体传感器",
// devImgUrl: "/images/camera.jpg",
// devState: "未开启",
// };
// const TemsensorsdevItem = {
// devName: "温度传感器",
// devImgUrl: "/images/camera.jpg",
// devState: "未开启",
// };
// const list = [cameradevItem, fandevItem, WindsensorsdevItem, GassensorsdevItem, TemsensorsdevItem];
// const devicesList = reactive(list);
// const checkIndex = ref(-1);
// //选择设备
// function checkDev(key) {
// checkIndex.value = key;
// }
// // 添加设备
// function addDev() {
// if (checkIndex.value === -1) {
// alert("请选择设备");
// return;
// }
// const devInfo = list[checkIndex.value];
// devInfo.checkIndex = checkIndex.value;
// emit("addDev", devInfo);
// }
// //删除设备
// function removeDev() {
// emit("removeDev");
// }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
#edit-dev { #edit-dev {
height: 300px; width: 540px;
width: 200px; height: 683px;
background-color: rgba(236, 236, 236, 0.836); background: rgba(7, 35, 72, 0.79);
position: absolute; border-radius: 20px;
z-index: 999; border: 2px solid #0F82AF;
display: block;
border-radius: 10px; .edit-dev-hole-distance {
text-align: center; width: 388px;
opacity: 0; height: 35px;
img { font-size: 26px;
width: 50px; font-family: MicrosoftYaHei;
color: #FFFFFF;
line-height: 35px;
} }
.title {
height: 20px; .edit-dev-input-type-font {
width: 130px;
height: 35px;
font-size: 26px;
font-family: MicrosoftYaHei;
color: #FFFFFF;
line-height: 35px;
} }
.option-btn {
height: 40px; .edit-dev-input-type {
display: flex; width: 284px;
justify-content: flex-end; height: 51px;
align-items: center; border: 1px solid #0F82AF;
margin-right: 10px;
}
.divice-list {
height: 240px;
}
.divice-list ul {
height: 100%;
padding: 7px;
display: flex;
flex-wrap: wrap;
gap: 7px;
align-content: first baseline;
}
.divice-list ul li {
border-radius: 5px;
overflow: hidden;
cursor: pointer;
} }
} }
.li-active { .li-active {
background: rgb(224, 114, 114); background: rgb(224, 114, 114);
} }

View File

@@ -2,6 +2,8 @@ export default function (devInfo) {
const dev = this.deviceList[devInfo.checkIndex].clone(); //克隆对应的moxin const dev = this.deviceList[devInfo.checkIndex].clone(); //克隆对应的moxin
const p = this.targetPoint.getWorldPosition(new this.THREE.Vector3()); const p = this.targetPoint.getWorldPosition(new this.THREE.Vector3());
dev.position.copy(p); dev.position.copy(p);
// console.log(this.targetPoint);
modelEffectProcess(dev, this.targetPoint)
this.scene.add(dev); this.scene.add(dev);
this.targetPoint.hasDevice = true; //标记还存在设备 this.targetPoint.hasDevice = true; //标记还存在设备
// 附着点记录信息 // 附着点记录信息
@@ -15,16 +17,35 @@ export default function (devInfo) {
return this.targetPoint.info; return this.targetPoint.info;
} }
function modelEffectProcess(model, point) {
if (model.children[0].name == "camera") {
console.log(model);
console.log(point);
model.scale.set(0.1, 0.1, 0.1)
}
if (model.children[0].name == "fan") {
console.log(model);
console.log(point);
}
if (model.children[0].name == "sensors") {
console.log(model);
console.log(point);
model.scale.set(0.2, 0.2, 0.2)
}
}
function transformPosition(position, distance) { function transformPosition(position, distance) {
return `${equal(position.charAt(position.lastIndexOf("_") + 1))}边隧道${equal( return `${equal(position.charAt(position.lastIndexOf("_") + 1))}边隧道${equal(
position.charAt(position.lastIndexOf("_") + 2) position.charAt(position.lastIndexOf("_") + 2)
)}侧设备约${ )}侧设备约${(Number(
(Number( position.substring(position.indexOf("_") + 1, position.lastIndexOf("_"))
position.substring(position.indexOf("_") + 1, position.lastIndexOf("_")) ) +
) + 1) *
1) * distance
distance }米处`;
}米处`;
} }
function equal(str) { function equal(str) {

View File

@@ -13,6 +13,7 @@ function handleLoadedDevice(model) {
const wp = this.targetPoint.getWorldPosition(new this.THREE.Vector3()); const wp = this.targetPoint.getWorldPosition(new this.THREE.Vector3());
model.position.copy(wp); model.position.copy(wp);
this.targetPoint.visible = false; this.targetPoint.visible = false;
model.scale = 0.1
this.scene.add(model); this.scene.add(model);
if (model.name === "camera") { if (model.name === "camera") {
@@ -20,6 +21,7 @@ function handleLoadedDevice(model) {
model.translateZ(4); model.translateZ(4);
model.translateY(-0.5); model.translateY(-0.5);
} }
// 添加的信息请求或初始化的信息 // 添加的信息请求或初始化的信息
this.targetPoint.info = { this.targetPoint.info = {
name: "摄像头", name: "摄像头",

View File

@@ -309,12 +309,18 @@ export default class Demo {
this.tagCSS2DObj.element.style.display = "none"; this.tagCSS2DObj.element.style.display = "none";
this.tag2CSS2DObj.element.style.display = "none"; this.tag2CSS2DObj.element.style.display = "none";
this.tag3CSS2DObj.element.style.display = "none"; this.tag3CSS2DObj.element.style.display = "none";
this.tagCSS2DObj.scale.set(0.1, 0.1, 0.1); this.tagCSS2DObj.scale.set(0.1, 0.1, 0.1);
this.tag2CSS2DObj.scale.set(0.1, 0.1, 0.1); this.tag2CSS2DObj.scale.set(0.1, 0.1, 0.1);
this.tag3CSS2DObj.scale.set(0.1, 0.1, 0.1); this.tag3CSS2DObj.scale.set(0.1, 0.1, 0.1);
this.tag3CSS2DObj.position.y = 1000;
this.tagCSS2DObj.scale.set(3, 3, 3); this.tagCSS2DObj.scale.set(3, 3, 3);
} }
clearTagsObj() { clearTagsObj() {
if (this.preDBLModel) { if (this.preDBLModel) {
this.preDBLModel.remove(this.tagCSS2DObj); this.preDBLModel.remove(this.tagCSS2DObj);
@@ -372,12 +378,7 @@ export default class Demo {
setDistance(distance = 10) { setDistance(distance = 10) {
this.distance = distance; this.distance = distance;
} }
loadBackground(hdrLoader, backColorSet) { loadBackground(backColorSet) {
// hdrLoader.load("/images/background/background.hdr", (texture) => {
// texture.mapping = this.THREE.EquirectangularReflectionMapping;
// this.scene.background = texture;
// this.scene.environment = texture;
// })
this.scene.background = new this.THREE.TextureLoader().load("/images/background/background.png", function (texture) { this.scene.background = new this.THREE.TextureLoader().load("/images/background/background.png", function (texture) {
texture.encoding = backColorSet; texture.encoding = backColorSet;
}); });

View File

@@ -0,0 +1,45 @@
<template>
<div class="tunnel-length">
<!-- 加上点击事件 -->
<div class="tunnel-length-container">
<!-- 显示长度 -->
<div class="tunnel-length-font">当前长度</div>
<!-- 包到下面的盒子 -->
<div>
<!-- 插入图片 -->
<div>
<img src="../../assets/images/tunnel/tunnel-length-icon.png" alt="">
<!-- 正方形覆盖 -->
<div></div>
<!-- 长方形覆盖 -->
<div></div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
.tunnel-length-container {
position: relative;
}
.tunnel-length-font {
position: absolute;
left: 40%;
top: -33%;
color: #0BE9FA;
font-size: 30px;
}
</style>

View File

@@ -1,8 +1,9 @@
<template> <template>
<div> <div>
<div class="box-top"> <div class="box-top">
<manage-btn v-model="selectIndex" @select="manageSelect"/> <manage-btn v-model="selectIndex" @select="manageSelect" />
<div class="tunnel-title"></div> <div class="tunnel-title"></div>
<manage-length class="tunnel-length"></manage-length>
<div class="top-right"> <div class="top-right">
<div class="current-site"> <div class="current-site">
当前站点<span>{{ currentSite }}</span> 当前站点<span>{{ currentSite }}</span>
@@ -15,52 +16,41 @@
</div> </div>
</div> </div>
</div> </div>
<tunnel-scene id="tunnel-box"/> <tunnel-scene id="tunnel-box" />
<div class="left"> <div class="left">
<el-drawer <el-drawer v-model="drawerLeft" direction="ltr" modal-class="modal-box" :modal="false" :show-close="false"
v-model="drawerLeft" :close-on-click-modal="false" :close-on-press-escape="false">
direction="ltr" <fan-info v-if="showFan" :list="socketData.frequencyState" />
modal-class="modal-box" <transducer-list :list="socketData.currentVoltage" :feedback="socketData.frequencyFeedback" />
:modal="false" <used-ele :list="socketData.electricityConsumption" />
:show-close="false"
:close-on-click-modal="false"
:close-on-press-escape="false"
>
<fan-info v-if="showFan" :list="socketData.frequencyState"/>
<transducer-list :list="socketData.currentVoltage" :feedback="socketData.frequencyFeedback"/>
<used-ele :list="socketData.electricityConsumption"/>
</el-drawer> </el-drawer>
<div v-if="drawerLeft" class="left-arrow" @click="closeLeft"></div> <div v-if="drawerLeft" class="left-arrow" @click="closeLeft"></div>
<div v-else class="shrink-left" @click="closeLeft"></div> <div v-else class="shrink-left" @click="closeLeft"></div>
</div> </div>
<div class="right"> <div class="right">
<el-drawer <el-drawer v-model="drawerRight" direction="rtl" modal-class="modal-box" :modal="false" :show-close="false"
v-model="drawerRight" :close-on-click-modal="false" :close-on-press-escape="false">
direction="rtl" <wind-pressure-list v-if="showFan" :list="socketData.windPressure" />
modal-class="modal-box" <air-info v-if="showFan" :list="socketData.sensor" />
:modal="false" <bad-gas-info v-if="showFan" :list="socketData.sensor" />
:show-close="false"
:close-on-click-modal="false"
:close-on-press-escape="false"
>
<wind-pressure-list v-if="showFan" :list="socketData.windPressure"/>
<air-info v-if="showFan" :list="socketData.sensor"/>
<bad-gas-info v-if="showFan" :list="socketData.sensor"/>
</el-drawer> </el-drawer>
<div v-if="drawerRight" class="right-arrow" @click="closeRight"></div> <div v-if="drawerRight" class="right-arrow" @click="closeRight"></div>
<div v-else class="shrink-right" @click="closeRight"></div> <div v-else class="shrink-right" @click="closeRight"></div>
</div> </div>
<div class="switch-btn"> <div class="switch-btn">
<div class="arrow" @click="previousBtn"></div> <div class="arrow" @click="previousBtn"></div>
<el-carousel height="150px" type="card" ref="tunnelBtn" :autoplay="false"> <el-carousel height="150px" type="card" ref="tunnelBtn" :autoplay="false">
<div class="btn"> <div class="btn">
<el-carousel-item v-for="(item,index) in tunnelList" :key="item.value"> <el-carousel-item v-for="(item, index) in tunnelList" :key="item.value">
{{ item.name }} {{ item.name }}
</el-carousel-item> </el-carousel-item>
</div> </div>
</el-carousel> </el-carousel>
<div class="arrow right" @click="nextBtn"></div> <div class="arrow right" @click="nextBtn"></div>
</div> </div>
</div> </div>
</template> </template>
@@ -73,15 +63,14 @@ import WindPressureList from "@/components/content/windPressure/WindPressureList
import AirInfo from "@/components/content/airInfo/AirInfo.vue"; import AirInfo from "@/components/content/airInfo/AirInfo.vue";
import BadGasInfo from "@/components/content/badGasInfo/BadGasInfo.vue"; import BadGasInfo from "@/components/content/badGasInfo/BadGasInfo.vue";
import ManageBtn from "@/components/manageBtn/index.vue"; import ManageBtn from "@/components/manageBtn/index.vue";
import {dateFormat} from "@/utils/date.js"; import { dateFormat } from "@/utils/date.js";
import {onMounted} from "vue"; import { onMounted } from "vue";
import {getToken} from "@/utils/auth"; import { getToken } from "@/utils/auth";
import {useAuthStore} from '@/store/userstore.js' import { useAuthStore } from '@/store/userstore.js'
const authStore = useAuthStore() const authStore = useAuthStore()
const router = useRouter() const router = useRouter()
const selectIndex = ref(1) const selectIndex = ref(1)
const showFan = ref(false)
const drawerLeft = ref(true) const drawerLeft = ref(true)
const drawerRight = ref(true) const drawerRight = ref(true)
const currentSite = ref('松江站') const currentSite = ref('松江站')
@@ -132,8 +121,8 @@ onMounted(() => {
}) })
}) })
const manageSelect = (index) => { const manageSelect = (index) => {
console.log('首页点击-',index) console.log('首页点击-', index)
if(index===0){ if (index === 0) {
console.log('站点管理=====-----') console.log('站点管理=====-----')
router.push('/site') router.push('/site')
} }
@@ -192,7 +181,7 @@ const initWebSocket = () => {
} else if (item.typeKey === 'windPressure') { } else if (item.typeKey === 'windPressure') {
console.log('风压风压') console.log('风压风压')
socketData.windPressure = data socketData.windPressure = data
}else if (item.typeKey === 'sensor') { } else if (item.typeKey === 'sensor') {
console.log('传感器==========?') console.log('传感器==========?')
socketData.sensor = data socketData.sensor = data
} }
@@ -214,6 +203,4 @@ const closeSocket = () => {
initWebSocket() initWebSocket()
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped></style>
</style>