完成了下拉框

This commit is contained in:
Hcat1314
2023-12-13 00:04:20 +08:00
17 changed files with 95484 additions and 437320 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

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

View File

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

View File

@@ -1,14 +1,10 @@
<template>
<div id="edit-dev">
<div class="title">编辑设备</div>
<!-- <div class="title">编辑设备</div>
<div class="divice-list">
<ul>
<li
v-for="(item, key) of devicesList"
:key="key"
@click="checkDev(key)"
:class="{ 'li-active': checkIndex === key }"
>
<li v-for="(item, key) of devicesList" :key="key" @click="checkDev(key)"
:class="{ 'li-active': checkIndex === key }">
<img :src="item.devImgUrl" />
<div>{{ item.devName + key }}</div>
</li>
@@ -17,6 +13,48 @@
<div class="option-btn">
<button @click="removeDev" :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>
</template>
@@ -24,80 +62,171 @@
<script setup>
import { reactive, defineEmits, onMounted, ref, defineProps } from "vue";
const params = defineProps(["hasDev", "meshId"]);
// 定义需要发射的事件
const emit = defineEmits(["addDev", "removeDev"]);
// 挂载后加所有的设备模型
const devItem = {
devName: "传感器",
devImgUrl: "/images/camera.jpg",
devState: "未开启",
};
const list = [devItem, devItem, devItem, devItem];
const devicesList = reactive(list);
const typeselected = ref("1");
const optionselected = ref("1");
const thresholdValue = ref("")
const checkIndex = ref(-1);
//选择设备
function checkDev(key) {
checkIndex.value = key;
const allAdate = reactive({
point: {
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() {
if (checkIndex.value === -1) {
alert("请选择设备");
return;
}
const devInfo = list[checkIndex.value];
devInfo.checkIndex = checkIndex.value;
emit("addDev", devInfo);
function optionhandleChange() {
}
//删除设备
function removeDev() {
emit("removeDev");
function thresholdChange() {
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>
<style lang="scss" scoped>
#edit-dev {
height: 300px;
width: 200px;
background-color: rgba(236, 236, 236, 0.836);
position: absolute;
z-index: 999;
display: block;
border-radius: 10px;
text-align: center;
opacity: 0;
img {
width: 50px;
width: 540px;
height: 683px;
background: rgba(7, 35, 72, 0.79);
border-radius: 20px;
border: 2px solid #0F82AF;
.edit-dev-hole-distance {
width: 388px;
height: 35px;
font-size: 26px;
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;
display: flex;
justify-content: flex-end;
align-items: center;
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;
.edit-dev-input-type {
width: 284px;
height: 51px;
border: 1px solid #0F82AF;
}
}
.li-active {
background: rgb(224, 114, 114);
}

View File

@@ -2,6 +2,8 @@ export default function (devInfo) {
const dev = this.deviceList[devInfo.checkIndex].clone(); //克隆对应的moxin
const p = this.targetPoint.getWorldPosition(new this.THREE.Vector3());
dev.position.copy(p);
// console.log(this.targetPoint);
modelEffectProcess(dev, this.targetPoint)
this.scene.add(dev);
this.targetPoint.hasDevice = true; //标记还存在设备
// 附着点记录信息
@@ -15,16 +17,35 @@ export default function (devInfo) {
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) {
return `${equal(position.charAt(position.lastIndexOf("_") + 1))}边隧道${equal(
position.charAt(position.lastIndexOf("_") + 2)
)}侧设备约${
(Number(
position.substring(position.indexOf("_") + 1, position.lastIndexOf("_"))
) +
1) *
distance
}米处`;
)}侧设备约${(Number(
position.substring(position.indexOf("_") + 1, position.lastIndexOf("_"))
) +
1) *
distance
}米处`;
}
function equal(str) {

View File

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

View File

@@ -309,12 +309,18 @@ export default class Demo {
this.tagCSS2DObj.element.style.display = "none";
this.tag2CSS2DObj.element.style.display = "none";
this.tag3CSS2DObj.element.style.display = "none";
this.tagCSS2DObj.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.position.y = 1000;
this.tagCSS2DObj.scale.set(3, 3, 3);
}
clearTagsObj() {
if (this.preDBLModel) {
this.preDBLModel.remove(this.tagCSS2DObj);
@@ -372,12 +378,7 @@ export default class Demo {
setDistance(distance = 10) {
this.distance = distance;
}
loadBackground(hdrLoader, backColorSet) {
// hdrLoader.load("/images/background/background.hdr", (texture) => {
// texture.mapping = this.THREE.EquirectangularReflectionMapping;
// this.scene.background = texture;
// this.scene.environment = texture;
// })
loadBackground(backColorSet) {
this.scene.background = new this.THREE.TextureLoader().load("/images/background/background.png", function (texture) {
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>
<div>
<div class="box-top">
<manage-btn v-model="selectIndex" @select="manageSelect"/>
<manage-btn v-model="selectIndex" @select="manageSelect" />
<div class="tunnel-title"></div>
<manage-length class="tunnel-length"></manage-length>
<div class="top-right">
<div class="current-site">
当前站点<span>{{ currentSite }}</span>
@@ -15,52 +16,41 @@
</div>
</div>
</div>
<tunnel-scene id="tunnel-box"/>
<tunnel-scene id="tunnel-box" />
<div class="left">
<el-drawer
v-model="drawerLeft"
direction="ltr"
modal-class="modal-box"
:modal="false"
:show-close="false"
:close-on-click-modal="false"
:close-on-press-escape="false"
>
<fan-info v-if="showFan"/>
<transducer-list/>
<used-ele/>
<el-drawer v-model="drawerLeft" direction="ltr" modal-class="modal-box" :modal="false" :show-close="false"
:close-on-click-modal="false" :close-on-press-escape="false">
<fan-info />
<transducer-list />
<used-ele />
</el-drawer>
<div v-if="drawerLeft" class="left-arrow" @click="closeLeft"></div>
<div v-else class="shrink-left" @click="closeLeft"></div>
</div>
<div class="right">
<el-drawer
v-model="drawerRight"
direction="rtl"
modal-class="modal-box"
:modal="false"
:show-close="false"
:close-on-click-modal="false"
:close-on-press-escape="false"
>
<wind-pressure-list v-if="showFan"/>
<air-info v-if="showFan"/>
<bad-gas-info v-if="showFan"/>
<el-drawer v-model="drawerRight" direction="rtl" modal-class="modal-box" :modal="false" :show-close="false"
:close-on-click-modal="false" :close-on-press-escape="false">
<wind-pressure-list />
<air-info />
<bad-gas-info />
</el-drawer>
<div v-if="drawerRight" class="right-arrow" @click="closeRight"></div>
<div v-else class="shrink-right" @click="closeRight"></div>
</div>
<div class="switch-btn">
<div class="arrow" @click="previousBtn"></div>
<el-carousel height="150px" type="card" ref="tunnelBtn" :autoplay="false">
<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 }}
</el-carousel-item>
</div>
</el-carousel>
<div class="arrow right" @click="nextBtn"></div>
</div>
</div>
</template>
@@ -73,14 +63,13 @@ import WindPressureList from "@/components/content/windPressure/WindPressureList
import AirInfo from "@/components/content/airInfo/AirInfo.vue";
import BadGasInfo from "@/components/content/badGasInfo/BadGasInfo.vue";
import ManageBtn from "@/components/manageBtn/index.vue";
import {dateFormat} from "@/utils/date.js";
import {useAuthStore} from '@/store/userstore.js'
import {onMounted} from "vue";
import ManageLength from "@/components/manageLength/index.vue";
import { dateFormat } from "@/utils/date.js";
import { useAuthStore } from '@/store/userstore.js'
const authStore = useAuthStore()
const router = useRouter()
const selectIndex = ref(1)
const showFan = ref(false)
const drawerLeft = ref(true)
const drawerRight = ref(true)
const currentSite = ref('松江站')
@@ -111,11 +100,6 @@ const tunnelList = ref([
name: '七号隧道'
},
])
onMounted(()=>{
nextTick(()=>{
showFan.value=true
})
})
const manageSelect = () => {
// getInfo();
};
@@ -134,9 +118,9 @@ const previousBtn = () => {
}
const nextBtn = () => {
tunnelBtn.value.next();
// tunnelList.value.push(tunnelList.value.shift())
// console.log('tunnelList.value', tunnelList.value)
}
</script>
<style lang="scss" scoped>
</style>
<style lang="scss" scoped></style>