cuijian
2025-07-28 accebdce93486d3b4f26e55ffdea047549cce20c
src/views/mdc/common/BaseTree.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,404 @@
<template>
  <a-card class="tree_con" :loading="cardLoading" :bordered="false" >
    <a-spin :spinning="loading">
      <div style="display: flex;flex-direction: column;height: 100%">
          <div>
            <a-alert type="info" :showIcon="false" style="margin-right: 54px;padding-left: 5px">
              <div slot="message">
                <span v-if="this.currSelected.title">{{ getCurrSelectedTitle() }}</span>
                <a v-if="this.currSelected.title" style="margin-left: 10px" @click="onClearSelected">取消</a>
                <span v-else>无</span>
              </div>
            </a-alert>
            <div class="drawer-bottom-button">
              <a-dropdown :trigger="['click']" placement="bottomCenter">
                <a-menu slot="overlay">
                  <a-menu-item key="1" @click="expandAll">展开所有</a-menu-item>
                  <a-menu-item key="2" @click="closeAll">合并所有</a-menu-item>
                  <a-menu-item key="3" @click="refreshTree">刷新</a-menu-item>
                </a-menu>
                <a-button>
                  <a-icon type="bars"/>
                </a-button>
              </a-dropdown>
            </div>
          </div>
        <a-input-search @search="handleSearch" style="width:100%;margin-top: 10px" placeholder="检索 ç±»åˆ«ç¼–码/名称" allowClear
                        v-model="searchInput" @change="handleChange"/>
        <!-- showLine -->
        <div style="flex: 1;overflow:auto;margin-top: 10px">
          <a-tree showLine ref="tree" :checkStrictly="checkStrictly" :expandedKeys.sync="expandedKeys"
                  :selectedKeys="selectedKeys" :dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
                  :treeData="treeDataSource"
                  :autoExpandParent="autoExpandParent" @select="onSelect" @expand="onExpand" slots="{}">
            <template slot="title" slot-scope="{ title, parentId, entity, key}">
          <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>
              <a-dropdown v-if="!editDisable && entity.parentId == -1" :trigger="['click']" placement="bottomCenter">
                <a-menu slot="overlay">
                  <a-menu-item>
                    <a href="javascript:;" @click="handleEdit(entity)">编辑</a>
                  </a-menu-item>
                  <a-menu-item>
                    <a href="javascript:;" @click="batchDel(entity)">
                      åˆ é™¤
                    </a>
                  </a-menu-item>
                </a-menu>
                <span :style="{position: 'absolute',right: 0}">
              <a-icon type="down"/>
            </span>
              </a-dropdown>
            </template>
          </a-tree>
        </div>
      </div>
    </a-spin>
    <tier-model ref="tierModalForm"  @ok="modalFormOk"></tier-model>
  </a-card>
