weatherBroadcast.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. <template>
  2. <div>
  3. <div class="btn" @click="showWarningBroad">
  4. <!-- <div>语音播报</div>
  5. <a-badge :count="10">
  6. <a href="#" class="head-example"></a>
  7. </a-badge> -->
  8. <div style="display: flex; flex-direction: row;align-items: center;" class="btn-header">
  9. <img :src="parseWeatherData(weatherObj.text)" class="weather-icon" />
  10. <span class="unit">{{ weatherObj.pressure }}&nbsp;hPa</span>
  11. <FileSearchOutlined style="font-size: 20px; color: #fff;" />
  12. </div>
  13. </div>
  14. <div v-if="isShowWeatherBroad" class="broadcast" ref="VoiceBroadcastRef" id="VoiceBroadcast">
  15. <div class="title">
  16. <div class="message-title">详情</div>
  17. </div>
  18. <div class="broadcast-context">
  19. <div class="context-tab">
  20. <div class="context-tab-item" :class="{ 'context-tab-item-active': activeKey == 0 }" @click="toSelectList(0)">
  21. 温度</div>
  22. <div class="context-tab-item" :class="{ 'context-tab-item-active': activeKey == 1 }" @click="toSelectList(1)">
  23. 气压</div>
  24. <div class="context-tab-item" :class="{ 'context-tab-item-active': activeKey == 2 }" @click="toSelectList(2)">
  25. 风力</div>
  26. </div>
  27. <div class="context-box">
  28. <div class="echarts-box">
  29. <BarAndLine v-if="activeKey == 0" xAxisPropType="fxTime" height="240px" :dataSource="monitorData"
  30. :chartsColumns="ChartsColumnsWD" :option="Option" />
  31. <BarAndLine v-if="activeKey == 1" xAxisPropType="fxTime" height="240px" :dataSource="monitorData"
  32. :chartsColumns="ChartsColumnsQY" :option="Option" />
  33. <BarAndLine v-if="activeKey == 2" xAxisPropType="fxTime" height="240px" :dataSource="monitorData"
  34. :chartsColumns="ChartsColumnsFL" :option="Option" />
  35. </div>
  36. </div>
  37. </div>
  38. </div>
  39. </div>
  40. </template>
  41. <script lang="ts">
  42. import BarAndLine from '/@/components/chart/BarAndLine.vue';
  43. import { Tooltip, Badge } from 'ant-design-vue';
  44. import { SoundOutlined, ClearOutlined, FileSearchOutlined, WarningOutlined } from '@ant-design/icons-vue';
  45. import Icon from '/@/components/Icon';
  46. import { defineComponent, ref, onMounted, nextTick } from 'vue';
  47. import { defHttp } from '/@/utils/http/axios';
  48. import { useDrag } from '@/hooks/event/useDrag';
  49. export default defineComponent({
  50. name: 'VoiceBroadcast',
  51. components: { Icon, Tooltip, Badge, SoundOutlined, ClearOutlined, FileSearchOutlined, WarningOutlined, BarAndLine },
  52. setup() {
  53. const getWeather = () => defHttp.post({ url: '/safety/ventanalyDevice/getWeatherData' });
  54. const activeKey = ref(0);
  55. const isShowWeatherBroad = ref(false);
  56. const monitorData = ref<any[]>([]);
  57. const ChartsColumnsWD = [
  58. {
  59. legend: '温度',
  60. seriesName: '(℃)',
  61. ymax: 0.8,
  62. yname: '℃',
  63. linetype: 'line',
  64. yaxispos: 'left',
  65. color: '#00FFA8',
  66. sort: 1,
  67. xRotate: 0,
  68. dataIndex: 'temp',
  69. },
  70. ];
  71. const ChartsColumnsQY = [
  72. {
  73. legend: '气压',
  74. seriesName: '(hPa)',
  75. ymax: 0.8,
  76. yname: 'hPa',
  77. linetype: 'line',
  78. yaxispos: 'left',
  79. color: '#00FFA8',
  80. sort: 1,
  81. xRotate: 0,
  82. dataIndex: 'pressure',
  83. },
  84. ];
  85. const ChartsColumnsFL = [
  86. {
  87. legend: '风力',
  88. seriesName: '(等级)',
  89. ymax: 0.8,
  90. yname: '等级',
  91. linetype: 'line',
  92. yaxispos: 'left',
  93. color: '#00FFA8',
  94. sort: 1,
  95. xRotate: 0,
  96. dataIndex: 'widnScale',
  97. },
  98. ];
  99. const Option = {
  100. grid: {
  101. top: '20%',
  102. left: '5%',
  103. right: '5%',
  104. bottom: '3%',
  105. containLabel: true,
  106. },
  107. toolbox: {
  108. feature: null,
  109. },
  110. };
  111. const weatherObj = ref({
  112. cloud: '',
  113. dew: '',
  114. fxTime: '',
  115. humidity: '',
  116. icon: '',
  117. pop: '',
  118. precip: '',
  119. pressure: '',
  120. temp: '',
  121. text: '',
  122. wind360: '',
  123. windDir: '',
  124. windScale: '',
  125. windSpeed: '',
  126. });
  127. const iconMap = {
  128. 晴: new URL('/src/assets/icons/sun.svg', import.meta.url).href,
  129. 雨: new URL('/src/assets/icons/rain.svg', import.meta.url).href,
  130. 雪: new URL('/src/assets/icons/snow.svg', import.meta.url).href,
  131. 多云: new URL('/src/assets/icons/clound.svg', import.meta.url).href,
  132. 风: new URL('/src/assets/icons/wind.svg', import.meta.url).href,
  133. };
  134. function parseWeatherData(res) {
  135. return iconMap[res] || new URL('/src/assets/icons/sun.svg', import.meta.url).href;
  136. }
  137. function showWarningBroad() {
  138. isShowWeatherBroad.value = !isShowWeatherBroad.value;
  139. if (isShowWeatherBroad.value) {
  140. toSelectList(0);
  141. nextTick(() => {
  142. const dom = document.getElementById('VoiceBroadcast');
  143. if (dom) useDrag(dom);
  144. });
  145. }
  146. }
  147. async function toSelectList(key) {
  148. activeKey.value = key;
  149. }
  150. async function getWeatherInfo() {
  151. const res = await getWeather();
  152. weatherObj.value = JSON.parse(res.weatherDataNow);
  153. monitorData.value = JSON.parse(res.weatherData);
  154. }
  155. onMounted(() => {
  156. nextTick(async () => {
  157. await getWeatherInfo();
  158. });
  159. });
  160. return {
  161. showWarningBroad,
  162. isShowWeatherBroad,
  163. activeKey,
  164. weatherObj,
  165. parseWeatherData,
  166. toSelectList,
  167. monitorData,
  168. ChartsColumnsWD,
  169. ChartsColumnsQY,
  170. ChartsColumnsFL,
  171. Option,
  172. };
  173. },
  174. });
  175. </script>
  176. <style lang="less" scoped>
  177. .unit {
  178. font-size: 14px;
  179. // line-height: 47px;
  180. color: #fff;
  181. padding-right: 10px;
  182. }
  183. .btn {
  184. // line-height: 30px;
  185. cursor: pointer;
  186. display: flex;
  187. align-items: center;
  188. }
  189. .btn-header {
  190. height: 48px;
  191. margin-right: 20px;
  192. }
  193. .weather-icon {
  194. width: 20px;
  195. height: 20px;
  196. // margin-top: 14px;
  197. margin-right: 10px;
  198. }
  199. .broadcast {
  200. width: 500px;
  201. height: 350px;
  202. border-radius: 4px;
  203. position: fixed;
  204. top: 50px;
  205. right: 20px;
  206. background-color: rgb(255, 255, 255);
  207. background: url('../../../../assets/images/warn-dialog-bg.png') no-repeat center;
  208. background-size: 100% 100%;
  209. z-index: 9999999;
  210. color: #fff;
  211. .title {
  212. text-align: center;
  213. padding: 0 20px;
  214. :deep(.ant-badge:not(.ant-badge-status)) {
  215. margin-right: 40px !important;
  216. }
  217. display: flex;
  218. align-items: center;
  219. padding-top: 10px;
  220. .badge-title {
  221. display: inline-block;
  222. width: 62px;
  223. line-height: 32px;
  224. background-color: #2174f0;
  225. border-radius: 26px;
  226. text-align: center;
  227. color: #fff;
  228. padding-bottom: 2px;
  229. }
  230. }
  231. }
  232. .broadcast-context {
  233. .context-tab {
  234. display: flex;
  235. .context-tab-item {
  236. line-height: 24px;
  237. background: url('../../../../assets/images/tab-1.png') no-repeat center;
  238. border-radius: 24px;
  239. text-align: center;
  240. color: #fff;
  241. cursor: pointer;
  242. font-size: 14px;
  243. width: 80px;
  244. }
  245. .context-tab-item-active {
  246. background: url('../../../../assets/images/tab-2.png') no-repeat center;
  247. }
  248. }
  249. .context-box {
  250. width: 100%;
  251. height: calc(100% - 32px);
  252. .echarts-box {
  253. width: 100%;
  254. height: 500px;
  255. }
  256. }
  257. }
  258. :deep(.zxm-badge-count) {
  259. width: 0px;
  260. height: 0px;
  261. }
  262. </style>