fix : 隧道模拟功能初步完成

This commit is contained in:
dj
2025-01-03 20:39:42 +08:00
parent 16df648f2b
commit 472bc3cb83
3 changed files with 98 additions and 80 deletions

View File

@@ -3,26 +3,26 @@
<div id="cvs" ref="content"></div> <div id="cvs" ref="content"></div>
<!-- 这里的预览模式需要做成不能修改的模式 --> <!-- 这里的预览模式需要做成不能修改的模式 -->
<edit-dialog <edit-dialog
ref="edit" ref="edit"
@addEquipment="handleAddEqu" @addEquipment="handleAddEqu"
@removeEquipment="handleRemoveEqu" @removeEquipment="handleRemoveEqu"
@cancel="handleCancel" @cancel="handleCancel"
:hasDev="hasDevice" :hasDev="hasDevice"
:pointNum="pointNum" :pointNum="pointNum"
:tunnelId="params.tunnelId" :tunnelId="params.tunnelId"
:position="targetP?.name" :position="targetP?.name"
:hasEquipment="hasDevice" :hasEquipment="hasDevice"
:pointGap="pointGap" :pointGap="pointGap"
:form="params.form" :form="params.form"
/> />
<pre-dialog <pre-dialog
ref="info" ref="info"
:pointNum="50" :pointNum="50"
:pointGap="50" :pointGap="50"
:equipmentType="equipmentType" :equipmentType="equipmentType"
:equipmentName="equipmentName" :equipmentName="equipmentName"
:equipmentValue="50" :equipmentValue="50"
:devRealtimeDetail="devRealtimeDetail" :devRealtimeDetail="devRealtimeDetail"
/> />
</div> </div>
</template> </template>
@@ -34,9 +34,9 @@ import DevInfo from "./displayInfoComp/DevInfo.vue";
import EditDialog from "./editEquComp/editDialog.vue"; import EditDialog from "./editEquComp/editDialog.vue";
import PreDialog from "./preEquComp/preDialog.vue"; import PreDialog from "./preEquComp/preDialog.vue";
// 导入模模型加载器 // 导入模模型加载器
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; import {GLTFLoader} from "three/examples/jsm/loaders/GLTFLoader";
// import { DRACOLoader } from "three/examples/jsm/loaders/dracoloader"; // import { DRACOLoader } from "three/examples/jsm/loaders/dracoloader";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; import {OrbitControls} from "three/examples/jsm/controls/OrbitControls";
import * as TWEEN from "three/examples/jsm/libs/tween.module"; import * as TWEEN from "three/examples/jsm/libs/tween.module";
import { import {
CSS2DRenderer, CSS2DRenderer,
@@ -44,8 +44,8 @@ import {
} from "three/addons/renderers/CSS2DRenderer.js"; } from "three/addons/renderers/CSS2DRenderer.js";
// 引入CSS2渲染器CSS2DRenderer和CSS2模型对象CSS2DObject // 引入CSS2渲染器CSS2DRenderer和CSS2模型对象CSS2DObject
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 {RGBELoader} from "three/examples/jsm/loaders/RGBELoader";
import { import {
onMounted, onMounted,
reactive, reactive,
@@ -54,12 +54,13 @@ import {
defineProps, defineProps,
defineExpose, defineExpose,
} from "vue"; } from "vue";
import { ElMessage } from "element-plus"; import {ElMessage} from "element-plus";
import { getScreenSimulateTunnel } from "@/api/tunnelManage"; import {getScreenSimulateTunnel} from "@/api/tunnelManage";
// 获取html标签跟随组件dom // 获取html标签跟随组件dom
const content = ref(null); const content = ref(null);
const info = ref(null); const info = ref(null);
const edit = ref(null); const edit = ref(null);
const realtimeData = ref([]);
let modelList = ref(null); let modelList = ref(null);
let demo; //定义demo对象 let demo; //定义demo对象
const loader = new OBJLoader(); const loader = new OBJLoader();
@@ -79,6 +80,7 @@ const params = defineProps([
// hover到设备回显参数 // hover到设备回显参数
let equipmentName = ref(""); let equipmentName = ref("");
let equipmentType = ref(""); let equipmentType = ref("");
let pointValue = ref({});
let devRealtimeDetail = ref({ let devRealtimeDetail = ref({
equipmentType: "", equipmentType: "",
value: "", value: "",
@@ -86,12 +88,12 @@ let devRealtimeDetail = ref({
}); });
watch( watch(
() => params.tunnelLength, () => params.tunnelLength,
(now) => { (now) => {
params.tunnelLength = now; params.tunnelLength = now;
pointGap = now / 20; pointGap = now / 20;
}, },
{ deep: true } {deep: true}
); );
let pointGap = reactive(params.tunnelLength); let pointGap = reactive(params.tunnelLength);
@@ -105,8 +107,8 @@ async function handleMounted() {
// "../../../../public/tunnelModel/chanel-have-wall-now-use.gltf" // "../../../../public/tunnelModel/chanel-have-wall-now-use.gltf"
demo.isedit = false; demo.isedit = false;
const loaded = await demo.loadModel( const loaded = await demo.loadModel(
GLTFLoader, GLTFLoader,
"/tunnelModel/chanel-have-wall-now-use.gltf" "/tunnelModel/chanel-have-wall-now-use.gltf"
); );
demo.addOrbitControls(OrbitControls, true); demo.addOrbitControls(OrbitControls, true);
demo.addTween(TWEEN); demo.addTween(TWEEN);
@@ -149,20 +151,21 @@ async function handleMounted() {
]; ];
// 初始化仿真參數 // 初始化仿真參數
const { data } = await getScreenSimulateTunnel(params.tunnelId); const {data} = await getScreenSimulateTunnel(params.tunnelId);
demo.enableLeftBtn = false; //关闭左键 demo.enableLeftBtn = false; //关闭左键
demo.pointsVisible(false); //隐藏附着点 demo.pointsVisible(false); //隐藏附着点
TunnelSceneSimulateRender(data); TunnelSceneSimulateRender(data);
// 初始化标牌信息 // 初始化标牌信息
renderRoadPlane({ nickname: params.tunnelAlias, length: params.tunnelLength }); renderRoadPlane({nickname: params.tunnelAlias, length: params.tunnelLength});
} catch (err) {} } catch (err) {
}
} }
// 从新渲染数据 // 从新渲染数据
async function rerender() { async function rerender() {
try { try {
// 初始化仿真參數 // 初始化仿真參數
const { data } = await getScreenSimulateTunnel(params.tunnelId); const {data} = await getScreenSimulateTunnel(params.tunnelId);
console.log(data); console.log(data);
const modeData = randomPosition([ const modeData = randomPosition([
...data.frequencyChangerList, ...data.frequencyChangerList,
@@ -171,8 +174,8 @@ async function rerender() {
]).map((item) => ({ ]).map((item) => ({
...item, ...item,
equipmentType: item.equipmentType.startsWith("frequency") equipmentType: item.equipmentType.startsWith("frequency")
? "frequency" ? "frequency"
: "sensor", : "sensor",
})); }));
demo.editTunnelInit(modeData); demo.editTunnelInit(modeData);
demo.SignsInf(params.form.tunnelAlias, String(params.tunnelLength)); demo.SignsInf(params.form.tunnelAlias, String(params.tunnelLength));
@@ -183,6 +186,7 @@ async function rerender() {
}); });
} }
} }
// 随机生成1-20的随机数 // 随机生成1-20的随机数
function randomNum(max = 20) { function randomNum(max = 20) {
const nums = new Set(); const nums = new Set();
@@ -191,6 +195,7 @@ function randomNum(max = 20) {
} }
return [...nums]; return [...nums];
} }
//随机定位 //随机定位
function randomPosition(simulateData) { function randomPosition(simulateData) {
const mid = Math.floor(simulateData.length / 2); const mid = Math.floor(simulateData.length / 2);
@@ -201,17 +206,17 @@ function randomPosition(simulateData) {
const leftData = simulateData.slice(0, mid).map((item, index) => ({ const leftData = simulateData.slice(0, mid).map((item, index) => ({
...item, ...item,
position: `point_0${leftPosition[index].padStart(2, 0)}_${ position: `point_0${leftPosition[index].padStart(2, 0)}_${
lr_position[lrIndex] lr_position[lrIndex]
}`, }`,
})); }));
const rightData = simulateData const rightData = simulateData
.slice(mid, simulateData.length) .slice(mid, simulateData.length)
.map((item, index) => ({ .map((item, index) => ({
...item, ...item,
position: `point_0${rightPosition[index].padStart(2, 0)}_${ position: `point_0${rightPosition[index].padStart(2, 0)}_${
lr_position[1 - lrIndex] lr_position[1 - lrIndex]
}`, }`,
})); }));
return [...leftData, ...rightData]; return [...leftData, ...rightData];
} }
@@ -219,14 +224,15 @@ function randomPosition(simulateData) {
function loadModel(path) { function loadModel(path) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
loader.load( loader.load(
path, path,
(obj) => { (obj) => {
resolve(obj); resolve(obj);
}, },
(xhr) => {}, (xhr) => {
(err) => { },
reject(err); (err) => {
} reject(err);
}
); );
}); });
} }
@@ -241,12 +247,12 @@ let devInfo = reactive({
// 对象建构赋值功能 // 对象建构赋值功能
function editDevInfo( function editDevInfo(
value = { value = {
meshId: null, meshId: null,
name: "无", name: "无",
state: "无", state: "无",
position: "无", position: "无",
} }
) { ) {
devInfo.meshId = value.meshId; devInfo.meshId = value.meshId;
devInfo.name = value.name; devInfo.name = value.name;
@@ -265,6 +271,7 @@ function lClickCallback(demo) {
} }
editDevInfo(targetPoint.info); editDevInfo(targetPoint.info);
} }
// 传给内部使用 // 传给内部使用
demo.addFunction("displayDevInfo", displayDevInfo); demo.addFunction("displayDevInfo", displayDevInfo);
} }
@@ -278,12 +285,13 @@ function rClickCallback(demo) {
hasDevice.value = targetPoint.hasDevice; hasDevice.value = targetPoint.hasDevice;
targetP.value = targetPoint; targetP.value = targetPoint;
pointNum.value = Number( pointNum.value = Number(
targetPoint.name.substring( targetPoint.name.substring(
targetPoint.name.indexOf("_") + 1, targetPoint.name.indexOf("_") + 1,
targetPoint.name.lastIndexOf("_") targetPoint.name.lastIndexOf("_")
) - 1 ) - 1
); );
if (!targetPoint.info) return; if (!targetPoint.info) return;
pointValue.value = targetPoint.info
hoverDevEquipmentCallback(targetPoint.info); hoverDevEquipmentCallback(targetPoint.info);
editDevInfo(targetPoint.info); editDevInfo(targetPoint.info);
} }
@@ -355,13 +363,13 @@ const ThreeConfig = {
}, },
msg: "dda", msg: "dda",
}; };
//=============隧模型道数据仿真==================== //=============隧模型道数据仿真====================
/** /**
* @description: 隧道中的设备重新模拟渲染 * @description: 隧道中的设备重新模拟渲染
* @param {Object} data 渲染数据格式 [{equipmentId,equipmentName,pointName,equipmentType,equipmentValue}] * @param {Object} data 渲染数据格式 [{equipmentId,equipmentName,pointName,equipmentType,equipmentValue}]
*/ */
function TunnelSceneSimulateRender(data) { function TunnelSceneSimulateRender(data) {
console.log('TunnelSceneSimulateRender',data)
if (!demo) return; if (!demo) return;
const modeData = randomPosition([ const modeData = randomPosition([
...data.frequencyChangerList, ...data.frequencyChangerList,
@@ -370,43 +378,51 @@ function TunnelSceneSimulateRender(data) {
]).map((item) => ({ ]).map((item) => ({
...item, ...item,
equipmentType: item.equipmentType.startsWith("frequency") equipmentType: item.equipmentType.startsWith("frequency")
? "frequency" ? "frequency"
: "sensor", : "sensor",
})); }));
demo.editTunnelInit(modeData); //渲染设备数据 demo.editTunnelInit(modeData); //渲染设备数据
} }
/** /**
* @description: 鼠标悬浮在设备上时回调函数 * @description: 鼠标悬浮在设备上时回调函数
*/ */
function hoverDevEquipmentCallback(targetPointInfo) { function hoverDevEquipmentCallback(targetPointInfo) {
console.log(targetPointInfo); //当前附着点信息
const { const {
equipmentId, equipmentId,
equipmentName: eName, equipmentName: eName,
equipmentType: eType, equipmentType: eType,
typeKey, typeKey,
unit: u, unit: u,
value
} = targetPointInfo; } = targetPointInfo;
//请求到的实时数据进行渲染 //请求到的实时数据进行渲染
//业务代码.... 获取设备实时数据(data) const value = .... //业务代码....获取设备实时数据
equipmentType.value = eType; equipmentType.value = eType;
equipmentName.value = eName; equipmentName.value = eName;
devRealtimeDetail.value.equipmentType =typeKey; devRealtimeDetail.value.equipmentType = typeKey;
devRealtimeDetail.value.unit = u; devRealtimeDetail.value.unit = u;
devRealtimeDetail.value.value = 1000; //1000替换为value devRealtimeDetail.value.value = value; //1000替换为value
} }
/** /**
* @description: 渲染隧道入口提示板信息 * @description: 渲染隧道入口提示板信息
* @param {Object} data 隧道信息 {nickname,length} * @param {Object} data 隧道信息 {nickname,length}
*/ */
function renderRoadPlane(data) { function renderRoadPlane(data) {
if (!demo) return; if (!demo) return;
const { nickname, length } = data; //隧道名称,长度 const {nickname, length} = data; //隧道名称,长度
demo.SignsInf(nickname, length + ""); demo.SignsInf(nickname, length + "");
} }
const changePointValue = (item) => {
if (item.equipmentId == pointValue.value.equipmentId) {
pointValue.value.value = item.value
}
hoverDevEquipmentCallback(pointValue.value)
}
defineExpose({ defineExpose({
rerender,TunnelSceneSimulateRender rerender, TunnelSceneSimulateRender, changePointValue
}); });
</script> </script>

View File

@@ -233,17 +233,17 @@ const changeNum = (item) => {
} }
} }
const setValueA = () => { const setValueA = () => {
if (electricityConsumptionMonthly.value === 0 || length.value === null) { if (electricityConsumptionMonthly.value === 0 || length.value === null||electricityConsumptionMonthly.value<0) {
valueA.value.style.height = `0px`; valueA.value.style.height = `0px`;
} }
let width = (electricityConsumptionMonthly.value * length.value?.offsetHeight) / 200000; let width = (electricityConsumptionMonthly.value * length.value?.offsetHeight) / 1000000;
valueA.value.style.height = `${width}px`; valueA.value.style.height = `${width}px`;
} }
const setValueB = () => { const setValueB = () => {
if (monthlySavings.value === 0 || length.value === null) { if (monthlySavings.value === 0 || length.value === null||monthlySavings.value<0) {
valueB.value.style.height = `0px`; valueB.value.style.height = `0px`;
} }
let width = (monthlySavings.value * length.value?.offsetHeight) / 200000; let width = (monthlySavings.value * length.value?.offsetHeight) / 1000000;
valueB.value.style.height = `${width}px`; valueB.value.style.height = `${width}px`;
} }
const getBasicData = (data) => { const getBasicData = (data) => {

View File

@@ -326,8 +326,8 @@ const handleLogout = () => {
const initWebSocket = () => { const initWebSocket = () => {
// let wsUrl = `ws://frp.toomewhy.top:38000/wstunnel/websocket/simulate/${token}/123`; // let wsUrl = `ws://frp.toomewhy.top:38000/wstunnel/websocket/simulate/${token}/123`;
// let wsUrl = `ws://192.168.31.175:9000/websocket/simulate/${token}/${serialNumber.value}`; // let wsUrl = `ws://192.168.31.175:9000/websocket/simulate/${token}/${serialNumber.value}`;
let wsUrl = `ws://tunnel.feashow.com/api/wstunnel/websocket/simulate/${token}/${serialNumber.value}`; // let wsUrl = `ws://tunnel.feashow.com/api/wstunnel/websocket/simulate/${token}/${serialNumber.value}`;
// let wsUrl = import.meta.env.VITE_BASE_WSURL+`/${token}/${serialNumber.value}`; let wsUrl = import.meta.env.VITE_BASE_WSURL+`/${token}/${serialNumber.value}`;
// let wsUrl = `ws://clay.frp.feashow.cn/wstunnel/websocket/equipment/${token}/${serialNumber.value}`; // let wsUrl = `ws://clay.frp.feashow.cn/wstunnel/websocket/equipment/${token}/${serialNumber.value}`;
// let wsUrl = `ws://frp.toomewhy.top:39000/websocket/simulate/${token}/${serialNumber.value}`; // let wsUrl = `ws://frp.toomewhy.top:39000/websocket/simulate/${token}/${serialNumber.value}`;
socket = new WebSocket(wsUrl); socket = new WebSocket(wsUrl);
@@ -348,7 +348,6 @@ const initWebSocket = () => {
data.forEach((item) => { data.forEach((item) => {
if (item.typeKey === "frequency") { if (item.typeKey === "frequency") {
socketData.leftData = data; socketData.leftData = data;
console.log(socketData.leftData);
} else if (item.typeKey === "windPressure") { } else if (item.typeKey === "windPressure") {
socketData.windPressure = data; socketData.windPressure = data;
} else if (item.typeKey === "sensor") { } else if (item.typeKey === "sensor") {
@@ -356,6 +355,9 @@ const initWebSocket = () => {
} else if (item.typeKey === "windSpeed") { } else if (item.typeKey === "windSpeed") {
socketData.windSpeed = data; socketData.windSpeed = data;
} }
nextTick(() => {
previewRef.value.changePointValue(item)
})
}); });
} }
}; };