Commit a6a460a6454d0416b85af7fc552a30fe1ab859e5

Authored by ww
1 parent bd736be5

fix: 修复单一组件无法接收多数据源

@@ -22,6 +22,10 @@ @@ -22,6 +22,10 @@
22 22
23 const wrapId = `bai-map-${buildUUID()}`; 23 const wrapId = `bai-map-${buildUUID()}`;
24 24
  25 + const getDeviceId = computed(() => {
  26 + return props.config.option.dataSource?.at(0)?.deviceId;
  27 + });
  28 +
25 /** 29 /**
26 * @description 经度key 30 * @description 经度key
27 */ 31 */
@@ -40,14 +44,18 @@ @@ -40,14 +44,18 @@
40 return !!(value && !isNaN(value as unknown as number)); 44 return !!(value && !isNaN(value as unknown as number));
41 }; 45 };
42 46
43 - const updateFn: MultipleDataFetchUpdateFn = (message) => { 47 + const updateFn: MultipleDataFetchUpdateFn = (message, deviceId) => {
  48 + if (unref(getDeviceId) !== deviceId) return;
  49 +
44 const { data = {} } = message; 50 const { data = {} } = message;
45 51
46 - const lngData = data[unref(getLngKey)] || []; 52 + const bindMessage = data[deviceId];
  53 +
  54 + const lngData = bindMessage[unref(getLngKey)] || [];
47 const [lngLatest] = lngData; 55 const [lngLatest] = lngData;
48 const [, lng] = lngLatest; 56 const [, lng] = lngLatest;
49 57
50 - const latData = data[unref(getLatKey)] || []; 58 + const latData = bindMessage[unref(getLatKey)] || [];
51 const [latLatest] = latData; 59 const [latLatest] = latData;
52 const [, lat] = latLatest; 60 const [, lat] = latLatest;
53 61
@@ -9,40 +9,48 @@ @@ -9,40 +9,48 @@
9 import { DeviceName } from '/@/views/visual/commonComponents/DeviceName'; 9 import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
10 import { unref } from 'vue'; 10 import { unref } from 'vue';
11 import { onMounted } from 'vue'; 11 import { onMounted } from 'vue';
  12 + import { useReceiveMessage } from '../../../hook/useReceiveMessage';
  13 + import { buildUUID } from '/@/utils/uuid';
  14 + import { useReceiveValue } from '../../../hook/useReceiveValue';
12 15
13 const props = defineProps<{ 16 const props = defineProps<{
14 config: ComponentPropsConfigType<typeof option>; 17 config: ComponentPropsConfigType<typeof option>;
15 }>(); 18 }>();
16 19
17 - const percentList = ref<any[]>([ 20 + interface PercentType {
  21 + value: number;
  22 + fontColor: string;
  23 + backgroundColor: string;
  24 + unit: string;
  25 + id: string;
  26 + attribute?: string;
  27 + attributeRename?: string;
  28 + deviceId?: string;
  29 + }
  30 +
  31 + const defaultValue: PercentType[] = [
18 { 32 {
19 value: 20, 33 value: 20,
20 fontColor: '#19eff', 34 fontColor: '#19eff',
21 backgroundColor: '#19eff', 35 backgroundColor: '#19eff',
22 - color: '#000',  
23 - fontSize: '16px',  
24 unit: '℃', 36 unit: '℃',
25 - id: 1, 37 + id: buildUUID(),
26 }, 38 },
27 { 39 {
28 value: 66, 40 value: 66,
29 fontColor: '#1E8667', 41 fontColor: '#1E8667',
30 backgroundColor: '#1E8667', 42 backgroundColor: '#1E8667',
31 - color: '#000',  
32 - fontSize: '16px',  
33 unit: '℃', 43 unit: '℃',
34 - id: 2, 44 + id: buildUUID(),
35 }, 45 },
36 { 46 {
37 value: 49, 47 value: 49,
38 fontColor: '#2196F3', 48 fontColor: '#2196F3',
39 backgroundColor: '#2196F3', 49 backgroundColor: '#2196F3',
40 - color: '#000',  
41 - fontSize: '16px',  
42 unit: '℃', 50 unit: '℃',
43 - id: 3, 51 + id: buildUUID(),
44 }, 52 },
45 - ]); 53 + ];
46 54
47 const getDesign = computed(() => { 55 const getDesign = computed(() => {
48 const { persetOption = {}, option } = props.config; 56 const { persetOption = {}, option } = props.config;
@@ -52,65 +60,52 @@ @@ -52,65 +60,52 @@
52 fontColor: presetFontColor, 60 fontColor: presetFontColor,
53 backgroundColor: persetBackgroundColor, 61 backgroundColor: persetBackgroundColor,
54 } = persetOption || {}; 62 } = persetOption || {};
  63 +
55 return { 64 return {
56 - dataSource: dataSource?.map((item) => {  
57 - const { unit, fontColor, fontSize, backgroundColor } = item.componentInfo || {};  
58 - const { attribute, attributeRename } = item; 65 + dataSource: dataSource.map((item) => {
  66 + const { unit, fontColor, backgroundColor } = item.componentInfo || {};
  67 + const { attribute, attributeRename, deviceId } = item;
59 return { 68 return {
60 unit: unit ?? presetUnit, 69 unit: unit ?? presetUnit,
61 fontColor: fontColor ?? presetFontColor, 70 fontColor: fontColor ?? presetFontColor,
62 - fontSize,  
63 backgroundColor: backgroundColor ?? persetBackgroundColor, 71 backgroundColor: backgroundColor ?? persetBackgroundColor,
64 attribute, 72 attribute,
65 attributeRename, 73 attributeRename,
66 - }; 74 + id: deviceId,
  75 + } as PercentType;
67 }), 76 }),
68 }; 77 };
69 }); 78 });
  79 + const percentList = ref(
  80 + props.config.option.dataSource ? unref(getDesign).dataSource : defaultValue
  81 + );
  82 + const { forEachGroupMessage } = useReceiveMessage();
