YZProjectCloud/yanzhu-ui-vue3/src/views/manage/plan/bimSelectionDialog2.vue

549 lines
16 KiB
Vue

<template>
<el-dialog v-model="show" append-to-body :close-on-click-modal="false" :close-on-press-escape="false" :title="title" modal-class="bim-selection-dialog">
<div id="bimSelectionDlg">
<div id="bimSelectionDlgContainer" class="bimSelectionDlgContainer"></div>
</div>
<div class="div-left" :class="{ 'is-hide': !leftExpend }">
<div class="div-left-title">
<el-tabs v-model="activeTab">
<el-tab-pane label="结构树" name="a1">
<div class="model-tree scroll" :key="treeKey">
<el-tree
:key="treeKey"
ref="tree"
:default-expanded-keys="treeExpendedKeys"
:props="{
children: 'children',
label: 'title',
isLeaf: 'leaf',
}"
node-key="key"
@check="onCheckTree"
:load="loadNode"
lazy
show-checkbox></el-tree>
</div>
</el-tab-pane>
<el-tab-pane label="已关联" name="a2">
<div class="sel-list scroll" :key="selEl">
<div v-for="(it, idx) in getSelectItems(selectItems)" :key="idx" class="div-sel-item">
<el-tooltip placement="bottom" :content="it.info">
<div class="sel-item-info">{{ it.info }}</div>
</el-tooltip>
<el-button link @click="delSelectItem(idx)">删除</el-button>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="已隐藏" name="a3">
<div style="padding: 0px 10px 10px" v-show="hideParts.length > 0">
<el-button @click="delAllDelList">删除所有</el-button>
</div>
<div class="sel-list scroll hide-list" :key="hideEl">
<div v-for="(it, idx) in getSelectItems(hideParts)" :key="idx" class="div-sel-item">
<el-tooltip placement="bottom" :content="it.info">
<div class="sel-item-info">{{ it.info }}</div>
</el-tooltip>
<el-button link @click="delHideItem(idx)">删除</el-button>
</div>
</div>
</el-tab-pane>
</el-tabs>
<div class="div-icon">
<el-icon v-show="leftExpend" @click="leftExpend = false"><ArrowUpBold /></el-icon>
<el-icon v-show="!leftExpend" @click="leftExpend = true"><ArrowDownBold /></el-icon>
</div>
</div>
</div>
<div v-show="bimLoaded">
<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="cancel" />
</div>
</el-tooltip>
<el-tooltip placement="top" content="点选">
<div class="footer-btn" @click="doMenu(2)" :class="activeMenu == 2 ? 'is-active' : ''">
<svg-icon icon-class="pointselect" />
</div>
</el-tooltip>
<el-tooltip placement="top" content="框选">
<div class="footer-btn" @click="doMenu(3)" :class="activeMenu == 3 ? 'is-active' : ''">
<svg-icon icon-class="boundselect" />
</div>
</el-tooltip>
<el-tooltip placement="top" content="隐藏构件">
<div class="footer-btn" @click="doMenu(4)" :class="activeMenu == 4 ? 'is-active' : ''">
<svg-icon icon-class="hide" />
</div>
</el-tooltip>
</div>
</div>
<div class="div-mode">
<el-switch v-model="showMode" class="ml-2" inline-prompt active-text="显示模式" inactive-text="隐藏模式" @change="doModeChange" style="--el-switch-off-color: #336699" />
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="show = false">取消</el-button>
<el-button type="primary" @click="doSave"> 保存构件 </el-button>
</div>
</template>
</el-dialog>
</template>
<script>
import useUserStore from "@/store/modules/user";
import { listBimModel } from "@/api/bim/bimModel";
import bimTools from "./bimSelectTools2";
import { updateBimInfo, getPlanAllBimInfo } from "@/api/bim/bim";
import { ElMessage, ElMessageBox } from "element-plus";
export default {
data() {
return {
title: "任务计划绑定BIM",
bimLoaded: false,
loadedModelCount: 0,
show: false,
partLoad: false, //部分加载构件
plan: null,
currentPrjId: null,
currentComId: null,
models: [],
viewPoint: null,
activeTab: "a1",
initSuccess: false,
leftExpend: true,
activeMenu: 0,
treeKey: 0,
elId: 0,
selEl: 0,
hideEl: 0,
showMode: true,
selectItems: [],
allBimData: [],
treeKey: 0,
modelTrees: [],
treeExpendedKeys: ["root"],
allFeatures: [], //所有构件集合
allParts: [], //所有构件ID集合
showParts: [], //显示构件ID集合
readlyParts: [], //隐藏构件ID集合
};
},
beforeDestroy() {
let api = bimSelectionDlgApi;
if (api) {
api.Public.clearScene();
api.Public.destroy();
window.bimSelectionDlgApi = null;
}
},
methods: {
loadNode(node, resolve) {
bimTools.loadNode(this, node, resolve);
},
delAllDelList() {
this.$modal.confirm("确定删除吗?").then(() => {
let api = bimSelectionDlgApi;
api.Feature.setVisible(this.hideParts.join("#"), true);
this.hideParts = [];
this.hideEl++;
});
},
delHideItem(idx) {
let api = bimSelectionDlgApi;
let featureId = this.hideParts[idx];
api.Feature.setVisible(featureId, true);
this.hideParts.splice(idx, 1);
this.hideEl++;
},
doModeChange() {
let api = bimSelectionDlgApi;
api.Feature.setVisible(this.selectItems.join("#"), this.showMode);
},
delSelectItem(idx) {
this.$modal.confirm("确定删除吗?").then(() => {
let api = bimSelectionDlgApi;
let featureId = this.selectItems[idx];
api.Feature.setColor(featureId, "rgba(255,255,255,1)");
this.selectItems.splice(idx, 1);
this.selEl++;
});
},
onCheckTree(node, event) {
bimTools.onCheckTree(this, node, event);
},
getSelectItems(items) {
return items.map((it) => {
return { info: it };
});
},
doSave() {
updateBimInfo({
id: this.plan.id,
text: this.selectItems.length > 0 ? JSON.stringify(this.selectItems) : "",
}).then((res) => {
if (res.success) {
ElMessage.success("保存成功");
this.show = false;
this.$emit("success");
} else {
ElMessage.error("保存失败");
}
});
},
doMenu(index) {
let api = bimSelectionDlgApi;
if (api) {
if ([0, 2, 4].includes(index)) {
api.Feature.closeBoxSelect();
}
}
switch (index) {
case 0:
this.activeMenu = 0;
this.resetScene();
break;
case 1:
bimTools.clearAllSelection(this);
break;
case 2:
this.activeMenu = 2;
bimTools.selectSingle(this);
break;
case 3:
this.activeMenu = 3;
bimTools.boxSelection(this);
break;
case 4:
this.activeMenu = 4;
bimTools.hideSelection(this);
break;
}
},
showDialog(plan) {
window.bimDlg = this;
this.plan = plan;
this.show = true;
this.activeTab = "a1";
this.userStore = useUserStore();
this.currentPrjId = this.userStore.currentPrjId;
this.currentComId = this.userStore.currentComId;
this.selectItems = [];
this.allBimData = [];
this.treeKey = 0;
this.partLoad = false;
this.modelTrees = [];
this.treeExpendedKeys = [];
this.allParts = [];
this.hideParts = [];
this.readlyParts = [];
this.allFeatures = [];
this.bimLoaded = false;
this.partLoad = false;
this.elId = 0;
this.hideEl = 0;
this.showMode = true;
this.loadedModelCount = 0;
getPlanAllBimInfo(this.plan.projectId).then((res) => {
this.allBimData = (res.data || []).map((it) => {
it.bim = this.$tryToJson(it.bimId || "[]", []);
return it;
});
});
this.initEngine();
},
initEngine() {
this.elId++;
setTimeout(() => {
this.loadEngine();
}, 10);
},
loadEngine() {
window.bimSelectionDlgApi = new SAPI(
{
serverIP: window.config.serverIP, //服务ip地址
port: window.config.port, //HTTP端口
useHttps: window.config.useHttps, //使用Https
container: "bimSelectionDlgContainer", //[必须]容器id
secretKey: window.config.secretKey,
openEarth: window.config.openEarth, //[可选]开启Gis场景
bgColor: window.config.bgColor, //[可选]bim场景背景色, 传值即为纯色天空盒
tintColor: window.config.tintColor, //[可选]osgb单体化颜色
sceneTime: window.config.sceneTime, //[可选]分别为当前时间、日出时间、日落时间
cadMode: window.config.cadMode, // 是否是Cad图纸预览模式
},
() => {
this.initSuccess = true;
console.log("初始化成功");
setTimeout(() => {
this.initLoadModel();
}, 10);
let mapOptions = {
imgs: {
// 六面图片
top: "./img/top.png",
bottom: "./img/under.png",
east: "./img/east.png",
south: "./img/south.png",
west: "./img/west.png",
north: "./img/north.png",
},
offset: {
// 屏幕坐标偏移
corner: GLENavigationCube.RightTop,
x: 25,
y: 20,
},
cube: {
hoverColor: "#7193dc", // 立方导航快鼠标移过显示颜色
size: 32, // 导航立方尺寸
hotPointSize: 7, // 导航立方棱角热点区域尺寸
cubeTextColor: "#4c4c4ccc", // cube 各个面文字颜色
cubeStrokeColor: "#374769cc", // cube 各个面边框颜色
cubeFillColor: "#374769cc", // cube 各个面填充颜色
},
zoomRatios: 1, // 缩放倍率
show: true, // 是否显示
showAxes: true, // 是否显示XYZ轴线
};
bimSelectionDlgApi.Plugin.initNavCube(mapOptions);
}
);
},
initLoadModel() {
listBimModel({
pageNum: 1,
pageSize: 10,
comId: this.currentComId,
projectId: this.currentPrjId,
}).then((d) => {
this.models = (d.rows || []).map((it) => {
it.modelId = it.lightweightName;
it.gis = this.$tryToJson(it.gisJson || "{}", {});
return it;
});
this.treeKey++;
if (this.models.length == 0) {
this.$modal.msgError("暂无模型,请先关联模型");
} else {
//bimTools.buildTreeData(this);
bimTools.partLoadModel(this);
}
});
},
addModel(modelId, cb) {
let url = `${window.config.modelUrl}/Tools/output/model/${modelId}/root.glt`;
bimSelectionDlgApi.Model.add(
url,
modelId,
() => {},
() => {
cb && cb();
console.log("加载模型成功");
this.loadedModelCount++;
setTimeout(() => {
bimSelectionDlgApi.Camera.getViewPort((p) => {
this.viewPoint = p;
this.$message.info("模型加载完成");
this.bimLoaded = true;
this.doMenu(2);
});
}, 1000);
}
);
},
resetScene() {
let api = bimSelectionDlgApi;
api.Camera.stopImmersiveRoam();
api.Model.location(api.m_model.keys().toArray()[0]);
api.Plugin.deleteMiniMap();
if (this.viewPoint) {
api.Camera.setViewPort(this.viewPoint);
}
},
},
};
</script>
<style lang="scss">
.bim-selection-dialog {
.el-dialog {
min-width: 960px;
width: 80%;
height: 80vh;
.el-dialog__body {
max-height: calc(100% - 80px) !important;
overflow: hidden !important;
height: calc(100% - 80px);
#bimSelectionDlg {
height: 100%;
.bimSelectionDlgContainer {
height: 100%;
}
}
.div-left {
position: absolute;
left: 40px;
top: 80px;
width: 300px;
background: rgba(0, 57, 64, 0.6);
height: calc(100% - 180px);
border-radius: 5px;
&.is-hide {
height: 45px;
}
.div-left-title {
height: 100%;
.el-tabs {
height: 100%;
.el-tabs__content {
height: 100%;
.el-tab-pane {
height: 100%;
padding-bottom: 10px;
}
}
}
.el-tabs__nav-wrap {
.el-tabs__nav-prev,
.el-tabs__nav-next {
display: none;
}
}
.el-tabs__nav {
&::after {
content: " ";
display: block;
width: 100px;
}
.el-tabs__active-bar {
background-color: rgb(0, 255, 174);
}
.el-tabs__item {
padding: 0px 15px;
color: #fff;
&.is-active {
color: rgb(0, 255, 174);
}
}
}
.div-icon {
position: absolute;
right: 10px;
top: 8px;
z-index: 9;
.el-icon {
font-size: 24px;
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);
}
}
}
}
.sel-list {
padding: 0px 10px 10px;
height: 100%;
overflow-y: auto;
&.hide-list {
height: calc(100% - 40px);
}
.div-sel-item {
background-color: #f7f7f975;
position: relative;
color: #fff;
line-height: 30px;
padding: 0px 10px;
margin-top: 5px;
.sel-item-info {
width: calc(100% - 40px);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
}
.el-button {
position: absolute;
right: 10px;
top: 4px;
color: #f40606;
}
}
}
.model-tree {
height: calc(100% - 36px);
overflow-y: auto;
.el-tree {
background: transparent;
color: #eee;
.el-checkbox {
color: #45fdfe;
}
.el-tree-node {
&:focus {
& > .el-tree-node__content {
background: #3489d966;
&:hover {
background: #3489d966;
}
}
}
.el-tree-node__content:hover {
background: #3489d966;
}
}
}
}
.div-mode {
position: absolute;
left: 360px;
top: 75px;
.el-switch__inner {
margin: 0px 4px;
}
}
}
}
</style>