天波h5前端应用
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

341 行
13KB

  1. <!--
  2. * @Date: 2023-10-10 15:29:50
  3. * @LastEditors: JinxChen
  4. * @LastEditTime: 2023-10-19 14:21:55
  5. * @FilePath: \TelpoH5FrontendWeb\src\views\gps-card-frontend\device-power\index.vue
  6. * @description:
  7. -->
  8. <template>
  9. <div class="device-power">
  10. <van-nav-bar :left-arrow="true" @click-left="onNavBack">
  11. <template #left>
  12. <van-icon name="arrow-left" size="24" style="padding: 0"/>
  13. <span>返回</span>
  14. </template>
  15. </van-nav-bar>
  16. <div class="top">
  17. <p>查看数据</p>
  18. </div>
  19. <div class="action">
  20. <div class="left">
  21. <van-dropdown-menu>
  22. <van-dropdown-item style="min-width: 150px" v-model="dayValue" :options="dayOption" @change="onChange" />
  23. </van-dropdown-menu>
  24. </div>
  25. <div class="right">
  26. <div class="btn-container">
  27. <van-button :class="['btn', {active: btnActive ===item.index }]" @click="onClickBtn(item.index)" v-for="(item, index) in btnList" :key="index">{{ item.text }}</van-button>
  28. </div>
  29. </div>
  30. </div>
  31. <div class="details-container" v-if="btnActive === 0 && data.length > 0 || tableData.length > 0 && btnActive === 1">
  32. <Echart :option="chartOption" v-show="btnActive === 0"/>
  33. <Table :columns="titleList" :data="tableData" v-show="btnActive === 1"/>
  34. </div>
  35. <div class="details-container no-data" v-else>
  36. <van-empty image="error" description="暂无数据" />
  37. </div>
  38. </div>
  39. </template>
  40. <script>
  41. import Echart from '@/components/echarts';
  42. import Table from '@/components/tables';
  43. import APIIot from '@/api/iot';
  44. import { DEVICE_POWER } from "@/config/models";
  45. import axios from 'axios';
  46. export default {
  47. name:'',
  48. components: { Echart,Table },
  49. data(){
  50. return {
  51. dayValue: 7,
  52. dayOption: [
  53. { text: '7天', value: 7 },
  54. { text: '30天', value: 30 },
  55. ],
  56. btnList: [
  57. { text: '图表', index: 0 },
  58. { text: '表格', index: 1 },
  59. ],
  60. btnActive: 0,
  61. chartOption: {},
  62. titleList: [
  63. { title: '时间', width: '40%', key: 'time'},
  64. { title: '原始值', width: '60%', key: 'value' },
  65. ],
  66. tableData: [],
  67. echarts: {
  68. title: '',
  69. type: '',
  70. },
  71. data: [],
  72. xAxisData: [],
  73. filterData: [],
  74. yAxisObject: {}
  75. }
  76. },
  77. created() {
  78. },
  79. mounted() {
  80. this.loadParams();
  81. },
  82. methods: {
  83. loadParams() {
  84. let params = this.$route.query;
  85. if(params) {
  86. this.echarts.title = DEVICE_POWER[params.title].title;
  87. this.echarts.type = DEVICE_POWER[params.title].value;
  88. // 获取接口数据
  89. this.getData();
  90. } else {
  91. // todo跳转404页面
  92. }
  93. },
  94. getData() {
  95. this.$toast.loading();
  96. let reqBody = {
  97. days: String(this.dayValue),
  98. identifier: this.echarts.type,
  99. imei: /* '861281060086216' *//* '862838050029479' */this.$store.getters.imei
  100. };
  101. // 线上地址
  102. let baseUrl = process.env.VUE_APP_BASE_API;
  103. let reqUrl = `${baseUrl}iotservice/getdeviceinfo`;
  104. // 开启代理如下
  105. /* let reqUrl = `/api/id/getdeviceinfo`; */
  106. axios.post(`${reqUrl}`, reqBody).then(res => {
  107. let data = res.data;
  108. if(data.code === 200) {
  109. if(this.echarts.type === 'BatteryLevel' || this.echarts.type === 'status') {
  110. this.filterData = data[this.echarts.type].data/* .list.propertyInfo */;
  111. } else if(this.echarts.type === 'offline') {
  112. this.filterData = data.Offline.data;
  113. }
  114. if(this.echarts.type === 'status') {
  115. // 信号强度
  116. this.yAxisObject = {
  117. type: "value",
  118. /* max: 4,
  119. min: 0,
  120. interval: 1,
  121. splitNumber : 1,
  122. boundaryGap : [ '5%', '5%' ], */
  123. }
  124. this.titleList = [
  125. { title: '时间', width: '40%', key: 'time'},
  126. { title: '原始值', width: '60%', key: 'value' },
  127. ];
  128. let propertyInfo = this.filterData.map(item => {
  129. return item.list.propertyInfo;
  130. });
  131. let result = [];
  132. for (let i = 0; i < propertyInfo.length; i++) {
  133. // 循环对象中的数组
  134. result = [].concat(...propertyInfo)
  135. }
  136. // 表格则要显示全部数据
  137. this.tableData = result.map(item => {
  138. return {
  139. value: item.value,
  140. time: this.$dayjs(this.$dayjs(Number(item.time))).format("YYYY/MM/DD hh:mm")
  141. }
  142. }).reverse();
  143. // 图表筛选过滤只显示 rssi <= 2的数据
  144. this.data = result.map(item => {
  145. // 序列化json
  146. let json = JSON.parse(item.value);
  147. return {
  148. value: json.rssi,
  149. time: this.$dayjs(this.$dayjs(Number(item.time))).format("YYYY/MM/DD hh:mm"),
  150. type: 'status'
  151. }
  152. }).filter(f => {
  153. return f.value <=2;
  154. })
  155. } else if (this.echarts.type === 'offline') {
  156. // 设备离线次数
  157. this.titleList = [
  158. { title: '时间', width: '60%', key: 'time'},
  159. { title: '离线次数', width: '40%', key: 'value' },
  160. ],
  161. this.yAxisObject = {
  162. type: "value",
  163. /* max: 10,
  164. min: 0,
  165. interval: 1,
  166. splitNumber : 1,
  167. boundaryGap : [ '5%', '5%' ], */
  168. };
  169. this.data = this.filterData.map(item => {
  170. return {
  171. /* value: item.value, */
  172. time: item.createTime.slice(0,10),
  173. day: item.createTime.slice(0,10),
  174. type: 'offline'
  175. }
  176. }).reduce((accumulator, currentValue) => {
  177. if (accumulator.find(obj => obj.day === currentValue.day)) {
  178. accumulator.find(obj => obj.day === currentValue.day).value++;
  179. } else {
  180. accumulator.push({ day: currentValue.day, time: currentValue.time, value: 1, type: 'offline' });
  181. }
  182. return accumulator;
  183. }, []).sort(function(date1, date2) {
  184. // 日期升序排序
  185. return date2.time < date1.time ? 1 : -1
  186. });
  187. this.tableData = this.filterData.map(item => {
  188. return {
  189. /* value: item.value, */
  190. time: item.createTime.slice(0,10),
  191. day: item.createTime.slice(0,10)
  192. }
  193. }).reduce((accumulator, currentValue) => {
  194. // 筛选遍历数据,获取相同日期的数据,计算出现的次数后重新累加组合到一个新的数组里面
  195. if (accumulator.find(obj => obj.day === currentValue.day)) {
  196. accumulator.find(obj => obj.day === currentValue.day).value++;
  197. } else {
  198. accumulator.push({ day: currentValue.day, time: currentValue.time, value: 1 });
  199. }
  200. return accumulator;
  201. }, []).sort(function(date1, date2) {
  202. // 日期升序排序
  203. return date2.time < date1.time ? 1 : -1
  204. }).reverse();
  205. } else {
  206. this.titleList = [
  207. { title: '时间', width: '40%', key: 'time'},
  208. { title: '电量', width: '60%', key: 'value' },
  209. ],
  210. this.yAxisObject = {
  211. type: "value",
  212. max: 100,
  213. min: 0,
  214. interval: 20,
  215. splitNumber : 1,
  216. boundaryGap : [ '5%', '5%' ],
  217. }
  218. let propertyInfo = this.filterData.map(item => {
  219. return item.list.propertyInfo;
  220. });
  221. let result = [];
  222. for (let i = 0; i < propertyInfo.length; i++) {
  223. // 循环对象中的数组
  224. result = [].concat(...propertyInfo)
  225. }
  226. this.data = result.map(item => {
  227. return {
  228. value: item.value,
  229. time: this.$dayjs(this.$dayjs(Number(item.time))).format("YYYY/MM/DD hh:mm"),
  230. }
  231. });
  232. this.tableData = result.map(item => {
  233. return {
  234. value: item.value,
  235. time: this.$dayjs(this.$dayjs(Number(item.time))).format("YYYY/MM/DD hh:mm")
  236. }
  237. }).reverse();
  238. }
  239. this.xAxisData = this.data.map(item => {
  240. return this.$dayjs(item.time).format("MM/DD");
  241. })
  242. this.chartOption = {
  243. title: {
  244. text: this.echarts.title,
  245. },
  246. xAxis: {
  247. type: "category",
  248. axisLine: {
  249. show: false
  250. },
  251. textStyle: {
  252. fontSize: 10
  253. },
  254. axisTick: {
  255. show: false
  256. },
  257. splitLine: {
  258. show: false,
  259. lineStyle: {
  260. color: "#ddd",
  261. width: 2
  262. }
  263. },
  264. nameLocation: 'center',
  265. axisLabel: {
  266. show: true,
  267. fontSize: 12,
  268. showMinLabel: true, //显示最小值
  269. showMaxLabel: true, //显示最大值
  270. },
  271. data: this.xAxisData
  272. },
  273. yAxis: this.yAxisObject,
  274. series: [
  275. {
  276. type: "line",
  277. data: this.data,
  278. /* areaStyle: {}, */
  279. },
  280. ],
  281. dataZoom: [
  282. {
  283. start: 0,
  284. end: 100,
  285. textStyle: {
  286. color: "#FFF",
  287. fontSize: 14
  288. },
  289. show: true,
  290. height: 20,
  291. bottom: 5,
  292. handleStyle: {
  293. borderWidth: 1,
  294. borderCap: "square"
  295. }
  296. }
  297. ],
  298. tooltip: {
  299. trigger: "axis",
  300. textStyle: {
  301. fontSize: 14,
  302. align: "center"
  303. },
  304. formatter: function(params) {
  305. return `${params[0].marker}${params[0].data.time}</br>
  306. ${ params[0].data.type === 'offline' ? '离线次数:' + params[0].data.value + '次' :
  307. params[0].data.type === 'status' ? 'rssi值:' + params[0].data.value :
  308. '电量:' + params[0].data.value}`
  309. }
  310. },
  311. }
  312. }
  313. }).catch(() => {
  314. }).finally(() => {
  315. this.$toast.clear();
  316. })
  317. },
  318. onClickBtn(value) {
  319. this.btnActive = value;
  320. this.getData();
  321. },
  322. onChange(value) {
  323. this.dayValue = value;
  324. this.getData();
  325. },
  326. onNavBack() {
  327. this.$router.push({
  328. name: 'deviceSetting'
  329. })
  330. }
  331. }
  332. }
  333. </script>
  334. <style scoped lang="scss">
  335. @import "./index.scss";
  336. </style>