产品结构树:
1、调整权限配置功能
2、调整指派到设备树组件子节点选中逻辑
已修改5个文件
245 ■■■■ 文件已修改
src/views/dnc/base/modules/ProductStructure/Document/NcDocumentAssignModal.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/ProductStructure/Permission/AssignPermissionModal.vue 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/ProductStructure/Permission/DepartPermissionTransfer.vue 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/ProductStructure/Permission/UserPermissionTransfer.vue 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/ProductStructure/ProductStructureTree.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dnc/base/modules/ProductStructure/Document/NcDocumentAssignModal.vue
@@ -52,9 +52,9 @@
                <!--产品结构树-->
                <div style="overflow:auto;margin-top: 10px;height: 400px">
                  <a-tree ref="tree" checkable :checkedKeys="checkedKeys" :expandedKeys.sync="expandedKeys"
                          :autoExpandParent="autoExpandParent"
                          :treeData="treeDataSource" @check="handleTreeNodeCheck" @expand="handleTreeExpand">
                  <a-tree blockNode checkable :checkedKeys="checkedKeys" :expandedKeys.sync="expandedKeys"
                          :autoExpandParent="autoExpandParent" @select="handleTreeNodeSelect"
                          :treeData="treeDataSource" @check="handleTreeNodeCheck" @expand="handleTreeNodeExpand">
                    <template slot="title" slot-scope="{ label, parentId, entity, key:treeKey,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>
