1、优化产品结构树以及设备结构树、列表右键菜单重复右键后出现window菜单问题
2、优化产品结构树节点删除后的loading展示时机
3、优化产品以及设备结构树权限配置获取列表时的loading展示时机
已修改9个文件
258 ■■■■■ 文件已修改
src/views/dnc/base/modules/DeviceStructure/DeviceStructureTree.vue 44 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/DeviceStructure/DeviceStructureTreeContextMenu.vue 55 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/DeviceStructure/Permission/AssignPermissionModal.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/ProductStructure/Permission/AssignPermissionModal.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/ProductStructure/Permission/DepartPermissionTransfer.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/ProductStructure/ProductStructureBaseContextMenu.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/ProductStructure/ProductStructureTree.vue 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/ProductStructure/ProductStructureTreeContextMenu.vue 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/common/TableContextMenu.vue 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/DeviceStructure/DeviceStructureTree.vue
@@ -22,9 +22,13 @@
          <a-tree blockNode show-icon :expandedKeys.sync="expandedKeys"
                  :selectedKeys="selectedKeys" :treeData="treeDataSource" :autoExpandParent="autoExpandParent"
                  @select="handleTreeSelect" @expand="handleTreeExpand" @rightClick="handleTreeRightClick">
            <template slot="title" slot-scope="{ title, parentId, entity, key:treeKey,equipmentId,type}">
              <DeviceStructureTreeContextMenu ref="contextMenuRef"
                                              :treeParams="{title,treeKey,searchValue,equipmentId,entity,type,param:currentDeviceDocClassCode}"/>
            <template slot="title" slot-scope="{ title }">
              <span v-if="title.indexOf(searchValue) > -1">
                {{ title.substr(0, title.indexOf(searchValue)) }}
                <span class="replaceSearch">{{ searchValue }}</span>
                {{ title.substr(title.indexOf(searchValue) + searchValue.length) }}
              </span>
              <span v-else>{{ title }}</span>
            </template>
            <a-icon slot="switcherIcon" type="down"/>
@@ -37,7 +41,11 @@
    <!--权限配置弹窗-->
    <AssignPermissionModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="getTreeDataByApi"/>
    <!--产品结构树基本右键菜单(空白处触发)-->
    <!--设备结构树树节点右键菜单(树节点触发)-->
    <device-structure-tree-context-menu ref="mainContextmenuRef" :treeParams="rightClickSelected"/>
    <!--设备结构树基本右键菜单(空白处触发)-->
    <DeviceStructureBaseContextMenu ref="baseContextmenuRef"/>
  </a-card>
</template>
@@ -145,7 +153,8 @@
      const record = node.dataRef
      // 若右键时当前右侧展示层级为设备层级且当前右键树层级同为设备层级时则在触发右键菜单功能时同时触发左键选中功能
      if (this.currentSelected.type === 2 && record.type === 2) this.handleTreeSelect([record.key], { node })
      this.rightClickSelected = Object.assign({}, record)
        this.rightClickSelected = Object.assign({ param: this.currentDeviceDocClassCode }, record)
        this.openMainContextMenu(event)
    },
    /**
@@ -154,7 +163,6 @@
     */
    handleTreeExpand(expandedKeys) {
      this.expandedKeys = this.beforeSearchExpandedKeys = expandedKeys
      console.log('beforeSearchExpandedKeys', this.beforeSearchExpandedKeys)
      this.autoExpandParent = false
    },
@@ -225,12 +233,24 @@
    },
    /**
       * 打开树节点菜单事件
       * @param event 树节点事件对象
       */
      openMainContextMenu(event) {
        this.$refs.mainContextmenuRef.menuStyle.top = event.clientY + 'px'
        this.$refs.mainContextmenuRef.menuStyle.left = event.clientX + 'px'
        this.$refs.mainContextmenuRef.menuVisible = true
        document.body.addEventListener('click', this.handleMainContextMenuClose)
      },
      /**
     * 树所在父元素的右键事件
     * @param event 事件对象
     */
    openBaseContextMenu(event) {
      event.preventDefault()
      if (event.target.id !== 'tree-container') return
        if (this.$refs.mainContextmenuRef) this.$refs.mainContextmenuRef.menuVisible = false
      this.$refs.baseContextmenuRef.menuStyle.top = event.clientY + 'px'
      this.$refs.baseContextmenuRef.menuStyle.left = event.clientX + 'px'
      this.$refs.baseContextmenuRef.menuVisible = true
@@ -247,6 +267,12 @@
      } else {
        treeNode.slots = { icon: 'device' }
      }
      },
      // 控制主要右键菜单关闭
      handleMainContextMenuClose() {
        if (this.$refs.mainContextmenuRef) this.$refs.mainContextmenuRef.menuVisible = false
        document.body.removeEventListener('click', this.handleMainContextMenuClose)
    },
    // 控制基础右键菜单关闭
