index.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. <template>
  2. <div class="page">
  3. <el-card shadow="never">
  4. <el-form inline>
  5. <el-form-item label="选择产品:" prop="productKey">
  6. <el-select v-model="params.productKey" filterable placeholder="请选择产品" @change="productChange">
  7. <el-option v-for="item in productList" :key="item.key" :label="item.name" :value="item.key">
  8. <span style="float: left">{{ item.name }}</span>
  9. <span style="float: right; font-size: 13px">{{ item.key }}</span>
  10. </el-option>
  11. </el-select>
  12. </el-form-item>
  13. <el-form-item label="选择设备:" prop="deviceKey">
  14. <el-select v-model="params.deviceKey" filterable placeholder="请选择设备">
  15. <el-option v-for="item in deviceList" :key="item.key" :label="item.name" :value="item.key">
  16. <span style="float: left">{{ item.name }}</span>
  17. <span style="float: right; font-size: 13px;margin-left: 12px;">{{ item.key }}</span>
  18. </el-option>
  19. </el-select>
  20. </el-form-item>
  21. <el-form-item label="选择属性:" prop="properties">
  22. <el-select v-model="params.properties" filterable placeholder="请选择属性" @change="propertyChange">
  23. <el-option v-for="item in propertyList" :key="item.key" :label="item.name" :value="item.key">
  24. <span style="float: left">{{ item.name }}</span>
  25. <span style="float: right; font-size: 13px">{{ item.key }}</span>
  26. </el-option>
  27. </el-select>
  28. </el-form-item>
  29. <el-form-item label="选择时间:" prop="dateRange">
  30. <el-date-picker v-model="params.dateRange" style="width: 360px" value-format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss" type="datetimerange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :clearable="false">
  31. </el-date-picker>
  32. <el-button-group class="ml10">
  33. <el-button @click="changeDate(1)" :type="activeIndex == 1 ? 'primary' : ''">最近一小时</el-button>
  34. <el-button @click="changeDate(2)" :type="activeIndex == 2 ? 'primary' : ''">最近24小时</el-button>
  35. <el-button @click="changeDate(3)" :type="activeIndex == 3 ? 'primary' : ''">最近一周</el-button>
  36. </el-button-group>
  37. </el-form-item>
  38. <el-form-item>
  39. <el-button type="primary" @click="getData">
  40. <el-icon>
  41. <ele-Search />
  42. </el-icon>
  43. 查询
  44. </el-button>
  45. <el-button type="primary" @click="handlePrintChart">
  46. <el-icon>
  47. <ele-Printer />
  48. </el-icon>
  49. 打印图表
  50. </el-button>
  51. </el-form-item>
  52. </el-form>
  53. <div class="title">
  54. <el-icon style="margin-right: 5px;">
  55. <ele-Histogram />
  56. </el-icon>
  57. 指标趋势统计图
  58. </div>
  59. <Chart class="flex1" height="12vw" ref="chart" :autoLoading="false" style="margin-top: 20px;" v-loading="loading"></Chart>
  60. </el-card>
  61. </div>
  62. </template>
  63. <script lang="ts" setup>
  64. import { ref, reactive } from 'vue';
  65. import { ElMessage } from 'element-plus';
  66. import api from '/@/api/device';
  67. import dayjs from 'dayjs';
  68. import Chart from '/@/components/chart/index.vue'
  69. import { getLineOption } from '/@/components/chart/options'
  70. import { printChart } from '/@/utils/print';
  71. const productList = ref<any[]>([])
  72. const deviceList = ref<any[]>([])
  73. const propertyList = ref<any[]>([])
  74. const chart = ref()
  75. const loading = ref(false)
  76. const propertyName = ref('')
  77. const activeIndex = ref(1);
  78. const params = reactive({
  79. productKey: '',
  80. deviceKey: '',
  81. properties: '',
  82. dateRange: [dayjs().subtract(1, 'hour').format('YYYY-MM-DD HH:mm:ss'), dayjs().format('YYYY-MM-DD HH:mm:ss')],
  83. })
  84. api.product.getLists({ status: 1 }).then((res: any) => {
  85. productList.value = res.product || [];
  86. });
  87. // 仪表盘折线按钮
  88. const changeDate = (key: number) => {
  89. if (!params.productKey) return ElMessage('请选选择产品')
  90. if (!params.deviceKey) return ElMessage('请选选择设备')
  91. if (!params.properties) return ElMessage('请选选择属性')
  92. // 1 近1小时 2近24小时 3近一周
  93. activeIndex.value = key;
  94. if (key === 1) {
  95. // 近1小时
  96. params.dateRange = [dayjs().subtract(1, 'hour').format('YYYY-MM-DD HH:mm:ss'), dayjs().format('YYYY-MM-DD HH:mm:ss')]
  97. } else if (key === 2) {
  98. // 近24小时
  99. params.dateRange = [
  100. dayjs().subtract(24, 'hour').format('YYYY-MM-DD HH:mm:ss'),
  101. dayjs().format('YYYY-MM-DD HH:mm:ss'),
  102. ]
  103. } else if (key === 3) {
  104. // 近一周
  105. params.dateRange = [
  106. dayjs().subtract(7, 'day').format('YYYY-MM-DD HH:mm:ss'),
  107. dayjs().format('YYYY-MM-DD HH:mm:ss'),
  108. ]
  109. }
  110. getData();
  111. }
  112. function getData() {
  113. if (!params.productKey) return ElMessage('请选选择产品')
  114. if (!params.deviceKey) return ElMessage('请选选择设备')
  115. if (!params.properties) return ElMessage('请选选择属性')
  116. loading.value = true
  117. api.analysis.deviceIndicatorTrend(params).then((data: any[]) => {
  118. const res = data || []
  119. chart.value.draw(
  120. getLineOption({
  121. datas: [res.map(item => item.dataValue)],
  122. xAxis: res.map(item => item.dataTime),
  123. legend: [propertyName.value],
  124. dataZoom: [{ // 这部分是dataZoom的配置
  125. type: 'slider', // 这里可以选择你需要的dataZoom类型
  126. start: 0, // 数据窗口范围的起始百分比
  127. end: 100,// 数据窗口范围的结束百分比
  128. xAxisIndex: [0, 2],
  129. }]
  130. })
  131. )
  132. }).finally(() => loading.value = false)
  133. }
  134. function productChange(productKey: string) {
  135. params.deviceKey = ''
  136. params.properties = ''
  137. deviceList.value = []
  138. propertyList.value = []
  139. api.device.allList({ productKey }).then((res: any) => {
  140. deviceList.value = res.device;
  141. });
  142. api.product.getpropertyList({ productKey }).then((res: any) => {
  143. propertyList.value = res;
  144. });
  145. }
  146. function propertyChange(property: string) {
  147. propertyName.value = propertyList.value.find(item => item.key === property)?.name
  148. }
  149. // 打印图表
  150. const handlePrintChart = async () => {
  151. if (!chart.value) {
  152. ElMessage.warning('图表未加载');
  153. return;
  154. }
  155. await printChart(chart.value.$el);
  156. };
  157. </script>
  158. <style scoped>
  159. .title {
  160. font-size: 14px;
  161. font-weight: bold;
  162. border-bottom: 1px solid #eee;
  163. display: flex;
  164. align-items: center;
  165. padding-bottom: 6px;
  166. }
  167. </style>