SysWindCard.vue 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. <!-- eslint-disable vue/multi-word-component-names -->
  2. <template>
  3. <!-- 基准的画廊模块,通过不同的 type 展示不同的样式 -->
  4. <div ref="container" class="syswind__container w-full h-full">
  5. <div v-for="item in data" :key="item.deviceID" v-data-picker="item" class="syswind__card">
  6. <!-- 画廊项的具体内容填充剩余宽度 -->
  7. <div class="syswind__card__title font-bold" :title="getFormattedText(item, config.title)">{{ getFormattedText(item, config.title) }}</div>
  8. <div class="flex items-center justify-between syswind__card__vol_wrapper">
  9. <div class="syswind__card__vol_image" :class="{ overlimit: isVolumnOverLimit(item) }"></div>
  10. <div>
  11. <div
  12. v-for="(ctx, idx) in config.volumns"
  13. :key="`v${idx}`"
  14. class="flex justify-between pl-20px pr-10px syswind__card__vol_space"
  15. :class="{ overlimit_space: isVolumnOverLimit(item) }"
  16. >
  17. <span>{{ getFormattedText(item, ctx.label) }}</span>
  18. <span class="font-bold">{{ getFormattedText(item, ctx.value) }}</span>
  19. </div>
  20. </div>
  21. </div>
  22. <div class="flex items-center justify-between syswind__card__spd_wrapper">
  23. <div class="syswind__card__spd_image" :class="{ overlimit: isSpeedOverLimit(item) }"></div>
  24. <div>
  25. <div
  26. v-for="(ctx, idx) in config.speeds"
  27. :key="`s${idx}`"
  28. class="flex justify-between pl-20px pr-10px syswind__card__spd_space"
  29. :class="{
  30. overlimit_space: isSpeedOverLimit(item),
  31. }"
  32. >
  33. <span>{{ getFormattedText(item, ctx.label) }}</span>
  34. <span class=".font-bold">{{ getFormattedText(item, ctx.value) }}</span>
  35. </div>
  36. </div>
  37. </div>
  38. </div>
  39. </div>
  40. </template>
  41. <script lang="ts" setup>
  42. import { defaultTo, inRange, first } from 'lodash-es';
  43. import { getFormattedText } from '../../hooks/helper';
  44. import { useDataPicker } from '/@/views/ventAI/dataPicker';
  45. const { directive: vDataPicker } = useDataPicker((item) => ({
  46. device_id: item.deviceID,
  47. device_name: item.strinstallpos,
  48. device_type: 'windrect',
  49. mode: 'fast',
  50. }));
  51. const props = defineProps<{
  52. config: {
  53. title: string;
  54. volumns: { value: string; label: string; lowerLimit: string }[];
  55. speeds: { value: string; label: string; lowerLimit: string; upperLimit: string }[];
  56. prop: string;
  57. };
  58. data: any[];
  59. }>();
  60. // defineEmits(['click']);
  61. // 判断val是否在low、high指定的范围内
  62. function isOverLimit(val: string, low: string = '', high: string = '') {
  63. const l = parseFloat(low);
  64. const h = parseFloat(high);
  65. const v = parseFloat(val);
  66. return !inRange(defaultTo(v, 0), defaultTo(l, -Infinity), defaultTo(h, Infinity));
  67. }
  68. function isVolumnOverLimit(item) {
  69. const ctx = first(props.config.volumns);
  70. if (!ctx) return false;
  71. return isOverLimit(getFormattedText(item, ctx.value), getFormattedText(item, ctx.lowerLimit));
  72. }
  73. function isSpeedOverLimit(item) {
  74. const ctx = first(props.config.speeds);
  75. if (!ctx) return false;
  76. return isOverLimit(getFormattedText(item, ctx.value), getFormattedText(item, ctx.lowerLimit), getFormattedText(item, ctx.upperLimit));
  77. }
  78. // const container = ref<HTMLElement>();
  79. // const { y, directions } = useScroll(container); // 当前滚动位置(响应式)
  80. // const STEP = 234;
  81. // useEventListener(
  82. // container,
  83. // 'scrollend',
  84. // (event) => {
  85. // console.log('debug rr', event);
  86. // event.preventDefault();
  87. // event.stopPropagation(); // 防止冒泡到外层
  88. // const direction = directions.top ? -1 : 1;
  89. // const targetY = y.value + direction * STEP;
  90. // container.value?.scrollTo({
  91. // top: targetY,
  92. // behavior: 'smooth',
  93. // });
  94. // },
  95. // { passive: false }
  96. // );
  97. </script>
  98. <style lang="less" scoped>
  99. @import '@/design/theme.less';
  100. @import '@/design/theme.less';
  101. @{theme-green} {
  102. .gallery {
  103. --image-gallery_I_2: url(/@/assets/images/themify/deepblue/home-container/configurable/dusthome/gallery_I_2.png);
  104. --image-gallery_I_1: url(/@/assets/images/themify/green/home-container/configurable/dusthome/gallery_I_1.png);
  105. }
  106. }
  107. .syswind__container {
  108. padding: 10px 30px;
  109. display: flex;
  110. flex-wrap: wrap;
  111. justify-content: space-between;
  112. overflow: auto;
  113. scroll-padding-top: 10px;
  114. scroll-snap-type: y mandatory;
  115. }
  116. .syswind__card {
  117. --image-syswind-space-red: url(/@/assets/images/home-container/configurable/preset/syswind-space-red.png);
  118. --image-syswind-space-blue: url(/@/assets/images/home-container/configurable/preset/syswind-space-blue.png);
  119. --image-syswind-space-green: url(/@/assets/images/home-container/configurable/preset/syswind-space-green.png);
  120. --image-syswind-border-blue: url(/@/assets/images/home-container/configurable/preset/syswind-border-blue.png);
  121. --image-syswind-border-green: url(/@/assets/images/home-container/configurable/preset/syswind-border-green.png);
  122. --image-syswind-module-title: url(/@/assets/images/home-container/configurable/preset/syswind-module-title.png);
  123. --image-syswind-module: url(/@/assets/images/home-container/configurable/preset/syswind-module.png);
  124. --image-syswind-icon-blue: url(/@/assets/images/home-container/configurable/preset/syswind-icon-blue.png);
  125. --image-syswind-icon-green: url(/@/assets/images/home-container/configurable/preset/syswind-icon-green.png);
  126. --image-syswind-icon-red: url(/@/assets/images/home-container/configurable/preset/syswind-icon-red.png);
  127. --image-syswind-icon-vol: url(/@/assets/images/home-container/configurable/preset/syswind-icon-vol.svg);
  128. --image-syswind-icon-vol-red: url(/@/assets/images/home-container/configurable/preset/syswind-icon-vol-red.svg);
  129. --image-syswind-icon-spd: url(/@/assets/images/home-container/configurable/preset/syswind-icon-spd.svg);
  130. --image-syswind-icon-spd-red: url(/@/assets/images/home-container/configurable/preset/syswind-icon-spd-red.svg);
  131. background-image: var(--image-syswind-module);
  132. background-repeat: no-repeat;
  133. width: 320px;
  134. // width: 320px;
  135. height: 234px;
  136. margin: 0 0 10px 0;
  137. scroll-padding-top: 10px;
  138. scroll-snap-align: start;
  139. .syswind__card__title {
  140. background-image: var(--image-syswind-module-title);
  141. width: 250px;
  142. height: 24px;
  143. padding-left: 10px;
  144. padding-right: 20px;
  145. font-size: 16px;
  146. background-size: 100% 100%;
  147. overflow: hidden; /* 隐藏溢出内容 */
  148. white-space: nowrap; /* 强制文本不换行 */
  149. text-overflow: ellipsis; /* 显示省略号 */
  150. }
  151. .syswind__card__vol_image {
  152. background-image: var(--image-syswind-icon-green), var(--image-syswind-icon-vol);
  153. background-position: center, center;
  154. background-repeat: no-repeat;
  155. width: 76px;
  156. height: 70px;
  157. }
  158. .syswind__card__spd_image {
  159. background-image: var(--image-syswind-icon-blue), var(--image-syswind-icon-spd);
  160. background-position: center, center;
  161. background-repeat: no-repeat;
  162. width: 76px;
  163. height: 70px;
  164. }
  165. .syswind__card__vol_space {
  166. background-image: var(--image-syswind-space-green);
  167. background-repeat: no-repeat;
  168. background-position: bottom left;
  169. width: 208px;
  170. height: 28px;
  171. line-height: 28px;
  172. }
  173. .syswind__card__spd_space {
  174. background-image: var(--image-syswind-space-blue);
  175. background-repeat: no-repeat;
  176. background-position: bottom left;
  177. width: 208px;
  178. height: 28px;
  179. line-height: 28px;
  180. }
  181. .syswind__card__vol_wrapper {
  182. background-image: var(--image-syswind-border-green);
  183. height: 72px;
  184. background-position: right center;
  185. background-repeat: no-repeat;
  186. margin: 10px;
  187. padding-right: 10px;
  188. .overlimit {
  189. background-image: var(--image-syswind-icon-red), var(--image-syswind-icon-vol-red);
  190. }
  191. }
  192. .syswind__card__spd_wrapper {
  193. background-image: var(--image-syswind-border-blue);
  194. height: 100px;
  195. background-position: right center;
  196. background-repeat: no-repeat;
  197. margin: 10px;
  198. padding-right: 10px;
  199. .overlimit {
  200. background-image: var(--image-syswind-icon-red), var(--image-syswind-icon-spd-red);
  201. }
  202. }
  203. .overlimit_space {
  204. background-image: var(--image-syswind-space-red);
  205. }
  206. }
  207. </style>