Commit fce71e9f4b5893f32cae23da8e30160bb54c6399
1 parent
fc25d5e8
feat(src/packages): 设备分布新增点击弹出抽屉展示设备最新属性数据值
Showing
11 changed files
with
95 additions
and
40 deletions
@@ -17,7 +17,8 @@ enum Api { | @@ -17,7 +17,8 @@ enum Api { | ||
17 | GEOJSONURL = '/map/geo_json/', | 17 | GEOJSONURL = '/map/geo_json/', |
18 | DEVICE_URL = '/device', | 18 | DEVICE_URL = '/device', |
19 | GET_ATTRBUTELIST = '/device/attributes/', | 19 | GET_ATTRBUTELIST = '/device/attributes/', |
20 | - GET_DEVICE_LATEST = '/plugins/telemetry/DEVICE/' | 20 | + GET_DEVICE_LATEST = '/plugins/telemetry/DEVICE/', |
21 | + DEVICE_ATTR = '/device/attributes', | ||
21 | } | 22 | } |
22 | 23 | ||
23 | export const getDictItemByCode = (value: string) => { | 24 | export const getDictItemByCode = (value: string) => { |
@@ -135,4 +136,13 @@ defHttp.get({ | @@ -135,4 +136,13 @@ defHttp.get({ | ||
135 | url: `${Api.GET_DEVICE_LATEST}${tbDeviceId}/values/timeseries` | 136 | url: `${Api.GET_DEVICE_LATEST}${tbDeviceId}/values/timeseries` |
136 | }, { | 137 | }, { |
137 | joinPrefix: false | 138 | joinPrefix: false |
138 | -}) | ||
139 | +}) | ||
140 | + | ||
141 | +//获取产品属性 | ||
142 | +export const getProfileAttrs = (params: { deviceProfileId: string; dataType?: string }) => { | ||
143 | + const { deviceProfileId, dataType } = params; | ||
144 | + return defHttp.get({ | ||
145 | + url: `${Api.DEVICE_ATTR}/${deviceProfileId}`, | ||
146 | + params: { dataType }, | ||
147 | + }); | ||
148 | +}; |
src/assets/external/marker/1.png
renamed from
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/1.png
1.24 KB
src/assets/external/marker/2.png
renamed from
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/2.png
1.4 KB
src/assets/external/marker/3.png
renamed from
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/3.png
904 Bytes
src/assets/external/marker/4.png
renamed from
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/4.png
1.02 KB
src/assets/external/marker/5.png
renamed from
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/5.png
970 Bytes
1 | <template> | 1 | <template> |
2 | <n-drawer display-directive="if" v-model:show="modelShow" :width="502" :placement="placement"> | 2 | <n-drawer display-directive="if" v-model:show="modelShow" :width="502" :placement="placement"> |
3 | - <n-drawer-content title="设备最新属性数据" closable> | 3 | + <n-drawer-content :title="drawerTitle" closable> |
4 | <n-space vertical> | 4 | <n-space vertical> |
5 | - <n-data-table size="small" :columns="dimensions" :data="source" :pagination="pagination" /> | 5 | + <n-data-table size="small" :columns="dimensions" :data="source" :pagination="paginationReactive" /> |
6 | </n-space> | 6 | </n-space> |
7 | </n-drawer-content> | 7 | </n-drawer-content> |
8 | </n-drawer> | 8 | </n-drawer> |
9 | </template> | 9 | </template> |
10 | 10 | ||
11 | <script lang="ts" setup> | 11 | <script lang="ts" setup> |
12 | -import { ref } from 'vue' | 12 | +import { ref, reactive } from 'vue' |
13 | import { NDataTable,NDrawer, NDrawerContent, NSpace } from 'naive-ui' | 13 | import { NDataTable,NDrawer, NDrawerContent, NSpace } from 'naive-ui' |
14 | -import { dimensions, pagination } from '../config' | 14 | +import { dimensions } from '../config' |
15 | import type { sourceInterface } from '../config' | 15 | import type { sourceInterface } from '../config' |
16 | import dayjs from 'dayjs' | 16 | import dayjs from 'dayjs' |
17 | +import { Placement } from 'naive-ui/es/drawer/src/DrawerBodyWrapper' | ||
17 | 18 | ||
18 | -// defineProps({ | ||
19 | -// modelShow: Boolean | ||
20 | -// }) | ||
21 | - | ||
22 | -const placement = ref('right') | 19 | +const placement = ref<Placement>('right') |
23 | 20 | ||
24 | const modelShow =ref(false) | 21 | const modelShow =ref(false) |
25 | 22 | ||
23 | +const drawerTitle = ref('') | ||
24 | + | ||
26 | const source =ref<sourceInterface[]>([]) | 25 | const source =ref<sourceInterface[]>([]) |
27 | 26 | ||
28 | -const setValue = (value: Recordable) => { | ||
29 | - if (!value) return | ||
30 | - source.value = Object.keys(value).map((item:string) => { | ||
31 | - return { | ||
32 | - key: item, | ||
33 | - value: value[item][0].value, | ||
34 | - lastUpdateTime: dayjs( value[item][0].ts).format('YYYY-MM-DD HH:mm:ss') | ||
35 | - } | ||
36 | - }) | 27 | +const paginationReactive = reactive({ |
28 | + page: 1, | ||
29 | + pageSize: 10, | ||
30 | + showSizePicker: true, | ||
31 | + pageSizes: [10, 20], | ||
32 | + onChange: (page: number) => { | ||
33 | + paginationReactive.page = page | ||
34 | + }, | ||
35 | + onUpdatePageSize: (pageSize: number) => { | ||
36 | + paginationReactive.pageSize = pageSize | ||
37 | + paginationReactive.page = 1 | ||
38 | + } | ||
39 | + }) | ||
40 | + | ||
41 | +const setValue = (value: Recordable, attrs: Recordable[]) => { | ||
42 | + source.value = [] | ||
43 | + try { | ||
44 | + if (!value) return | ||
45 | + const deviceLatestList = Object.keys(value).map((item:string) => { | ||
46 | + return { | ||
47 | + key: item, | ||
48 | + value: value[item][0]?.value, | ||
49 | + lastUpdateTime: dayjs( value[item][0]?.ts)?.format('YYYY-MM-DD HH:mm:ss') | ||
50 | + } | ||
51 | + }) | ||
52 | + const list = deviceLatestList?.reduce((acc:sourceInterface[],curr: sourceInterface)=>{ | ||
53 | + const byKeyFindName = attrs?.find(item => item.identifier === curr.key)?.name | ||
54 | + curr.key = byKeyFindName | ||
55 | + acc.push({...curr}) | ||
56 | + return [...acc] | ||
57 | + },[]) | ||
58 | + source.value = list.filter(item=>Boolean(item.key)) | ||
59 | + }catch(e){ | ||
60 | + console.log(e) | ||
61 | + } | ||
37 | } | 62 | } |
38 | 63 | ||
64 | +const setDrawerTitle = (title:string) => drawerTitle.value = title | ||
65 | + | ||
39 | const openDrawer = () => modelShow.value = true | 66 | const openDrawer = () => modelShow.value = true |
40 | 67 | ||
41 | defineExpose({ | 68 | defineExpose({ |
42 | setValue, | 69 | setValue, |
43 | - openDrawer | 70 | + openDrawer, |
71 | + setDrawerTitle | ||
44 | }) | 72 | }) |
45 | </script> | 73 | </script> |
46 | 74 |
@@ -4,7 +4,7 @@ import { OverrideMapAmapConfig } from './index' | @@ -4,7 +4,7 @@ import { OverrideMapAmapConfig } from './index' | ||
4 | import { chartInitConfig } from '@/settings/designSetting' | 4 | import { chartInitConfig } from '@/settings/designSetting' |
5 | import cloneDeep from 'lodash/cloneDeep' | 5 | import cloneDeep from 'lodash/cloneDeep' |
6 | import dataJson from './data.json' | 6 | import dataJson from './data.json' |
7 | -import defaultImg from './images/marker/1.png' | 7 | +import defaultImg from '../../../../../../assets/external/marker/1.png' |
8 | 8 | ||
9 | export type dataExtraInfoType = typeof dataJson.markers[number]['extraInfo'] //data.json下的extraInfo类型 | 9 | export type dataExtraInfoType = typeof dataJson.markers[number]['extraInfo'] //data.json下的extraInfo类型 |
10 | 10 | ||
@@ -26,6 +26,7 @@ export const filterDevice = (items: any) => { | @@ -26,6 +26,7 @@ export const filterDevice = (items: any) => { | ||
26 | organizationDTO: curr.organizationDTO, | 26 | organizationDTO: curr.organizationDTO, |
27 | deviceState: curr.deviceState, | 27 | deviceState: curr.deviceState, |
28 | deviceProfile: curr.deviceProfile, | 28 | deviceProfile: curr.deviceProfile, |
29 | + deviceProfileId: curr.deviceProfileId, | ||
29 | deviceInfo: curr.deviceInfo | 30 | deviceInfo: curr.deviceInfo |
30 | } | 31 | } |
31 | }) | 32 | }) |
@@ -36,6 +37,13 @@ export const filterDevice = (items: any) => { | @@ -36,6 +37,13 @@ export const filterDevice = (items: any) => { | ||
36 | } | 37 | } |
37 | } | 38 | } |
38 | 39 | ||
40 | +export interface devicePartInfoInterface{ | ||
41 | + tbDeviceId:string | ||
42 | + name:string | ||
43 | + alias:string | ||
44 | + deviceProfileId:string | ||
45 | +} | ||
46 | + | ||
39 | export const dimensions= [ | 47 | export const dimensions= [ |
40 | { | 48 | { |
41 | "title": "键", | 49 | "title": "键", |
@@ -57,11 +65,6 @@ export interface sourceInterface { | @@ -57,11 +65,6 @@ export interface sourceInterface { | ||
57 | lastUpdateTime: string | 65 | lastUpdateTime: string |
58 | } | 66 | } |
59 | 67 | ||
60 | -export const pagination = { | ||
61 | - page: 1, | ||
62 | - pageSize: 10 | ||
63 | -} | ||
64 | - | ||
65 | export enum ThemeEnum { | 68 | export enum ThemeEnum { |
66 | NORMAL = 'normal', | 69 | NORMAL = 'normal', |
67 | DARK = 'dark', | 70 | DARK = 'dark', |
@@ -254,7 +254,7 @@ const isHref = (url: string) => { | @@ -254,7 +254,7 @@ const isHref = (url: string) => { | ||
254 | 254 | ||
255 | // import.meta.glob 这个不能封装,必须是字符串,不能通过传值传进去 | 255 | // import.meta.glob 这个不能封装,必须是字符串,不能通过传值传进去 |
256 | const iconMarkerOptions = computed(() => { | 256 | const iconMarkerOptions = computed(() => { |
257 | - const pathList = import.meta.glob('./images/marker/*') | 257 | + const pathList = import.meta.glob('../../../../../../assets/external/marker/*') |
258 | return Object.keys(pathList).map(item => { | 258 | return Object.keys(pathList).map(item => { |
259 | const imgName = item.split('/').at(-1) | 259 | const imgName = item.split('/').at(-1) |
260 | return { | 260 | return { |
@@ -266,7 +266,7 @@ const iconMarkerOptions = computed(() => { | @@ -266,7 +266,7 @@ const iconMarkerOptions = computed(() => { | ||
266 | // | 266 | // |
267 | 267 | ||
268 | const getMarkerImagePath = (name: string) => { | 268 | const getMarkerImagePath = (name: string) => { |
269 | - return isHref(name) ? name : new URL(`./images/marker/${name}`, import.meta.url).href | 269 | + return isHref(name) ? name : new URL(`../../../../../../assets/external/marker/${name}`, import.meta.url).href |
270 | } | 270 | } |
271 | 271 | ||
272 | const renderOption = (option: SelectOption) => { | 272 | const renderOption = (option: SelectOption) => { |
@@ -334,6 +334,7 @@ const selectMapBorderHandle = (value: string) => { | @@ -334,6 +334,7 @@ const selectMapBorderHandle = (value: string) => { | ||
334 | onMounted(() => { | 334 | onMounted(() => { |
335 | iconMarkerValue.value = props.optionData.mapOptions.iconMarker?.split('/')?.at(-1) as string | 335 | iconMarkerValue.value = props.optionData.mapOptions.iconMarker?.split('/')?.at(-1) as string |
336 | props.optionData.mapOptions.iconMarker = getMarkerImagePath(iconMarkerValue.value) | 336 | props.optionData.mapOptions.iconMarker = getMarkerImagePath(iconMarkerValue.value) |
337 | + console.log(getMarkerImagePath(iconMarkerValue.value)); | ||
337 | mapSelectBorderValue.value = `${props.optionData.mapOptions.mpBorderConfig.value?.toLocaleLowerCase()}.png` | 338 | mapSelectBorderValue.value = `${props.optionData.mapOptions.mpBorderConfig.value?.toLocaleLowerCase()}.png` |
338 | }) | 339 | }) |
339 | </script> | 340 | </script> |
@@ -15,6 +15,7 @@ | @@ -15,6 +15,7 @@ | ||
15 | "deviceProfile": { | 15 | "deviceProfile": { |
16 | "transportType": "MQTT" | 16 | "transportType": "MQTT" |
17 | }, | 17 | }, |
18 | + "deviceProfileId":"", | ||
18 | "deviceInfo": { | 19 | "deviceInfo": { |
19 | "address": "四川省", | 20 | "address": "四川省", |
20 | "longitude": 103.856504, | 21 | "longitude": 103.856504, |
@@ -37,6 +38,7 @@ | @@ -37,6 +38,7 @@ | ||
37 | "deviceProfile": { | 38 | "deviceProfile": { |
38 | "transportType": "TCP" | 39 | "transportType": "TCP" |
39 | }, | 40 | }, |
41 | + "deviceProfileId":"", | ||
40 | "deviceInfo": { | 42 | "deviceInfo": { |
41 | "address": "四川省", | 43 | "address": "四川省", |
42 | "longitude": 104.095368, | 44 | "longitude": 104.095368, |
1 | <template> | 1 | <template> |
2 | <div class="chart-amap" ref="vChartRef"> | 2 | <div class="chart-amap" ref="vChartRef"> |
3 | - <device-latest-table ref="deviceLatestTableRef" :tbDeviceId="tbDeviceIdStr"></device-latest-table> | 3 | + <device-latest-table ref="deviceLatestTableRef"></device-latest-table> |
4 | </div> | 4 | </div> |
5 | </template> | 5 | </template> |
6 | 6 | ||
7 | <script setup lang="ts"> | 7 | <script setup lang="ts"> |
8 | -import { ref, PropType, toRefs, watch, render, h, onMounted, onUnmounted} from 'vue' | 8 | +import { ref, PropType, toRefs, watch, render, h, onMounted, onUnmounted, reactive} from 'vue' |
9 | import AMapLoader from '@amap/amap-jsapi-loader' | 9 | import AMapLoader from '@amap/amap-jsapi-loader' |
10 | import { CreateComponentType } from '@/packages/index.d' | 10 | import { CreateComponentType } from '@/packages/index.d' |
11 | import { useChartDataFetch } from '@/hooks' | 11 | import { useChartDataFetch } from '@/hooks' |
12 | import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | 12 | import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' |
13 | -import { MarkerEnum, ThemeEnum, dataExtraInfoType, dataJsonType, dataJsonMarkersType } from './config' | 13 | +import { MarkerEnum, ThemeEnum, dataExtraInfoType, dataJsonType, dataJsonMarkersType, devicePartInfoInterface } from './config' |
14 | import { isArray } from '@/utils' | 14 | import { isArray } from '@/utils' |
15 | import djh from './images/djh.png' | 15 | import djh from './images/djh.png' |
16 | import online from './images/online.png' | 16 | import online from './images/online.png' |
17 | import lx1 from './images/lx1.png' | 17 | import lx1 from './images/lx1.png' |
18 | -import onLineImg from './images/marker/3.png' | 18 | +import onLineImg from '../../../../../../assets/external/marker/3.png' |
19 | import listImg from './images/list.png' | 19 | import listImg from './images/list.png' |
20 | import { getDeviceActiveTime } from '@/api/external/common/index' | 20 | import { getDeviceActiveTime } from '@/api/external/common/index' |
21 | import dayjs from 'dayjs' | 21 | import dayjs from 'dayjs' |
22 | import DeviceLatestTable from './components/DeviceLatestTable.vue' | 22 | import DeviceLatestTable from './components/DeviceLatestTable.vue' |
23 | -import { getDeviceLatest } from '@/api/external/common' | 23 | +import { getDeviceLatest, getProfileAttrs } from '@/api/external/common' |
24 | 24 | ||
25 | const props = defineProps({ | 25 | const props = defineProps({ |
26 | chartConfig: { | 26 | chartConfig: { |
@@ -97,13 +97,22 @@ const initMap = (newData: any) => { | @@ -97,13 +97,22 @@ const initMap = (newData: any) => { | ||
97 | } | 97 | } |
98 | 98 | ||
99 | 99 | ||
100 | -const tbDeviceIdStr = ref('') | 100 | +//携带设备的tbDeviceId和别名或者名称 |
101 | +const devicePartInfo = reactive<devicePartInfoInterface>({ | ||
102 | + tbDeviceId:'', | ||
103 | + name:'', | ||
104 | + alias:'', | ||
105 | + deviceProfileId:'', | ||
106 | +}) | ||
101 | 107 | ||
102 | //创建信息弹窗 | 108 | //创建信息弹窗 |
103 | const createInfoWindow = async (extraInfo: dataExtraInfoType) => { | 109 | const createInfoWindow = async (extraInfo: dataExtraInfoType) => { |
104 | try { | 110 | try { |
105 | - const { name, alias, organizationDTO, deviceState, deviceProfile, deviceInfo, tbDeviceId } = extraInfo | ||
106 | - tbDeviceIdStr.value = tbDeviceId | 111 | + const { name, alias, organizationDTO, deviceState, deviceProfile, deviceInfo, tbDeviceId, deviceProfileId } = extraInfo |
112 | + devicePartInfo.tbDeviceId = tbDeviceId | ||
113 | + devicePartInfo.alias = alias | ||
114 | + devicePartInfo.name = name | ||
115 | + devicePartInfo.deviceProfileId = deviceProfileId | ||
107 | if (tbDeviceId.startsWith('@')) return //假的模拟数据则终止 | 116 | if (tbDeviceId.startsWith('@')) return //假的模拟数据则终止 |
108 | const res = await getDeviceActiveTime(tbDeviceId) //查询设备最后离线时间 | 117 | const res = await getDeviceActiveTime(tbDeviceId) //查询设备最后离线时间 |
109 | let { lastUpdateTs } = res[0] | 118 | let { lastUpdateTs } = res[0] |
@@ -164,9 +173,11 @@ const createInfoWindow = async (extraInfo: dataExtraInfoType) => { | @@ -164,9 +173,11 @@ const createInfoWindow = async (extraInfo: dataExtraInfoType) => { | ||
164 | 173 | ||
165 | const handleOpenDrawer = async () => { | 174 | const handleOpenDrawer = async () => { |
166 | deviceLatestTableRef.value?.openDrawer() | 175 | deviceLatestTableRef.value?.openDrawer() |
167 | - if (!tbDeviceIdStr.value) return | ||
168 | - const resp = await getDeviceLatest(tbDeviceIdStr.value) | ||
169 | - deviceLatestTableRef.value?.setValue(resp) | 176 | + deviceLatestTableRef.value?.setDrawerTitle(devicePartInfo.alias || devicePartInfo.name) |
177 | + if (!devicePartInfo.tbDeviceId) return | ||
178 | + const resp = await getDeviceLatest(devicePartInfo.tbDeviceId) | ||
179 | + const respGetAttrs = await getProfileAttrs({deviceProfileId: devicePartInfo.deviceProfileId}) | ||
180 | + deviceLatestTableRef.value?.setValue(resp,respGetAttrs) | ||
170 | } | 181 | } |
171 | 182 | ||
172 | onMounted(() => { | 183 | onMounted(() => { |