rykb.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <script setup lang="ts">
  2. import { DESIGN_HEIGHT, DESIGN_WIDTH } from '@/utils/kb'
  3. import rysummary from './rykb/rysummary.vue'
  4. import safeday from './rykb/safeday.vue'
  5. import rydeviceStatus from './rykb/rydeviceStatus.vue'
  6. import zjStatsSwitch from './rykb/zjStatsSwitch.vue'
  7. import xjwork from './rykb/xjwork.vue'
  8. import rydeviceList from './rykb/rydeviceList.vue'
  9. import ryProductionBriefs from './rykb/ryProductionBriefs.vue'
  10. import rydeviceType from './rykb/rydeviceType.vue'
  11. defineOptions({
  12. name: 'IotRyStatt'
  13. })
  14. const company = ref('瑞鹰')
  15. const wrapperRef = ref<HTMLDivElement>()
  16. const scale = ref(1)
  17. let resizeObserver: ResizeObserver | null = null
  18. let resizeRaf = 0
  19. provide('ryKbScale', scale)
  20. const targetWrapperStyle = computed(() => ({
  21. width: `${DESIGN_WIDTH * scale.value}px`,
  22. height: `${DESIGN_HEIGHT * scale.value}px`
  23. }))
  24. const targetAreaStyle = computed(() => {
  25. return {
  26. '--kb-scale': scale.value,
  27. width: `${DESIGN_WIDTH * scale.value}px`,
  28. height: `${DESIGN_HEIGHT * scale.value}px`
  29. }
  30. })
  31. function updateScale() {
  32. cancelAnimationFrame(resizeRaf)
  33. resizeRaf = requestAnimationFrame(() => {
  34. const wrapper = wrapperRef.value
  35. if (!wrapper) return
  36. const { clientWidth, clientHeight } = wrapper
  37. if (!clientWidth || !clientHeight) return
  38. scale.value = Math.min(clientWidth / DESIGN_WIDTH, clientHeight / DESIGN_HEIGHT)
  39. nextTick(() => {
  40. window.dispatchEvent(new Event('rykb:resize'))
  41. })
  42. })
  43. }
  44. onMounted(() => {
  45. nextTick(updateScale)
  46. resizeObserver = new ResizeObserver(updateScale)
  47. if (wrapperRef.value) {
  48. resizeObserver.observe(wrapperRef.value)
  49. }
  50. window.addEventListener('resize', updateScale)
  51. })
  52. onUnmounted(() => {
  53. resizeObserver?.disconnect()
  54. window.removeEventListener('resize', updateScale)
  55. cancelAnimationFrame(resizeRaf)
  56. })
  57. </script>
  58. <template>
  59. <div ref="wrapperRef" class="bg absolute top-0 left-0 size-full z-10">
  60. <div class="mx-a overflow-hidden" :style="targetWrapperStyle">
  61. <div class="bg kb-screen" :style="targetAreaStyle">
  62. <header class="header">{{ company }}</header>
  63. <div class="kb-content">
  64. <rysummary class="kb-stage-card kb-stage-card--1" />
  65. <div class="kb-chart-grid">
  66. <rydeviceStatus class="kb-stage-card kb-stage-card--2" />
  67. <rydeviceType class="kb-stage-card kb-stage-card--6" />
  68. <rydeviceList class="kb-stage-card kb-stage-card--4 kb-stage-card--list" />
  69. <safeday class="kb-stage-card kb-stage-card--3" />
  70. <zjStatsSwitch class="kb-stage-card kb-stage-card--5" />
  71. <xjwork class="kb-stage-card kb-stage-card--7" />
  72. </div>
  73. <ryProductionBriefs class="kb-stage-card kb-stage-card--8 kb-stage-card--list" />
  74. </div>
  75. </div>
  76. </div>
  77. </div>
  78. </template>
  79. <style scoped lang="scss">
  80. @import url('@/styles/kb.scss');
  81. .kb-screen {
  82. overflow: hidden;
  83. }
  84. .kb-content {
  85. padding: calc(12px * var(--kb-scale)) calc(20px * var(--kb-scale)) 0;
  86. }
  87. .kb-chart-grid {
  88. display: grid;
  89. width: 100%;
  90. height: calc(592px * var(--kb-scale));
  91. margin-top: calc(12px * var(--kb-scale));
  92. gap: calc(12px * var(--kb-scale));
  93. grid-template-rows: repeat(2, minmax(0, 1fr));
  94. grid-template-columns: repeat(3, minmax(0, 1fr));
  95. }
  96. </style>