123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512 |
- <template>
- <div id="graphContainer" ref="graphContainer">
- <div v-show="floorKey" v-loading="canvasLoading">
- <el-row class="buttons-box">
- <div>
- <el-autocomplete popper-class="my-autocomplete" v-model="search" :fetch-suggestions="querySearch"
- placeholder="输入平面图中已有的业务空间名称进行查找" width="180px" @select="handleSelect">
- <i class="el-icon-search el-input__icon" slot="suffix"></i>
- <template slot-scope="{ item }">
- <div class="name"
- style="position: relative;padding-right:40px;overflow: hidden;text-overflow:ellipsis;white-space: nowrap;"
- :title="item.data.RoomLocalName">
- {{ item.data.RoomLocalName }}
- <span class="addr" style="position: absolute;right:0;color:#409EFF;">定位</span>
- </div>
- </template>
- </el-autocomplete>
- </div>
- <div class="button-group">
- <!-- 默认操作模式 -->
- <div v-show="type==1">
- <el-dropdown split-button type="primary" @click="editGraphy" @command="handleCommand">
- 创建业务空间
- <el-dropdown-menu slot="dropdown">
- <!-- <el-dropdown-item command="groupCreateBSpace">批量创建业务空间</el-dropdown-item> -->
- <el-dropdown-item command="createWall">创建墙体</el-dropdown-item>
- </el-dropdown-menu>
- </el-dropdown>
- <!-- 点击已经关联的业务空间 -->
- <el-button plain @click="refactorBSP" :disabled="zoneDisable" style="margin-left:10px;">编辑业务空间</el-button>
- <!-- <el-button plain :disabled="zoneDisable" style="margin-left:10px;">维护空间信息</el-button> -->
- <el-button plain @click="cancelGraphy" v-show="!zoneDisable">取 消</el-button>
- </div>
- <!-- 点击未关联的业务空间 -->
- <div v-show="type==3">
- <el-button plain @click="createNewZone">创建单个全新的业务空间</el-button>
- <el-button plain @click="cancelGraphy">取 消</el-button>
- </div>
- <!-- 重新划分业务空间 -->
- <div v-show="type==4">
- <el-button plain @click="cancelGraphy">取 消</el-button>
- <el-button type="primary" @click="saveRefactorBSP">保存</el-button>
- </div>
- <!-- 批量创建所选业务空间 -->
- <div v-show="type==5">
- <el-button type="primary" @click="groupCreateZone">批量创建所选业务空间</el-button>
- <el-button plain @click="cancelGraphy">取 消</el-button>
- </div>
- </div>
- </el-row>
- <canvas id="spaceCanvas" :width="canvasWidth" :height="canvasHeight" tabindex="0"></canvas>
- <el-row class="canvas-actions-box">
- <canvas-fun :config="config" @fit="fit" @savePng="savePng" @saveSvg="saveSvg" @divide="divide" @clearDivide="clearDivide"
- ref="canvasFun" @saveJson="saveJson" @changeAbsorb="changeAbsorb" @scale="scale" @groupSelect="groupSelect" />
- </el-row>
- </div>
- <div v-show="!floorKey">
- <p style="text-align:center;margin-top:199px;">
- 暂无数据
- </p>
- </div>
- <!-- 创建新的业务空间 -->
- <createBSP ref="createBSP" @createRoom="createRoom"></createBSP>
- </div>
- </template>
- <script lang="ts">
- import { Vue, Component, Watch } from "vue-property-decorator";
- import { FloorView } from "@/utils/graph/FloorView";
- import { FloorScene } from "@/utils/graph/FloorScene";
- import canvasFun from "./canvasFun.vue";
- import {
- queryZone,
- queryIspace,
- createZone,
- updateZone,
- } from "@/api/datacenter";
- import createBSP from "./createBSP";
- import colorArr from "@/utils/graph/config/zoneColor";
- import { SObject } from "@persagy-web/base/lib";
- import { ItemColor } from "@persagy-web/big/lib";
- import { SSpaceItem } from "@persagy-web/big/lib/items/floor/SSpaceItem";
- import { SZoneItem } from "@persagy-web/big/lib/items/floor/ZoneItem";
- @Component({
- components: { canvasFun, createBSP },
- })
- export default class spaceGraph extends Vue {
- canvasWidth = 800;
- canvasHeight = 800;
- view: FloorView | null = null;
- scene: FloorScene | null = null;
- mapBaseUrl = "/image-service/common/file_get?systemId=revit&key=";
- canvasLoading = false;
- type = 1;
- config = {
- isEdit: false,
- divide: true,
- groupSelect: false,
- };
- search = ""; //搜索
- zoneDisable = true;
- curZoneItem = {};
- zoneList = [];
- buildFloor: string[] = [];
- floor = {}; // 当前楼层对象
- floorKey = ""; // 当前楼层底图请求完整url
- curZoneType = "";
- allzone = [];
- BSPRelaISPList = [];
- businessSpaceList = [];
- BIMIDToSID = {};
- BIMIDToSIName = {};
- sourceIdToISP = {};
- // 挂载
- mounted(): void {
- this.canvasWidth = this.$refs.graphContainer.offsetWidth;
- this.canvasHeight = this.$refs.graphContainer.offsetHeight;
- this.getGraph();
- }
- // 父组件调用查询楼层底图
- getData(floor, zoneType) {
- this.curZoneType = zoneType[zoneType.length - 1];
- this.canvasLoading = true;
- if (floor.infos && floor.infos.floorMap) {
- this.floor = floor;
- this.floorKey = this.mapBaseUrl + floor.infos.floorMap;
- this.init(1);
- } else {
- this.noMap();
- }
- }
- // 无底图时操作
- noMap() {
- this.floorKey = "";
- this.canvasLoading = false;
- }
- // 初始化
- init(initType: number): void {
- this.type = 1;
- if (this.scene) {
- this.scene.selectContainer.clear();
- this.scene.initSpaceColor();
- this.zoneDisable = true;
- this.scene.isZoneSelectable = true;
- this.scene.isSpaceSelectable = false;
- }
- if (
- this.buildFloor.indexOf("all") > -1 ||
- this.buildFloor.indexOf("noKnow") > -1
- ) {
- return;
- }
- if (initType == 1) {
- // 底图
- this.getGraph();
- } else {
- // 业务空间
- this.getBussiness();
- }
- this.config = {
- isEdit: false,
- divide: true,
- groupSelect: true,
- };
- // 获取当前楼层的元空间
- this.getFloorISpace();
- }
- // 获取底图
- getGraph(): void {
- const scene = new FloorScene();
- this.canvasLoading = true;
- this.clearGraphy();
- this.scene = null;
- scene.loadUrl(this.floorKey).then((res) => {
- if (this.view) {
- this.view.scene = scene;
- }
- this.scene = scene;
- this.getGraphSuc(res);
- });
- }
- // 获取底图成功
- getGraphSuc(res: any): void {
- this.canvasLoading = false;
- if (res == "error") {
- this.noMap();
- this.$message.warning("数据解析异常");
- return;
- }
- if (this.view) {
- this.view.fitSceneToView();
- this.view.minScale = this.view.scale;
- }
- if (this.$refs.canvasFun) {
- // @ts-ignore
- this.$refs.canvasFun.everyScale = this.view.scale;
- }
- if (this.scene) {
- this.scene.changeSelect = this.changeSelect;
- this.scene.isSpaceSelectable = false;
- }
- this.getBussiness();
- this.canvasLoading = false;
- }
- // 清除canvas
- clearGraphy() {
- if (this.view) {
- this.view.scene = null;
- return;
- }
- this.view = new FloorView("spaceCanvas");
- }
- // 搜索
- querySearch(queryString: string, cb: Function) {
- let restaurants = this.zoneList;
- let results = queryString
- ? restaurants.filter(this.createFilter(queryString))
- : restaurants;
- // 调用 callback 返回建议列表的数据
- cb(results);
- }
- // 过滤器
- createFilter(queryString: any) {
- return (restaurant: any) => {
- return restaurant.data.RoomLocalName.indexOf(queryString) > -1;
- };
- }
- // 查询选中,定位
- handleSelect(zone) {
- // 清空选中
- this.scene?.selectContainer.clear();
- this.curZoneItem = zone;
- this.scene?.selectContainer.setItem(zone);
- this.zoneDisable = false;
- this.view.fitSelectedToView();
- }
- // 点击创建业务空间
- editGraphy() {
- this.type = 3;
- this.config.isEdit = true;
- this.config.groupSelect = false;
- this.config.divide = true;
- this.scene!.isSpaceSelectable = true;
- this.scene!.isZoneSelectable = false;
- this.view?.update();
- console.log(12312312);
- }
- // 创建新的业务空间
- createNewZone() {
- let arr = this.scene?.selectContainer.itemList;
- if (arr.length) {
- let tempArr = [];
- arr.map((t) => {
- tempArr.push(this.BIMIDToSIName[t.data.SourceId]);
- });
- this.$refs.createBSP.showDialog(tempArr.toString());
- } else {
- this.$message.warning("请至少选择一个空间");
- }
- }
- handleCommand() {}
- // 编辑业务空间
- refactorBSP() {
- this.scene!.isZoneSelectable = false;
- this.scene!.isSpaceSelectable = true;
- this.type = 4;
- this.curZoneItem.visible = false;
- }
- editeSpaceDetail() {}
- // 获取元空间
- getFloorISpace() {
- const pa = {
- floorId: this.floor.id,
- buildingId: this.floor.buildingId,
- pageSize: 2000,
- };
- queryIspace(pa).then((res) => {
- if (res.message == this.floor.id) {
- this.BIMIDToSID = {};
- this.BIMIDToSIName = {};
- this.sourceIdToISP = {};
- res.content.map((t) => {
- let key = t.bimId.split(":")[1];
- this.BIMIDToSID[key] = t.id;
- this.BIMIDToSIName[key] = t.localName || t.name;
- this.sourceIdToISP[key] = t;
- });
- }
- });
- }
- // 获取业务空间
- getBussiness() {
- const pa = {
- filters: `classCode='${this.curZoneType}';floorId='${this.floor.id}';buildingId='${this.floor.buildingId}'`,
- pageSize: 2000,
- };
- this.canvasLoading = true;
- queryZone(pa).then((res) => {
- // if (res.FloorId == this.buildFloor[1] && res.ZoneType == tempType) {
- // 所有业务空间
- this.businessSpaceList = res.content;
- // 已关联元空间的业务空间
- this.BSPRelaISPList = [];
- res.content.map((t) => {
- if (t.outline && t.outline.length) {
- this.BSPRelaISPList.push(t);
- }
- });
- // 绘制业务空间
- let tempArr = this.BSPRelaISPList.map((t, i) => {
- return {
- RoomLocalName: t.localName || t.name,
- OutLine: t.outline,
- RoomID: t.id,
- Color: colorArr[i % colorArr.length],
- };
- }).filter((item) => item);
- console.log(this.scene);
- this.scene.removeAllZone();
- this.scene.addZoneList(tempArr);
- this.zoneList = this.scene.zoneList;
- this.view.update();
- this.canvasLoading = false;
- // }
- });
- }
- // 取消(所有取消公用)
- cancelGraphy() {
- this.init(2);
- }
- // 重新划分业务空间保存
- saveRefactorBSP() {
- const arr = this.scene?.selectContainer.itemList;
- const zoneObj = {
- id: this.curZoneItem.data.RoomID,
- classCode: this.curZoneType,
- outline: [],
- };
- if (arr.length) {
- arr?.forEach((t) => {
- zoneObj.outline.push(t.data.OutLine);
- });
- }
- const pa = {
- content: [zoneObj]
- }
- this.canvasLoading = true;
- updateZone(pa).then((res) => {
- this.$message.success("更新成功");
- this.init(2);
- });
- }
- groupCreateZone() {}
- //
- changeSelect(selectContainer: SObject, data: any[]) {
- if (data.length) {
- if (data[0].length) {
- if (data[0][0] instanceof SSpaceItem) {
- this.scene?.initSpaceColor();
- } else if (data[0][0] instanceof SZoneItem) {
- this.scene?.initZoneColor();
- this.zoneDisable = false;
- this.curZoneItem = data[0][0];
- }
- }
- data[0].forEach((t) => {
- t.fillColor = ItemColor.selectColor;
- });
- } else {
- this.scene?.initSpaceColor();
- this.scene?.initZoneColor();
- this.zoneDisable = true;
- }
- }
- // 根据图创建新的业务空间-弹窗返回确认创建
- createRoom(val) {
- const zoneObj = {
- outline: [],
- localName: val,
- buildingId: this.floor.buildingId,
- floorId: this.floor.id,
- classCode: this.curZoneType,
- };
- let arr = this.scene?.selectContainer.itemList;
- arr?.forEach((t) => {
- zoneObj.outline.push(t.data.OutLine);
- });
- const pa = {
- content: [zoneObj],
- };
- this.canvasLoading = true;
- createZone(pa).then((res) => {
- this.$message.success("创建成功");
- this.init(2);
- });
- }
- // 适配底图到窗口
- fit() {
- this.view?.fitSceneToView();
- }
- // 保存为png
- savePng() {
- this.view?.saveImage(`1.png`, "png");
- }
- // 保存为svg
- saveSvg() {
- this.view?.saveSceneSvg(`1.svg`, 6400, 4800);
- }
- // 保存json
- saveJson() {
- this.view?.saveFloorJson(`1.json`);
- }
- // 切割划分
- divide() {
- this.scene.isCutting = true;
- }
- // 清除切割划分
- clearDivide() {
- // @ts-ignore
- this.view!.scene.clearCut();
- }
- // 缩放
- scale(val: number) {
- if (!this.view) {
- return;
- }
- let scale = this.view.scale;
- this.view.scaleByPoint(
- val / scale,
- this.canvasWidth / 2,
- this.canvasHeight / 2
- );
- }
- groupSelect() {
- console.log("groupSelect");
- }
- changeAbsorb() {
- console.log("changeAbsorb");
- }
- @Watch("view.scale", { immediate: true, deep: true })
- onScaleChange(n: number) {
- if (this.$refs.canvasFun) {
- // @ts-ignore
- let s = (n * 10) / this.view.minScale;
- // @ts-ignore
- this.$refs.canvasFun.sliderVal = s > 1000 ? 1000 : s;
- }
- }
- }
- </script>
- <style lang="scss">
- #graphContainer {
- position: relative;
- width: 100%;
- height: 100%;
- .canvas-actions-box {
- position: absolute;
- bottom: 14px;
- left: 50%;
- transform: translateX(-50%);
- z-index: 99;
- }
- .buttons-box {
- position: absolute;
- top: 16px;
- left: 0;
- padding: 0 16px;
- width: 100%;
- z-index: 999;
- & > div {
- float: left;
- }
- .el-autocomplete {
- display: inline-block;
- width: 320px;
- margin-right: 10px;
- }
- .button-group button,
- .button-group .el-dropdown {
- display: block;
- float: left;
- }
- .my-autocomplete {
- li {
- line-height: normal;
- padding: 7px;
- .name {
- text-overflow: ellipsis;
- overflow: hidden;
- }
- .addr {
- font-size: 12px;
- color: #b4b4b4;
- }
- .highlighted .addr {
- color: #ddd;
- }
- }
- }
- }
- }
- </style>
|