weatherBroadcast.vue 8.2 KB

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