Browse Source

Merge branch 'master' of git.sagacloud.cn:web/wanda-adm

zhangyu 4 years ago
parent
commit
c7f40287ec

+ 4 - 1
package.json

@@ -13,6 +13,10 @@
     "test:unit": "jest --clearCache && vue-cli-service test:unit"
   },
   "dependencies": {
+    "@persagy-web/base": "2.2.1",
+    "@persagy-web/draw": "2.2.10",
+    "@persagy-web/graph": "2.2.40",
+    "@persagy-web/big": "2.2.43",
     "@babel/runtime": "^7.12.5",
     "axios": "^0.21.1",
     "core-js": "^3.6.5",
@@ -60,7 +64,6 @@
     "eslint-plugin-promise": "^4.2.1",
     "eslint-plugin-standard": "^4.0.2",
     "eslint-plugin-vue": "^7.1.0",
-    "fibers": "^5.0.0",
     "sass": "^1.28.0",
     "sass-loader": "^10.0.4",
     "style-resources-loader": "^1.3.3",

+ 1 - 1
src/components/public/adm-search.vue

@@ -1,6 +1,6 @@
 <template>
     <el-input
-        placeholder="请输入"
+        placeholder="请输入关键字"
         prefix-icon="el-icon-search"
         v-model="input"
         @change="handleSearch"

+ 7 - 2
src/styles/index.scss

@@ -13,7 +13,6 @@ body {
     font-size: 14px;
 }
 
-
 #app {
     height: 100%;
 }