70 83
71 - const newPercentList = ref<any[]>([]);  
72 -  
73 - const updateFn: MultipleDataFetchUpdateFn = (message) => {  
74 - const { data = {} } = message;  
75 - const { dataSource } = unref(getDesign);  
76 - newPercentList.value = dataSource.map((item) => {  
77 - const { attribute, fontSize, attributeRename, fontColor, unit, backgroundColor } = item;  
78 -  
79 - const [latest] = data[attribute] || [];  
80 - const [_timespan, value] = latest || [];  
81 - return {  
82 - value: Number(value),  
83 - name: attributeRename ?? attribute,  
84 - fontSize,  
85 - unit,  
86 - backgroundColor: backgroundColor,  
87 - fontColor: fontColor,  
88 - }; 84 + const { getNumberValue } = useReceiveValue();
  85 + const updateFn: MultipleDataFetchUpdateFn = (message, deviceId, attribute) => {
  86 + forEachGroupMessage(message, deviceId, attribute, (attribute, value) => {
  87 + percentList.value.forEach((item) => {
  88 + if (item.id === deviceId && item.attribute === attribute) {
  89 + item.value = getNumberValue(value);
  90 + }
  91 + });
89 }); 92 });
90 - // console.log(numberList, 'numberList');  
91 }; 93 };
92 94
93 - onMounted(() => {  
94 - newPercentList.value = percentList.value;  
95 - !props.config.option.uuid;  
96 - }); 95 + onMounted(() => {});
97 96
98 useMultipleDataFetch(props, updateFn); 97 useMultipleDataFetch(props, updateFn);
99 -  
100 - // const { getScale } = useComponentScale(props);  
101 </script> 98 </script>
102 99
103 <template> 100 <template>
104 <main class="w-full h-full flex flex-col justify-center"> 101 <main class="w-full h-full flex flex-col justify-center">
105 <DeviceName :config="config" /> 102 <DeviceName :config="config" />
106 103
107 - <div  
108 - v-for="item in newPercentList"  
109 - :key="item.id"  
110 - class="flex flex-col ml-3 mr-3 items-stretch"  
111 - > 104 + <div v-for="item in percentList" :key="item.id" class="flex flex-col ml-3 mr-3 items-stretch">
112 <div class="flex justify-between"> 105 <div class="flex justify-between">
113 - <div class="text-gray-500 text-lg truncate">{{ item.name || '温度' }}</div> 106 + <div class="text-gray-500 text-lg truncate">
  107 + {{ item.attributeRename || item.attribute || '温度' }}
  108 + </div>
