Browse Source

1.feat> 新增底图显隐功能
2.feat> 新增修改画布背景色功能

yunxing 4 năm trước cách đây
mục cha
commit
5b09fefd6e

+ 114 - 26
src/components/editview/basePlanEditer.vue

@@ -53,6 +53,7 @@ export default {
             changeScaleByClick: false, //区分滚轮,点击 事件改变的缩放比例
             initScale: 1,
             planLoading: true, //平面图顶部loading提示
+            parser: null, //底图解析后的数据
         };
     },
     computed: {
@@ -107,7 +108,6 @@ export default {
         this.$once("hook:beforeDestroy", () => {
             clearInterval(this.autoSave);
         });
-
     },
     methods: {
         ...mapMutations([
@@ -123,6 +123,7 @@ export default {
             "INITSTYLE",
             "INITRULELIST",
             "INITOBJEXTINFO",
+            "ADDSTYLE",
         ]),
 
         // 清空画布
@@ -140,13 +141,14 @@ export default {
         init() {
             this.clearImg();
             this.view ? (this.view.scene = this.scene) : null;
-            // 判断是否有楼层底图,有则获取数据并解析
-            if (this.floorMap) this.getMapBlob();
             // 读取平面图数据
-            this.readPlanMsg();
+            this.readPlanMsg().then((showBaseMap) => {
+                // 判断是否有楼层底图,有则获取数据并解析
+                if (this.floorMap) this.getMapBlob(showBaseMap);
+            });
         },
         // 请求获取地图的压缩包
-        getMapBlob() {
+        getMapBlob(showBaseMap) {
             if (this.floorMap.includes("png") || this.floorMap.includes("jpg")) {
                 const url = `/image-service/common/image_get?systemId=dataPlatform&key=${this.floorMap}`;
                 this.getImage(url);
@@ -154,7 +156,7 @@ export default {
                 const url = `/image-service/common/file_get?systemId=revit&key=${this.floorMap}`;
                 getJsonz(url).then((data) => {
                     // 解析数据并放入压缩包中
-                    this.parserData(data);
+                    this.parserData(data, showBaseMap);
                 });
             }
         },
@@ -170,12 +172,22 @@ export default {
             });
         },
         // 解析数据并注入 scene 类中
-        parserData(data) {
+        parserData(data, showBaseMap) {
+            // 修改 vuex 底图显隐
+            this.ADDSTYLE({
+                id: "defaultMapStyle",
+                style: {
+                    ...this.styleMap.defaultMapStyle,
+                    showBaseMap, //显隐值
+                },
+            });
             const parser = new SFloorParser();
             parser.parseData(data);
+            this.parser = parser;
             parser.spaceList.forEach((t) => {
                 //是否显示空间
                 // t.visible = this.isSpaceSelectable;
+                t.visible = showBaseMap;
                 //设置样式
                 Object.assign(t, this.baseMapStyle.default);
                 //是否展示名称
@@ -190,6 +202,7 @@ export default {
             parser.wallList.forEach((t) => {
                 // 是否显示
                 // t.visible = this.isShowWall;
+                t.visible = showBaseMap;
                 // 是否可选
                 t.selectable = false;
                 this.scene.addItem(t);
@@ -197,6 +210,7 @@ export default {
             parser.virtualWallList.forEach((t) => {
                 // 是否显示
                 // t.visible = this.isShowVirtualWall;
+                t.visible = showBaseMap;
                 // 是否可选
                 t.selectable = false;
                 this.scene.addItem(t);
@@ -204,6 +218,7 @@ export default {
             parser.doorList.forEach((t) => {
                 // 是否显示
                 // t.visible = this.isShowDoor;
+                t.visible = showBaseMap;
                 // 是否可选
                 t.selectable = false;
                 this.scene.addItem(t);
@@ -211,6 +226,7 @@ export default {
             parser.columnList.forEach((t) => {
                 // 是否显示
                 // t.visible = this.isShowColumn;
+                t.visible = showBaseMap;
                 // 是否可选
                 t.selectable = false;
                 this.scene.addItem(t);
@@ -218,6 +234,7 @@ export default {
             parser.casementList.forEach((t) => {
                 // 是否显示
                 // t.visible = this.isShowWindow;
+                t.visible = showBaseMap;
                 // 是否可选
                 t.selectable = false;
                 this.scene.addItem(t);
@@ -365,9 +382,62 @@ export default {
             });
             // 更改对齐方式
             bus.$off("changeAlignItem");
-            bus.$on("changeAlignItem", val => {
+            bus.$on("changeAlignItem", (val) => {
                 this.scene.changeAlignItem(val);
             });
+            // 底图显隐
+            bus.$off("showBaseMap");
+            bus.$on("showBaseMap", (val) => {
+                this.showBaseMapFn(val);
+            });
+            // 更改背景色
+            bus.$off("changeBackgroundColor");
+            bus.$on("changeBackgroundColor", (val) => {
+                this.changeBackgroundColor(val);
+            });
+        },
+        // 更改底图背景色
+        changeBackgroundColor(backgroundColor) {
+            // 更新 vuex 中 styleMap 下 defaultMapStyle 的 backgroundColor 值
+            this.ADDSTYLE({
+                id: "defaultMapStyle",
+                style: {
+                    ...this.styleMap.defaultMapStyle,
+                    backgroundColor, //背景色
+                },
+            });
+            this.scene.changeBackgroundColor(backgroundColor);
+        },
+        // 是否显示底图
+        showBaseMapFn(val) {
+            // 更新 vuex 中 styleMap 下 defaultMapStyle 的 showBaseMap 值
+            this.ADDSTYLE({
+                id: "defaultMapStyle",
+                style: {
+                    ...this.styleMap.defaultMapStyle,
+                    showBaseMap: val, //显隐值
+                },
+            });
+            const { parser } = this;
+            parser.spaceList.forEach((t) => {
+                //是否显示空间
+                t.visible = val;
+            });
+            parser.wallList.forEach((t) => {
+                t.visible = val;
+            });
+            parser.virtualWallList.forEach((t) => {
+                t.visible = val;
+            });
+            parser.doorList.forEach((t) => {
+                t.visible = val;
+            });
+            parser.columnList.forEach((t) => {
+                t.visible = val;
+            });
+            parser.casementList.forEach((t) => {
+                t.visible = val;
+            });
         },
         // 读取拓扑图
         readPlanMsg() {
@@ -375,8 +445,16 @@ export default {
                 graphId: this.graphId,
                 id: this.id,
             };
-            planerRead(obj).then((res) => {
-                this.getDataSuc(res);
+            return new Promise((resolve, reject) => {
+                planerRead(obj).then((res) => {
+                    // resolve 是否显示底图,供 parserData 使用
+                    if (res?.content?.style?.defaultMapStyle?.showBaseMap === false) {
+                        resolve(false);
+                    } else {
+                        resolve(true);
+                    }
+                    this.getDataSuc(res);
+                });
             });
         },
         // 读图成功回调
@@ -402,13 +480,20 @@ export default {
             } else {
                 this.INITSTYLE({});
             }
-
+            // 底图背景颜色
+            if (this.scene) {
+                const backgroundColor = res.content.style?.defaultMapStyle?.backgroundColor
+                    ? res.content.style?.defaultMapStyle?.backgroundColor
+                    : "#00000000";
+                this.changeBackgroundColor(backgroundColor);
+                // 初始化保存图背景色
+            }
             // 加载规则,显示实例数据
             if (res.content.ruleList?.length) {
                 this.INITRULELIST(res.content.ruleList);
                 this.ruleNum = res.content.ruleList.length;
 
-                const ruleList = res.content.ruleList
+                const ruleList = res.content.ruleList;
                 // 同步执行规则,进行设备/设备组/空间的添加,删除
                 for (let index = 0; index < ruleList.length; index++) {
                     const rule = ruleList[index];
@@ -426,20 +511,23 @@ export default {
                             this.loadedRuleNum++;
                             if (this.ruleNum === this.loadedRuleNum) this.loadMarkRelation();
                         }
-                    } else if (rule.commond && rule.commond === "delete") { // 删除规则
+                    } else if (rule.commond && rule.commond === "delete") {
+                        // 删除规则
                         // console.error("删除命令!!!", rule);
                         // 删除设备实例
                         if (rule?.returnType === "equip") {
-                            const classCode = rule?.params?.classCode
+                            const classCode = rule?.params?.classCode;
                             if (classCode) {
-                                this.removeEquipment(classCode)
+                                this.removeEquipment(classCode);
                             }
-                        } else if (rule?.returnType === "zone") { // 删除空间实例
-                            const classCode = rule?.params?.classCode
+                        } else if (rule?.returnType === "zone") {
+                            // 删除空间实例
+                            const classCode = rule?.params?.classCode;
                             if (classCode) {
-                                this.removeZone(classCode)
+                                this.removeZone(classCode);
                             }
-                        } else if (rule?.returnType === "equipGroup") { // 删除设备组
+                        } else if (rule?.returnType === "equipGroup") {
+                            // 删除设备组
                             //
                             this.loadedRuleNum++;
                             if (this.ruleNum === this.loadedRuleNum) this.loadMarkRelation();
@@ -491,17 +579,17 @@ export default {
         },
         /**
          * 删除设备实例
-         * 
+         *
          * @param { string }  classCode 删除的设备类code值
          */
         removeEquipment(classCode) {
             for (const key in this.equipItemMap) {
-                const equipItem = this.equipItemMap[key]
+                const equipItem = this.equipItemMap[key];
                 if (equipItem?.legendData?.classCode === classCode) {
                     // 删除vuex中保存的设备实例
                     this.REMOVEEQUIP(equipItem);
                     // 删除图上的设备实例
-                    this.scene.removeItem(equipItem)
+                    this.scene.removeItem(equipItem);
                 }
             }
             this.view.update();
@@ -537,17 +625,17 @@ export default {
         },
         /**
          * 删除设备实例
-         * 
+         *
          * @param { string }  classCode 删除的设备类code值
          */
         removeZone(classCode) {
             for (const key in this.zoneIteMap) {
-                const zoneItem = this.zoneIteMap[key]
+                const zoneItem = this.zoneIteMap[key];
                 if (zoneItem?.legendData?.classCode === classCode) {
                     // 删除vuex中保存的空间实例
                     this.REMOVEZONE(zoneItem);
                     // 删除图上的空间实例
-                    this.scene.removeItem(zoneItem)
+                    this.scene.removeItem(zoneItem);
                 }
             }
             this.view.update();
@@ -621,7 +709,7 @@ export default {
             this.initScale = this.view.scale;
             bus.$emit("initScale", this.view.scale);
             // 关闭顶部的loading提示
-            this.planLoading = false
+            this.planLoading = false;
         },
         // 生成快照并保存草稿
         savePlanDraft() {

+ 25 - 7
src/components/editview/bottomToolBar.vue

@@ -3,17 +3,17 @@
         <div class="action-box">
             <div class="small-block" @click="showArea">
                 <span>
-                    <el-tooltip v-if="isShowArea" effect="dark" content="区域显示" placement="top">
+                    <el-tooltip v-if="!isShowArea" effect="dark" content="区域显示" placement="top">
                         <img src="@/assets/images/bottomToolBar/showArea.png" />
                     </el-tooltip>
-                    <el-tooltip v-else effect="dark" content="区域隐藏" placement="top">
+                    <el-tooltip v-else effect="dark" content="取消区域显示" placement="top">
                         <img src="@/assets/images/bottomToolBar/hideArea.png" />
                     </el-tooltip>
                 </span>
             </div>
             <div class="small-block" @click="showBaseMap">
                 <span>
-                    <el-tooltip v-if="isShowBaseMap" effect="dark" content="底图显示" placement="top">
+                    <el-tooltip v-if="!isShowBaseMap" effect="dark" content="底图显示" placement="top">
                         <img src="@/assets/images/bottomToolBar/showBaseMap.png" />
                     </el-tooltip>
                     <el-tooltip v-else effect="dark" content="底图隐藏" placement="top">
@@ -31,7 +31,8 @@
 </template>
 <script>
 import bus from "@/bus/bus";
-import "@/assets/font/iconfont.js";
+import { mapState } from "vuex";
+// import "@/assets/font/iconfont.js";
 export default {
     data() {
         return {
@@ -42,13 +43,24 @@ export default {
             max: 5,
             isSwitch: false, // 是否开启吸附
             isShowArea: false,
-            isShowBaseMap: false,
         };
     },
     computed: {
         sliderValPercent() {
             return `${(this.sliderVal * 100).toFixed(0)}%`;
         },
+        ...mapState(["styleMap"]),
+        isShowBaseMap: {
+            get() {
+                if (this.styleMap?.defaultMapStyle?.showBaseMap === false) {
+                    return false;
+                }
+                return true;
+            },
+            set(val) {
+                return val;
+            },
+        },
     },
     methods: {
         // 适配大小
@@ -107,9 +119,12 @@ export default {
             // this.isShowArea = !this.isShowArea;
             // this.$emit("showArea", this.isShowArea);
         },
+        /**
+         * 区域显示/隐藏
+         */
         showBaseMap() {
-            // this.isShowBaseMap = !this.isShowBaseMap;
-            // this.$emit("showBaseMap", this.isShowBaseMap);
+            this.isShowBaseMap = !this.isShowBaseMap;
+            bus.$emit("showBaseMap", !this.isShowBaseMap);
         },
     },
     mounted() {
@@ -138,6 +153,9 @@ export default {
         justify-content: center;
         // padding: 12px;
         cursor: not-allowed;
+        & + .small-block {
+            cursor: pointer;
+        }
         & > span {
             width: 16px;
             height: 16px;

+ 2 - 1
src/components/editview/planEditer.vue

@@ -48,7 +48,8 @@ export default {
         display: flex;
         justify-content: flex-start;
         .right-bar {
-            // width: 240px;
+            // TODO: right-bar
+            width: 240px;
             height: 100%;
         }
         .base-plan-editer {

+ 135 - 0
src/components/editview/rightPropertyBar/BaseView.vue

@@ -0,0 +1,135 @@
+<!-- 背景的属性框 -->
+<template>
+    <div class="base-view">
+        <div class="title">属性</div>
+        <ul>
+            <li>
+                <div class="small-title"></div>
+                <div class="property">
+                    <div class="color-box">
+                        <div class="cololorSelect">
+                            <el-color-picker
+                                show-alpha
+                                popper-class="line-color-picker"
+                                class="fix-box-1"
+                                v-model="backgroundColor"
+                            ></el-color-picker>
+                        </div>
+                        <span class="text">画布背景色</span>
+                    </div>
+                </div>
+            </li>
+        </ul>
+    </div>
+</template>
+<script>
+import bus from "@/bus/bus";
+import { rgbaNum } from "@persagy-web/big-edit/lib/until";
+import { SColor } from "@persagy-web/draw";
+import { mapState } from "vuex";
+export default {
+    props: [],
+    data() {
+        return {
+            // backgroundColor: "",
+        };
+    },
+    computed: {
+        ...mapState(["styleMap"]),
+        /**
+         * 底图背景颜色
+         */
+        backgroundColor: {
+            get() {
+                const backgroundColor = this.styleMap.defaultMapStyle.backgroundColor;
+                return new SColor(backgroundColor).toRgba();
+            },
+            set(val) {
+                const colorList = rgbaNum(val);
+                const backgroundColor = new SColor(Number(colorList[0]), Number(colorList[1]), Number(colorList[2]), colorList[3] * 255).value;
+                bus.$emit("changeBackgroundColor", backgroundColor);
+            },
+        },
+    },
+    mounted() {},
+    methods: {},
+};
+</script>
+
+<style lang="less" >
+.line-color-picker {
+    /deep/.el-input__inner {
+        padding-right: 0 !important;
+    }
+}
+.line-select {
+    text-align: center;
+}
+</style>
+<style lang="less" scoped>
+ul,
+li {
+    margin: 0;
+    padding: 0;
+    list-style-type: none;
+}
+.base-view {
+    & > .title {
+        height: 40px;
+        line-height: 40px;
+        color: #000000;
+        background: #f8f9fa;
+        font-size: 14px;
+        padding-left: 12px;
+        box-sizing: border-box;
+        font-weight: 600;
+    }
+    ul {
+        width: 100%;
+        li {
+            padding: 0 12px;
+            margin-bottom: 16px;
+            .small-title {
+                font-size: 12px;
+                color: #8d9399;
+                margin: 12px 0;
+                font-weight: 600;
+            }
+            .property {
+                display: flex;
+                align-items: center;
+                // justify-content: space-around;
+                .color-box {
+                    display: flex;
+                    align-items: center;
+                    flex-direction: column;
+                    .cololorSelect {
+                        width: 32px;
+                        height: 20px;
+                        overflow: hidden;
+                        position: relative;
+                        margin: 4px 0;
+                        .fix-box-1 {
+                            margin-top: -8px;
+                            margin-left: -8px;
+                            /deep/ .el-color-picker__trigger {
+                                width: 200px;
+                                height: 200px;
+                            }
+                        }
+                    }
+                }
+                .text {
+                    font-size: 12px;
+                    color: #1f2429;
+                    font-weight: 600;
+                    margin-top: 4px;
+                }
+            }
+        }
+    }
+    /deep/ .el-input-number .el-input__inner {
+        padding-right: 40px !important;
+    }
+}
+</style>

+ 5 - 1
src/components/editview/rightPropertyBar/property.vue

@@ -1,6 +1,7 @@
 <!--属性栏-->
 <template>
-    <div class="propertys" :class="{ width: itemType }">
+    <!-- <div class="propertys" :class="{ width: itemType }"> -->
+    <div class="propertys width">
         <baseTextPro v-if="itemObj && ['BaseText', 'BaseExplain'].includes(itemType)" :TextItem="itemObj"></baseTextPro>
         <baseLinePro v-if="itemObj && itemType == 'BaseArrow'" :LineItem="itemObj"></baseLinePro>
         <BaseGraphy
@@ -11,6 +12,7 @@
         <BgImagePro v-if="itemObj && itemType == 'BgImage'" :ImageItem="itemObj"></BgImagePro>
         <BaseEquipment :EquipItem="itemObj" v-if="itemObj && itemType == 'BaseEquipment'"></BaseEquipment>
         <BaseZone :ZoneItem="itemObj" v-if="itemObj && itemType == 'BaseZone'"></BaseZone>
+        <BaseView v-if="!itemObj"></BaseView>
     </div>
 </template>
 <script>
@@ -21,6 +23,7 @@ import BaseImagePro from "./BaseImagePro";
 import BgImagePro from "./BgImagePro";
 import BaseEquipment from "./BaseEquipment";
 import BaseZone from "./BaseZone";
+import BaseView from "./BaseView";
 import bus from "@/bus/bus";
 const lineStyle = {
     0: "Solid",
@@ -49,6 +52,7 @@ export default {
         BgImagePro,
         BaseEquipment,
         BaseZone,
+        BaseView,
     },
     data() {
         return {

+ 39 - 11
src/lib/SPlanScene.ts

@@ -109,31 +109,39 @@ export class SPlanScene extends SBaseEditScene {
         } else if (this.editCmd == "EditBasePolyLine") {
             item = this.addPolyLine(event);
             this.clearCmdStatus();
-        } else if (this.editCmd == "EditBasetext") { // 文字
+        } else if (this.editCmd == "EditBasetext") {
+            // 文字
             item = this.addTextItem(event);
             this.clearCmdStatus();
-        } else if (this.editCmd == "BaseExplain") { // 批注
+        } else if (this.editCmd == "BaseExplain") {
+            // 批注
             item = this.addExplainItem(event);
             this.clearCmdStatus();
-        } else if (this.editCmd == "EditBaseImage") { // 图片
+        } else if (this.editCmd == "EditBaseImage") {
+            // 图片
             item = this.addImageItem(event);
             this.clearCmdStatus();
-        } else if (this.editCmd == "EditBgImage") { // 背景图片
+        } else if (this.editCmd == "EditBgImage") {
+            // 背景图片
             item = this.addBgImageItem(event);
             this.clearCmdStatus();
-        } else if (this.editCmd == "EditBasePolygon") { // 多边形
+        } else if (this.editCmd == "EditBasePolygon") {
+            // 多边形
             item = this.addPolygonItem(event);
             this.clearCmdStatus();
-        } else if (this.editCmd == "EditBaseRect") { // 矩形
+        } else if (this.editCmd == "EditBaseRect") {
+            // 矩形
             item = this.addRectItem(event);
             this.clearCmdStatus();
         } else if (this.editCmd == "EditBaseTriangle") {
             item = this.addTriangleItem(event);
             this.clearCmdStatus();
-        } else if (this.editCmd == "EditBaseCircle") { // 圆
+        } else if (this.editCmd == "EditBaseCircle") {
+            // 圆
             item = this.addCircleItem(event);
             this.clearCmdStatus();
-        } else if (this.editCmd == "EditBaseArrows") { // 箭头
+        } else if (this.editCmd == "EditBaseArrows") {
+            // 箭头
             item = this.addPolygonArrow(event);
             this.clearCmdStatus();
         } else if (this.editCmd == "wantou" || this.editCmd == "santong" || this.editCmd == "sitong") {
@@ -147,7 +155,8 @@ export class SPlanScene extends SBaseEditScene {
             super.onMouseDown(event);
         }
         // 创建通用元素时,层级设置为 9800 (设备 9700 ,设备关系 9600 ,空间 9500,背景图片3000 )
-        if (this.editCmd &&
+        if (
+            this.editCmd &&
             [
                 "EditBaseLine",
                 "EditBasetext",
@@ -399,9 +408,9 @@ export class SPlanScene extends SBaseEditScene {
             if (item instanceof SGraphEdit && !(item instanceof SGraphSelectContainer)) {
                 // 添加节点数据
                 if (item.data && Marktype.includes(item.data.properties.type)) {
-                    const itemData = item.toData()
+                    const itemData = item.toData();
                     // 保存通用元素的 层级
-                    itemData.style.default.zOrder = item.zOrder
+                    itemData.style.default.zOrder = item.zOrder;
                     markers.push(itemData);
                 }
 
@@ -582,4 +591,23 @@ export class SPlanScene extends SBaseEditScene {
             });
         }
     }
+
+    /**
+     *  改变 view 背景色
+     *
+     * @param val 颜色值
+     */
+    changeBackgroundColor(val: any): void {
+        if (!this.view) return;
+        if (val) {
+            if (val.includes("#")) {
+                this.view.backgroundColor = new SColor(val);
+            } else {
+                const colorlist: any = rgbaNum(val);
+                if (!colorlist) return;
+                this.view.backgroundColor = new SColor(Number(colorlist[0]), Number(colorlist[1]), Number(colorlist[2]), colorlist[3] * 255);
+            }
+            this.view.update();
+        }
+    }
 }

+ 2 - 2
src/lib/SPlanView.ts

@@ -38,8 +38,8 @@ export class SPlanView extends SGraphView {
      * @param painter     绘制对象
      */
     protected drawBackground(painter: SPainter): void {
-        painter.brush.color = SColor.White;
-        painter.pen.color = SColor.Transparent;
+        painter.brush.color = this.backgroundColor;
+        painter.pen.color = this.backgroundColor;
         painter.drawRect(0, 0, this.width, this.height);
     } // Function drawBackground()
 }

+ 8 - 0
src/store/index.ts

@@ -104,6 +104,14 @@ export default new Vuex.Store({
                 strokeColor: "#007CC8ff",
                 formula: [],
             };
+            // 底图默认样式,底图显隐,底图背景颜色
+            if (!data.defaultMapStyle) {
+                data.defaultMapStyle = {
+                    showBaseMap: true,
+                    backgroundColor: "#00000000",
+                };
+            }
+            // outline = []
             state.styleMap = data;
         },
         // 初始化 equipItemMap, equipItemNum