@@ -78,8 +77,14 @@ div:focus {
 
 .el-scrollbar {
     height: 100%;
-
     .el-scrollbar__view {
         height: 100%;
     }
 }
+
+canvas {
+    outline: none;
+    &:focus {
+        outline: none;
+    }
+}

+ 181 - 0
src/utils/graph/FloorScene.ts

@@ -0,0 +1,181 @@
+import { getJsonz, ItemColor } from "@persagy-web/big/lib";
+import { SColumnItem } from "@persagy-web/big/lib/items/floor/SColumnItem";
+import { SDoorItem } from "@persagy-web/big/lib/items/floor/SDoorItem";
+import { SSpaceItem } from "@persagy-web/big/lib/items/floor/SSpaceItem";
+import { SVirtualWallItem } from "@persagy-web/big/lib/items/floor/SVirtualWallItem";
+import { SWallItem } from "@persagy-web/big/lib/items/floor/SWallItem";
+import { SWindowItem } from "@persagy-web/big/lib/items/floor/SWindowItem";
+import { Casement } from "@persagy-web/big/lib/types/floor/Casement";
+import { Column } from "@persagy-web/big/lib/types/floor/Column";
+import { Door } from "@persagy-web/big/lib/types/floor/Door";
+import { Space } from "@persagy-web/big/lib/types/floor/Space";
+import { VirtualWall } from "@persagy-web/big/lib/types/floor/VirtualWall";
+import { Wall } from "@persagy-web/big/lib/types/floor/Wall";
+import { FloorData } from "@persagy-web/big/lib/types/FloorData";
+import { SGraphScene } from "@persagy-web/graph/lib";
+
+/**
+ * 楼层平面图
+ */
+export class FloorScene extends SGraphScene {
+    /** json数据  */
+    json: string | null = null;
+    /** 墙list   */
+    wallList: SWallItem[] = [];
+    /** 柱子list   */
+    columnList: SColumnItem[] = [];
+    /** 门list   */
+    doorList: SDoorItem[] = [];
+    /** 窗list   */
+    casementList: SWindowItem[] = [];
+    /** 虚拟墙list   */
+    virtualWallList: SVirtualWallItem[] = [];
+    /** 空间list   */
+    spaceList: SSpaceItem[] = [];
+
+    /** 空间是否可选  */
+    _isSpaceSelectable: boolean = true;
+    get isSpaceSelectable(): boolean {
+        return this._isSpaceSelectable;
+    } // Get isSpaceSelectable
+    set isSpaceSelectable(v: boolean) {
+        if (this._isSpaceSelectable === v) {
+            return;
+        }
+        this._isSpaceSelectable = v;
+        this.spaceList.map(
+            (t: SSpaceItem): SSpaceItem => {
+                t.selectable = this._isSpaceSelectable;
+                return t;
+            }
+        );
+    } // Set isSpaceSelectable
+
+    constructor() {
+        super()
+        // 设置始终不出现选择器
+        this.selectContainer.showSelect = false;
+    }
+
+    /**
+     *  获取底图压缩文件
+     *
+     *  @param  url     请求数据文件路径
+     */
+    loadUrl(url: string): Promise<void> {
+        return getJsonz(url).then((res: any) => {
+            this.addBaseMapItem(res)
+            this.json = JSON.stringify(res);
+            return res;
+        })
+    } // Function loadUrl()
+
+    /**
+     *  增添所有底图item;
+     *
+     *  @param  data    itemList对象
+     */
+    private addBaseMapItem(data: FloorData): void {
+        if (data.Walls) {
+            data.Walls.forEach((t: Wall): void => {
+                this.addWall(t);
+            });
+        }
+        if (data.Columns) {
+            data.Columns.forEach((t: Column): void => {
+                this.addColumn(t);
+            });
+        }
+        if (data.Windows) {
+            data.Windows.forEach((t: Casement): void => {
+                this.addCasement(t);
+            });
+        }
+        if (data.VirtualWalls) {
+            data.VirtualWalls.forEach((t: VirtualWall): void => {
+                this.addVirtualWall(t);
+            });
+        }
+        if (data.Doors) {
+            data.Doors.forEach((t: Door): void => {
+                this.addDoor(t);
+            });
+        }
+        if (data.Spaces) {
+            data.Spaces.forEach((t: Space): void => {
+                this.addSpace(t);
+            });
+        }
+    } // Function addBaseMapItem()
+
+    /**
+     *  添加空间到scene 中
+     *
+     *  @param  space   空间item
+     */
+    addSpace(space: Space): void {
+        let item = new SSpaceItem(null, space);
+        item.selectable = this.isSpaceSelectable;
+        item.fillColor = ItemColor.spaceColor;
+        item.strokeColor = ItemColor.spaceBorderColor;
+        this.spaceList.push(item);
+        this.addItem(item);
+    } // Function addSpace()
+
+    /**
+     *  添加柱子到scene 中
+     *
+     *  @param  column   柱子item
+     */
+    addColumn(column: Column): void {
+        let item = new SColumnItem(null, column);
+        item.fillColor = ItemColor.columnColor;
+        this.columnList.push(item);
+        this.addItem(item);
+    } // Function addColumn()
+
+    /**
+     *  添加墙到scene 中
+     *
+     *  @param  wall   墙item
+     */
+    addWall(wall: Wall): void {
+        let item = new SWallItem(null, wall);
+        item.fillColor = ItemColor.wallColor;
+        this.wallList.push(item);
+        this.addItem(item);
+    } // Function addWall()
+
+    /**
+     *  添加所有虚拟墙到scene中
+     *
+     *  @param  virtualWall   虚拟墙item
+     */
+    addVirtualWall(virtualWall: VirtualWall): void {
+        let item = new SVirtualWallItem(null, virtualWall);
+        this.virtualWallList.push(item);
+        this.addItem(item);
+    } // Function addVirtualWall()
+
+    /**
+     *  添加门到scene 中
+     *
+     * @param door
+     */
+    addDoor(door: Door): void {
+        let item = new SDoorItem(null, door);
+        this.doorList.push(item);
+        this.addItem(item);
+    } // Function addDoor()
+
+    /**
+     *  添加窗户到scene 中
+     *
+     * @param casement
+     */
+    addCasement(casement: Casement): void {
+        let item = new SWindowItem(null, casement);
+        this.casementList.push(item);
+        this.addItem(item);
+    } // Function addCasement()
+}

+ 20 - 0
src/utils/graph/FloorView.ts

@@ -0,0 +1,20 @@
+import { SNetUtil } from "@persagy-web/base/lib";
+import { SGraphView } from "@persagy-web/graph/lib";
+
+/** 
+ * 楼层视图
+*/
+export class FloorView extends SGraphView {
+    /**
+       * 保存底图json
+       *
+       * @param   name    文件名
+       */
+    saveFloorJson(name: string): void {
+        // @ts-ignore
+        if (!this.scene || !this.scene.json) return;
+        // @ts-ignore
+        let url = URL.createObjectURL(new Blob([this.scene.json]));
+        SNetUtil.downLoad(name, url);
+    } // Function saveSceneSvg()
+}

+ 22 - 0
src/utils/graph/config/ItemColor.ts

@@ -0,0 +1,22 @@
+import { SColor } from "@persagy-web/draw/lib";
+
+export class ItemColor {
+  /** 墙颜色 */
+  static wallColor = new SColor("#2b2b2b");
+  /** 柱子颜色 */
+  static columnColor = SColor.Black;
+  /** 虚拟墙颜色 */
+  // static virtualWallColor = SColor.Black;
+  /** 空间颜色 */
+  static spaceColor = new SColor("#f1fffd80");
+  /** 门颜色 */
+  // static doorColor = new SColor("#f5b36f");
+  /** 窗户颜色 */
+  // static windowColor = new SColor("#fcd6ff");
+  /** 空间边框颜色 */
+  static spaceBorderColor = new SColor("#2b2b2b");
+  /** 空间,业务空间选中颜色 */
+  static selectColor = new SColor("#1abc9c");
+  /** 业务空间不可选中颜色 */
+  static zoneUnselectColor = new SColor("#cecece");
+}

+ 68 - 0
src/views/maintain/space/components/spaceGraph.vue

@@ -0,0 +1,68 @@
+<template>
+    <div id="graphContainer" ref="graphContainer">
+        <canvas id="spaceCanvas" :width="canvasWidth" :height="canvasHeight" tabindex="0"></canvas>
+    </div>
+</template>
+<script lang="ts">
+import { Vue, Component } from "vue-property-decorator";
+import { FloorView } from "@/utils/graph/FloorView";
+import { FloorScene } from "@/utils/graph/FloorScene";
+
+@Component
+export default class spaceGraph extends Vue {
+    canvasWidth = 800;
+    canvasHeight = 800;
+    view: FloorView | undefined = undefined;
+    floorMap =
+        "/image-service/common/file_get?systemId=revit&key=base/76233a3214dd11eb94d469663ce1649a.jsonz";
+    canvasLoading = false;
+
+    mounted(): void {
+        this.canvasWidth = this.$refs.graphContainer.offsetWidth;
+        this.canvasHeight = this.$refs.graphContainer.offsetHeight;
+        this.getGraph();
+    }
+
+    init(): void {
+        console.log('init');
+    }
+
+    getGraph(): void {
+        const scene = new FloorScene();
+        this.canvasLoading = true;
+        this.clearGraphy()
+        scene.loadUrl(this.floorMap).then((res) => {
+            if (this.view) {
+                this.view.scene = scene;
+            }
+            this.getGraphSuc(res);
+        });
+    }
+
+    getGraphSuc(res: any): void {
+        this.canvasLoading = false;
+        if (res == "error") {
+            this.floorMap = "";
+            this.$message.warning("数据解析异常");
+            return;
+        }
+        this.view?.fitSceneToView()
+    }
+
+    // 清除canvas
+    clearGraphy() {
+      if (this.view) {
+        this.view.scene = null;
+        return
+      }
+      this.view = new FloorView('spaceCanvas')
+    }
+}
+</script>
+<style lang="scss">
+#graphContainer {
+    position: relative;
+    width: 100%;
+    height: 100%;
+}
+</style>