</template>
<script>
  import {
    getAction,
    postAction,
    deleteAction
  } from '@/api/manage'
  import Tooltip from 'ant-design-vue/es/tooltip'
  import TierModel from './modules/baseTree/TierModel'
  import {mapActions} from 'vuex'
  export default {
    name: 'BaseTree',
    props: {
      editDisable: {
        type: Boolean,
        default() {
          return true
        }
      }
    },
    components: {
      Tooltip,
      TierModel
    },
    data() {
      return {
        searchInput: '',
        cardLoading: false,
        loading: false,
        treeDataSource: [],
        selectedKeys: [],
        expandedKeys: [],
        url: {
          getBaseTree: '/mdc/mdcEquipment/queryTreeListByProduction',
          deleteBatch: '/mdc/mdcequipment/deleteBatch'
        },
        searchValue: '',
        dataList: [],
        autoExpandParent: true,
        checkStrictly: true,
        allTreeKeys: [],
        currSelected: {},
        hiding: false,
        mathChange:''
      }
    }
    ,
    created() {
      this.queryTreeData()
      this.closeAll()
    }
    ,
    methods: {
      ...mapActions(['QueryProduction']),
      getCurrSelectedTitle() {
        return !this.currSelected.title ? '' : this.currSelected.title
      },
      /**
       * å–消车间选中项
       */
      onClearSelected() {
        this.hiding = true
        this.currSelected = {}
        this.selectedKeys = []
        // console.log('发送')
        // this.$bus.$emit('treeClearSelected','重置列表')
        this.$emit('sendSelectBaseTree', '')
      },
      onSelect(selectedKeys, e) {
        this.hiding = false
        let record = e.node.dataRef
        this.currSelected = Object.assign({}, record)
        this.selectedKeys = [record.key]
        this.$emit('sendSelectBaseTree', this.selectedKeys)
      },
      handleEdit(entity) {
        this.$refs.tierModalForm.edit(entity)
        this.$refs.tierModalForm.title = '编辑层级'
        this.$refs.tierModalForm.disableSubmit = false
      },
      onExpand(expandedKeys) {
        this.expandedKeys = expandedKeys
        this.autoExpandParent = false
      },
      queryTreeData() {
        this.loading = true
        this.cardLoading = true
        this.QueryProduction().then(res => {
          if (res.success) {
            this.dataList = []
            this.allTreeKeys = []
            this.treeDataSource = res.result
            this.generateList(res.result)
            this.expandedKeys=this.allTreeKeys
          } else {
            this.$message.warn(res.message)
          }
        }).finally(() =>{
          this.loading = false
          this.cardLoading = false
        })
        // getAction(this.url.getBaseTree).then((res) => {
        //   if (res.success) {
        //     this.dataList = []
        //     this.allTreeKeys = []
        //     this.treeDataSource = res.result
        //     this.generateList(res.result)
        //   } else {
        //     this.$message.warn(res.message)
        //   }
        // }).finally(() => {
        //   this.loading = false
        //   this.cardLoading = false
        // })
      },
      handleChange() {
        let search = this.searchInput
        let expandedKeys = this.dataList
          .map(item => {
            if(item.title !=null){
              if (item.title.indexOf(search) > -1) {
                return this.getParentKey(item.key, this.treeDataSource)
              }
              return null
            }
          })
          .filter((item, i, self) => item && self.indexOf(item) === i)
        Object.assign(this, {
          expandedKeys,
          searchValue: search,
          autoExpandParent: true
        })
      },
      handleSearch(value) {
        let search = value
        let expandedKeys = this.dataList
          .map(item => {
            if(item.title !=null){
              if (item.title.indexOf(search) > -1) {
                return this.getParentKey(item.key, this.treeDataSource)
              }
              return null
            }
          })
          .filter((item, i, self) => item && self.indexOf(item) === i)
        Object.assign(this, {
          expandedKeys,
          searchValue: search,
          autoExpandParent: true
        })
      },
      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
      },
      generateList(data) {
        for (let i = 0; i < data.length; i++) {
          const node = data[i]
          const key = node.key
          const title = node.title
          this.dataList.push({
            key,
            title: title
          })
          this.allTreeKeys.push(key)
          if (node.children) {
            this.generateList(node.children)
          }
        }
      },
      expandAll() {
        this.expandedKeys = this.allTreeKeys
      },
      closeAll() {
        this.expandedKeys = ['-1']
      },
      refreshTree() {
        this.queryTreeData()
      },
      batchDel: function(entity) {
        if (!this.url.deleteBatch) {
          this.$message.error('请设置url.deleteBatch属性!')
          return
        }
        let ids = entity.id
        if (!ids) {
          // this.$message.warning('请选择一条记录!')
          this.$notification.warning({
            message:'消息',
            description:"请选择一条记录"
          });
          return
        } else {
          var that = this
          this.$confirm({
            title: '确认删除',
            content: '是否删除选中数据?',
            onOk: function() {
              that.loading = true
              deleteAction(that.url.deleteBatch, { ids: ids }).then((res) => {
                if (res.success) {
                  that.$message.success(res.message)
                  that.queryTreeData();
                } else {
                  that.$message.warning(res.message)
                }
              }).finally(() => {
                that.loading = false
              })
            }
          })
        }
      },
      modalFormOk(val) {
        console.log("mmm")
        // æ–°å¢ž/修改 æˆåŠŸæ—¶ï¼Œé‡è½½åˆ—è¡¨
        this.queryTreeData()
        // æ–°å¢ž/修改 æˆåŠŸæ—¶ï¼Œé‡è½½åˆ—è¡¨
      }
    },
    //监听
    watch: {
      currSelected(val) { //监听currSelected å˜åŒ–,将变化后的数值传递给 getCurrSelected äº‹ä»¶
        this.$emit('getCurrSelected', val)
      },
    }
  }
</script>
<style lang="less" scoped>
  .replaceSearch {
    color: #40a9ff;
    font-weight: bold;
    background-color: rgb(204, 204, 204);
  }
  .ant-card-body .table-operator {
    margin: 15px;
  }
  .anty-form-btn {
    width: 100%;
    text-align: center;
  }
  .anty-form-btn button {
    margin: 0 5px;
  }
  .anty-node-layout .ant-layout-header {
    padding-right: 0;
  }
  .header {
    padding: 0 8px;
  }
  .header button {
    margin: 0 3px;
  }
  .ant-modal-cust-warp {
    height: 100%;
  }
  .ant-modal-cust-warp .ant-modal-body {
    height: calc(100% - 110px) !important;
    overflow-y: auto;
  }
  .ant-modal-cust-warp .ant-modal-content {
    height: 90% !important;
    overflow-y: hidden;
  }
  /** Button按钮间距 */
  .ant-btn {
    margin-left: 3px;
  }
  .ant-alert {
    padding: 5px 15px 5px 37px;
  }
  .drawer-bottom-button {
    position: absolute;
    top: 1px;
    /* padding: 10px 16px; */
    text-align: left;
    right: 0;
    background: #fff;
    border-radius: 0 0 2px 2px;
  }
  .tree_con{
    overflow: hidden;
  }
  @media screen and (min-width: 1920px){
    .tree_con{
      height: 748px!important;
    }
  }
  @media screen and (min-width: 1680px) and (max-width: 1920px){
    .tree_con{
      height: 748px!important;
    }
  }
  @media screen and (min-width: 1400px) and (max-width: 1680px){
    .tree_con{
      height: 600px!important;
    }
  }
  @media screen and (min-width: 1280px) and (max-width: 1400px){
    .tree_con{
      height: 501px!important;
    }
  }
  @media screen and (max-width: 1280px){
    .tree_con{
      height: 501px!important;
    }
  }
  /deep/ .ant-card-body,/deep/ .ant-spin-nested-loading,/deep/ .ant-spin-container{
    height: 100%;
  }
</style>