DeviceControl.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <script setup lang="ts">
  2. import { computed, ref } from 'vue';
  3. import { t } from '@/i18n';
  4. import { addUnit } from '@/utils';
  5. import AdvancedSettings from './AdvancedSettings.vue';
  6. import AIOptimization from './AIOptimization.vue';
  7. import AIStartStop from './AIStartStop.vue';
  8. import type { Component, CSSProperties } from 'vue';
  9. interface ConfigItem {
  10. label: string;
  11. component: Component;
  12. style?: CSSProperties;
  13. }
  14. const activeConfigIndex = ref(-1);
  15. const configs = computed<ConfigItem[]>(() => {
  16. return [
  17. { label: t('realTimeMonitor.aiStartStop'), component: AIStartStop },
  18. { label: t('realTimeMonitor.aiOptimization'), component: AIOptimization },
  19. {
  20. label: t('common.advancedSettings'),
  21. component: AdvancedSettings,
  22. style: {
  23. paddingBlock: addUnit(16),
  24. },
  25. },
  26. ];
  27. });
  28. const showCtrlPanel = computed(() => {
  29. return activeConfigIndex.value !== -1;
  30. });
  31. const toggleConfig = (index: number) => {
  32. if (activeConfigIndex.value === index) {
  33. closeCtrlPanel();
  34. } else {
  35. activeConfigIndex.value = index;
  36. }
  37. };
  38. const closeCtrlPanel = () => {
  39. activeConfigIndex.value = -1;
  40. };
  41. defineExpose({
  42. closeCtrlPanel,
  43. });
  44. </script>
  45. <template>
  46. <div class="ctrl-button-conatiner top-1/2 flex flex-col -translate-y-1/2" @click.stop>
  47. <div
  48. :class="['ctrl-button', { 'ctrl-button-active': activeConfigIndex === index }]"
  49. v-for="(item, index) in configs"
  50. :key="index"
  51. :style="item.style"
  52. @click="toggleConfig(index)"
  53. >
  54. <div class="corner-border lt-border"></div>
  55. <div class="corner-border rt-border"></div>
  56. <div class="corner-border lb-border"></div>
  57. <div class="corner-border rb-border"></div>
  58. {{ item.label }}
  59. </div>
  60. <div class="ctrl-panel" v-if="showCtrlPanel">
  61. <div class="ctrl-panel-title">{{ configs[activeConfigIndex].label }}</div>
  62. <component :is="configs[activeConfigIndex].component" />
  63. </div>
  64. </div>
  65. </template>
  66. <style lang="scss" scoped>
  67. .ctrl-button-conatiner {
  68. position: fixed;
  69. right: 16px;
  70. margin-inline: 16px;
  71. }
  72. .ctrl-button {
  73. position: relative;
  74. width: 32px;
  75. height: 96px;
  76. padding: 8px;
  77. font-size: 14px;
  78. line-height: 16px;
  79. color: #fff;
  80. cursor: pointer;
  81. background-color: #323a47;
  82. border: 1px solid rgb(134 141 152 / 40%);
  83. box-shadow: inset 0 0 3px 0 rgb(255 255 255 / 24%);
  84. & + & {
  85. margin-top: 16px;
  86. }
  87. }
  88. .ctrl-button-active {
  89. background-color: var(--antd-color-primary);
  90. border: 1px solid rgb(255 255 255 / 50%);
  91. box-shadow: inset 0 0 6px 1px rgb(255 255 255 / 70%);
  92. .corner-border {
  93. --corner-border-color: #fff;
  94. }
  95. }
  96. .ctrl-panel {
  97. position: absolute;
  98. top: -147px;
  99. right: 48px;
  100. width: 464px;
  101. height: 630px;
  102. padding: 24px;
  103. background: rgb(30 37 48 / 50%);
  104. backdrop-filter: blur(12px);
  105. border: 1px solid rgb(255 255 255 / 24%);
  106. border-radius: 8px;
  107. }
  108. .ctrl-panel-title {
  109. margin-bottom: 16px;
  110. font-size: 16px;
  111. font-weight: 500;
  112. line-height: 22px;
  113. color: #fff;
  114. }
  115. :deep(.ant-switch) {
  116. background: rgb(255 255 255 / 25%);
  117. &:hover:not(.ant-switch-disabled) {
  118. background: rgb(255 255 255 / 45%);
  119. }
  120. &.ant-switch-checked {
  121. background: var(--antd-color-primary);
  122. &:hover:not(.ant-switch-disabled) {
  123. background: var(--antd-color-primary-hover);
  124. }
  125. }
  126. }
  127. </style>