ModuleCommon.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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">
  8. <template v-if="moduleName" #title>
  9. <div :class="{ 'cursor-pointer': !!moduleData.to }" @click="redirectTo">{{ moduleName }}</div>
  10. </template>
  11. <template #container>
  12. <slot>
  13. <Header :deviceType="deviceType" :moduleData="moduleData" :data="data" @select="selectedData = $event" />
  14. <Content :style="{ height: header.show ? 'calc(100% - 30px)' : '100%' }" :moduleData="moduleData" :data="selectedData" />
  15. </slot>
  16. </template>
  17. </ventBox1>
  18. </Transition>
  19. </template>
  20. <script lang="ts" setup>
  21. import Header from './header.vue';
  22. import Content from './content.vue';
  23. // import ModuleLeft from './original/moduleLeft.vue';
  24. // import ModuleBottom from './original/moduleBottom.vue';
  25. import { computed, ref } from 'vue';
  26. import ventBox1 from '/@/components/vent/ventBox1.vue';
  27. import { openWindow } from '/@/utils';
  28. import { getFormattedText } from '../hooks/helper';
  29. // import { ModuleProps } from '../types';
  30. const props = defineProps<{
  31. /** 配置的详细模块信息 */
  32. moduleData: any;
  33. /** 配置的详细样式信息 */
  34. showStyle: any;
  35. /** 该模块配置中的设备标识符 */
  36. deviceType: string;
  37. /** api返回的数据 */
  38. data: any;
  39. moduleName: string;
  40. visible: boolean;
  41. }>();
  42. defineEmits(['close', 'click']);
  43. const { header } = props.moduleData;
  44. const selectedData = ref();
  45. const style = computed(() => {
  46. const size = props.showStyle.size;
  47. const position = props.showStyle.position;
  48. return size + position + 'position: absolute; pointer-events: auto;';
  49. });
  50. const capitalizedPosition = computed(() => {
  51. return props.showStyle.position.includes('left') ? 'Left' : 'Right';
  52. });
  53. // 根据配置里的定位判断应该使用哪个class
  54. function getModuleClass({ size, position }) {
  55. const [_, width] = size.match(/width:([0-9]+)px/) || [];
  56. if (position.includes('bottom') || parseInt(width) > 800) {
  57. return 'module-common module-common-longer';
  58. }
  59. return 'module-common';
  60. }
  61. function redirectTo() {
  62. const { to } = props.moduleData;
  63. if (!to) return;
  64. openWindow(getFormattedText(selectedData.value, to));
  65. }
  66. </script>
  67. <style lang="less" scoped>
  68. @import '/@/design/theme.less';
  69. .module-common .box1-center {
  70. height: calc(100% - 48px);
  71. }
  72. :deep(.box1-center) {
  73. height: calc(100% - 48px);
  74. }
  75. :deep(.box1-center > .box-container) {
  76. height: 100%;
  77. padding: 0 !important;
  78. width: 100% !important;
  79. }
  80. @{theme-deepblue} {
  81. .module-common-longer {
  82. :deep(.box1-top) {
  83. --image-box1-top: url('/@/assets/images/themify/deepblue/vent/border/box2-top-long.png');
  84. }
  85. :deep(.box1-bottom) {
  86. --image-box1-bottom: none;
  87. }
  88. }
  89. }
  90. .module-common-longer {
  91. :deep(.box1-top) {
  92. --image-box1-top: url('/@/assets/images/vent/box-top-bg.png');
  93. background-image: var(--image-box1-top);
  94. }
  95. :deep(.box1-bottom) {
  96. --image-box1-bottom: url('/@/assets/images/vent/box-bottom-bg.png');
  97. background-image: var(--image-box1-bottom);
  98. }
  99. }
  100. </style>