Commit 179744a60385270a0ab088ad8d1daa6b93f53823
1 parent
5e373602
feat: data component history trend add table mode
Showing
2 changed files
with
137 additions
and
26 deletions
... | ... | @@ -289,7 +289,7 @@ |
289 | 289 | <Alert type="info" show-icon v-if="isMapComponent"> |
290 | 290 | <template #description> |
291 | 291 | <div> |
292 | - 地图组件,需绑定两个数据源,且数据源为同一设备。第一数据源为经度,第二数据源为维度,否则地图组件不能正常显示。 | |
292 | + 地图组件,需绑定两个数据源,且数据源为同一设备。第一数据源为经度,第二数据源为纬度,否则地图组件不能正常显示。 | |
293 | 293 | </div> |
294 | 294 | </template> |
295 | 295 | </Alert> | ... | ... |
1 | 1 | <script lang="ts" setup> |
2 | 2 | import { nextTick, Ref, ref, unref } from 'vue'; |
3 | 3 | import { getDeviceHistoryInfo } from '/@/api/alarm/position'; |
4 | - import { Empty } from 'ant-design-vue'; | |
4 | + import { Empty, Tooltip, Button } from 'ant-design-vue'; | |
5 | 5 | import { useECharts } from '/@/hooks/web/useECharts'; |
6 | 6 | import { AggregateDataEnum } from '/@/views/device/localtion/config.data'; |
7 | 7 | import { useGridLayout } from '/@/hooks/component/useGridLayout'; |
... | ... | @@ -14,17 +14,29 @@ |
14 | 14 | import { useModalInner } from '/@/components/Modal'; |
15 | 15 | import { getAllDeviceByOrg } from '/@/api/dataBoard'; |
16 | 16 | import { useHistoryData } from '/@/views/device/list/hook/useHistoryData'; |
17 | + import { BasicTable, useTable } from '/@/components/Table'; | |
18 | + import { LineChartOutlined, BarsOutlined } from '@ant-design/icons-vue'; | |
19 | + import { formatToDateTime } from '/@/utils/dateUtil'; | |
17 | 20 | |
18 | 21 | type DeviceOption = Record<'label' | 'value' | 'organizationId', string>; |
19 | 22 | |
20 | 23 | defineEmits(['register']); |
21 | 24 | |
25 | + enum Mode { | |
26 | + TABLE = 'table', | |
27 | + CHART = 'chart', | |
28 | + } | |
29 | + | |
30 | + const mode = ref<Mode>(Mode.CHART); | |
31 | + | |
22 | 32 | const chartRef = ref(); |
23 | 33 | |
24 | 34 | const loading = ref(false); |
25 | 35 | |
26 | 36 | const isNull = ref(false); |
27 | 37 | |
38 | + const historyData = ref<{ ts: number; value: string; name: string }[]>([]); | |
39 | + | |
28 | 40 | const { deviceAttrs, getDeviceKeys, getSearchParams, setChartOptions, getDeviceAttribute } = |
29 | 41 | useHistoryData(); |
30 | 42 | |
... | ... | @@ -52,30 +64,74 @@ |
52 | 64 | loading: loading as unknown as boolean, |
53 | 65 | }, |
54 | 66 | async submitFunc() { |
55 | - // 表单验证 | |
56 | - await method.validate(); | |
57 | - const value = method.getFieldsValue(); | |
58 | - const searchParams = getSearchParams(value); | |
59 | - if (!hasDeviceAttr()) return; | |
60 | - // 发送请求 | |
61 | - loading.value = true; | |
62 | - const res = await getDeviceHistoryInfo(searchParams); | |
63 | - loading.value = false; | |
64 | - // 判断数据对象是否为空 | |
65 | - if (!Object.keys(res).length) { | |
66 | - isNull.value = false; | |
67 | - return; | |
68 | - } else { | |
69 | - isNull.value = true; | |
70 | - } | |
71 | - | |
72 | - const selectedKeys = unref(deviceAttrs).find( | |
73 | - (item) => item.identifier === value[SchemaFiled.KEYS] | |
74 | - ); | |
75 | - setOptions(setChartOptions(res, selectedKeys)); | |
67 | + search(); | |
76 | 68 | }, |
77 | 69 | }); |
78 | 70 | |
71 | + const search = async () => { | |
72 | + // 表单验证 | |
73 | + await method.validate(); | |
74 | + const value = method.getFieldsValue(); | |
75 | + const searchParams = getSearchParams(value); | |
76 | + if (!hasDeviceAttr()) return; | |
77 | + // 发送请求 | |
78 | + loading.value = true; | |
79 | + const res = await getDeviceHistoryInfo(searchParams); | |
80 | + historyData.value = getTableHistoryData(res); | |
81 | + loading.value = false; | |
82 | + // 判断数据对象是否为空 | |
83 | + if (!Object.keys(res).length) { | |
84 | + isNull.value = false; | |
85 | + return; | |
86 | + } else { | |
87 | + isNull.value = true; | |
88 | + } | |
89 | + | |
90 | + const selectedKeys = unref(deviceAttrs).find( | |
91 | + (item) => item.identifier === value[SchemaFiled.KEYS] | |
92 | + ); | |
93 | + setOptions(setChartOptions(res, selectedKeys)); | |
94 | + }; | |
95 | + | |
96 | + const getTableHistoryData = (record: Recordable<{ ts: number; value: string }[]>) => { | |
97 | + const keys = Object.keys(record); | |
98 | + const list = keys.reduce((prev, next) => { | |
99 | + const list = record[next].map((item) => { | |
100 | + return { | |
101 | + ...item, | |
102 | + name: next, | |
103 | + }; | |
104 | + }); | |
105 | + return [...prev, ...list]; | |
106 | + }, []); | |
107 | + return list; | |
108 | + }; | |
109 | + | |
110 | + const [registerTable] = useTable({ | |
111 | + showIndexColumn: false, | |
112 | + showTableSetting: false, | |
113 | + dataSource: historyData, | |
114 | + maxHeight: 300, | |
115 | + size: 'small', | |
116 | + columns: [ | |
117 | + { | |
118 | + title: '属性', | |
119 | + dataIndex: 'name', | |
120 | + }, | |
121 | + { | |
122 | + title: '值', | |
123 | + dataIndex: 'value', | |
124 | + }, | |
125 | + { | |
126 | + title: '更新时间', | |
127 | + dataIndex: 'ts', | |
128 | + format: (val) => { | |
129 | + return formatToDateTime(val, 'YYYY-MM-DD HH:mm:ss'); | |
130 | + }, | |
131 | + }, | |
132 | + ], | |
133 | + }); | |
134 | + | |
79 | 135 | const getDeviceDataKey = async (record: DeviceOption) => { |
80 | 136 | const { organizationId, value } = record; |
81 | 137 | try { |
... | ... | @@ -115,9 +171,9 @@ |
115 | 171 | agg: AggregateDataEnum.NONE, |
116 | 172 | limit: 7, |
117 | 173 | }); |
118 | - | |
174 | + historyData.value = getTableHistoryData(res); | |
119 | 175 | // 判断对象是否为空 |
120 | - if (!Object.keys(res).length) { | |
176 | + if (!Object.keys(unref(historyData)).length) { | |
121 | 177 | isNull.value = false; |
122 | 178 | return; |
123 | 179 | } else { |
... | ... | @@ -181,6 +237,10 @@ |
181 | 237 | const handleCancel = () => { |
182 | 238 | destory(); |
183 | 239 | }; |
240 | + | |
241 | + const switchMode = (flag: Mode) => { | |
242 | + mode.value = flag; | |
243 | + }; | |
184 | 244 | </script> |
185 | 245 | |
186 | 246 | <template> |
... | ... | @@ -201,14 +261,65 @@ |
201 | 261 | <BasicForm @register="register" /> |
202 | 262 | </section> |
203 | 263 | <section class="bg-white p-3" style="min-height: 350px"> |
204 | - <div v-show="isNull" ref="chartRef" :style="{ height: '350px', width: '100%' }"> | |
264 | + <div v-show="mode === Mode.CHART" class="flex h-70px items-center justify-end p-2"> | |
265 | + <Tooltip title="图表模式"> | |
266 | + <Button | |
267 | + :class="[mode === Mode.CHART && '!bg-blue-500 svg:text-light-50']" | |
268 | + class="!p-2 !children:flex flex justify-center items-center border-r-0" | |
269 | + @click="switchMode(Mode.CHART)" | |
270 | + > | |
271 | + <LineChartOutlined /> | |
272 | + </Button> | |
273 | + </Tooltip> | |
274 | + | |
275 | + <Tooltip title="列表模式"> | |
276 | + <Button | |
277 | + class="!p-2 !children:flex flex justify-center items-center" | |
278 | + @click="switchMode(Mode.TABLE)" | |
279 | + > | |
280 | + <BarsOutlined /> | |
281 | + </Button> | |
282 | + </Tooltip> | |
283 | + </div> | |
284 | + | |
285 | + <div | |
286 | + v-show="isNull && mode === Mode.CHART" | |
287 | + ref="chartRef" | |
288 | + :style="{ height: '350px', width: '100%' }" | |
289 | + > | |
205 | 290 | <Loading :loading="loading" :absolute="true" /> |
206 | 291 | </div> |
207 | 292 | <Empty |
293 | + v-if="mode === Mode.CHART" | |
208 | 294 | class="h-350px flex flex-col justify-center items-center" |
209 | 295 | description="暂无数据,请选择设备查询" |
210 | 296 | v-show="!isNull" |
211 | 297 | /> |
298 | + | |
299 | + <BasicTable v-show="mode === Mode.TABLE" @register="registerTable"> | |
300 | + <template #toolbar> | |
301 | + <div v-show="mode === Mode.TABLE" class="flex h-70px items-center justify-end p-2"> | |
302 | + <Tooltip title="图表模式"> | |
303 | + <Button | |
304 | + class="!p-2 !children:flex flex justify-center items-center border-r-0" | |
305 | + @click="switchMode(Mode.CHART)" | |
306 | + > | |
307 | + <LineChartOutlined /> | |
308 | + </Button> | |
309 | + </Tooltip> | |
310 | + | |
311 | + <Tooltip title="列表模式"> | |
312 | + <Button | |
313 | + :class="[mode === Mode.TABLE && '!bg-blue-500 svg:text-light-50']" | |
314 | + class="!p-2 !children:flex flex justify-center items-center" | |
315 | + @click="switchMode(Mode.TABLE)" | |
316 | + > | |
317 | + <BarsOutlined /> | |
318 | + </Button> | |
319 | + </Tooltip> | |
320 | + </div> | |
321 | + </template> | |
322 | + </BasicTable> | |
212 | 323 | </section> |
213 | 324 | </section> |
214 | 325 | </BasicModal> | ... | ... |