DeviceGroupLevel.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <template>
  2. <div class="c-device-group-level">
  3. <template v-if="hasData">
  4. <device-group-level-item
  5. v-for="item in groupOptions.list"
  6. :key="item.id"
  7. class="c-sibling-item--v far"
  8. v-bind="$attrs"
  9. :group="item"
  10. @volume="onVolume"
  11. />
  12. <volume-dialog ref="volumeDialog" />
  13. </template>
  14. <div
  15. v-else-if="groupOptions.loading"
  16. class="has-padding--v u-text--center"
  17. >
  18. <i class="el-icon-loading u-font-size--lg" />
  19. </div>
  20. <el-empty v-else />
  21. </div>
  22. </template>
  23. <script>
  24. import { getDepartmentDeviceTreeByGroup } from '@/api/device'
  25. import groupMixin from './mixins/group.js'
  26. import DeviceGroupLevelItem from './DeviceGroupLevelItem.vue'
  27. import VolumeDialog from './VolumeDialog.vue'
  28. export default {
  29. name: 'DeviceGroupLevel',
  30. components: {
  31. DeviceGroupLevelItem,
  32. VolumeDialog
  33. },
  34. mixins: [groupMixin],
  35. inject: ['dashboard'],
  36. props: {
  37. path: {
  38. type: String,
  39. required: true
  40. }
  41. },
  42. computed: {
  43. hasData () {
  44. return this.groupOptions.list.length > 0
  45. }
  46. },
  47. watch: {
  48. path () {
  49. this.refreshGroups(true)
  50. }
  51. },
  52. methods: {
  53. refreshGroups (force) {
  54. if (!this.path || !force && this.groupOptions.loading) {
  55. return
  56. }
  57. this.onResetGroupOptions()
  58. const groupOptions = this.createGroupOptions({ loading: true })
  59. this.groupOptions = groupOptions
  60. this.onChanged()
  61. getDepartmentDeviceTreeByGroup(this.path, { custom: true }).then(
  62. ({ data }) => {
  63. if (groupOptions.ignore) {
  64. return
  65. }
  66. const cache = { list: [], map: {}, topics: [] }
  67. this.flatTree('', data, cache)
  68. groupOptions.list = cache.list
  69. groupOptions.map = cache.map
  70. groupOptions.loaded = true
  71. this.onChanged()
  72. this.onSubscribe(cache.topics)
  73. },
  74. ({ isCancel }) => {
  75. if (isCancel || groupOptions.ignore) {
  76. return
  77. }
  78. this.$timer = setTimeout(this.refreshGroups, 2000)
  79. }
  80. ).finally(() => {
  81. groupOptions.loading = false
  82. })
  83. },
  84. flatTree (parent, { id = 'root', name, children, devices }, cache) {
  85. const group = parent && name ? `${parent} / ${name}` : name
  86. if (devices.length) {
  87. cache.list.push({
  88. id,
  89. name: group || '我的部门',
  90. children: devices.map(device => {
  91. const item = this.transformDevice(device)
  92. cache.map[item.id] = item
  93. cache.topics.push(...this.createTopics(item))
  94. return item
  95. })
  96. })
  97. }
  98. children?.forEach(node => {
  99. this.flatTree(group, node, cache)
  100. })
  101. },
  102. onChanged () {
  103. this.$emit('change', [...this.groupOptions.list])
  104. },
  105. onVolume ({ value, device }) {
  106. this.$refs.volumeDialog.show(value, device)
  107. }
  108. }
  109. }
  110. </script>
  111. <style lang="scss" scoped>
  112. .c-device-group-level {
  113. min-height: 400px;
  114. }
  115. </style>