floorUnitTree.vue 3.54 KB
<template>
  <el-card class="tree-card">
    <el-tree
      ref="tree"
      :data="treeData"
      :props="defaultProps"
      node-key="id"
      :default-expanded-keys="expandedKeys"
      :highlight-current="true"
      @node-click="handleNodeClick"
    >
      <template #default="{ node, data }">
        <span class="custom-tree-node">
          <img :src="data.icon" class="tree-icon" v-if="data.icon">
          <span>{{ node.label }}</span>
        </span>
      </template>
    </el-tree>
    <div v-if="!treeData || treeData.length === 0" class="no-data">
      {{ $t('floorUnitTree.noBuilding') }}
    </div>
  </el-card>
</template>

<script>
import { queryFloorAndUnits } from '@/api/car/carStructureApi'
import { getCommunityId } from '@/api/community/communityApi'

export default {
  name: 'FloorUnitTree',
  props: {
    floorId: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      treeData: [],
      defaultProps: {
        children: 'children',
        label: 'text'
      },
      expandedKeys: [],
      communityId: ''
    }
  },
  watch: {
    floorId(newVal) {
      this.$nextTick(() => {
        if (newVal) {
          const node = this.$refs.tree.getNode('f_' + newVal)
          if (node) {
            this.$refs.tree.setCurrentKey(node.key)
          }
        }
      })
    }
  },
  created() {
    this.communityId = getCommunityId()
    this.loadFloorAndUnits()
  },
  methods: {
    async loadFloorAndUnits() {
      try {
        const params = {
          communityId: this.communityId
        }
        const data = await queryFloorAndUnits(params)
        this.treeData = this.formatTreeData(data)
        this.setDefaultExpanded()
      } catch (error) {
        this.$message.error(this.$t('floorUnitTree.fetchError'))
      }
    },
    formatTreeData(data) {
      const formattedData = []
      const floorMap = {}

      // First pass: create floor nodes
      data.forEach(item => {
        if (!floorMap[item.floorId]) {
          floorMap[item.floorId] = {
            id: 'f_' + item.floorId,
            floorId: item.floorId,
            floorNum: item.floorNum,
            icon: require('@/assets/img/floor.png'),
            text: `${item.floorNum}${this.$t('floorUnitTree.building')}(${item.floorName})`,
            children: []
          }
          formattedData.push(floorMap[item.floorId])
        }

        // Add unit if it exists and not '0'
        if (item.unitId && item.unitNum !== '0') {
          floorMap[item.floorId].children.push({
            id: 'u_' + item.unitId,
            unitId: item.unitId,
            text: `${item.unitNum}${this.$t('floorUnitTree.unit')}`,
            icon: require('@/assets/img/unit.png')
          })
        }
      })

      return formattedData
    },
    setDefaultExpanded() {
      if (this.treeData.length > 0) {
        this.expandedKeys = [this.treeData[0].id]
      }
    },
    handleNodeClick(data) {
      if (data.id.startsWith('f_')) {
        this.$emit('switchFloor', { floorId: data.floorId })
      } else if (data.id.startsWith('u_')) {
        this.$emit('switchUnit', { unitId: data.unitId })
      }
    },
    refreshTree(params) {
      if (params && params.floorId) {
        this.floorId = params.floorId
      }
      this.loadFloorAndUnits()
    }
  }
}
</script>

<style lang="scss" scoped>
.tree-card {
  height: 100%;

  .custom-tree-node {
    display: flex;
    align-items: center;
  }

  .tree-icon {
    width: 16px;
    height: 16px;
    margin-right: 5px;
  }

  .no-data {
    padding: 10px;
    text-align: center;
    color: #909399;
  }
}
</style>