Commit 4c16f116ea72e4fdf7ebe21709ad7476f339f771

Authored by ww
1 parent 2d6023c8

perf: 优化折现图名称

@@ -16,7 +16,7 @@ enum Api { @@ -16,7 +16,7 @@ enum Api {
16 RPC_ONEWAY = '/rpc/oneway', 16 RPC_ONEWAY = '/rpc/oneway',
17 17
18 GEN_MODBUS_COMMAND = '/js/modbus', 18 GEN_MODBUS_COMMAND = '/js/modbus',
19 - GET_DEVICE = '/device/', // 获取设备详情 19 + GET_DEVICE_DETAIL = '/device/', // 获取设备详情
20 } 20 }
21 21
22 export interface GenModbusCommandType { 22 export interface GenModbusCommandType {
@@ -125,7 +125,7 @@ export const getDeviceActiveTime = (entityId: string) => { @@ -125,7 +125,7 @@ export const getDeviceActiveTime = (entityId: string) => {
125 export const getDeviceInfo = (deviceId: string) => { 125 export const getDeviceInfo = (deviceId: string) => {
126 return defHttp.get( 126 return defHttp.get(
127 { 127 {
128 - url: `${Api.GET_DEVICE}${deviceId}`, 128 + url: `${Api.GET_DEVICE_DETAIL}${deviceId}`,
129 }, 129 },
130 ) 130 )
131 } 131 }
1 -import type { ThingsModel } from '@/api/device/model' 1 +import type { ThingsModelItemType } from '@/api/device/model'
2 import type { ImageSelectorDataType } from '@/core/Library/components/ImageSelector' 2 import type { ImageSelectorDataType } from '@/core/Library/components/ImageSelector'
3 import type { CommandWayEnum } from '@/enums/commandEnum' 3 import type { CommandWayEnum } from '@/enums/commandEnum'
4 import type { ActTypeEnum, AggregateTypeEnum, CommandDeliveryWayEnum, DeviceTypeEnum, EventActionTypeEnum, EventTypeEnum, SocketSubscriberEnum, TransportTypeEnum } from '@/enums/datasource' 4 import type { ActTypeEnum, AggregateTypeEnum, CommandDeliveryWayEnum, DeviceTypeEnum, EventActionTypeEnum, EventTypeEnum, SocketSubscriberEnum, TransportTypeEnum } from '@/enums/datasource'
@@ -79,11 +79,20 @@ export interface AlarmListOptionType { @@ -79,11 +79,20 @@ export interface AlarmListOptionType {
79 79
80 } 80 }
81 81
  82 +export interface DeviceInfoType {
  83 + code?: string
  84 + transportType?: string
  85 + deviceType?: string
  86 + deviceProfileId?: string
  87 + deviceName?: string
  88 + codeType?: string
  89 +}
  90 +
82 export interface NodeDataDataSourceJsonType { 91 export interface NodeDataDataSourceJsonType {
83 deviceId: string 92 deviceId: string
84 deviceProfileId: string 93 deviceProfileId: string
85 attr: string 94 attr: string
86 - attrInfo: ThingsModel 95 + attrInfo: ThingsModelItemType
87 96
88 deviceType?: DeviceTypeEnum 97 deviceType?: DeviceTypeEnum
89 transportType?: TransportTypeEnum 98 transportType?: TransportTypeEnum
@@ -92,13 +101,7 @@ export interface NodeDataDataSourceJsonType { @@ -92,13 +101,7 @@ export interface NodeDataDataSourceJsonType {
92 chartOption?: ChartOptionType 101 chartOption?: ChartOptionType
93 videoOption?: VideoOptionType 102 videoOption?: VideoOptionType
94 alarmListOption?: AlarmListOptionType 103 alarmListOption?: AlarmListOptionType
95 - deviceInfo?: {  
96 - code?: string  
97 - transportType?: string  
98 - deviceType?: string  
99 - deviceProfileId?: string  
100 - label?: string  
101 - } 104 + deviceInfo?: DeviceInfoType
102 circularFlowMeterOption?: FlowMeterColorItemType[] // 圆形水球图数据暂定any 105 circularFlowMeterOption?: FlowMeterColorItemType[] // 圆形水球图数据暂定any
103 rectFlowMeterOption?: FlowMeterColorItemType[] // 方形水球图颜色配置数据暂定any 106 rectFlowMeterOption?: FlowMeterColorItemType[] // 方形水球图颜色配置数据暂定any
104 107
@@ -126,7 +129,7 @@ export interface DoubleClickEventDataType { @@ -126,7 +129,7 @@ export interface DoubleClickEventDataType {
126 serviceCommand?: Recordable 129 serviceCommand?: Recordable
127 way?: CommandWayEnum 130 way?: CommandWayEnum
128 customCommand?: string 131 customCommand?: string
129 - deviceInfo?: any 132 + deviceInfo?: DeviceInfoType
130 commandWay?: CommandDeliveryWayEnum 133 commandWay?: CommandDeliveryWayEnum
131 callType?: string 134 callType?: string
132 operationPassword?: { 135 operationPassword?: {
@@ -161,7 +164,7 @@ export interface BasicActDataType { @@ -161,7 +164,7 @@ export interface BasicActDataType {
161 attr: string 164 attr: string
162 enable?: boolean 165 enable?: boolean
163 deviceProfileId?: string | number 166 deviceProfileId?: string | number
164 - attrInfo?: ThingsModel 167 + attrInfo?: ThingsModelItemType
165 } 168 }
166 169
167 export interface FlashActDataType extends BasicActDataType { 170 export interface FlashActDataType extends BasicActDataType {
1 <script lang="ts" setup> 1 <script lang="ts" setup>
2 import { computed, ref, unref, watch, watchEffect } from 'vue' 2 import { computed, ref, unref, watch, watchEffect } from 'vue'
3 import { Select } from 'ant-design-vue' 3 import { Select } from 'ant-design-vue'
4 -import { isFunction, isString } from '@wry-smile/utils-is' 4 +import { isFunction } from '@wry-smile/utils-is'
5 import { get } from 'lodash-es' 5 import { get } from 'lodash-es'
6 -import type { DefaultOptionType, SelectValue } from 'ant-design-vue/es/select' 6 +import type { DefaultOptionType, SelectProps, SelectValue } from 'ant-design-vue/es/select'
7 import { Icon } from '@iconify/vue' 7 import { Icon } from '@iconify/vue'
8 import { useRuleFormItem } from '@/hooks/component/useFormItem' 8 import { useRuleFormItem } from '@/hooks/component/useFormItem'
9 9
@@ -18,21 +18,20 @@ const props = withDefaults( @@ -18,21 +18,20 @@ const props = withDefaults(
18 api?: ((arg?: any) => Promise<DefaultOptionType[]>) | null 18 api?: ((arg?: any) => Promise<DefaultOptionType[]>) | null
19 params?: any 19 params?: any
20 resultField?: string 20 resultField?: string
21 - labelField?: string | string[]  
22 - valueField?: string 21 + aliasField?: string
23 immediate?: boolean 22 immediate?: boolean
24 alwaysLoad?: boolean 23 alwaysLoad?: boolean
25 options?: DefaultOptionType[] 24 options?: DefaultOptionType[]
  25 + fieldNames?: SelectProps['fieldNames']
26 }>(), 26 }>(),
27 { 27 {
28 api: null, 28 api: null,
29 params: () => ({}), 29 params: () => ({}),
30 resultFiled: '', 30 resultFiled: '',
31 - labelField: 'label',  
32 - valueFiled: 'value',  
33 immediate: true, 31 immediate: true,
34 alwaysLoad: false, 32 alwaysLoad: false,
35 options: () => ([]), 33 options: () => ([]),
  34 + fieldNames: () => ({ label: 'label', value: 'value', options: 'options' }),
36 }, 35 },
37 ) 36 )
38 37
@@ -47,39 +46,29 @@ const emitData = ref<any[]>([]) @@ -47,39 +46,29 @@ const emitData = ref<any[]>([])
47 const [state] = useRuleFormItem(props, 'value', 'change', emitData) 46 const [state] = useRuleFormItem(props, 'value', 'change', emitData)
48 47
49 const getOptions = computed(() => { 48 const getOptions = computed(() => {
50 - const { labelField: _labelField = 'label', valueField = 'value', numberToString } = props 49 + const { numberToString, fieldNames } = props
  50 + const { value: valueField = 'value' } = fieldNames
51 51
52 const data = unref(optionsRef).reduce((prev, next: any) => { 52 const data = unref(optionsRef).reduce((prev, next: any) => {
53 if (next) { 53 if (next) {
54 const value = get(next, valueField) 54 const value = get(next, valueField)
55 - const { label } = getAliasLabelInfo(next, _labelField) 55 +
56 prev.push({ 56 prev.push({
57 - // ...omit(next, [labelField, valueField]),  
58 ...next, 57 ...next,
59 - label,  
60 - value: numberToString ? `${value}` : value,  
61 - }) 58 + [valueField]: numberToString ? `${value}` : value,
  59 + } as DefaultOptionType)
62 } 60 }
63 return prev 61 return prev
64 }, [] as DefaultOptionType[]) 62 }, [] as DefaultOptionType[])
  63 +
65 return data.length > 0 ? data : props.options 64 return data.length > 0 ? data : props.options
66 }) 65 })
67 66
68 -function getAliasLabelInfo(data: any, labelField: string | string[]) {  
69 - labelField = isString(labelField) ? [labelField] : labelField  
70 -  
71 - let value  
72 - let labelKey = labelField[0]  
73 - for (const label of labelField) {  
74 - value = get(data, label)  
75 - if (value) {  
76 - labelKey = label  
77 - break  
78 - }  
79 - }  
80 -  
81 - return { labelField: labelKey, label: value }  
82 -} 67 +const getFieldNames = computed<SelectProps['fieldNames']>(() => {
  68 + const { fieldNames, aliasField } = props
  69 + const { label, value, options } = fieldNames
  70 + return { label: aliasField || label, value, options }
  71 +})
83 72
84 watchEffect(() => { 73 watchEffect(() => {
85 props.immediate && !props.alwaysLoad && fetch() 74 props.immediate && !props.alwaysLoad && fetch()
@@ -149,7 +138,11 @@ function handleChange(value: SelectValue, ...args: any[]) { @@ -149,7 +138,11 @@ function handleChange(value: SelectValue, ...args: any[]) {
149 138
150 <template> 139 <template>
151 <Select 140 <Select
152 - v-bind="$attrs" v-model:value="state" :options="getOptions" @dropdown-visible-change="handleFetch" 141 + v-bind="$attrs"
  142 + v-model:value="state"
  143 + :options="getOptions"
  144 + :field-names="getFieldNames"
  145 + @dropdown-visible-change="handleFetch"
153 @change="handleChange" 146 @change="handleChange"
154 > 147 >
155 <template v-for="item in (Object.keys($slots as Slots) as SlotName[])" #[item]="data"> 148 <template v-for="item in (Object.keys($slots as Slots) as SlotName[])" #[item]="data">
@@ -181,8 +181,7 @@ export const getFormSchemas = (event: EventTypeEnum): FormSchema[] => { @@ -181,8 +181,7 @@ export const getFormSchemas = (event: EventTypeEnum): FormSchema[] => {
181 return { 181 return {
182 api: getThingsModelServices, 182 api: getThingsModelServices,
183 params: deviceProfileId, 183 params: deviceProfileId,
184 - labelField: 'functionName',  
185 - valueField: 'identifier', 184 + fieldNames: { label: 'functionName', value: 'identifier' },
186 onSelect(value: string, options: ThingsModel) { 185 onSelect(value: string, options: ThingsModel) {
187 formModel[FormFieldsEnum.THINGS_MODEL] = value ? options : null 186 formModel[FormFieldsEnum.THINGS_MODEL] = value ? options : null
188 formModel.callType = options.callType 187 formModel.callType = options.callType
@@ -3,9 +3,10 @@ import { getDeviceAttributes, getListByDeviceProfileIds } from '@/api/device' @@ -3,9 +3,10 @@ import { getDeviceAttributes, getListByDeviceProfileIds } from '@/api/device'
3 import type { DeviceItemType, ThingsModelItemType } from '@/api/device/model' 3 import type { DeviceItemType, ThingsModelItemType } from '@/api/device/model'
4 import type { FormSchema } from '@/components/Form' 4 import type { FormSchema } from '@/components/Form'
5 import { ComponentEnum } from '@/components/Form/src/enum' 5 import { ComponentEnum } from '@/components/Form/src/enum'
6 -import { ContentDataFieldsEnum, ContentDataFieldsNameEnum } from '@/enums/datasource' 6 +import { ContentDataFieldsEnum, ContentDataFieldsNameEnum, DataTypeEnum } from '@/enums/datasource'
7 import { useContentDataStoreWithOut } from '@/store/modules/contentData' 7 import { useContentDataStoreWithOut } from '@/store/modules/contentData'
8 import type { ProductAndDevice } from '@/api/content/model' 8 import type { ProductAndDevice } from '@/api/content/model'
  9 +import { ControlComponentEnum } from '@/core/Library/packages/Control'
9 10
10 const contentDataStore = useContentDataStoreWithOut() 11 const contentDataStore = useContentDataStoreWithOut()
11 export const formSchemas = (componentKey?: string): FormSchema[] => { 12 export const formSchemas = (componentKey?: string): FormSchema[] => {
@@ -51,15 +52,15 @@ export const formSchemas = (componentKey?: string): FormSchema[] => { @@ -51,15 +52,15 @@ export const formSchemas = (componentKey?: string): FormSchema[] => {
51 deviceProfileIds: (unref(contentDataStore.getProductAndDevice) || []).map((item: ProductAndDevice) => item?.profileId), 52 deviceProfileIds: (unref(contentDataStore.getProductAndDevice) || []).map((item: ProductAndDevice) => item?.profileId),
52 organizationId, 53 organizationId,
53 }, 54 },
54 - labelField: ['alias', 'name'],  
55 - valueField: 'tbDeviceId', 55 + aliasField: 'alias',
  56 + fieldNames: { label: 'name', value: 'tbDeviceId' },
56 onSelect(value: string, option: DeviceItemType) { 57 onSelect(value: string, option: DeviceItemType) {
57 formModel[ContentDataFieldsEnum.DEVICE_PROFILE_ID] = value ? option.deviceProfileId : null 58 formModel[ContentDataFieldsEnum.DEVICE_PROFILE_ID] = value ? option.deviceProfileId : null
58 - formModel[ContentDataFieldsEnum.DEVICE_INFO] = value && option ? { code: option.code, transportType: option.transportType, deviceType: option.deviceType, deviceProfileId: option.deviceProfileId, label: option.alias || option.name } : null 59 + formModel[ContentDataFieldsEnum.DEVICE_INFO] = value && option ? { code: option.code, transportType: option.transportType, deviceType: option.deviceType, deviceProfileId: option.deviceProfileId, deviceName: option.alias || option.name } : null
59 formModel[ContentDataFieldsEnum.ATTR] = null 60 formModel[ContentDataFieldsEnum.ATTR] = null
60 }, 61 },
61 - filterOption: (inputValue: string, option: Record<'label' | 'value', string>) =>  
62 - option.label.includes(inputValue), 62 + filterOption: (inputValue: string, option: DeviceItemType) =>
  63 + option.alias?.includes?.(inputValue) || option.name?.includes?.(inputValue),
63 } 64 }
64 }, 65 },
65 }, 66 },
@@ -75,21 +76,20 @@ export const formSchemas = (componentKey?: string): FormSchema[] => { @@ -75,21 +76,20 @@ export const formSchemas = (componentKey?: string): FormSchema[] => {
75 api: async (params: string) => { 76 api: async (params: string) => {
76 if (!deviceProfileId) return [] 77 if (!deviceProfileId) return []
77 const options = await getDeviceAttributes(params) 78 const options = await getDeviceAttributes(params)
78 - if (componentKey === 'Switch') { // 开关只返回bool 79 + if (componentKey === ControlComponentEnum.SWITCH) { // 开关只返回bool
79 return options.filter((item) => { 80 return options.filter((item) => {
80 - return item.detail.dataType.type === 'BOOL' 81 + return item.detail.dataType.type === DataTypeEnum.BOOL
81 }) 82 })
82 } 83 }
83 return options 84 return options
84 }, 85 },
85 params: deviceProfileId, 86 params: deviceProfileId,
86 - labelField: 'name',  
87 - valueField: 'identifier', 87 + fieldNames: { label: 'name', value: 'identifier' },
88 onSelect(value: string, option: ThingsModelItemType) { 88 onSelect(value: string, option: ThingsModelItemType) {
89 formModel[ContentDataFieldsEnum.ATTR_INFO] = value && option ? toRaw(unref(option)) : null 89 formModel[ContentDataFieldsEnum.ATTR_INFO] = value && option ? toRaw(unref(option)) : null
90 }, 90 },
91 - filterOption: (inputValue: string, option: Record<'label' | 'value', string>) =>  
92 - option.label.includes(inputValue), 91 + filterOption: (inputValue: string, option: ThingsModelItemType) =>
  92 + option.name.includes(inputValue),
93 } 93 }
94 }, 94 },
95 }, 95 },
@@ -121,14 +121,14 @@ export const formSchemas: FormSchema[] = [ @@ -121,14 +121,14 @@ export const formSchemas: FormSchema[] = [
121 deviceProfileIds: unref(contentDataStore.getProductIds), 121 deviceProfileIds: unref(contentDataStore.getProductIds),
122 organizationId, 122 organizationId,
123 }, 123 },
124 - labelField: ['alias', 'name'],  
125 - valueField: 'id', 124 + aliasField: 'alias',
  125 + fieldNames: { label: 'name', value: 'id' },
126 maxTagCount: 4, 126 maxTagCount: 4,
127 onSelect(value: string, option: DeviceItemType) { 127 onSelect(value: string, option: DeviceItemType) {
128 formModel[AlarmListFieldsEnum.DEVICE_PROFILE_ID] = value ? option.deviceProfileId : null 128 formModel[AlarmListFieldsEnum.DEVICE_PROFILE_ID] = value ? option.deviceProfileId : null
129 }, 129 },
130 - filterOption: (inputValue: string, option: Record<'label' | 'value', string>) =>  
131 - option.label.includes(inputValue), 130 + filterOption: (inputValue: string, option: DeviceItemType) =>
  131 + option.alias?.includes?.(inputValue) || option.name?.includes?.(inputValue),
132 } 132 }
133 }, 133 },
134 }, 134 },
1 const data = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] 1 const data = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
2 const seriesList = [ 2 const seriesList = [
3 -  
4 { value: 120, name: '123', itemStyle: { color: '#5470c6' } }, 3 { value: 120, name: '123', itemStyle: { color: '#5470c6' } },
5 { value: 150, name: '456', itemStyle: { color: '#5470c6' } }, 4 { value: 150, name: '456', itemStyle: { color: '#5470c6' } },
6 { value: 40, name: '789', itemStyle: { color: '#5470c6' } }, 5 { value: 40, name: '789', itemStyle: { color: '#5470c6' } },
@@ -3,6 +3,7 @@ import { isLightboxMode } from '@/utils/env' @@ -3,6 +3,7 @@ import { isLightboxMode } from '@/utils/env'
3 3
4 export const getDefaultOption = (): EChartsOption => { 4 export const getDefaultOption = (): EChartsOption => {
5 return { 5 return {
  6 + legend: [],
6 xAxis: { 7 xAxis: {
7 type: 'category', 8 type: 'category',
8 data: isLightboxMode() ? [] : ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], 9 data: isLightboxMode() ? [] : ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
@@ -10,6 +10,7 @@ import type { SubscriptionData } from '@/core/websocket/type/message' @@ -10,6 +10,7 @@ import type { SubscriptionData } from '@/core/websocket/type/message'
10 import { SocketSubscriberEnum } from '@/enums/datasource' 10 import { SocketSubscriberEnum } from '@/enums/datasource'
11 import { formatToDateTime } from '@/utils/dateUtil' 11 import { formatToDateTime } from '@/utils/dateUtil'
12 import { useLatestMessageValue } from '@/core/Library/hook/useLatestMessageValue' 12 import { useLatestMessageValue } from '@/core/Library/hook/useLatestMessageValue'
  13 +import type { CommandSource } from '@/core/websocket/processor'
13 14
14 const props = defineProps<{ 15 const props = defineProps<{
15 config: CreateComponentType 16 config: CreateComponentType
@@ -49,7 +50,10 @@ function sliceData(data: any[], maxLength = 20) { @@ -49,7 +50,10 @@ function sliceData(data: any[], maxLength = 20) {
49 return data 50 return data
50 } 51 }
51 52
52 -const handlerTimeSeriesData = (message: SubscriptionData, attr: string) => { 53 +const handlerTimeSeriesData = (commandSource: CommandSource, message: SubscriptionData, attr: string) => {
  54 + const { data } = commandSource
  55 + const { attrInfo, deviceInfo } = data as NodeDataDataSourceJsonType
  56 + const { deviceName } = deviceInfo || {}
53 const { ts, latestValue } = useLatestMessageValue(message, attr) 57 const { ts, latestValue } = useLatestMessageValue(message, attr)
54 const option = unref(chartInstance)?.getOption() as EChartsOption 58 const option = unref(chartInstance)?.getOption() as EChartsOption
55 const xAxisData = ((option.xAxis as XAXisComponentOption[])?.[0] as { data: string[] }).data 59 const xAxisData = ((option.xAxis as XAXisComponentOption[])?.[0] as { data: string[] }).data
@@ -57,6 +61,9 @@ const handlerTimeSeriesData = (message: SubscriptionData, attr: string) => { @@ -57,6 +61,9 @@ const handlerTimeSeriesData = (message: SubscriptionData, attr: string) => {
57 xAxisData.push(formatToDateTime(ts)) 61 xAxisData.push(formatToDateTime(ts))
58 seriesData.push(latestValue) 62 seriesData.push(latestValue)
59 unref(chartInstance)?.setOption({ 63 unref(chartInstance)?.setOption({
  64 + title: {
  65 + text: `${deviceName}-${attrInfo.name}`,
  66 + },
60 xAxis: { data: sliceData(xAxisData) }, 67 xAxis: { data: sliceData(xAxisData) },
61 series: { data: sliceData(seriesData) }, 68 series: { data: sliceData(seriesData) },
62 } as EChartsOption) 69 } as EChartsOption)
@@ -69,7 +76,7 @@ const { onMessage } = useOnMessage({ @@ -69,7 +76,7 @@ const { onMessage } = useOnMessage({
69 const { queryType } = chartOption || {} 76 const { queryType } = chartOption || {}
70 77
71 if (queryType === SocketSubscriberEnum.TS_SUB_CMDS) 78 if (queryType === SocketSubscriberEnum.TS_SUB_CMDS)
72 - handlerTimeSeriesData(message.data, attr) 79 + handlerTimeSeriesData(commandSource, message.data, attr)
73 else if (queryType === SocketSubscriberEnum.HISTORY_CMDS) 80 else if (queryType === SocketSubscriberEnum.HISTORY_CMDS)
74 handleHistoryData(message.data, attr) 81 handleHistoryData(message.data, attr)
75 }, 82 },
  1 +export enum ControlComponentEnum {
  2 + SWITCH = 'Switch',
  3 + PARAMETER_SETTINGS = 'ParameterSettings',
  4 +}
  5 +
  6 +export enum ControlComponentNameEnum {
  7 + SWITCH = '开关',
  8 + PARAMETER_SETTINGS = '参数设置',
  9 +}