114 <span class="text-lg" :style="{ color: item.fontColor }" 109 <span class="text-lg" :style="{ color: item.fontColor }"
115 >{{ item.value }} {{ item.unit }}</span 110 >{{ item.value }} {{ item.unit }}</span
116 > 111 >
  1 +import { ReceiveGroupMessageType } from '../index.type';
  2 +
  3 +export const useReceiveMessage = () => {
  4 + const forEachGroupMessage = (
  5 + message: ReceiveGroupMessageType,
  6 + deviceId: string,
  7 + attributes: string[],
  8 + Fn: (attribute: string, value: any, timespan: number) => void
  9 + ) => {
  10 + const { data = {} } = message;
  11 + const bindMessage = data[deviceId];
  12 +
  13 + for (const attribute of attributes) {
  14 + const [latest] = bindMessage[attribute] || [];
  15 + const [timespan, value] = latest || [];
  16 + Fn?.(attribute, value, timespan);
  17 + }
  18 + };
  19 +
  20 + return { forEachGroupMessage };
  21 +};
  1 +export const useReceiveValue = () => {
  2 + const getNumberValue = (value: any, defaultValue = 0) => {
  3 + const newValue = isNaN(value) ? defaultValue : Number(value);
  4 + return newValue;
  5 + };
  6 +
  7 + return { getNumberValue };
  8 +};
@@ -10,6 +10,7 @@ import { @@ -10,6 +10,7 @@ import {
10 DataFetchUpdateFn, 10 DataFetchUpdateFn,
11 EntityTypeEnum, 11 EntityTypeEnum,
12 MultipleDataFetchUpdateFn, 12 MultipleDataFetchUpdateFn,
  13 + ReceiveGroupMessageType,
13 ReceiveMessageType, 14 ReceiveMessageType,
14 ScopeTypeEnum, 15 ScopeTypeEnum,
15 SubscribeMessageItemType, 16 SubscribeMessageItemType,
@@ -115,6 +116,20 @@ class Subscriber { @@ -115,6 +116,20 @@ class Subscriber {
115 } as ReceiveMessageType; 116 } as ReceiveMessageType;
116 } 117 }
117 118
  119 + getGroupScopeMessage(message: ReceiveMessageType, attribute: string[], deviceId: string) {
  120 + const result = this.getScopeMessage(message, attribute);
  121 +
  122 + return {
  123 + ...result,
  124 + data: {
  125 + [deviceId]: result.data,
  126 + },
  127 + latestValues: {
  128 + [deviceId]: result.latestValues,
  129 + },
  130 + } as ReceiveGroupMessageType;
  131 + }
  132 +
