Browse Source

'合并批量绑定功能'

zhangyu 4 years ago
parent
commit
ed6c2cef33

+ 10 - 0
src/api/editer.js

@@ -116,4 +116,14 @@ export function graphElementOrderInfoLocal(params){
 // 查询图
 export function graphQuery(params){
     return httputils.postJson(`${testApi}/graph/query`, params)
+}
+
+// 查询图例绑定的楼层
+export function queryFloorByNode(params) {
+    return httputils.getJson(`${testApi}/node/qfloor`, params)
+}
+
+// 批量绑定工程信息化数据
+export function bindAttachObject(params){
+    return httputils.postJson(`${testApi}/node/bindAttachObject`, params)
 }

BIN
src/assets/images/iconBlackBottom.png


BIN
src/assets/images/iconBlackTop.png


BIN
src/assets/images/iconLightBottom.png


BIN
src/assets/images/iconLightTop.png


+ 2 - 9
src/components/edit/attr_select.vue

@@ -428,15 +428,8 @@
         </a-collapse-panel>
       </a-collapse>
     </div>
-    <editDialog
-      ref="dialog"
-      :attrCards="attrCards"
-      :GraphElementId="GraphElementId"
-      :InfoLocal="InfoLocal"
-      :sysNum="imageNum"
-      :key="keys"
-    />
-    <!--    <editDialog ref="dialog" :attrCards="attrCards" :getmajorId="getmajorId" :InfoLocal="InfoLocal" :sysNum="imageNum" :key="new Date().getTime()" />-->
+    <editDialog ref="dialog" :attrCards="attrCards" :lengedName="lengedName" :GraphElementId="GraphElementId" :InfoLocal="InfoLocal" :sysNum="imageNum" :key="keys" />
+<!--    <editDialog ref="dialog" :attrCards="attrCards" :getmajorId="getmajorId" :InfoLocal="InfoLocal" :sysNum="imageNum" :key="new Date().getTime()" />-->
     <!--    <editDialog ref="dialog" :typeEdit="2" :getmajorId="'1001'" :sysNum="5" />-->
   </div>
 </template>

File diff suppressed because it is too large
+ 1381 - 0
src/components/edit/edit-dialog-tree.vue


File diff suppressed because it is too large
+ 736 - 117
src/components/edit/edit-dialog.vue


+ 233 - 0
src/components/edit/floorList.vue

@@ -0,0 +1,233 @@
+<template>
+  <div class='floor-box'>
+    <div class='floor-list'>
+      <div class='icon-top' v-if='floorsArr.length>8'>
+        <!-- @click='changeFloor(1,currIndex)' -->
+        <img v-show='parseInt(marginTop) !== 0' v-repeat-click='increase' src='@/assets/images/iconBlackTop.png' alt />
+        <img class='disabled' v-show='parseInt(marginTop) === 0' src='@/assets/images/iconLightTop.png' alt />
+      </div>
+      <div class='floor-out' :style='{ height:conHeight + "px" }'>
+        <!--  放开marginTop样式  -->
+        <div class='floor-center' :style='{ marginTop : marginTop }'>
+          <div class='floor-item' :class='item.FloorId == currentFloorId?"isActive":""' @click='tabFloor(item,index)'
+            v-for='(item,index) in floorsArr' :key='index'>{{item.Name}}</div>
+        </div>
+      </div>
+      <div class='icon-bottom' v-if='floorsArr.length>8'>
+        <!-- v-repeat-click='decrease' -->
+        <img v-show='parseInt(marginTop) !== marginTopMax' v-repeat-click='decrease'
+          src='@/assets/images/iconBlackBottom.png' alt />
+        <img class='disabled' v-show='parseInt(marginTop) === marginTopMax' src='@/assets/images/iconLightBottom.png'
+          alt />
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import RepeatClick from '@/directives/repeat-click'
+
+export default {
+  directives: {
+    repeatClick: RepeatClick,
+  },
+  data() {
+    return {
+      currentFloorId: null,
+      marginTop: 0,
+      marginTopMax: 0,
+      showNumber: 8, //需要展示的楼层数   //TODO:
+      height: 39, //一个楼层的高度
+      currIndex: 0, //当前楼层在 楼层数组中的下标,上下箭头使用
+      conHeight: 0, // floor-out 的高度
+    }
+  },
+  props: {
+    floorsArr: {
+      type: Array,
+      default: () => {
+        return []
+      },
+    }
+  },
+  methods: {
+    /**
+     * @description 点击上箭头,marginTop<0时执行楼层滚动
+     */
+    increase() {
+      const marginTop = parseInt(this.marginTop)
+      marginTop < 0 && this.changeFloor(1, this.currIndex)
+    },
+    /**
+     * @description 点击下箭头,marginTop小于最大值marginTopMax时,执行楼层滚动
+     */
+    decrease() {
+      const marginTop = Math.abs(parseInt(this.marginTop)),
+      marginTopMax = Math.abs(parseInt(this.marginTopMax))
+      marginTop < marginTopMax && this.changeFloor(-1, this.currIndex)
+    },
+    init() {
+      // 修复在设备设施页面中,楼层组件不够 8个楼层时,出现的样式问题,
+      this.conHeight = this.floorsArr.length * 37.5
+      this.conHeight = this.conHeight >= 300 ? 300 : this.conHeight
+      this.showNumber = this.floorsArr.length > 8 ? 8 : this.floorsArr.length
+
+      this.marginTopMax = -(this.floorsArr.length - this.showNumber) * this.height
+      this.changeFloor(0, 0);
+      this.tabFloor(this.floorsArr[0], 0);
+    },
+    /**
+     * @name changeFloor
+     * @param {Number} flag 1:向上滚动楼层, -1向下滚动 , 0:进入页面初始化时,执行位置处理
+     * @description 点击图例下方的,上下切换按钮
+     */
+    changeFloor(flag, index) {
+      const len = this.floorsArr.length
+      this.currIndex = index
+      // 点击上箭头
+      if (flag === 1) {
+        index--
+        this.currIndex = index
+      } else if (flag === -1) {
+        //点击下箭头
+        index++
+        this.currIndex = index
+      }
+      this.handlePosition(flag, index, len)
+    },
+    /**
+     * @name tabFloor
+     * @param {Object} item 选中的楼层信息
+     * @param {Number} index 楼层信息在floorsArr数组中的位置
+     */
+    tabFloor(item, index) {
+      this.currentFloorId = item.FloorId;
+      this.$emit("emitFloor", item)
+      this.handlePosition(2, index, this.floorsArr.length)
+    },
+    /**
+     * @description 楼层位置动画处理
+     * @param flag 1:向上滚动楼层, -1向下滚动 , 0:进入页面初始化时,执行位置处理 2:直接点击楼层
+     * @param index 楼层 floorsArr
+     * @param len floorsArr
+     */
+    handlePosition(flag, index, len) {
+      // 取出当前 marginTop
+      let marginTop = parseInt(this.marginTop)
+      switch (flag) {
+        // 初始化进入页面,位置处理
+        case 0:
+        // 直接点击楼层,滚动楼层
+        case 2:
+          // 将 marginTop 设置为对应的index 应滚动的距离
+          marginTop = -index * this.height
+          // marginTop 过大时,取最大值marginTopMax
+          if (Math.abs(marginTop) >= Math.abs(this.marginTopMax)) {
+            marginTop = parseInt(this.marginTopMax)
+          }
+          // marginTop>0时,取0,防止楼层上边出现空白
+          marginTop = marginTop >= 0 ? 0 : marginTop
+          // index为0,marginTop设置为0
+          index == 0 && (marginTop = 0)
+          // index为最后一个,设置为最大marginTopMax
+          index == len - 1 && (marginTop = parseInt(this.marginTopMax))
+          this.marginTop = marginTop + 'px'
+          break
+        //  1:向上滚动楼层
+        case 1:
+          this.marginTop = marginTop + this.height + 'px'
+          break
+        // -1向下滚动楼层
+        case -1:
+          this.marginTop = marginTop + this.height * -1 + 'px'
+          break
+        default:
+          break
+      }
+    },
+  },
+  watch: {
+    floorsArr: {
+      handler() {
+        this.init()
+      },
+      immediate: true,
+      deep: true
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+.floor-box {
+  .floor-list {
+    width: 44px;
+    // height: 212px;
+    background: rgba(255, 255, 255, 1);
+    box-shadow: 0px 2px 15px 0px rgba(31, 36, 41, 0.08);
+    border-radius: 2px;
+    position: relative;
+    padding: 6px 4px;
+    text-align: center;
+    .floor-out {
+      // max-height: 300px; //TODO:
+      min-height: 38px;
+      overflow: hidden;
+      position: relative;
+      overflow-y: auto;
+      &::-webkit-scrollbar {
+        display: none;
+      }
+
+      .floor-center {
+        transition: all linear 0.5s;
+        .floor-item {
+          line-height: 28px;
+          height: 28px;
+          cursor: pointer;
+          position: relative;
+          &::after {
+            position: absolute;
+            left: 50%;
+            margin-left: -20%;
+            bottom: -6px;
+            content: "";
+            width: 14px;
+            height: 1px;
+            background: rgba(195, 199, 203, 1);
+            border: 0px solid rgba(228, 229, 231, 1);
+          }
+          & + .floor-item {
+            margin-top: 10px;
+          }
+        }
+      }
+    }
+
+    .icon-top {
+      cursor: pointer;
+      height: 18px;
+      img {
+        width: 18px;
+        height: 100%;
+        margin-top: -10px;
+      }
+    }
+    .icon-bottom {
+      cursor: pointer;
+      height: 18px;
+      img {
+        width: 18px;
+        height: 100%;
+        margin-top: -10px;
+      }
+    }
+    .isActive {
+      border-radius: 4px;
+      color: #025baa;
+      background: #e1f2ff;
+    }
+  }
+  .disabled {
+    cursor: not-allowed !important;
+  }
+}
+</style>

+ 3 - 0
src/components/mapClass/EditScence.ts

@@ -758,6 +758,9 @@ export class EditScence extends SGraphScene {
                 let arr = item.data.AttachObjectIds;
                 if (arr && arr.length && arr[arr.length - 1].name && flag) {
                     let name = item.name;
+                    let nameArr = name.split("\n");
+                    // if (nameArr[nameArr.length - 1] != arr[arr.length - 1].name) //最后一行的名称和将要添加的名称如果不同(增加)
+                    if (nameArr.indexOf(arr[arr.length - 1].name) == -1) //将要添加的名称和每一行的名称都不同(新增)
                     if (name) {
                         item.name = name + `\n${arr[arr.length - 1].name}`;
                         item.text = name + `\n${arr[arr.length - 1].name}`;

+ 230 - 0
src/directives/dom.js

@@ -0,0 +1,230 @@
+/* istanbul ignore next */
+
+import Vue from 'vue'
+
+const isServer = Vue.prototype.$isServer
+const SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g
+const MOZ_HACK_REGEXP = /^moz([A-Z])/
+const ieVersion = isServer ? 0 : Number(document.documentMode)
+
+/* istanbul ignore next */
+const trim = function(string) {
+    return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, '')
+}
+/* istanbul ignore next */
+const camelCase = function(name) {
+    return name
+        .replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
+            return offset ? letter.toUpperCase() : letter
+        })
+        .replace(MOZ_HACK_REGEXP, 'Moz$1')
+}
+
+/* istanbul ignore next */
+export const on = (function() {
+    if (!isServer && document.addEventListener) {
+        return function(element, event, handler) {
+            if (element && event && handler) {
+                element.addEventListener(event, handler, false)
+            }
+        }
+    } else {
+        return function(element, event, handler) {
+            if (element && event && handler) {
+                element.attachEvent('on' + event, handler)
+            }
+        }
+    }
+})()
+
+/* istanbul ignore next */
+export const off = (function() {
+    if (!isServer && document.removeEventListener) {
+        return function(element, event, handler) {
+            if (element && event) {
+                element.removeEventListener(event, handler, false)
+            }
+        }
+    } else {
+        return function(element, event, handler) {
+            if (element && event) {
+                element.detachEvent('on' + event, handler)
+            }
+        }
+    }
+})()
+
+/* istanbul ignore next */
+export const once = function(el, event, fn) {
+    var listener = function() {
+        if (fn) {
+            fn.apply(this, arguments)
+        }
+        off(el, event, listener)
+    }
+    on(el, event, listener)
+}
+
+/* istanbul ignore next */
+export function hasClass(el, cls) {
+    if (!el || !cls) return false
+    if (cls.indexOf(' ') !== -1) throw new Error('className should not contain space.')
+    if (el.classList) {
+        return el.classList.contains(cls)
+    } else {
+        return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1
+    }
+}
+
+/* istanbul ignore next */
+export function addClass(el, cls) {
+    if (!el) return
+    var curClass = el.className
+    var classes = (cls || '').split(' ')
+
+    for (var i = 0, j = classes.length; i < j; i++) {
+        var clsName = classes[i]
+        if (!clsName) continue
+
+        if (el.classList) {
+            el.classList.add(clsName)
+        } else if (!hasClass(el, clsName)) {
+            curClass += ' ' + clsName
+        }
+    }
+    if (!el.classList) {
+        el.className = curClass
+    }
+}
+
+/* istanbul ignore next */
+export function removeClass(el, cls) {
+    if (!el || !cls) return
+    var classes = cls.split(' ')
+    var curClass = ' ' + el.className + ' '
+
+    for (var i = 0, j = classes.length; i < j; i++) {
+        var clsName = classes[i]
+        if (!clsName) continue
+
+        if (el.classList) {
+            el.classList.remove(clsName)
+        } else if (hasClass(el, clsName)) {
+            curClass = curClass.replace(' ' + clsName + ' ', ' ')
+        }
+    }
+    if (!el.classList) {
+        el.className = trim(curClass)
+    }
+}
+
+/* istanbul ignore next */
+export const getStyle =
+    ieVersion < 9
+        ? function(element, styleName) {
+              if (isServer) return
+              if (!element || !styleName) return null
+              styleName = camelCase(styleName)
+              if (styleName === 'float') {
+                  styleName = 'styleFloat'
+              }
+              try {
+                  switch (styleName) {
+                      case 'opacity':
+                          try {
+                              return element.filters.item('alpha').opacity / 100
+                          } catch (e) {
+                              return 1.0
+                          }
+                      default:
+                          return element.style[styleName] || element.currentStyle ? element.currentStyle[styleName] : null
+                  }
+              } catch (e) {
+                  return element.style[styleName]
+              }
+          }
+        : function(element, styleName) {
+              if (isServer) return
+              if (!element || !styleName) return null
+              styleName = camelCase(styleName)
+              if (styleName === 'float') {
+                  styleName = 'cssFloat'
+              }
+              try {
+                  var computed = document.defaultView.getComputedStyle(element, '')
+                  return element.style[styleName] || computed ? computed[styleName] : null
+              } catch (e) {
+                  return element.style[styleName]
+              }
+          }
+
+/* istanbul ignore next */
+export function setStyle(element, styleName, value) {
+    if (!element || !styleName) return
+
+    if (typeof styleName === 'object') {
+        for (var prop in styleName) {
+            if (styleName.hasOwnProperty(prop)) {
+                setStyle(element, prop, styleName[prop])
+            }
+        }
+    } else {
+        styleName = camelCase(styleName)
+        if (styleName === 'opacity' && ieVersion < 9) {
+            element.style.filter = isNaN(value) ? '' : 'alpha(opacity=' + value * 100 + ')'
+        } else {
+            element.style[styleName] = value
+        }
+    }
+}
+
+export const isScroll = (el, vertical) => {
+    if (isServer) return
+
+    const determinedDirection = vertical !== null || vertical !== undefined
+    const overflow = determinedDirection ? (vertical ? getStyle(el, 'overflow-y') : getStyle(el, 'overflow-x')) : getStyle(el, 'overflow')
+
+    return overflow.match(/(scroll|auto)/)
+}
+
+export const getScrollContainer = (el, vertical) => {
+    if (isServer) return
+
+    let parent = el
+    while (parent) {
+        if ([window, document, document.documentElement].includes(parent)) {
+            return window
+        }
+        if (isScroll(parent, vertical)) {
+            return parent
+        }
+        parent = parent.parentNode
+    }
+
+    return parent
+}
+
+export const isInContainer = (el, container) => {
+    if (isServer || !el || !container) return false
+
+    const elRect = el.getBoundingClientRect()
+    let containerRect
+
+    if ([window, document, document.documentElement, null, undefined].includes(container)) {
+        containerRect = {
+            top: 0,
+            right: window.innerWidth,
+            bottom: window.innerHeight,
+            left: 0,
+        }
+    } else {
+        containerRect = container.getBoundingClientRect()
+    }
+
+    return (
+        elRect.top < containerRect.bottom &&
+        elRect.bottom > containerRect.top &&
+        elRect.right > containerRect.left &&
+        elRect.left < containerRect.right
+    )
+}

+ 24 - 0
src/directives/repeat-click.js

@@ -0,0 +1,24 @@
+import { once, on } from './dom'
+
+export default {
+    bind(el, binding, vnode) {
+        let interval = null
+        let startTime
+        const handler = () => vnode.context[binding.expression].apply()
+        const clear = () => {
+            if (Date.now() - startTime < 100) {
+                handler()
+            }
+            clearInterval(interval)
+            interval = null
+        }
+
+        on(el, 'mousedown', (e) => {
+            if (e.button !== 0) return
+            startTime = Date.now()
+            once(document, 'mouseup', clear)
+            clearInterval(interval)
+            interval = setInterval(handler, 100)
+        })
+    },
+}

+ 11 - 1
src/store/index.ts

@@ -9,7 +9,9 @@ export default new Vuex.Store({
     GraphCategoryIds: ['NTXT'], //系统类型
     TypeIdToGraphElement: {}, //typeid到图例元素的映射
     token: null,
-    GraphElement:[]
+    GraphElement:[],
+    isRemember: false,
+    rememberBtn: "bind"
   },
   mutations: {
     TypeIdToGraphElement(state, data) {
@@ -32,6 +34,12 @@ export default new Vuex.Store({
     SETSSOTOKEN(state, data) {
       state.token = data
     },
+    setIsRemember(state, data) {
+      state.isRemember = data
+    },
+    setRememberBtn(state, data) {
+      state.rememberBtn = data
+    },
   },
   actions: {
     getElementType({ commit }, params) {
@@ -47,6 +55,8 @@ export default new Vuex.Store({
   },
   getters: {
     token: (state) => state.token,
+    isRemember: (state) => state.isRemember,
+    rememberBtn: (state) => state.rememberBtn,
   },
   modules: {
   }