@@ -287,7 +287,7 @@
       * 树节点展开合并时触发
       * @param expandedKeys 展开项key
       */
      handleTreeExpand(expandedKeys) {
      handleTreeNodeExpand(expandedKeys) {
        this.expandedKeys = expandedKeys
        this.autoExpandParent = false
      },
@@ -302,6 +302,10 @@
        this.checkedKeys = checkedKeys
      },
      handleTreeNodeSelect(selectedKeys, { node }) {
        node.$el.childNodes[1].click()
      },
      /**
       * 递归获得输入项的父级key
       * @param key 子项key
src/views/dnc/base/modules/ProductStructure/Permission/AssignPermissionModal.vue
@@ -5,7 +5,7 @@
      <a-form-item label="名称">
        <a-input readOnly :value="currentTreeNodeInfo.label"></a-input>
      </a-form-item>
      <a-form-item label="是否分配子节点">
      <a-form-item label="是否同时配置子节点">
        <a-switch v-model="isAssignSonNode"></a-switch>
      </a-form-item>
    </a-form-model>
@@ -13,7 +13,8 @@
    <a-tabs v-model="activeTabKey">
      <a-tab-pane :key="1" tab="分配部门">
        <DepartPermissionTransfer ref="departPermissionTransferRef" :currentTreeNodeInfo="currentTreeNodeInfo"
                                      :dataSource="allDepartmentsList" :isAssignSonNode="isAssignSonNode"/>
                                  :treeDataProps="allDepartmentsList" :allTreeKeys="allTreeKeys"
                                  :isAssignSonNode="isAssignSonNode"/>
      </a-tab-pane>
      <a-tab-pane :key="2" tab="分配用户">
@@ -28,6 +29,7 @@
  import dncApi from '@/api/dnc'
  import DepartPermissionTransfer from './DepartPermissionTransfer'
  import UserPermissionTransfer from './UserPermissionTransfer'
  import { queryProductionTreeList } from '@/api/api'
  export default {
    name: 'AssignPermissionModal',
@@ -45,6 +47,7 @@
        activeTabKey: 1,
        allDepartmentsList: [],
        allUsersList: [],
        allTreeKeys: [],
        hasLoadedDataTabKeyArray: []
      }
    },
@@ -77,11 +80,18 @@
      // 调用接口获取所有部门列表
      getAllDepartmentsListByApi() {
        dncApi.getAllDepartmentsListApi()
        this.allTreeKeys = []
        queryProductionTreeList()
          .then(res => {
            console.log('res-------------------', res)
            if (res.success) {
              this.allDepartmentsList = res.list
              this.$nextTick(() => this.$refs.departPermissionTransferRef.getHasPermissionDepartByApi())
              this.allDepartmentsList = res.result
              this.generateList(this.allDepartmentsList)
              this.$nextTick(() => {
                this.$refs.departPermissionTransferRef.getHasPermissionDepartByApi()
                this.$refs.departPermissionTransferRef.expandedKeys = this.allTreeKeys
                this.$refs.departPermissionTransferRef.flatten(JSON.parse(JSON.stringify(this.allDepartmentsList)))
              })
              // 只有上次退出时在部门分配tab界面才会进入此判断
              // 若上次退出时在用户分配tab界面则再次进入时key由2变为1时会触发watch监测activeTabKey变化则会将key:1加入hasLoadedDataTabKeyArray,因此无需再次加入key:1
              if (!this.hasLoadedDataTabKeyArray.includes(this.activeTabKey)) this.hasLoadedDataTabKeyArray.push(this.activeTabKey)
@@ -89,12 +99,30 @@
          })
      },
      /**
       * 递归获得所有树节点key
       * @param data
       */
      generateList(data) {
        for (let i = 0; i < data.length; i++) {
          const node = data[i]
          const key = node.key
          this.allTreeKeys.push(key)
          if (node.children) this.generateList(node.children)
        }
      },
      // 调用接口获取所有用户列表
      getAllUsersListByApi() {
        dncApi.getAllUsersListApi()
          .then(res => {
            if (res.success) {
              this.allUsersList = res.result.records
              this.allUsersList = res.result.records.map(item => {
                return {
                  ...item,
                  disabled: item.username === 'admin'
                }
              })
              this.$nextTick(() => this.$refs.userPermissionTransferRef.getHasPermissionUserByApi())
            }
          })
src/views/dnc/base/modules/ProductStructure/Permission/DepartPermissionTransfer.vue
@@ -1,17 +1,44 @@
<template>
  <a-spin :spinning="spinning">
    <a-transfer
      class="transfer-container"
      class="tree-transfer"
      :data-source="dataSource"
      show-search
      :list-style="{flex:1,height: '500px'}"
      :titles="['未分配部门', '已分配部门']"
      :operations="['分配部门', '移除部门']"
      :target-keys="targetKeys"
      :render="item => `${item.departName}`"
      :render="item => `${item.title}`"
      @change="handleChange"
      :rowKey="record => record.departId"
      @search="handleSearch"
    >
      <template slot="children" slot-scope="{ props: { direction, selectedKeys }, on: { itemSelect } }">
        <a-tree
          v-if="direction === 'left'"
          blockNode
          checkable
          checkStrictly
          :expandedKeys="expandedKeys"
          :autoExpandParent="autoExpandParent"
          @expand="handleTreeNodeExpand"
          :checkedKeys="[...selectedKeys, ...targetKeys]"
          :treeData="treeData"
          @check="(_, props) => {onChecked(_, props, [...selectedKeys, ...targetKeys], itemSelect);}"
          @select="(_, props) => {onChecked(_, props, [...selectedKeys, ...targetKeys], itemSelect); }">
          <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-tree>
      </template>
      <template slot="footer" slot-scope="{direction}" v-if="direction==='left'">
        <a-button type="primary" style="float:right;margin: 5px;margin-right: 10px"
                  @click="isExpandAllTreeNode=!isExpandAllTreeNode">
          展开/折叠
        </a-button>
      </template>
      <span slot="notFoundContent">暂无数据</span>
    </a-transfer>
@@ -21,6 +48,8 @@
<script>
  import dncApi from '@/api/dnc'
  const transferDataSource = []
  export default {
    name: 'DepartPermissionTransfer',
    components: {},
@@ -28,7 +57,10 @@
      currentTreeNodeInfo: {
        type: Object
      },
      dataSource: {
      allTreeKeys: {
        type: Array
      },
      treeDataProps: {
        type: Array
      },
      isAssignSonNode: {
@@ -38,15 +70,65 @@
    data() {
      return {
        targetKeys: [],
        spinning: false
        spinning: false,
        isExpandAllTreeNode: true,
        searchValue: '',
        expandedKeys: [],
        autoExpandParent: true,
        dataSource: transferDataSource
      }
    },
    watch: {
      isExpandAllTreeNode: {
        handler(value) {
          if (value) this.expandedKeys = this.allTreeKeys
          else this.expandedKeys = []
        }
      }
    },
    computed: {
      treeData() {
        return this.handleTreeData(this.treeDataProps, this.targetKeys)
      }
    },
    methods: {
      // 调用接口获取有权限的部门列表
      getHasPermissionDepartByApi() {
        const that = this
        that.spinning = true
        dncApi.getHasPermissionDepartApi(this.currentTreeNodeInfo)
          .then(res => {
            if (res.success) this.targetKeys = res.list.map(item => item.departId)
            if (res.success) this.targetKeys = res.list.map(item => item.id)
          })
          .finally(() => {
            that.spinning = false
          })
      },
      /**
       * 穿梭框搜索框输入时触发
       * @param direction 穿梭框的左右 "left"||"right"
       * @param value 输入值
       */
      handleSearch(direction, value) {
        if (direction === 'left') {
          let search = value
          let expandedKeys = transferDataSource
            .map(item => {
              if (item.title != null) {
                if (item.title.indexOf(search) > -1) {
                  return this.getParentKey(item.key, this.treeDataProps)
                }
                return null
              }
            })
            .filter((item, i, self) => item && self.indexOf(item) === i)
          Object.assign(this, {
            expandedKeys,
            searchValue: search,
            autoExpandParent: true
          })
        }
      },
      handleChange(targetKeys, direction, moveKeys) {
@@ -91,14 +173,92 @@
          .finally(() => {
            that.spinning = false
          })
      },
      onChecked(_, e, checkedKeys, itemSelect) {
        const { eventKey } = e.node
        itemSelect(eventKey, !this.isChecked(checkedKeys, eventKey))
      },
      handleTreeData(data, targetKeys = []) {
        data.forEach(item => {
          item['disabled'] = targetKeys.includes(item.key)
          if (item.children) {
            this.handleTreeData(item.children, targetKeys)
          }
        })
        return data
      },
      handleTreeNodeExpand(expandedKeys) {
        this.expandedKeys = expandedKeys
        this.autoExpandParent = false
      },
      /**
       * 递归获得输入项的父级key
       * @param key 子项key
       * @param tree 子项
       */
      getParentKey(key, tree) {
        let parentKey
        for (let i = 0; i < tree.length; i++) {
          const node = tree[i]
          if (node.children) {
            if (node.children.some(item => item.key === key)) {
              parentKey = node.key
            } else if (
              this.getParentKey(key, node.children)) {
              parentKey = this.getParentKey(key, node.children)
            }
          }
        }
        return parentKey
      },
      isChecked(selectedKeys, eventKey) {
        return selectedKeys.indexOf(eventKey) !== -1
      },
      flatten(list = []) {
        list.forEach(item => {
          transferDataSource.push(item)
          if (item.children) {
            this.flatten(item.children)
          }
        })
      }
    }
  }
</script>
<style scoped lang="less">
  .transfer-container {
  .tree-transfer {
    display: flex;
    align-items: center;
    ::-webkit-scrollbar {
      width: 8px;
    }
  }
  .tree-transfer .ant-transfer-list .ant-transfer-list-body {
    display: flex;
    flex-direction: column;
  }
  /deep/ .ant-transfer-list-body {
    display: flex;
    flex-direction: column;
    .ant-transfer-list-body-customize-wrapper {
      flex: 1;
      overflow: auto;
    }
  }
  .replaceSearch {
    color: #40a9ff;
    font-weight: bold;
    background-color: rgb(204, 204, 204);
  }
</style>
src/views/dnc/base/modules/ProductStructure/Permission/UserPermissionTransfer.vue
@@ -42,9 +42,14 @@
    },
    methods: {
      getHasPermissionUserByApi() {
        const that = this
        that.spinning = true
        dncApi.getHasPermissionUserApi(this.currentTreeNodeInfo)
          .then(res => {
            if (res.success) this.targetKeys = res.list.map(item => item.id)
          })
          .finally(() => {
            that.spinning = false
          })
      },
@@ -64,14 +69,6 @@
          method = dncApi.assignPermissionToUser
        } else {
          method = dncApi.removePermissionFromUser
          const adminId = dataSource.find(item => item.username === 'admin').id
          if (moveKeys.includes(adminId)) {
            $notification.warning({
              message: '消息',
              description: '不能移除管理员权限'
            })
            return
          }
        }
        that.spinning = true
        method(params)
src/views/dnc/base/modules/ProductStructure/ProductStructureTree.vue
@@ -24,7 +24,7 @@
        <!--产品结构树-->
        <div style="flex: 1;overflow:auto;margin-top: 10px">
          <a-tree ref="tree" show-icon :expandedKeys.sync="expandedKeys"
          <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="{ label, parentId, entity, key:treeKey,type}">
@@ -298,10 +298,6 @@
  /deep/ .ant-card-body, /deep/ .ant-spin-nested-loading, /deep/ .ant-spin-container {
    height: 100%;
  }
  /deep/ .ant-tree-node-content-wrapper {
    width: calc(100% - 24px);
  }
  /deep/ .ant-tree-title, .ant-tree-title .ant-dropdown-trigger {