118 trackUpdate(uuid: string, fn: Fn) { 133 trackUpdate(uuid: string, fn: Fn) {
119 if (!uuid || !fn) return; 134 if (!uuid || !fn) return;
120 this.componentUpdateFnMap.set(uuid, fn); 135 this.componentUpdateFnMap.set(uuid, fn);
@@ -144,7 +159,7 @@ class Subscriber { @@ -144,7 +159,7 @@ class Subscriber {
144 const { attributes, fn } = item; 159 const { attributes, fn } = item;
145 try { 160 try {
146 if (!fn) return; 161 if (!fn) return;
147 - fn?.(this.getScopeMessage(message, attributes), attributes); 162 + fn?.(this.getGroupScopeMessage(message, attributes, deviceId), deviceId, attributes);
148 } catch (error) { 163 } catch (error) {
149 console.error(`deviceId: ${deviceId}`); 164 console.error(`deviceId: ${deviceId}`);
150 throw error; 165 throw error;
@@ -253,23 +268,47 @@ export const useMultipleDataFetch = ( @@ -253,23 +268,47 @@ export const useMultipleDataFetch = (
253 props: { config: ComponentPropsConfigType }, 268 props: { config: ComponentPropsConfigType },
254 updateFn: MultipleDataFetchUpdateFn 269 updateFn: MultipleDataFetchUpdateFn
255 ) => { 270 ) => {
256 - const getBindAttributes = computed(() => {  
257 - const attributes = props.config.option.dataSource?.map((item) => item.attribute);  
258 - return [...new Set(attributes)];  
259 - }); 271 + const getDataSourceGroup = computed(() => {
  272 + const { config } = props;
  273 + const { option } = config;
  274 + const { dataSource } = option || {};
260 275
261 - if (!unref(getBindAttributes).length) return; 276 + const group: Record<string, DataSource[]> = {};
262 277
263 - const getDeviceId = computed(() => {  
264 - return props.config.option.dataSource?.at(0)?.deviceId; 278 + dataSource?.forEach((item) => {
  279 + const { deviceId } = item;
  280 + if (group[deviceId]) {
  281 + group[deviceId].push(item);
  282 + } else {
  283 + group[deviceId] = [item];
  284 + }
  285 + });
  286 +
  287 + return group;
265 }); 288 });
266 289
  290 + if (!Object.keys(unref(getDataSourceGroup)).length) return;
  291 + // const getBindAttributes = computed(() => {
  292 + // const attributes = props.config.option.dataSource?.map((item) => item.attribute);
  293 + // return [...new Set(attributes)];
  294 + // });
  295 +
  296 + // if (!unref(getBindAttributes).length) return;
  297 +
  298 + // const getDeviceId = computed(() => {
  299 + // return props.config.option.dataSource?.at(0)?.deviceId;
  300 + // });
  301 +
267 watch( 302 watch(
268 - () => getDeviceId, 303 + () => getDataSourceGroup,
269 () => { 304 () => {
270 - subscriber.trackUpdateGroup(unref(getDeviceId)!, {  
271 - attributes: unref(getBindAttributes),  
272 - fn: updateFn, 305 + Object.keys(unref(getDataSourceGroup)).forEach((key) => {
  306 + const item = unref(getDataSourceGroup)[key];
  307 + const attributes = [...new Set(item.map((item) => item.attribute))];
  308 + subscriber.trackUpdateGroup(key, {
  309 + attributes,
  310 + fn: updateFn,
  311 + });
273 }); 312 });
274 }, 313 },
275 { 314 {
@@ -277,5 +316,5 @@ export const useMultipleDataFetch = ( @@ -277,5 +316,5 @@ export const useMultipleDataFetch = (
277 } 316 }
278 ); 317 );
279 318
280 - return { getDeviceId, getBindAttributes }; 319 + return {};
281 }; 320 };
@@ -162,6 +162,18 @@ export interface ReceiveMessageType { @@ -162,6 +162,18 @@ export interface ReceiveMessageType {
162 latestValues: Record<string, number>; 162 latestValues: Record<string, number>;
163 } 163 }
164 164
  165 +export interface ReceiveGroupMessageType {
  166 + subscriptionId: number;
  167 + errorCode: number;
  168 + errorMsg: Nullable<string>;
  169 + data: {
  170 + string: Record<string, [number, string][]>;
  171 + };
  172 + latestValues: {
  173 + string: Record<string, number>;
  174 + };
  175 +}
  176 +
165 export enum EntityTypeEnum { 177 export enum EntityTypeEnum {
166 DEVICE = 'DEVICE', 178 DEVICE = 'DEVICE',
167 } 179 }
@@ -172,7 +184,11 @@ export enum ScopeTypeEnum { @@ -172,7 +184,11 @@ export enum ScopeTypeEnum {
172 184
173 export type DataFetchUpdateFn = (message: ReceiveMessageType, attr: string) => void; 185 export type DataFetchUpdateFn = (message: ReceiveMessageType, attr: string) => void;
174 186
175 -export type MultipleDataFetchUpdateFn = (message: ReceiveMessageType, attr: string[]) => void; 187 +export type MultipleDataFetchUpdateFn = (
  188 + message: ReceiveGroupMessageType,
  189 + deviceId: string,
  190 + attr: string[]
  191 +) => void;
176 192
177 // 旧 组件key 193 // 旧 组件key
178 // TEXT_COMPONENT_1 = 'text-component-1', 194 // TEXT_COMPONENT_1 = 'text-component-1',