Commit 7004bf55fa568ce651a18ace8d42166fb241e6dd

Authored by sqy
1 parent edb22231

feat地理位置---:历史记录

@@ -11,7 +11,19 @@ export const getDeviceHistoryInfo = (params) => { @@ -11,7 +11,19 @@ export const getDeviceHistoryInfo = (params) => {
11 return defHttp.get( 11 return defHttp.get(
12 { 12 {
13 url: `/plugins/telemetry/DEVICE/${params.entityId}/values/timeseries`, 13 url: `/plugins/telemetry/DEVICE/${params.entityId}/values/timeseries`,
14 - params: { ...params, entityId: null }, 14 + params: { ...params, entityId: null, orderBy: 'ASC' },
  15 + },
  16 + {
  17 + joinPrefix: false,
  18 + }
  19 + );
  20 +};
  21 +
  22 +// 获取设备数据的keys
  23 +export const getDeviceDataKeys = (id: string) => {
  24 + return defHttp.get(
  25 + {
  26 + url: `/plugins/telemetry/DEVICE/${id}/keys/timeseries`,
15 }, 27 },
16 { 28 {
17 joinPrefix: false, 29 joinPrefix: false,
@@ -106,19 +106,19 @@ function generateOptions(value: number) { @@ -106,19 +106,19 @@ function generateOptions(value: number) {
106 }, 106 },
107 { 107 {
108 label: '30秒', 108 label: '30秒',
109 - value: 300000, 109 + value: 30000,
110 }, 110 },
111 { 111 {
112 label: '1分钟', 112 label: '1分钟',
113 - value: 600000, 113 + value: 60000,
114 }, 114 },
115 { 115 {
116 label: '2分钟', 116 label: '2分钟',
117 - value: 1200000, 117 + value: 120000,
118 }, 118 },
119 { 119 {
120 label: '5分钟', 120 label: '5分钟',
121 - value: 3600000, 121 + value: 300000,
122 }, 122 },
123 ]; 123 ];
124 } else if (value === 7200000) { 124 } else if (value === 7200000) {
@@ -129,27 +129,27 @@ function generateOptions(value: number) { @@ -129,27 +129,27 @@ function generateOptions(value: number) {
129 }, 129 },
130 { 130 {
131 label: '30秒', 131 label: '30秒',
132 - value: 300000, 132 + value: 30000,
133 }, 133 },
134 { 134 {
135 label: '1分钟', 135 label: '1分钟',
136 - value: 600000, 136 + value: 60000,
137 }, 137 },
138 { 138 {
139 label: '2分钟', 139 label: '2分钟',
140 - value: 1200000, 140 + value: 120000,
141 }, 141 },
142 { 142 {
143 label: '5分钟', 143 label: '5分钟',
144 - value: 3600000, 144 + value: 300000,
145 }, 145 },
146 { 146 {
147 label: '10分钟', 147 label: '10分钟',
148 - value: 6000000, 148 + value: 600000,
149 }, 149 },
150 { 150 {
151 label: '15分钟', 151 label: '15分钟',
152 - value: 9000000, 152 + value: 900000,
153 }, 153 },
154 ]; 154 ];
155 } else if (value === 18000000) { 155 } else if (value === 18000000) {
@@ -164,7 +164,7 @@ function generateOptions(value: number) { @@ -164,7 +164,7 @@ function generateOptions(value: number) {
164 }, 164 },
165 { 165 {
166 label: '5分钟', 166 label: '5分钟',
167 - value: 360000, 167 + value: 300000,
168 }, 168 },
169 { 169 {
170 label: '10分钟', 170 label: '10分钟',
@@ -187,7 +187,7 @@ function generateOptions(value: number) { @@ -187,7 +187,7 @@ function generateOptions(value: number) {
187 }, 187 },
188 { 188 {
189 label: '5分钟', 189 label: '5分钟',
190 - value: 360000, 190 + value: 300000,
191 }, 191 },
192 { 192 {
193 label: '10分钟', 193 label: '10分钟',
@@ -214,7 +214,7 @@ function generateOptions(value: number) { @@ -214,7 +214,7 @@ function generateOptions(value: number) {
214 }, 214 },
215 { 215 {
216 label: '5分钟', 216 label: '5分钟',
217 - value: 360000, 217 + value: 300000,
218 }, 218 },
219 { 219 {
220 label: '10分钟', 220 label: '10分钟',
@@ -237,7 +237,7 @@ function generateOptions(value: number) { @@ -237,7 +237,7 @@ function generateOptions(value: number) {
237 return [ 237 return [
238 { 238 {
239 label: '5分钟', 239 label: '5分钟',
240 - value: 360000, 240 + value: 300000,
241 }, 241 },
242 { 242 {
243 label: '10分钟', 243 label: '10分钟',
@@ -384,6 +384,32 @@ export const schemas: FormSchema[] = [ @@ -384,6 +384,32 @@ export const schemas: FormSchema[] = [
384 }, 384 },
385 componentProps: { 385 componentProps: {
386 placeholder: '请选择分组间隔', 386 placeholder: '请选择分组间隔',
  387 + options: [
  388 + {
  389 + label: '5分钟',
  390 + value: 300000,
  391 + },
  392 + {
  393 + label: '10分钟',
  394 + value: 600000,
  395 + },
  396 + {
  397 + label: '15分钟',
  398 + value: 900000,
  399 + },
  400 + {
  401 + label: '30分钟',
  402 + value: 1800000,
  403 + },
  404 + {
  405 + label: '1小时',
  406 + value: 3600000,
  407 + },
  408 + {
  409 + label: '2小时',
  410 + value: 7200000,
  411 + },
  412 + ],
387 }, 413 },
388 }, 414 },
389 { 415 {
@@ -34,7 +34,7 @@ @@ -34,7 +34,7 @@
34 :canFullscreen="false" 34 :canFullscreen="false"
35 > 35 >
36 <BasicForm @register="registerForm" /> 36 <BasicForm @register="registerForm" />
37 - <div ref="chartRef" :style="{ height: '400px', width }"></div> 37 + <div ref="chartRef" :style="{ height: '600px', width }"></div>
38 </BasicModal> 38 </BasicModal>
39 </div> 39 </div>
40 </template> 40 </template>
@@ -51,7 +51,7 @@ @@ -51,7 +51,7 @@
51 import { BasicForm, useForm } from '/@/components/Form'; 51 import { BasicForm, useForm } from '/@/components/Form';
52 import { schemas } from './config.data'; 52 import { schemas } from './config.data';
53 import { useECharts } from '/@/hooks/web/useECharts'; 53 import { useECharts } from '/@/hooks/web/useECharts';
54 - import { getDeviceHistoryInfo } from '/@/api/alarm/position'; 54 + import { getDeviceHistoryInfo, getDeviceDataKeys } from '/@/api/alarm/position';
55 import moment from 'moment'; 55 import moment from 'moment';
56 export default defineComponent({ 56 export default defineComponent({
57 name: 'BaiduMap', 57 name: 'BaiduMap',
@@ -83,7 +83,6 @@ @@ -83,7 +83,6 @@
83 if (!wrapEl) return; 83 if (!wrapEl) return;
84 const map = new BMap.Map(wrapEl); 84 const map = new BMap.Map(wrapEl);
85 const point = new BMap.Point(104.04666605565338, 30.543516387560476); 85 const point = new BMap.Point(104.04666605565338, 30.543516387560476);
86 -  
87 map.centerAndZoom(point, 15); 86 map.centerAndZoom(point, 15);
88 map.enableScrollWheelZoom(true); 87 map.enableScrollWheelZoom(true);
89 } 88 }
@@ -97,6 +96,9 @@ @@ -97,6 +96,9 @@
97 }, 96 },
98 showIndexColumn: false, 97 showIndexColumn: false,
99 useSearchForm: true, 98 useSearchForm: true,
  99 + pagination: {
  100 + showSizeChanger: false,
  101 + },
100 }); 102 });
101 // 点击表格某一行触发 103 // 点击表格某一行触发
102 const deviceRowClick = (record) => { 104 const deviceRowClick = (record) => {
@@ -166,101 +168,81 @@ @@ -166,101 +168,81 @@
166 let infoWindow = new BMap.InfoWindow('该设备暂无地理位置', options); // 创建信息窗口对象 168 let infoWindow = new BMap.InfoWindow('该设备暂无地理位置', options); // 创建信息窗口对象
167 map.openInfoWindow(infoWindow, map.getCenter()); 169 map.openInfoWindow(infoWindow, map.getCenter());
168 } 170 }
169 -  
170 - console.log(record);  
171 }; 171 };
172 - 172 + let keys = [];
173 const [registerModal, { openModal }] = useModal(); 173 const [registerModal, { openModal }] = useModal();
174 - const [registerForm, { resetFields, getFieldsValue, validate }] = useForm({ 174 + const [registerForm, { resetFields, getFieldsValue, setFieldsValue, validate }] = useForm({
175 labelWidth: 120, 175 labelWidth: 120,
176 schemas, 176 schemas,
177 async submitFunc() { 177 async submitFunc() {
  178 + // 表单验证
178 await validate(); 179 await validate();
179 let { endTs, interval, agg } = getFieldsValue(); 180 let { endTs, interval, agg } = getFieldsValue();
180 if (!endTs) return; 181 if (!endTs) return;
  182 + // 数据收集
  183 + const dataArray: any[] = [];
181 const startTs = Date.now() - endTs; 184 const startTs = Date.now() - endTs;
182 endTs = Date.now(); 185 endTs = Date.now();
183 - console.log(startTs, endTs); 186 + // 发送请求
184 const res = await getDeviceHistoryInfo({ 187 const res = await getDeviceHistoryInfo({
185 entityId: entityId.value, 188 entityId: entityId.value,
186 - keys: 'co,co2',  
187 - interval, 189 + keys: keys.join(),
188 startTs, 190 startTs,
189 endTs, 191 endTs,
  192 + interval,
190 agg, 193 agg,
191 }); 194 });
192 - const dateArray: { key: string; time: string }[] = [];  
193 - const valueArray: { key: string; value: string }[] = []; 195 + // 处理数据
194 for (const key in res) { 196 for (const key in res) {
195 for (const item1 of res[key]) { 197 for (const item1 of res[key]) {
196 let { ts, value } = item1; 198 let { ts, value } = item1;
197 - const time = moment(ts).format('YYYY-MM-DD');  
198 - dateArray.push({  
199 - key,  
200 - time,  
201 - });  
202 - valueArray.push({  
203 - key,  
204 - value,  
205 - }); 199 + const time = moment(ts).format('YYYY-MM-DD HH:mm:ss');
  200 + value = Number(value).toFixed(2);
  201 + dataArray.push([time, value, key]);
206 } 202 }
207 } 203 }
208 - console.log(dateArray, valueArray);  
209 - const keys = ['co', 'co2']; 204 +
210 const series: any = keys.map((item) => { 205 const series: any = keys.map((item) => {
211 return { 206 return {
212 name: item, 207 name: item,
213 type: 'line', 208 type: 'line',
214 - smooth: true,  
215 - showAllSymbol: 'auto',  
216 - symbol: 'emptyCircle',  
217 - symbolSize: 15,  
218 - data: valueArray.filter((item1) => item1.key === item).map((item1) => item1.value), 209 + stack: 'Total',
  210 + data: dataArray.filter((item1) => item1[2] === item),
219 }; 211 };
220 }); 212 });
  213 + // 设置数据
221 setOptions({ 214 setOptions({
222 tooltip: { 215 tooltip: {
223 trigger: 'axis', 216 trigger: 'axis',
224 - axisPointer: {  
225 - lineStyle: {  
226 - width: 1,  
227 - color: '#019680',  
228 - },  
229 - },  
230 }, 217 },
231 - xAxis: {  
232 - type: 'category',  
233 - boundaryGap: false,  
234 - data: dateArray.map((item) => item.time),  
235 - splitLine: {  
236 - show: true,  
237 - lineStyle: {  
238 - width: 1,  
239 - type: 'solid',  
240 - color: 'rgba(226,226,226,0.5)',  
241 - },  
242 - },  
243 - axisTick: {  
244 - show: false,  
245 - }, 218 + legend: {
  219 + data: keys,
  220 + },
  221 + grid: {
  222 + left: '3%',
  223 + right: '4%',
  224 + bottom: '3%',
  225 + containLabel: true,
246 }, 226 },
247 - yAxis: [ 227 + dataZoom: [
248 { 228 {
249 - type: 'value',  
250 - max: 1000,  
251 - splitNumber: 4,  
252 - axisTick: {  
253 - show: false,  
254 - },  
255 - splitArea: {  
256 - show: true,  
257 - areaStyle: {  
258 - color: ['rgba(255,255,255,0.2)', 'rgba(226,226,226,0.2)'],  
259 - },  
260 - }, 229 + type: 'inside',
  230 + start: 0,
  231 + end: 50,
  232 + },
  233 + {
  234 + start: 20,
  235 + end: 40,
261 }, 236 },
262 ], 237 ],
263 - grid: { left: '1%', right: '1%', top: '2 %', bottom: 0, containLabel: true }, 238 + xAxis: {
  239 + type: 'time',
  240 + boundaryGap: false,
  241 + },
  242 + yAxis: {
  243 + type: 'value',
  244 + boundaryGap: [0, '100%'],
  245 + },
264 series, 246 series,
265 }); 247 });
266 }, 248 },
@@ -270,85 +252,84 @@ @@ -270,85 +252,84 @@
270 const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); 252 const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
271 253
272 const openHistoryModal = async () => { 254 const openHistoryModal = async () => {
273 - const startTs = Date.now() - 86400000; 255 + openModal(true);
  256 +
  257 + // 收集参数
  258 + const dataArray: any[] = [];
  259 + const startTs = Date.now() - 86400000; //最近一天
274 const endTs = Date.now(); 260 const endTs = Date.now();
275 - console.log(startTs, endTs); 261 + // 发送请求
  262 + keys = await getDeviceDataKeys(entityId.value);
276 const res = await getDeviceHistoryInfo({ 263 const res = await getDeviceHistoryInfo({
277 entityId: entityId.value, 264 entityId: entityId.value,
278 - keys: 'co,co2', 265 + keys: keys.join(),
279 startTs, 266 startTs,
280 endTs, 267 endTs,
  268 + interval: 7200000, //间隔两小时
  269 + agg: 'AVG',
281 }); 270 });
282 - const dateArray: { key: string; time: string }[] = [];  
283 - const valueArray: { key: string; value: string }[] = []; 271 + // 处理数据
284 for (const key in res) { 272 for (const key in res) {
285 for (const item1 of res[key]) { 273 for (const item1 of res[key]) {
286 let { ts, value } = item1; 274 let { ts, value } = item1;
287 const time = moment(ts).format('YYYY-MM-DD HH:mm:ss'); 275 const time = moment(ts).format('YYYY-MM-DD HH:mm:ss');
288 - dateArray.push({  
289 - key,  
290 - time,  
291 - });  
292 - valueArray.push({  
293 - key,  
294 - value,  
295 - }); 276 + value = Number(value).toFixed(2);
  277 + dataArray.push([time, value, key]);
296 } 278 }
297 } 279 }
298 -  
299 - const keys = ['co', 'co2'];  
300 const series: any = keys.map((item) => { 280 const series: any = keys.map((item) => {
301 return { 281 return {
302 - smooth: true,  
303 - data: valueArray.filter((item1) => item1.key === item).map((item1) => item1.value),  
304 - type: 'line',  
305 name: item, 282 name: item,
306 - itemStyle: {  
307 - color: '#5ab1ef',  
308 - }, 283 + type: 'line',
  284 + stack: 'Total',
  285 + data: dataArray.filter((item1) => item1[2] === item),
309 }; 286 };
310 }); 287 });
  288 + // 设置数据;
311 setOptions({ 289 setOptions({
312 tooltip: { 290 tooltip: {
313 trigger: 'axis', 291 trigger: 'axis',
314 - axisPointer: {  
315 - lineStyle: {  
316 - width: 1,  
317 - color: '#019680',  
318 - },  
319 - },  
320 }, 292 },
321 - xAxis: {  
322 - type: 'category',  
323 - boundaryGap: false,  
324 - data: dateArray.map((item) => item.time),  
325 - splitLine: {  
326 - show: true,  
327 - lineStyle: {  
328 - width: 1,  
329 - type: 'solid',  
330 - color: 'rgba(226,226,226,0.5)',  
331 - }, 293 + legend: {
  294 + data: keys,
  295 + },
  296 + grid: {
  297 + left: '3%',
  298 + right: '4%',
  299 + bottom: '3%',
  300 + containLabel: true,
  301 + },
  302 + dataZoom: [
  303 + {
  304 + type: 'inside',
  305 + start: 0,
  306 + end: 50,
332 }, 307 },
333 - axisTick: {  
334 - show: false, 308 + {
  309 + start: 0,
  310 + end: 20,
335 }, 311 },
  312 + ],
  313 + xAxis: {
  314 + type: 'time',
  315 + boundaryGap: false,
336 }, 316 },
337 yAxis: { 317 yAxis: {
338 - splitLine: { show: false },  
339 - axisLine: {  
340 - lineStyle: {  
341 - color: '#ccc',  
342 - },  
343 - }, 318 + type: 'value',
  319 + boundaryGap: [0, '100%'],
344 }, 320 },
345 - grid: { left: '1%', right: '1%', top: '2 %', bottom: 0, containLabel: true },  
346 series, 321 series,
347 }); 322 });
348 - openModal(true); 323 +
  324 + setFieldsValue({
  325 + endTs: 86400000,
  326 + interval: 7200000,
  327 + agg: 'AVG',
  328 + });
349 }; 329 };
350 const cancelHistoryModal = () => { 330 const cancelHistoryModal = () => {
351 resetFields(); 331 resetFields();
  332 + setOptions({});
352 }; 333 };
353 onMounted(() => { 334 onMounted(() => {
354 initMap(); 335 initMap();
@@ -367,14 +348,10 @@ @@ -367,14 +348,10 @@
367 }, 348 },
368 }); 349 });
369 </script> 350 </script>
370 -  
371 <style scoped> 351 <style scoped>
372 .wrapper { 352 .wrapper {
373 position: relative; 353 position: relative;
374 } 354 }
375 - .active {  
376 - background-color: #fff;  
377 - }  
378 .right-wrap { 355 .right-wrap {
379 padding-top: 10px; 356 padding-top: 10px;
380 width: 22%; 357 width: 22%;
@@ -13,32 +13,35 @@ @@ -13,32 +13,35 @@
13 light:border-#F2F2F5 13 light:border-#F2F2F5
14 " 14 "
15 > 15 >
16 - <img :src="item.imgUrl" style="width: 90px; height: 90px" /> 16 + <img :src="item.imgUrl" style="width: 5rem; height: 5rem" />
17 <div class="growCardItem-right"> 17 <div class="growCardItem-right">
18 <div class="flex justify-between ml-3"> 18 <div class="flex justify-between ml-3">
19 - <div style="font-size: 26px; color: #333">{{ item.value }}</div>  
20 - <img src="../../../../assets/images/tip.png" style="width: 20px; height: 20px" /> 19 + <div style="font-size: 1.625rem; color: #333">{{ item.value }}</div>
  20 + <img src="../../../../assets/images/tip.png" style="width: 1.4rem; height: 1.4rem" />
21 </div> 21 </div>
22 <div class="ml-3">{{ item.title }}</div> 22 <div class="ml-3">{{ item.title }}</div>
23 - <div class="ml-1.5 mt-3 flex flex-nowrap" style="width: 240px" v-if="item.offLine"> 23 + <div class="ml-1.5 mt-3 flex flex-nowrap" style="width: 15rem" v-if="item.offLine">
24 <div class="count"> 24 <div class="count">
25 <img 25 <img
26 src="../../../../assets/images/online.png" 26 src="../../../../assets/images/online.png"
27 - style="width: 10px; height: 10px; margin-right: 4px" 27 + style="width: 0.6rem; height: 0.6rem"
  28 + class="mr-1"
28 /> 29 />
29 在线 {{ item.onLine }} 30 在线 {{ item.onLine }}
30 </div> 31 </div>
31 <div class="count"> 32 <div class="count">
32 <img 33 <img
33 src="../../../../assets/images/offline.png" 34 src="../../../../assets/images/offline.png"
34 - style="width: 10px; height: 10px; margin-right: 4px" 35 + style="width: 0.6rem; height: 0.6rem"
  36 + class="mr-1"
35 /> 37 />
36 离线 {{ item.offLine }} 38 离线 {{ item.offLine }}
37 </div> 39 </div>
38 <div class="count"> 40 <div class="count">
39 <img 41 <img
40 src="../../../../assets/images/inactive.png" 42 src="../../../../assets/images/inactive.png"
41 - style="width: 10px; height: 10px; margin-right: 4px" 43 + style="width: 0.6rem; height: 0.6rem"
  44 + class="mr-1"
42 /> 45 />
43 未激活 {{ item.inactive }} 46 未激活 {{ item.inactive }}
44 </div> 47 </div>
@@ -56,24 +59,24 @@ @@ -56,24 +59,24 @@
56 59
57 <style scoped lang="less"> 60 <style scoped lang="less">
58 .growCardItem { 61 .growCardItem {
59 - height: 179px; 62 + height: 11.187rem;
60 color: #666; 63 color: #666;
61 .growCardItem-top { 64 .growCardItem-top {
62 display: flex; 65 display: flex;
63 - margin: 20px;  
64 - padding-bottom: 10px; 66 + margin: 1.25rem;
  67 + padding-bottom: 0.625rem;
65 .growCardItem-right { 68 .growCardItem-right {
66 - width: 300px; 69 + width: 18.75rem;
67 .count { 70 .count {
68 display: flex; 71 display: flex;
69 - font-size: 12px; 72 + font-size: 0.75rem;
70 align-items: center; 73 align-items: center;
71 - margin-left: 8px; 74 + margin-left: 0.5rem;
72 } 75 }
73 } 76 }
74 } 77 }
75 .growCardItem-bottom { 78 .growCardItem-bottom {
76 - margin-left: 20px; 79 + margin-left: 1.25rem;
77 } 80 }
78 } 81 }
79 </style> 82 </style>