YZProjectCloud/yanzhu-ui-vue3/src/views/bim/sandTableSetting/index.vue

592 lines
16 KiB
Vue

<template>
<div class="bim-sand-table-setting app-container2">
<div id="bimSandTableSetting" :key="elId">
<div id="bimSandTableSettingContainer" class="bimSandTableSettingContainer"></div>
</div>
<div class="footer-box" v-if="models.length > 0">
<el-tooltip placement="top" content="主视图">
<div class="footer-btn" @click="doMenu(0)" :class="activeMenu == 0 ? 'is-active' : ''">
<svg-icon icon-class="home" />
</div>
</el-tooltip>
<el-tooltip placement="top" content="视频监控">
<div class="footer-btn" @click="doMenu(1)" :class="activeMenu == 1 ? 'is-active' : ''">
<svg-icon icon-class="videoMonitor" />
</div>
</el-tooltip>
<el-tooltip placement="top" content="基坑监控">
<div class="footer-btn" @click="doMenu(2)" :class="activeMenu == 2 ? 'is-active' : ''">
<svg-icon icon-class="pitMonitor" />
</div>
</el-tooltip>
<el-tooltip placement="top" content="塔机监控">
<div class="footer-btn" @click="doMenu(3)" :class="activeMenu == 3 ? 'is-active' : ''">
<svg-icon icon-class="towerMonitor" />
</div>
</el-tooltip>
<el-tooltip placement="top" content="电箱监控">
<div class="footer-btn" @click="doMenu(4)" :class="activeMenu == 4 ? 'is-active' : ''">
<svg-icon icon-class="power" />
</div>
</el-tooltip>
</div>
<div class="bim-setting-tools" v-show="activeMenu > 0">
<div class="tools-title">
<svg-icon icon-class="videoMonitor" v-if="activeMenu == 1" />
<svg-icon icon-class="pitMonitor" v-if="activeMenu == 2" />
<svg-icon icon-class="towerMonitor" v-if="activeMenu == 3" />
<svg-icon icon-class="power" v-if="activeMenu == 4" />
{{ title }}
</div>
<el-icon @click="doToolsClose" style="color: #000; font-size: 20px; cursor: pointer" class="tools-close">
<Close />
</el-icon>
<div class="device-list scroll">
<div class="device-item" v-for="(item, index) in devices" :key="index">
<div class="device-name">
<svg-icon icon-class="videoMonitor" v-if="activeMenu == 1" />
<svg-icon icon-class="pitMonitor" v-if="activeMenu == 2" />
<svg-icon icon-class="towerMonitor" v-if="activeMenu == 3" />
<svg-icon icon-class="power" v-if="activeMenu == 4" />
{{ item.name }}
</div>
<el-switch v-model="item.show" size="small" />
<svg-icon icon-class="position" class="guide" @click="getPosition(item, index)" />
</div>
</div>
<div class="tools-bottom">
<el-button type="primary" @click="doSave" :loading="loading"></el-button>
</div>
</div>
<div class="test-box">
<div class="tag-box">
<img :src="'images/2.png'" alt="" />
<span class="tag-txt" style="color: #ffffff; font-size: 14px">
<img :src="'images/videoMonitor.svg'" style="width: 20px; height: 20px" />
aaa</span>
</div>
</div>
</div>
</template>
<script>
import useUserStore from "@/store/modules/user";
import { listBimModel } from "@/api/bim/bimModel";
import { ElMessage, ElMessageBox, ElTooltip } from "element-plus";
import { emitter } from "@/router/index.js";
import { devicePositionGet, devicePositionAddItems, devicePositionUpdateItems, getDefaultViewPoint } from "@/api/bim/bim.js";
import { getProjectBimConfig } from "@/api/manage/proProjectInfo.js";
import { debounce } from "lodash-es";
import BimTools from '../bimTools'
export default {
name: "SandTableSetting",
components: {
// attItem
ElTooltip
},
data() {
return {
currentPrjId: null,
currentComId: null,
models: [],
elId: 1,
activeMenu: 0,
title: "",
devices: [],
positionByModalId: "",
selItem: null,
addLabels: [],
viewPoint: null,
loading: false,
bimCfg: {},
isClient: false,
};
},
created() {
emitter.on("routeChanged", ({ to, from }) => {
if (to.name === "SandTableSetting") {
this.initEngine();
}
// 在这里可以添加你需要执行的逻辑
});
},
beforeUnmount() {
emitter.off("routeChanged");
document.body.classList.remove("is-sapi");
},
mounted() {
this.userStore = useUserStore();
this.currentPrjId = this.userStore.currentPrjId;
this.currentComId = this.userStore.currentComId;
document.body.classList.add("is-sapi");
getProjectBimConfig(this.currentPrjId).then(d => {
let config = this.$tryToJson(d.msg, {});
this.bimCfg = {
background: config.background || "",
showGis: config.showGis || false,
clientApi: config.clientApi || false
}
this.isClient = this.bimCfg.clientApi;
this.initEngine();
});
},
methods: {
doSave: debounce(function () {
this.toSave();
}, 300),
toSave() {
ElMessageBox.confirm("确认保存修改?", "提示", {
type: "warning",
confirmButtonText: "确 认",
cancelButtonText: "取 消",
}).then(() => {
this.loading = true
let adds = this.devices
.filter((item) => {
return item.id == null;
})
.map((item) => {
return {
deviceId: item.deviceId,
deviceType: item.deviceType,
projectId: this.currentPrjId,
position: JSON.stringify(item.position),
enabled: item.show ? 1 : 0,
currentUser: this.userStore.name,
remark: "",
};
});
let updates = this.devices
.filter((item) => {
return item.id != null;
})
.map((item) => {
return {
id: item.id,
position: JSON.stringify(item.position),
currentUser: this.userStore.name,
enabled: item.show ? 1 : 0,
};
});
let ajaxs = [];
if (adds.length > 0) {
ajaxs.push(devicePositionAddItems({ items: adds }));
}
if (updates.length > 0) {
ajaxs.push(devicePositionUpdateItems({ items: updates }));
}
Promise.all(ajaxs).then((res) => {
this.loading = false
ElMessage.success("保存成功");
});
});
},
clearLabels() {
this.addLabels.forEach((id) => {
if (this.isClient) {
window.sandSettingApi.Label.removeCustomHtml(id);
} else {
window.sandSettingApi.Label.removeBalloon(id);
}
});
this.addLabels = [];
},
addDeviceLabel() {
this.devices.forEach((d) => {
if (d.position && d.position.length > 0) {
if (this.isClient) {
this.AddClientLable(d)
} else {
this.AddLable(d);
}
}
});
},
AddClientLable(item) {
let img = "videoMonitor";
if (this.activeMenu == 1) {
img = "videoMonitor";
} else if (this.activeMenu == 2) {
img = "pitMonitor";
} else if (this.activeMenu == 3) {
img = "towerMonitor";
} else if (this.activeMenu == 4) {
img = "power";
}
let html = `
<div class='tag-box-client' style='width:230px;height:228px'>
<img class='tag-img' src='/cdn/bim/sapi/images/2.png' alt=''>
<img src="/cdn/bim/sapi/images/red.svg" class='tag-svg'>
<div class='tag-box'>
<span class='tag-txt' style=''>
<img src='/cdn/bim/sapi/images/${img}.png' style="width:20px;height:20px;">
${item.name}
</span>
</div>
</div>`;
window.sandSettingApi.Label.addCustomHtml({
axisType: 1,
attachmentPoint: 2,
displayRange: [0, 1000],
maxDistance: 1000,
html: html,
id: item.elId,
position: item.position
});
this.addLabels.push(item.elId);
},
AddLable: function (item) {
let img = "videoMonitor";
if (this.activeMenu == 1) {
img = "videoMonitor";
} else if (this.activeMenu == 2) {
img = "pitMonitor";
} else if (this.activeMenu == 3) {
img = "towerMonitor";
} else if (this.activeMenu == 4) {
img = "power";
}
let html = `<style>
.tag-box{position: relative;}
.tag-txt{position: absolute;top:30%;left: 50%;transform: translate(-50%, -50%);
text-align: center;color: #ffffff;display: flex;font-size:12px;}</style>
<div class='tag-box'>
<img src='/cdn/bim/sapi/images/2.png' alt='' style='top:6px;position: relative;'>
<span class='tag-txt' style='color:#ffffff;font-size:14px'>
<img src='/cdn/bim/sapi/images/${img}.png' style="width:20px;height:20px;">
${item.name}
</span>
</div>`;
window.sandSettingApi.Label.addBalloon({
Html: html,
ID: item.elId,
Pivot:2,
Position: item.position,
Title: item.name,
MaxDistance: 1e6,
});
this.addLabels.push(item.elId);
},
getPosition(item, index) {
this.selItem = item;
let api = window.sandSettingApi;
api.Public.clearHandler();
ElMessage.info("请在场景中左键拾取坐标位置,右键取消");
api.Public.event("RIGHT_CLICK", (e) => {
api.Public.clearHandler();
ElMessage.info("已取消拾取");
});
if (this.isClient) {
this.getCLientPosition(item, index);
return;
}
api.Public.pickupCoordinate(false);
api.Public.event("LEFT_CLICK", (e) => {
api.Feature.getByPosition([e.x, e.y], (n) => {
if (n && n["id"]) {
this.positionByModalId = n.id.split("^")[0];
} else {
ElMessage.warning("请在模型上选点!");
}
});
});
api.Public.pickupCoordinate(true, (e) => {
if (!this.positionByModalId) {
return;
}
this.selItem.position = e;
api.Label.removeBalloon(item.elId);
this.AddLable(this.selItem);
api.Public.pickupCoordinate(false);
api.Public.clearHandler();
});
},
getCLientPosition(item, index) {
let api = window.sandSettingApi;
api.Public.event("LEFT_CLICK", (e) => {
if (this.isClient) {
api.Feature.getByEvent(e.position, (json) => {
if (json != undefined) {
if (json && json["id"]) {
this.positionByModalId = json.id.split("^")[0];
api.Public.pickupCoordinate(e.position, pos => {
this.selItem.position = pos;
api.Label.removeBalloon(item.elId);
this.AddClientLable(this.selItem);
api.Public.clearHandler();
});
} else {
ElMessage.warning("请在模型上选点!");
}
}
},false);
}
});
},
doToolsClose() {
this.activeMenu = 0;
this.resetScene();
},
resetScene() {
this.clearLabels();
sandSettingApi.Camera.stopImmersiveRoam();
sandSettingApi.Model.location(sandSettingApi.m_model.keys().toArray()[0]);
if(!this.isClient){
sandSettingApi.Plugin.deleteMiniMap();
}
if (this.viewPoint) {
sandSettingApi.Camera.setViewPort(this.viewPoint);
}
},
doMenu(n) {
if (n == this.activeMenu) {
if (n == 0) {
this.resetScene();
}
return;
}
this.activeMenu = n;
if (n == 1) {
this.title = "视频监控";
} else if (n == 2) {
this.title = "基坑监控";
} else if (n == 3) {
this.title = "塔机监控";
} else if (n == 4) {
this.title = "电箱监控";
}
this.loadPoisionData();
},
loadPoisionData() {
devicePositionGet({ projectId: this.currentPrjId }).then((d) => {
let cnt = 0;
this.devices = (d.data || [])
.filter((item) => item.deviceType == this.activeMenu)
.map((item) => {
item.show = item.enabled != 0;
item.position = this.$tryToJson(item.position, []);
item.elId = "label_" + (item.id ? item.id : cnt++) + "_" + item.deviceType;
return item;
});
this.clearLabels();
this.addDeviceLabel();
});
},
initEngine() {
this.elId++;
this.activeMenu = 0;
setTimeout(() => {
BimTools.initEngine("sandSettingApi", "bimSandTableSettingContainer", this.bimCfg, () => {
this.initLoadModel();
})
}, 10);
},
initLoadModel() {
getDefaultViewPoint(this.currentPrjId, 1).then(d => {
let pt = "";
if (d.data && d.data.length > 0) {
pt = d.data[0].viewPosition;
pt = this.$tryToJson(pt, null);
}
if (pt) {
this.viewPoint = pt;
}
});
listBimModel({
pageNum: 1,
pageSize: 10,
comId: this.currentComId,
projectId: this.currentPrjId,
}).then((d) => {
this.models = (d.rows || []).map((it) => {
it.modelId = it.lightweightName;
it.bimCfg = this.$tryToJson(it.bimConfig || "{}", {});
it.visible = false;
it.checked = true;
it.gis = this.$tryToJson(it.gisJson || "{}", {});
return it;
});
if (this.models.length == 0) {
ElMessage.error("暂无模型,请先关联模型");
} else {
BimTools.addModelList(window.sandSettingApi, this.bimCfg, this.models, (hideParts) => {
setTimeout(() => {
BimTools.setDefaultViewPoint(window.sandSettingApi, this.bimCfg, this.viewPoint)
BimTools.hideParts(window.sandSettingApi, hideParts);
this.resetScene();
}, 1000);
});
}
});
},
},
};
</script>
<style lang="scss">
.bim-sand-table-setting {
position: absolute;
height: calc(100% - 0px);
width: 100%;
#bimSandTableSetting {
height: 100%;
#bimSandTableSettingContainer {
height: 100%;
.tag-box-client {
width: 100%;
.tag-box {
height: 120px;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
position: relative;
}
.tag-svg {
width: 38px;
height: 38px;
position: absolute;
bottom: -17px;
left: 50%;
margin-left: -19px;
}
.tag-img {
position: absolute;
}
.tag-txt {
font-size: 16px;
color: #fff;
}
}
}
}
.footer-box {
position: absolute;
bottom: 6vh;
left: 50%;
margin-left: -75px;
background: #274754;
border-radius: 4px;
.footer-btn {
display: inline-flex;
width: 40px;
height: 40px;
justify-content: center;
align-items: center;
cursor: pointer;
svg {
width: 20px;
height: 20px;
fill: #fff;
}
&:hover {
background: #408edb97;
}
&.is-active {
svg {
fill: rgb(0, 255, 174);
}
}
}
}
.bim-setting-tools {
position: absolute;
top: 80px;
right: 10px;
background: rgba(255, 255, 255, 0.5);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
min-width: 300px;
min-height: 400px;
padding-bottom: 50px;
.tools-title {
padding: 10px;
color: #114c5f;
size: 24px;
}
.tools-close {
position: absolute;
top: 10px;
right: 10px;
cursor: pointer;
}
.device-list {
padding: 0px 10px;
max-height: 60vh;
overflow-y: auto;
.device-item {
display: flex;
align-items: center;
.device-name {
flex-grow: 1;
font-size: 12px;
.svg-icon {
fill: #19849f;
}
}
.guide {
cursor: pointer;
color: #409eff;
margin: 10px;
}
}
}
.tools-bottom {
position: absolute;
bottom: 10px;
width: 100%;
text-align: center;
}
}
.test-box {
position: absolute;
display: none;
top: 10px;
left: 10px;
.tag-box {
position: relative;
}
.tag-txt {
position: absolute;
top: 30%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
color: #ffffff;
display: flex;
}
}
}
</style>