Commit fce71e9f4b5893f32cae23da8e30160bb54c6399

Authored by fengtao
1 parent fc25d5e8

feat(src/packages): 设备分布新增点击弹出抽屉展示设备最新属性数据值

@@ -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(() => {