@@ -285,6 +311,12 @@
  width: 8px;
}
  .replaceSearch {
    color: #40a9ff;
    font-weight: bold;
    background-color: rgb(204, 204, 204);
  }
@media screen and (min-width: 1920px) {
  .tree_con {
    height: 748px !important;
src/views/dnc/base/modules/DeviceStructure/DeviceStructureTreeContextMenu.vue
@@ -1,18 +1,12 @@
<template>
  <a-dropdown :trigger="['contextmenu']">
    <span v-if="treeParams.title.indexOf(treeParams.searchValue) > -1">{{ treeParams.title.substr(0, treeParams.title.indexOf(treeParams.searchValue)) }}<span
      class="replaceSearch">{{ treeParams.searchValue }}</span>{{ treeParams.title.substr(treeParams.title.indexOf(treeParams.searchValue) + treeParams.searchValue.length) }}</span>
    <span v-else>{{ treeParams.title }}</span>
    <template #overlay>
      <a-menu @click="({ key: menuKey }) => onContextMenuClick(treeParams.treeKey, menuKey)"
              @contextmenu="event=>event.preventDefault()">
        <a-menu-item v-for="item in defaultContextMenuList[getCurrentMenuLevel]" :key="item.code" v-has="item.code">
          <a-icon :type="item.icon"/>
          {{item.label}}
  <a-menu :style="menuStyle" @click="menuItemClick" v-if="menuVisible" mode="vertical" @contextmenu="menuContextMenu">
    <template v-for="menuItem in defaultContextMenuList[getCurrentMenuLevel]">
      <a-menu-item :key="menuItem.code" v-has="menuItem.code">
        <a-icon :type="menuItem.icon"/>
        {{ menuItem.label }}
        </a-menu-item>
      </a-menu>
    </template>
  </a-dropdown>
  </a-menu>
</template>
<script>
@@ -26,6 +20,15 @@
    },
    data() {
      return {
        menuVisible: false,
        menuStyle: {
          position: 'fixed',
          top: 0,
          left: 0,
          border: '1px solid #eee',
          boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)',
          zIndex: 999
        },
        defaultContextMenuList: {
          //车间
          workshop: [
@@ -46,11 +49,10 @@
      }
    },
    methods: {
      onContextMenuClick(treeKey, menuKey) {
      menuItemClick({ key }) {
        const menuKey = key
        const level = this.getCurrentMenuLevel
        const { param } = this.treeParams
        const treeNodeInfo = Object.assign({}, this.treeParams, { param })
        console.log('treeNodeInfo++++++++++++++++++++++++++++', treeNodeInfo)
        const treeNodeInfo = Object.assign({ treeKey: this.treeParams.key }, this.treeParams)
        if (treeNodeInfo.type === 2) treeNodeInfo.type = 7
        // 设备结构树节点中的设备层级为2,但在产品结构树中将设备层级的type设置为7,因此在此处设置为7
        const menuKeyArray = menuKey.split('_')
@@ -63,21 +65,18 @@
        } else {
          methodName = 'handle' + menuKeyArray.map(item => item[0].toUpperCase() + item.slice(1)).join('')
        }
        console.log('methodName------------------------------------', methodName)
        console.log('treeParams------------------------------------', this.treeParams)
        const modalTitle = this.defaultContextMenuList[level].find(item => item.code === menuKey).label
        this.$bus.$emit('treeMenuItemMethodTrigger', { methodName, modalTitle, treeNodeInfo })
      },
      /**
       * 避免单次重复右键后关闭菜单或打开window菜单
       * @param event 事件对象
       */
      menuContextMenu(event) {
        event.preventDefault()
        event.stopPropagation()
      }
    }
  }
</script>
<style scoped>
  .replaceSearch {
    color: #40a9ff;
    font-weight: bold;
    background-color: rgb(204, 204, 204);
  }
</style>
src/views/dnc/base/modules/DeviceStructure/Permission/AssignPermissionModal.vue
@@ -66,6 +66,11 @@
      // 调用接口获取所有用户列表
      getAllUsersListByApi() {
        this.$nextTick(() => {
          this.$refs.userPermissionTransferRef.spinning = true
          this.allUsersList = []
          this.$refs.userPermissionTransferRef.targetKeys = []
        })
        dncApi.getAllUsersListApi()
          .then(res => {
            if (res.success) {
src/views/dnc/base/modules/ProductStructure/Permission/AssignPermissionModal.vue
@@ -80,7 +80,11 @@
    // 调用接口获取所有车间列表
    getAllDepartmentsListByApi() {
      this.allTreeKeys = []
        this.allTreeKeys = this.allDepartmentsList = []
        this.$nextTick(() => {
          this.$refs.departPermissionTransferRef.targetKeys = this.$refs.departPermissionTransferRef.dataSource = []
          this.$refs.departPermissionTransferRef.spinning = true
        })
      dncApi.getAllDepartmentsListApi()
        .then(res => {
          if (res.success) {
@@ -113,6 +117,10 @@
    // 调用接口获取所有用户列表
    getAllUsersListByApi() {
        this.$nextTick(() => {
          this.allUsersList = []
          this.$refs.userPermissionTransferRef.spinning = true
        })
      dncApi.getAllUsersListApi()
        .then(res => {
          if (res.success) {
src/views/dnc/base/modules/ProductStructure/Permission/DepartPermissionTransfer.vue
@@ -48,8 +48,6 @@
<script>
  import dncApi from '@/api/dnc'
  const transferDataSource = []
  export default {
    name: 'DepartPermissionTransfer',
    components: {},
src/views/dnc/base/modules/ProductStructure/ProductStructureBaseContextMenu.vue
@@ -18,11 +18,6 @@
export default {
  name: 'ProductStructureBaseContextMenu',
  components: {},
  props: {
    tableRowInfo: {
      type: Object
    }
  },
  data() {
    return {
      menuVisible: false,
@@ -34,7 +29,6 @@
        boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)',
        zIndex: 999
      },
      currentMenuLevel: '',
      baseContextMenuList: [
        { label: '刷新', code: 'tree_reload', icon: 'reload', isHasPermission: false, isCommonMethod: false },
        { label: '添加产品', code: 'product_add', icon: 'plus', isHasPermission: true, isCommonMethod: false }
@@ -43,7 +37,6 @@
  },
  methods: {
    menuItemClick({ key }) {
      console.log('menuKey', key)
      const isCommonMethod = this.baseContextMenuList.find(item => item.code === key).isCommonMethod
      const modalTitle = this.baseContextMenuList.find(item => item.code === key).label
      const menuKeyArray = key.split('_')
src/views/dnc/base/modules/ProductStructure/ProductStructureTree.vue
@@ -30,8 +30,12 @@
                  :selectedKeys="selectedKeys" :treeData="treeDataSource" :autoExpandParent="autoExpandParent"
                  @select="handleTreeSelect" @expand="handleTreeExpand" @rightClick="handleTreeRightClick">
            <template slot="title" slot-scope="{ label, parentId, key:treeKey,type}">
              <ProductStructureTreeContextMenu ref="contextMenuRef"
                                               :treeParams="{label,treeKey,searchValue,type}"/>
              <span v-if="label.indexOf(searchValue) > -1">
                {{label.substr(0, label.indexOf(searchValue))}}
                <span class="replaceSearch">{{searchValue}}</span>
                {{label.substr(label.indexOf(searchValue) + searchValue.length)}}
              </span>
              <span v-else>{{ label }}</span>
            </template>
            <a-icon slot="switcherIcon" type="down"/>
@@ -68,6 +72,10 @@
                             @submitSuccess="modalFormSubmitSuccess"/>
    <!--引用部件-->
    <NcComponentBorrowModal :currentBorrowInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess"/>
    <!--产品结构树右键菜单(树节点触发)-->
    <product-structure-tree-context-menu ref="mainContextmenuRef" :treeParams="rightClickSelected"/>
    <!--产品结构树基本右键菜单(空白处触发)-->
    <ProductStructureBaseContextMenu ref="baseContextmenuRef"/>
@@ -204,9 +212,10 @@
      /**
       * 树节点右键单击节点时触发
       * @param event 事件对象
       * @param node 节点对象
       */
      handleTreeRightClick({ node }) {
      handleTreeRightClick({ event, node }) {
        if (this.$refs.baseContextmenuRef) this.$refs.baseContextmenuRef.menuVisible = false
        const that = this
        const record = node.dataRef
@@ -222,7 +231,9 @@
                  message: '消息',
                  description: '暂无该节点详细信息'
                })
                return
              }
              this.openMainContextMenu(event)
            } else {
              that.$notification.error({
                message: '消息',
@@ -243,10 +254,7 @@
          okType: 'danger',
          cancelText: '取消',
          onOk: () => {
            if (!url.delete) {
              this.$message.error('请设置url.delete属性!')
              return
            }
            that.loading = true
            deleteAction(url.delete + `/${id}/${type}`)
              .then((res) => {
                if (res.success) {
@@ -272,7 +280,7 @@
        })
      },
      // 树节点右键单击菜单中删除按钮时触发
      // 发送nc程序至三维工艺
      handleSendNcToPlm() {
        const that = this
        const { rightClickSelected: { id, type }, $confirm, url, $notification } = that
@@ -446,12 +454,24 @@
      },
      /**
       * 打开树节点菜单事件
       * @param event 树节点事件对象
       */
      openMainContextMenu(event) {
        this.$refs.mainContextmenuRef.menuStyle.top = event.clientY + 'px'
        this.$refs.mainContextmenuRef.menuStyle.left = event.clientX + 'px'
        this.$refs.mainContextmenuRef.menuVisible = true
        document.body.addEventListener('click', this.handleMainContextMenuClose)
      },
      /**
       * 树所在父元素的右键事件
       * @param event 事件对象
       */
      openBaseContextMenu(event) {
        event.preventDefault()
        if (event.target.id !== 'tree-container') return
        if (this.$refs.mainContextmenuRef) this.$refs.mainContextmenuRef.menuVisible = false
        this.$refs.baseContextmenuRef.menuStyle.top = event.clientY + 'px'
        this.$refs.baseContextmenuRef.menuStyle.left = event.clientX + 'px'
        this.$refs.baseContextmenuRef.menuVisible = true
@@ -484,6 +504,12 @@
            break
          default:
        }
      },
      // 控制主要右键菜单关闭
      handleMainContextMenuClose() {
        if (this.$refs.mainContextmenuRef) this.$refs.mainContextmenuRef.menuVisible = false
        document.body.removeEventListener('click', this.handleMainContextMenuClose)
      },
      // 控制基础右键菜单关闭
@@ -537,6 +563,12 @@
    align-items: center;
  }
  .replaceSearch {
    color: #40a9ff;
    font-weight: bold;
    background-color: rgb(204, 204, 204);
  }
  @media screen and (min-width: 1920px) {
    .tree_con {
      height: 748px !important;
src/views/dnc/base/modules/ProductStructure/ProductStructureTreeContextMenu.vue
@@ -1,24 +1,12 @@
<template>
  <a-dropdown :trigger="['contextmenu']">
    <span v-if="treeParams.label.indexOf(treeParams.searchValue) > -1">{{
        treeParams.label.substr(0, treeParams.label.indexOf(treeParams.searchValue))
      }}<span
        class="replaceSearch">{{
          treeParams.searchValue
        }}</span>{{
        treeParams.label.substr(treeParams.label.indexOf(treeParams.searchValue) + treeParams.searchValue.length)
      }}</span>
    <span v-else>{{ treeParams.label }}</span>
    <template #overlay>
      <a-menu @click="({ key: menuKey }) => onContextMenuClick(treeParams.treeKey, menuKey)"
              @contextmenu="event=>event.preventDefault()">
        <a-menu-item v-for="item in defaultContextMenuList[getCurrentMenuLevel]" :key="item.code" v-has="item.code">
          <a-icon :type="item.icon"/>
          {{ item.label }}
  <a-menu :style="menuStyle" @click="menuItemClick" v-if="menuVisible" mode="vertical" @contextmenu="menuContextMenu">
    <template v-for="menuItem in defaultContextMenuList[getCurrentMenuLevel]">
      <a-menu-item :key="menuItem.code" v-has="menuItem.code">
        <a-icon :type="menuItem.icon"/>
        {{ menuItem.label }}
        </a-menu-item>
      </a-menu>
    </template>
  </a-dropdown>
  </a-menu>
</template>
<script>
@@ -32,6 +20,15 @@
  },
  data() {
    return {
        menuVisible: false,
        menuStyle: {
          position: 'fixed',
          top: 0,
          left: 0,
          border: '1px solid #eee',
          boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)',
          zIndex: 999
        },
      defaultContextMenuList: {
        //产品
        product: [
@@ -131,30 +128,14 @@
        case 6:
          return 'processStep'
      }
    },
    // getCurrentDocClassCode() {
    //   switch (+this.treeParams.type) {
    //     case 1:
    //       return 'OTHER'
    //     case 2:
    //       return 'OTHER'
    //     case 3:
    //       return 'OTHER'
    //     case 4:
    //       return 'OTHER'
    //     case 5:
    //       return 'NC'
    //     case 6:
    //       return 'NC'
    //   }
    // }
      }
  },
  methods: {
    onContextMenuClick(treeKey, menuKey) {
      menuItemClick({ key }) {
        const menuKey = key
      const level = this.getCurrentMenuLevel
      console.log('level---------------------', level)
      const treeNodeInfo = Object.assign({}, this.treeParams)
      console.log('treeNodeInfo******************', treeNodeInfo)
        const treeNodeInfo = Object.assign({ treeKey: this.treeParams.key }, this.treeParams)
        console.log('treeNodeInfo', treeNodeInfo)
      const menuKeyArray = menuKey.split('_')
      const isCommonMethod = this.defaultContextMenuList[level].find(item => item.code === menuKey).isCommonMethod
      // product_add => handleAdd 触发对应组件事件
@@ -165,19 +146,26 @@
      } else {
        methodName = 'handle' + menuKeyArray.map(item => item[0].toUpperCase() + item.slice(1)).join('')
      }
      console.log('methodName', methodName)
      const modalTitle = this.defaultContextMenuList[level].find(item => item.code === menuKey).label
      this.$bus.$emit('treeMenuItemMethodTrigger', { methodName, modalTitle, treeNodeInfo })
      },
      /**
       * 避免单次重复右键后关闭菜单或打开window菜单
       * @param event 事件对象
       */
      menuContextMenu(event) {
        event.preventDefault()
        event.stopPropagation()
    }
  }
}
</script>
<style scoped>
.replaceSearch {
  color: #40a9ff;
  font-weight: bold;
  background-color: rgb(204, 204, 204);
  /deep/ .ant-menu-item {
    height: 32px;
    line-height: 32px;
}
</style>
src/views/dnc/common/TableContextMenu.vue
@@ -1,5 +1,5 @@
<template>
  <a-menu :style="menuStyle" @click="menuItemClick" v-if="menuVisible" mode="vertical">
  <a-menu :style="menuStyle" @click="menuItemClick" v-if="menuVisible" mode="vertical" @contextmenu="menuContextMenu">
    <template v-for="menuItem in defaultContextMenuList[tableRowInfo.param]">
      <a-menu-item :key="menuItem.code" v-has="menuItem.code" v-if="menuItem.subMenu.length===0">
        <a-icon :type="menuItem.icon"/>
@@ -168,6 +168,15 @@
          modalTitle,
          tableRowInfo: this.tableRowInfo
        })
      },
      /**
       * 避免单次重复右键后关闭菜单或打开window菜单
       * @param event 事件对象
       */
      menuContextMenu(event) {
        event.preventDefault()
        event.stopPropagation()
      }
    }
  }