+ 89 - 11
src/views/maintain/space/index.vue

@@ -1,29 +1,107 @@
 <template>
-  <div class="space-index">
-    <statistics :statistics-msg="statisticsMsg" />
-  </div>
+    <div class="space-index">
+        <statistics :statistics-msg="statisticsMsg" />
+        <el-divider class="small-divider"></el-divider>
+        <div class="tabs">
+            <el-tabs v-model="activeName" type="card">
+                <el-tab-pane label="列表" name="table"></el-tab-pane>
+                <el-tab-pane label="平面图" name="picture"></el-tab-pane>
+            </el-tabs>
+            <div class="tab-content">
+                <div class="search">
+                    <el-cascader v-model="value1" :options="options" @change="handleChange" placeholder="请选择楼层" class="item"></el-cascader>
+                    <el-cascader v-model="value2" :options="options" @change="handleChange" placeholder="请选择分区" class="item"
+                        v-if="activeName==='picture'"></el-cascader>
+                    <admSearch @SearchValue="searchValue" class="item" v-if="activeName==='table'" />
+                </div>
+                <div v-if="activeName==='table'">
+                    <admMultiTable />
+                </div>
+                <div class="graph" v-if="activeName==='picture'">
+                    <spaceGraph />
+                </div>
+            </div>
+        </div>
+    </div>
 </template>
 
 <script lang="ts">
 import { Vue, Component, Watch } from "vue-property-decorator";
 import Bus from "@/utils/bus";
-import statistics from "@/components/public/adm-statistics.vue";
+import { Statistics, AdmSearch, AdmMultiTable } from "../components/index";
+import spaceGraph from "./components/spaceGraph";
 @Component({
-    name: 'space-index',
-    components: { statistics }
+    name: "space-index",
+    components: { Statistics, AdmSearch, AdmMultiTable, spaceGraph },
 })
-export default class extends Vue {
+
+export default class spaceIndex extends Vue {
     private statisticsMsg = {
-        title: '全部空间',
-        total: 93640
+        title: "全部空间",
+        total: 93640,
+    };
+    activeName = "table";
+    value1 = ["zhinan", "shejiyuanze"];
+    value2 = [];
+    options = [
+        {
+            value: "zhinan",
+            label: "指南",
+            children: [
+                {
+                    value: "shejiyuanze",
+                    label: "设计原则",
+                },
+                {
+                    value: "yizhi",
+                    label: "一致",
+                },
+                {
+                    value: "fankui",
+                    label: "反馈",
+                },
+            ],
+        },
+    ];
+    // 建筑楼层更改
+    handleChange(v) {
+        console.log(v);
+    }
+    // 搜索
+    searchValue(val: string) {
+        console.log(val);
     }
 }
 </script>
 
-<style scoped>
-.space-index{
+<style lang="scss" scoped>
+.space-index {
     background: #fff;
     padding: 12px;
     height: 100%;
+    .small-divider {
+        margin: 12px 0;
+    }
+    .tabs {
+        position: relative;
+        height: calc(100% - 92px);
+        ::v-deep .el-tabs__header {
+            margin: 0;
+        }
+        .tab-content {
+            height: calc(100% - 41px);
+            border: 1px solid #e1e7ea;
+            border-top: none;
+            .search {
+                padding: 16px;
+                & > .item + .item {
+                    margin-left: 16px;
+                }
+            }
+            .graph{
+                height: calc(100% - 64px)
+            }
+        }
+    }
 }
 </style>