ModuleCommon.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <template>
  2. <!-- 常用模块 -->
  3. <Transition
  4. :enter-active-class="`animate__animated animate__fadeIn${capitalizedPosition}`"
  5. :leave-active-class="`animate__animated animate__fadeOut${capitalizedPosition}`"
  6. >
  7. <ventBox1 v-if="visible" :class="getModuleClass(showStyle)" :style="style" :pageType="pageType">
  8. <template v-if="moduleName" #title>
  9. <div :class="{ 'cursor-pointer': !!moduleData.to }" style="font-weight: bold; font-style: italic" @click="redirectTo">{{ moduleName }}</div>
  10. </template>
  11. <template #container>
  12. <slot>
  13. <Header :deviceType="deviceType" :moduleData="moduleData" :data="data" @select="handleSelect" />
  14. <Content
  15. :style="{ height: header.show ? 'calc(100% - 30px)' : '100%' }"
  16. :moduleData="moduleData"
  17. :data="selectedDevice"
  18. :chartData="chartData"
  19. />
  20. </slot>
  21. </template>
  22. </ventBox1>
  23. </Transition>
  24. </template>
  25. <script lang="ts" setup>
  26. import Header from './header.vue';
  27. import Content from '../../components/content.vue';
  28. // import ModuleLeft from './original/moduleLeft.vue';
  29. // import ModuleBottom from './original/moduleBottom.vue';
  30. import { computed, ref, watch } from 'vue';
  31. import ventBox1 from './ventBoxBelt.vue';
  32. import { openWindow } from '/@/utils';
  33. import { getFormattedText } from '../../hooks/helper';
  34. import { useInitModule } from '../../hooks/useInit';
  35. // import { ModuleProps } from '../types';
  36. const props = defineProps<{
  37. pageType: string;
  38. /** 配置的详细模块信息 */
  39. moduleData: any;
  40. /** 配置的详细样式信息 */
  41. showStyle: any;
  42. /** 该模块配置中的设备标识符 */
  43. deviceType: string;
  44. /** api返回的数据 */
  45. data: any;
  46. moduleName: string;
  47. visible: boolean;
  48. chartData?: any;
  49. }>();
  50. defineEmits(['close', 'click']);
  51. const { header } = props.moduleData;
  52. const { selectedDeviceID, selectedDevice, options, init } = useInitModule(props.deviceType, props.moduleData);
  53. const selectedData = ref();
  54. const style = computed(() => {
  55. const size = props.showStyle.size;
  56. const position = props.showStyle.position;
  57. return size + position + 'position: absolute; pointer-events: auto; z-index: 1';
  58. });
  59. const pageType = computed(() => {
  60. return props.pageType || '';
  61. });
  62. const capitalizedPosition = computed(() => {
  63. return props.showStyle.position.includes('left') ? 'Left' : 'Right';
  64. });
  65. // 根据配置里的定位判断应该使用哪个class
  66. function getModuleClass({ size, position }) {
  67. const [_, width] = size.match(/width:([0-9]+)px/) || [];
  68. if (position.includes('bottom') || parseInt(width) > 800) {
  69. return 'module-common module-common-longer';
  70. }
  71. return 'module-common';
  72. }
  73. function redirectTo() {
  74. const { to } = props.moduleData;
  75. if (!to) return;
  76. openWindow(getFormattedText(props.data, to));
  77. }
  78. /**
  79. * 模块选择切换事件
  80. * @param selectedItem
  81. */
  82. function handleSelect(selectedItem: any) {
  83. selectedData.value = selectedItem;
  84. if (!selectedItem) return;
  85. selectedDeviceID.value = options.value[0]?.value;
  86. if (selectedItem.id !== undefined && selectedItem.id !== null) {
  87. // 确保这个 ID 在当前的 options 里存在
  88. const isValid = options.value.some((opt) => opt.value === selectedItem.id);
  89. if (isValid) {
  90. selectedDeviceID.value = selectedItem.id;
  91. }
  92. }
  93. }
  94. watch(
  95. () => props.data,
  96. (d) => {
  97. init(d);
  98. if (!selectedDeviceID.value) {
  99. console.log(selectedDeviceID.value, '------');
  100. selectedDeviceID.value = options.value[0]?.value;
  101. }
  102. },
  103. {
  104. immediate: true,
  105. }
  106. );
  107. </script>
  108. <style lang="less" scoped>
  109. @import '/@/design/theme.less';
  110. .module-common .box1-center {
  111. height: calc(100% - 48px);
  112. }
  113. :deep(.box1-center) {
  114. height: calc(100% - 48px);
  115. }
  116. :deep(.box1-center > .box-container) {
  117. height: 100%;
  118. padding: 0 !important;
  119. width: 100% !important;
  120. }
  121. .module-common-longer {
  122. :deep(.box1-top) {
  123. --image-box1-top: url('/@/assets/images/beltFire/1-1.png');
  124. background-image: url('/@/assets/images/beltFire/1-1.png');
  125. }
  126. :deep(.box1-bottom) {
  127. --image-box1-bottom: url('/@/assets/images/beltFire/1-2.png');
  128. background-image: url('/@/assets/images/beltFire/1-2.png');
  129. }
  130. }
  131. </style>