Commit ea180dd732cdc56be5366c8ec9d242d4781b87c8

Authored by dev001
2 parents acc9ab19 289e59e2

Merge branch 'perf/main_dev' into local_dev_ft

@@ -4,6 +4,8 @@ export interface ProductAndDevice { @@ -4,6 +4,8 @@ export interface ProductAndDevice {
4 name: string 4 name: string
5 profileName?: string 5 profileName?: string
6 profileId: string 6 profileId: string
  7 + transportType?: string
  8 + deviceType?: string
7 deviceList: { 9 deviceList: {
8 deviceId: string 10 deviceId: string
9 name: string 11 name: string
@@ -55,8 +55,10 @@ export interface ChartOptionType { @@ -55,8 +55,10 @@ export interface ChartOptionType {
55 unit?: string 55 unit?: string
56 } 56 }
57 57
58 -export interface FlowMeterOptionType {  
59 - 58 +export interface FlowMeterColorItemType {
  59 + key: string
  60 + value: string
  61 + label: string
60 } 62 }
61 63
62 export interface VideoOptionType { 64 export interface VideoOptionType {
@@ -97,10 +99,9 @@ export interface NodeDataDataSourceJsonType { @@ -97,10 +99,9 @@ export interface NodeDataDataSourceJsonType {
97 deviceProfileId?: string 99 deviceProfileId?: string
98 label?: string 100 label?: string
99 } 101 }
100 - circularFlowMeterOption?: FlowMeterOptionType// 圆形水球图数据暂定any  
101 - additional?: any// 圆形水球图颜色配置数据暂定any  
102 - rectFlowMeterOption?: FlowMeterOptionType// 方形水球图颜色配置数据暂定any  
103 - thermometerOption?: any// 温度计数据暂定any 102 + circularFlowMeterOption?: FlowMeterColorItemType[] // 圆形水球图数据暂定any
  103 + rectFlowMeterOption?: FlowMeterColorItemType[] // 方形水球图颜色配置数据暂定any
  104 +
104 } 105 }
105 106
106 export interface DeviceCommandListItemType { 107 export interface DeviceCommandListItemType {
@@ -12,6 +12,15 @@ import { ThingsModelForm } from '@/core/Library/components/ThingsModelForm' @@ -12,6 +12,15 @@ import { ThingsModelForm } from '@/core/Library/components/ThingsModelForm'
12 import { useMessage } from '@/hooks/web/useMessage' 12 import { useMessage } from '@/hooks/web/useMessage'
13 import type { StructJSON } from '@/api/device/model' 13 import type { StructJSON } from '@/api/device/model'
14 14
  15 +interface ServiceInfo {
  16 + title?: string
  17 + serviceCommand?: Object
  18 + inputData?: []
  19 + transportType?: string
  20 + callType?: string
  21 + code?: string
  22 +}
  23 +
15 const visible = ref<boolean>(false) 24 const visible = ref<boolean>(false)
16 25
17 const { createMessage } = useMessage() 26 const { createMessage } = useMessage()
@@ -33,12 +42,13 @@ const deviceTitle = ref<string | undefined>()// 设备名称 @@ -33,12 +42,13 @@ const deviceTitle = ref<string | undefined>()// 设备名称
33 42
34 const isPasswordInfo = ref<{ checked?: boolean; value?: string | number; label?: string }>({})// 是否需要操作密码才进行命令下发 43 const isPasswordInfo = ref<{ checked?: boolean; value?: string | number; label?: string }>({})// 是否需要操作密码才进行命令下发
35 44
36 -const serviceInfo = reactive<any>({ 45 +const serviceInfo = reactive<ServiceInfo>({
37 title: '', 46 title: '',
38 serviceCommand: {}, 47 serviceCommand: {},
39 inputData: [], 48 inputData: [],
40 transportType: '', 49 transportType: '',
41 callType: '', 50 callType: '',
  51 + code: '',
42 }) 52 })
43 53
44 const [register, { getFieldsValue, validate, setFieldsValue, updateSchema, setProps }] = useForm({ // 自定义下发值 54 const [register, { getFieldsValue, validate, setFieldsValue, updateSchema, setProps }] = useForm({ // 自定义下发值
@@ -64,13 +74,12 @@ const [registerPassword, { getFieldsValue: getPasswordValue, validate: validateP @@ -64,13 +74,12 @@ const [registerPassword, { getFieldsValue: getPasswordValue, validate: validateP
64 labelWidth: 110, 74 labelWidth: 110,
65 }) 75 })
66 76
67 -const getServiceInfo = async (deviceProfileId: string, transportType: string, service?: string, serviceCommand?: Recordable) => { 77 +const getServiceInfo = async (deviceProfileId: string, service?: string, serviceCommand?: Recordable) => {
68 isInputData.value = true 78 isInputData.value = true
69 const functionJson: any = await getThingsModelServices(deviceProfileId) 79 const functionJson: any = await getThingsModelServices(deviceProfileId)
70 serviceInfo.inputData = functionJson.filter((item: any) => item.identifier === service)?.[0].functionJson.inputData 80 serviceInfo.inputData = functionJson.filter((item: any) => item.identifier === service)?.[0].functionJson.inputData
71 serviceInfo.title = functionJson[0].functionName 81 serviceInfo.title = functionJson[0].functionName
72 serviceInfo.serviceCommand = serviceCommand 82 serviceInfo.serviceCommand = serviceCommand
73 - serviceInfo.transportType = transportType  
74 } 83 }
75 84
76 // 获取设备信息 85 // 获取设备信息
@@ -102,11 +111,14 @@ const open = async (_data: SingleClickEventDataType) => { @@ -102,11 +111,14 @@ const open = async (_data: SingleClickEventDataType) => {
102 isShowActionType.value = !!actionType // 判断modBUS类型时 物模型是否填写扩展描述 111 isShowActionType.value = !!actionType // 判断modBUS类型时 物模型是否填写扩展描述
103 serviceInfo.callType = callType // 服务命令调用方式 是同步还是异步 112 serviceInfo.callType = callType // 服务命令调用方式 是同步还是异步
104 113
  114 + serviceInfo.transportType = transportType
  115 + serviceInfo.code = code
  116 +
105 visible.value = true 117 visible.value = true
106 118
107 if (transportType === TransportTypeEnum.TCP) { 119 if (transportType === TransportTypeEnum.TCP) {
108 if (commandWay === CommandDeliveryWayEnum.SERVICE) { // 命令下发方式是服务或则自定义调用 120 if (commandWay === CommandDeliveryWayEnum.SERVICE) { // 命令下发方式是服务或则自定义调用
109 - getServiceInfo(deviceProfileId, transportType, service, serviceCommand) 121 + getServiceInfo(deviceProfileId, service, serviceCommand)
110 } 122 }
111 else if (commandWay === CommandDeliveryWayEnum.CUSTOM) { // 自定义 123 else if (commandWay === CommandDeliveryWayEnum.CUSTOM) { // 自定义
112 await nextTick() 124 await nextTick()
@@ -138,7 +150,7 @@ const open = async (_data: SingleClickEventDataType) => { @@ -138,7 +150,7 @@ const open = async (_data: SingleClickEventDataType) => {
138 isShowModBUS.value = false 150 isShowModBUS.value = false
139 151
140 // 命令下发方式是服务或则自定义调用 152 // 命令下发方式是服务或则自定义调用
141 - if (commandWay === CommandDeliveryWayEnum.SERVICE) { getServiceInfo(deviceProfileId, transportType, service, serviceCommand) } 153 + if (commandWay === CommandDeliveryWayEnum.SERVICE) { getServiceInfo(deviceProfileId, service, serviceCommand) }
142 154
143 else if (commandWay === CommandDeliveryWayEnum.CUSTOM) { 155 else if (commandWay === CommandDeliveryWayEnum.CUSTOM) {
144 await nextTick() 156 await nextTick()
@@ -173,7 +185,6 @@ const handleSubmit = async () => { @@ -173,7 +185,6 @@ const handleSubmit = async () => {
173 return 185 return
174 } 186 }
175 } 187 }
176 -  
177 if (serviceInfo.callType === 'SYNC') { // 服务命令调用方式 是同步 需要调用设备是否在线才能下发 188 if (serviceInfo.callType === 'SYNC') { // 服务命令调用方式 是同步 需要调用设备是否在线才能下发
178 const res = await getDeviceActiveTime(dataSourceJson.value.deviceId) 189 const res = await getDeviceActiveTime(dataSourceJson.value.deviceId)
179 const { value } = res 190 const { value } = res
@@ -191,6 +202,11 @@ const handleSubmit = async () => { @@ -191,6 +202,11 @@ const handleSubmit = async () => {
191 createMessage.warning('当前物模型扩展描述没有填写') 202 createMessage.warning('当前物模型扩展描述没有填写')
192 return 203 return
193 } 204 }
  205 +
  206 + if (!serviceInfo.code) {
  207 + createMessage.error('当前缺少设备地址码')
  208 + return
  209 + }
194 const oldValue = getFieldsValue()[unref(formField)] 210 const oldValue = getFieldsValue()[unref(formField)]
195 modBUSForm.value.registerNumber = 1 211 modBUSForm.value.registerNumber = 1
196 modBUSForm.value.registerValues = [oldValue] 212 modBUSForm.value.registerValues = [oldValue]
@@ -237,7 +253,7 @@ const handleSubmit = async () => { @@ -237,7 +253,7 @@ const handleSubmit = async () => {
237 sendValue.value = values 253 sendValue.value = values
238 } 254 }
239 else { 255 else {
240 - const values = typeof JSON.parse(getFieldsValue().sendValue) ? JSON.parse(getFieldsValue().sendValue) : getFieldsValue().sendValue || {} 256 + const values = serviceInfo.transportType === TransportTypeEnum.TCP ? getFieldsValue().sendValue : JSON.parse(getFieldsValue().sendValue) || {}
241 sendValue.value = values 257 sendValue.value = values
242 } 258 }
243 } 259 }
@@ -37,8 +37,6 @@ export const getFormSchemas = (event: EventTypeEnum): FormSchema[] => { @@ -37,8 +37,6 @@ export const getFormSchemas = (event: EventTypeEnum): FormSchema[] => {
37 const { deviceProfileId, deviceInfo } = dataSourceJson || {} 37 const { deviceProfileId, deviceInfo } = dataSourceJson || {}
38 // transportType:判断是什么类型的设备 code:设备地址码 deviceType:设备类型 38 // transportType:判断是什么类型的设备 code:设备地址码 deviceType:设备类型
39 const { transportType, deviceType } = deviceInfo || {} 39 const { transportType, deviceType } = deviceInfo || {}
40 - // if (!deviceProfileId)  
41 - // createMessage.warn('请先绑定数据源')  
42 40
43 return [ 41 return [
44 { 42 {
1 <script setup lang="ts"> 1 <script setup lang="ts">
2 import { ref } from 'vue' 2 import { ref } from 'vue'
  3 +import type { RenderComponentExposeType } from '@/core/Library/types'
  4 +import { useOnMessage } from '@/core/Library/hook/useOnMessage'
  5 +import { useLatestMessageValue } from '@/core/Library/hook/useLatestMessageValue'
  6 +import type { CommandSource } from '@/core/websocket/processor'
  7 +import type { SubscriptionUpdateMsg } from '@/core/websocket/type/message'
  8 +import type { NodeDataDataSourceJsonType } from '@/api/node/model'
3 9
4 const imageSrc = ref('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="24" height="24" viewBox="0 0 24 24"%3E%3Cpath fill="currentColor" d="M19 2H5a3.009 3.009 0 0 0-3 3v8.86l3.88-3.88a3.075 3.075 0 0 1 4.24 0l2.871 2.887l.888-.888a3.008 3.008 0 0 1 4.242 0L22 15.86V5a3.009 3.009 0 0 0-3-3z" opacity=".5"%2F%3E%3Cpath fill="currentColor" d="M10.12 9.98a3.075 3.075 0 0 0-4.24 0L2 13.86V19a3.009 3.009 0 0 0 3 3h14a3 3 0 0 0 2.16-.92L10.12 9.98z"%2F%3E%3Cpath fill="currentColor" d="m22 15.858l-3.879-3.879a3.008 3.008 0 0 0-4.242 0l-.888.888l8.165 8.209c.542-.555.845-1.3.844-2.076v-3.142z" opacity=".25"%2F%3E%3C%2Fsvg%3E') 10 const imageSrc = ref('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="24" height="24" viewBox="0 0 24 24"%3E%3Cpath fill="currentColor" d="M19 2H5a3.009 3.009 0 0 0-3 3v8.86l3.88-3.88a3.075 3.075 0 0 1 4.24 0l2.871 2.887l.888-.888a3.008 3.008 0 0 1 4.242 0L22 15.86V5a3.009 3.009 0 0 0-3-3z" opacity=".5"%2F%3E%3Cpath fill="currentColor" d="M10.12 9.98a3.075 3.075 0 0 0-4.24 0L2 13.86V19a3.009 3.009 0 0 0 3 3h14a3 3 0 0 0 2.16-.92L10.12 9.98z"%2F%3E%3Cpath fill="currentColor" d="m22 15.858l-3.879-3.879a3.008 3.008 0 0 0-4.242 0l-.888.888l8.165 8.209c.542-.555.845-1.3.844-2.076v-3.142z" opacity=".25"%2F%3E%3C%2Fsvg%3E')
5 -defineExpose() 11 +
  12 +const onReceiveDataSourceMessage = (commandSource: CommandSource, message: SubscriptionUpdateMsg) => {
  13 + const { data } = commandSource
  14 + const { attr } = data as NodeDataDataSourceJsonType
  15 + const { latestValue } = useLatestMessageValue(message.data, attr)
  16 + imageSrc.value = latestValue
  17 +}
  18 +
  19 +const { onMessage } = useOnMessage({
  20 + onReceiveDataSourceMessage,
  21 +})
  22 +defineExpose<RenderComponentExposeType>({ onMessage })
6 </script> 23 </script>
7 24
8 <template> 25 <template>
9 <div class="w-full h-full flex justify-center items-center"> 26 <div class="w-full h-full flex justify-center items-center">
10 - <img class="w-50 h-50" :src="imageSrc"> 27 + <img class="w-full" :src="imageSrc">
11 </div> 28 </div>
12 </template> 29 </template>
1 <script setup lang="ts"> 1 <script setup lang="ts">
2 import { Button, Divider, Space } from 'ant-design-vue' 2 import { Button, Divider, Space } from 'ant-design-vue'
3 import { onMounted, ref, unref } from 'vue' 3 import { onMounted, ref, unref } from 'vue'
  4 +import { defaultFlowmetmerColorConfig } from './form.config'
4 import { DataSourceForm } from '@/core/Library/components/PublicForm/components/DataSourceForm' 5 import { DataSourceForm } from '@/core/Library/components/PublicForm/components/DataSourceForm'
5 import { useNodeData } from '@/core/Library/hook/useNodeData' 6 import { useNodeData } from '@/core/Library/hook/useNodeData'
6 import type { ConfigComponentProps } from '@/core/Library/types' 7 import type { ConfigComponentProps } from '@/core/Library/types'
7 import { useMessage } from '@/hooks/web/useMessage' 8 import { useMessage } from '@/hooks/web/useMessage'
8 -import type { NodeDataDataSourceJsonType } from '@/api/node/model' 9 +import type { FlowMeterColorItemType, NodeDataDataSourceJsonType } from '@/api/node/model'
9 import { useSavePageContent } from '@/core/Library/hook/useSavePageContent' 10 import { useSavePageContent } from '@/core/Library/hook/useSavePageContent'
10 -  
11 const props = defineProps<ConfigComponentProps>() 11 const props = defineProps<ConfigComponentProps>()
12 12
13 const { createMessage } = useMessage() 13 const { createMessage } = useMessage()
14 14
15 const loading = ref(false) 15 const loading = ref(false)
16 16
17 -const colorConfig = ref([  
18 - {  
19 - label: '背景色',  
20 - value: '#8BADCB',  
21 - },  
22 - {  
23 - label: '颜色一',  
24 - value: '#4579e2',  
25 - },  
26 - {  
27 - label: '颜色二',  
28 - value: '#3461c1',  
29 - },  
30 - {  
31 - label: '颜色三',  
32 - value: '#2d55aa',  
33 - },  
34 -]) 17 +const colorConfig = ref<FlowMeterColorItemType[]>(defaultFlowmetmerColorConfig)
35 18
36 -const nodeDataActinType = useNodeData({ cell: props.cell!, immediate: true }) 19 +const nodeDataActinType = useNodeData({ cell: props.cell!, immediate: false })
37 20
38 const { getNodeAllData, saveNodeAllData, getNodeData } = nodeDataActinType 21 const { getNodeAllData, saveNodeAllData, getNodeData } = nodeDataActinType
39 22
@@ -57,11 +40,11 @@ const handleSubmit = async () => { @@ -57,11 +40,11 @@ const handleSubmit = async () => {
57 40
58 onMounted(async () => { 41 onMounted(async () => {
59 await getNodeAllData() 42 await getNodeAllData()
60 - if (unref(getNodeData)?.dataSourceJson) {  
61 - const { circularFlowMeterOption, additional } = unref(getNodeData)?.dataSourceJson as NodeDataDataSourceJsonType  
62 - colorConfig.value = additional || unref(colorConfig)  
63 - if (!circularFlowMeterOption) return  
64 - dataSourceFormRef.value?.setFieldsValue(circularFlowMeterOption) 43 + const { dataSourceJson } = unref(getNodeData) || {}
  44 + if (dataSourceJson) {
  45 + const { circularFlowMeterOption } = unref(getNodeData)?.dataSourceJson as NodeDataDataSourceJsonType
  46 + colorConfig.value = circularFlowMeterOption || unref(colorConfig)
  47 + unref(dataSourceFormRef)?.setFieldsValue(unref(getNodeData)?.dataSourceJson)
65 } 48 }
66 }) 49 })
67 </script> 50 </script>
@@ -69,18 +52,20 @@ onMounted(async () => { @@ -69,18 +52,20 @@ onMounted(async () => {
69 <template> 52 <template>
70 <main class="w-full h-full flex flex-col px-2 py-4 box-border"> 53 <main class="w-full h-full flex flex-col px-2 py-4 box-border">
71 <main class="form-container"> 54 <main class="form-container">
72 - <Divider orientation="left"> 55 + <Divider orientation="left" class="!text-sm">
73 数据源 56 数据源
74 </Divider> 57 </Divider>
75 <DataSourceForm ref="dataSourceFormRef" /> 58 <DataSourceForm ref="dataSourceFormRef" />
76 </main> 59 </main>
77 <main class="form-container mt-2"> 60 <main class="form-container mt-2">
78 - <Divider orientation="left"> 61 + <Divider orientation="left" class="!text-sm">
79 流量计配置 62 流量计配置
80 </Divider> 63 </Divider>
81 <Space direction="vertical"> 64 <Space direction="vertical">
82 - <div v-for="(item, index) in colorConfig" :key="index" class="mt-3 ml-5">  
83 - <span>{{ item.label }}</span> 65 + <div v-for="(item, index) in colorConfig" :key="index" class="mt-3 ml-5 flex">
  66 + <div class="w-20">
  67 + {{ item.label }}
  68 + </div>
84 <input v-model="item.value" class="ml-3" type="color"> 69 <input v-model="item.value" class="ml-3" type="color">
85 </div> 70 </div>
86 </Space> 71 </Space>
@@ -91,3 +76,4 @@ onMounted(async () => { @@ -91,3 +76,4 @@ onMounted(async () => {
91 </Button> 76 </Button>
92 </main> 77 </main>
93 </template> 78 </template>
  79 +
  1 +import type { FlowMeterColorItemType } from '@/api/node/model'
  2 +
  3 +export enum FormFieldsEnum {
  4 + BACKGROUND = 'background',
  5 + COLOR_FIRST = 'colorFirst',
  6 + COLOR_SECOND = 'colorSecond',
  7 + COLOR_THIRD = 'colorThird',
  8 +}
  9 +
  10 +export const colorItemName = {
  11 + [FormFieldsEnum.BACKGROUND]: '背景颜色',
  12 + [FormFieldsEnum.COLOR_FIRST]: '颜色一',
  13 + [FormFieldsEnum.COLOR_SECOND]: '颜色二',
  14 + [FormFieldsEnum.COLOR_THIRD]: '颜色三',
  15 +}
  16 +
  17 +export const defaultFlowmetmerColorConfig: FlowMeterColorItemType[] = [
  18 + {
  19 + key: FormFieldsEnum.BACKGROUND,
  20 + label: colorItemName[FormFieldsEnum.BACKGROUND],
  21 + value: '#0d396b',
  22 + },
  23 + {
  24 + key: FormFieldsEnum.COLOR_FIRST,
  25 + label: colorItemName[FormFieldsEnum.COLOR_FIRST],
  26 + value: '#25498b',
  27 + },
  28 + {
  29 + key: FormFieldsEnum.COLOR_SECOND,
  30 + label: colorItemName[FormFieldsEnum.COLOR_SECOND],
  31 + value: '#0d5cb8',
  32 + },
  33 + {
  34 + key: FormFieldsEnum.COLOR_THIRD,
  35 + label: colorItemName[FormFieldsEnum.COLOR_THIRD],
  36 + value: '#008adf',
  37 + },
  38 +]
1 -const value = 40 // 水球图数据源  
2 -export const defaultOption = {  
3 - series: [  
4 - {  
5 - type: 'liquidFill',  
6 - radius: '90%',  
7 - data: [  
8 - value / 100,  
9 - {  
10 - value: (value - 10) / 100,  
11 - direction: 'left', 1 +import { FormFieldsEnum, defaultFlowmetmerColorConfig } from './form.config'
  2 +import { isLightboxMode } from '@/utils/env'
  3 +import type { FlowMeterColorItemType } from '@/api/node/model'
  4 +
  5 +export function getSetValue(value: number) {
  6 + return [
  7 + value / 100,
  8 + (value - 10) / 100,
  9 + (value - 20) / 100,
  10 + ]
  11 +}
  12 +export const setOption = (value: number = 40, circularFlowMeterOption: FlowMeterColorItemType[] = defaultFlowmetmerColorConfig) => {
  13 + const colorMap = (isLightboxMode() ? circularFlowMeterOption : defaultFlowmetmerColorConfig).reduce((prev, next) => ({ ...prev, [next.key]: next.value }), {} as Record<FormFieldsEnum, string>)
  14 + return {
  15 + series: [
  16 + {
  17 + type: 'liquidFill',
  18 + radius: '90%',
  19 + data: getSetValue(value),
  20 + color: [colorMap[FormFieldsEnum.COLOR_FIRST], colorMap[FormFieldsEnum.COLOR_SECOND], colorMap[FormFieldsEnum.COLOR_THIRD]],
  21 + itemStyle: {
  22 + opacity: 0.6,
12 }, 23 },
13 - ],  
14 - backgroundStyle: {  
15 - borderWidth: 1,  
16 - color: 'transparent', // 这里设置背景色  
17 - },  
18 - label: {  
19 - color: '#27e5f1',  
20 - insideColor: '#f7e8c1',  
21 - left: '50%',  
22 - top: '40%',  
23 - textAlign: 'center',  
24 - fontSize: 20,  
25 - fontWeight: 600,  
26 - textBorderColor: 'rgba(0, 0, 0, 0)',  
27 - textShadowColor: '#000',  
28 - textShadowBlur: 0,  
29 - textShadowOffsetX: 0,  
30 - textShadowOffsetY: 1,  
31 - },  
32 - color: [  
33 - {  
34 - type: 'linear',  
35 - x: 0,  
36 - y: 0,  
37 - x2: 1,  
38 - y2: 1,  
39 - colorStops: [  
40 - {  
41 - offset: 0,  
42 - color: '#324791', // 这里设置水球波动 0% 处的颜色  
43 - }, {  
44 - offset: 1,  
45 - color: '#449090', // 这里设置水球波动 100% 处的颜色  
46 - }],  
47 - global: false, 24 + backgroundStyle: {
  25 + borderWidth: 1,
  26 + color: colorMap[FormFieldsEnum.BACKGROUND], // 这里设置背景色
48 }, 27 },
49 - ],  
50 - outline: {  
51 - show: true,  
52 - borderDistance: 1,  
53 - itemStyle: {  
54 - borderWidth: 0,  
55 - color: {  
56 - type: 'linear',  
57 - x: 0,  
58 - y: 0,  
59 - x2: 1,  
60 - y2: 0,  
61 - colorStops: [  
62 - {  
63 - offset: 0, color: '#0b2355', // 这里设置水球外边框 0% 处的颜色  
64 - },  
65 - {  
66 - offset: 1, color: '#195b9d', // 这里设置水球外边框 100% 处的颜色  
67 - },  
68 - ],  
69 - global: false, 28 + emphasis: {
  29 + itemStyle: {
  30 + opacity: 0.9,
  31 + },
  32 + },
  33 + label: {
  34 + color: '#fff',
  35 + insideColor: '#f7e8c1',
  36 + left: '50%',
  37 + top: '40%',
  38 + textAlign: 'center',
  39 + fontSize: 20,
  40 + fontWeight: 600,
  41 + textBorderColor: 'rgba(0, 0, 0, 0)',
  42 + textShadowColor: '#000',
  43 + textShadowBlur: 0,
  44 + textShadowOffsetX: 0,
  45 + textShadowOffsetY: 1,
  46 + },
  47 +
  48 + outline: {
  49 + show: true,
  50 + borderDistance: 1,
  51 + itemStyle: {
  52 + borderWidth: 0,
  53 + color: {
  54 + type: 'linear',
  55 + x: 0,
  56 + y: 0,
  57 + x2: 1,
  58 + y2: 0,
  59 + colorStops: [
  60 + {
  61 + offset: 0,
  62 + color: '#0b2355', // 这里设置水球外边框 0% 处的颜色
  63 + },
  64 + {
  65 + offset: 1,
  66 + color: '#195b9d', // 这里设置水球外边框 100% 处的颜色
  67 + },
  68 + ],
  69 + global: false,
  70 + },
70 }, 71 },
71 }, 72 },
72 }, 73 },
73 - },  
74 - ], 74 + ],
  75 + }
75 } 76 }
@@ -2,17 +2,22 @@ @@ -2,17 +2,22 @@
2 import { computed, onMounted, onUnmounted, ref, unref } from 'vue' 2 import { computed, onMounted, onUnmounted, ref, unref } from 'vue'
3 import type { ECharts, EChartsOption } from 'echarts' 3 import type { ECharts, EChartsOption } from 'echarts'
4 import { init } from 'echarts' 4 import { init } from 'echarts'
5 -import { defaultOption } from './index.config' 5 +import { getSetValue, setOption } from './index.config'
6 import type { CreateComponentType, RenderComponentExposeType } from '@/core/Library/types' 6 import type { CreateComponentType, RenderComponentExposeType } from '@/core/Library/types'
7 import 'echarts-liquidfill' // 水球图插件 7 import 'echarts-liquidfill' // 水球图插件
8 import { useOnMessage } from '@/core/Library/hook/useOnMessage' 8 import { useOnMessage } from '@/core/Library/hook/useOnMessage'
9 import type { NodeDataDataSourceJsonType } from '@/api/node/model' 9 import type { NodeDataDataSourceJsonType } from '@/api/node/model'
10 import { useLatestMessageValue } from '@/core/Library/hook/useLatestMessageValue' 10 import { useLatestMessageValue } from '@/core/Library/hook/useLatestMessageValue'
  11 +import { useContentDataStore } from '@/store/modules/contentData'
11 12
12 const props = defineProps<{ 13 const props = defineProps<{
13 config: CreateComponentType 14 config: CreateComponentType
14 }>() 15 }>()
15 16
  17 +const contentDataStore = useContentDataStore()
  18 +
  19 +const getCurrentNodeData = computed(() => contentDataStore.contentData.find(item => item.id === props.config.cellInfo?.id))
  20 +
16 const getCellBounds = computed(() => props.config.cellBounds || { width: 300, height: 300, x: 0, y: 0 }) 21 const getCellBounds = computed(() => props.config.cellBounds || { width: 300, height: 300, x: 0, y: 0 })
17 22
18 const chartElRef = ref<Nullable<HTMLDivElement>>() 23 const chartElRef = ref<Nullable<HTMLDivElement>>()
@@ -20,8 +25,10 @@ const chartElRef = ref<Nullable<HTMLDivElement>>() @@ -20,8 +25,10 @@ const chartElRef = ref<Nullable<HTMLDivElement>>()
20 const chartInstance = ref<Nullable<ECharts>>() 25 const chartInstance = ref<Nullable<ECharts>>()
21 26
22 function initChartInstance() { 27 function initChartInstance() {
  28 + const { dataSourceJson } = unref(getCurrentNodeData) || {}
  29 + const { circularFlowMeterOption } = dataSourceJson || {}
23 chartInstance.value = init(unref(chartElRef)) 30 chartInstance.value = init(unref(chartElRef))
24 - chartInstance.value.setOption(defaultOption) 31 + chartInstance.value.setOption(setOption(40, circularFlowMeterOption))
25 } 32 }
26 33
27 const { onMessage } = useOnMessage({ 34 const { onMessage } = useOnMessage({
@@ -31,13 +38,7 @@ const { onMessage } = useOnMessage({ @@ -31,13 +38,7 @@ const { onMessage } = useOnMessage({
31 const { latestValue } = useLatestMessageValue(message.data, attr) 38 const { latestValue } = useLatestMessageValue(message.data, attr)
32 unref(chartInstance)?.setOption({ 39 unref(chartInstance)?.setOption({
33 series: [{ 40 series: [{
34 - data: [  
35 - Number(latestValue) / 100,  
36 - {  
37 - value: (Number(latestValue) - 10) / 100,  
38 - direction: 'left',  
39 - },  
40 - ], 41 + data: getSetValue(Number(latestValue)),
41 }], 42 }],
42 } as EChartsOption) 43 } as EChartsOption)
43 }, 44 },
1 <script setup lang="ts"> 1 <script setup lang="ts">
2 import { Button, Divider, Space } from 'ant-design-vue' 2 import { Button, Divider, Space } from 'ant-design-vue'
3 import { onMounted, ref, unref } from 'vue' 3 import { onMounted, ref, unref } from 'vue'
  4 +import { defaultFlowmetmerColorConfig } from '../CircularFlowMeter/form.config'
4 import { DataSourceForm } from '@/core/Library/components/PublicForm/components/DataSourceForm' 5 import { DataSourceForm } from '@/core/Library/components/PublicForm/components/DataSourceForm'
5 import { useNodeData } from '@/core/Library/hook/useNodeData' 6 import { useNodeData } from '@/core/Library/hook/useNodeData'
6 import type { ConfigComponentProps } from '@/core/Library/types' 7 import type { ConfigComponentProps } from '@/core/Library/types'
7 import { useMessage } from '@/hooks/web/useMessage' 8 import { useMessage } from '@/hooks/web/useMessage'
8 -import type { NodeDataDataSourceJsonType } from '@/api/node/model' 9 +import type { FlowMeterColorItemType } from '@/api/node/model'
9 import { useSavePageContent } from '@/core/Library/hook/useSavePageContent' 10 import { useSavePageContent } from '@/core/Library/hook/useSavePageContent'
10 11
11 const props = defineProps<ConfigComponentProps>() 12 const props = defineProps<ConfigComponentProps>()
@@ -14,24 +15,7 @@ const { createMessage } = useMessage() @@ -14,24 +15,7 @@ const { createMessage } = useMessage()
14 15
15 const loading = ref(false) 16 const loading = ref(false)
16 17
17 -const colorConfig = ref([  
18 - {  
19 - label: '背景色',  
20 - value: '#8BADCB',  
21 - },  
22 - {  
23 - label: '颜色一',  
24 - value: '#4579e2',  
25 - },  
26 - {  
27 - label: '颜色二',  
28 - value: '#3461c1',  
29 - },  
30 - {  
31 - label: '颜色三',  
32 - value: '#2d55aa',  
33 - },  
34 -]) 18 +const colorConfig = ref<FlowMeterColorItemType[]>(defaultFlowmetmerColorConfig)
35 19
36 const nodeDataActinType = useNodeData({ cell: props.cell!, immediate: true }) 20 const nodeDataActinType = useNodeData({ cell: props.cell!, immediate: true })
37 21
@@ -57,11 +41,11 @@ const handleSubmit = async () => { @@ -57,11 +41,11 @@ const handleSubmit = async () => {
57 41
58 onMounted(async () => { 42 onMounted(async () => {
59 await getNodeAllData() 43 await getNodeAllData()
60 - if (unref(getNodeData)?.dataSourceJson) {  
61 - const { rectFlowMeterOption, additional } = unref(getNodeData)?.dataSourceJson as NodeDataDataSourceJsonType  
62 - colorConfig.value = additional || unref(colorConfig)  
63 - if (!rectFlowMeterOption) return  
64 - dataSourceFormRef.value?.setFieldsValue(rectFlowMeterOption) 44 + const { dataSourceJson } = unref(getNodeData) || {}
  45 + if (dataSourceJson) {
  46 + const { rectFlowMeterOption } = dataSourceJson || {}
  47 + colorConfig.value = rectFlowMeterOption || unref(colorConfig)
  48 + dataSourceFormRef.value?.setFieldsValue(dataSourceJson)
65 } 49 }
66 }) 50 })
67 </script> 51 </script>
@@ -69,18 +53,20 @@ onMounted(async () => { @@ -69,18 +53,20 @@ onMounted(async () => {
69 <template> 53 <template>
70 <main class="w-full h-full flex flex-col px-2 py-4 box-border"> 54 <main class="w-full h-full flex flex-col px-2 py-4 box-border">
71 <main class="form-container"> 55 <main class="form-container">
72 - <Divider orientation="left"> 56 + <Divider orientation="left" class="!text-sm">
73 数据源 57 数据源
74 </Divider> 58 </Divider>
75 <DataSourceForm ref="dataSourceFormRef" /> 59 <DataSourceForm ref="dataSourceFormRef" />
76 </main> 60 </main>
77 <main class="form-container mt-2"> 61 <main class="form-container mt-2">
78 - <Divider orientation="left"> 62 + <Divider orientation="left" class="!text-sm">
79 流量计配置 63 流量计配置
80 </Divider> 64 </Divider>
81 <Space direction="vertical"> 65 <Space direction="vertical">
82 - <div v-for="(item, index) in colorConfig" :key="index" class="mt-3 ml-5">  
83 - <span>{{ item.label }}</span> 66 + <div v-for="(item, index) in colorConfig" :key="index" class="flex mt-3 ml-5">
  67 + <div class="w-20">
  68 + {{ item.label }}
  69 + </div>
84 <input v-model="item.value" class="ml-3" type="color"> 70 <input v-model="item.value" class="ml-3" type="color">
85 </div> 71 </div>
86 </Space> 72 </Space>
1 -const value = 40 // 水球图数据源  
2 -export const defaultOption = {  
3 - series: [  
4 - {  
5 - type: 'liquidFill',  
6 - shape: 'rect', // 设置水球图形状  
7 - radius: '90%',  
8 - data: [  
9 - value / 100,  
10 - {  
11 - value: (value - 10) / 100,  
12 - direction: 'left',  
13 - },  
14 - ],  
15 - backgroundStyle: {  
16 - borderWidth: 1,  
17 - color: 'transparent', // 这里设置背景色  
18 - },  
19 - label: {  
20 - color: '#27e5f1',  
21 - insideColor: '#f7e8c1',  
22 - left: '50%',  
23 - top: '40%',  
24 - textAlign: 'center',  
25 - fontSize: 20,  
26 - fontWeight: '600',  
27 - textBorderColor: 'rgba(0, 0, 0, 0)',  
28 - textShadowColor: '#000',  
29 - textShadowBlur: '0',  
30 - textShadowOffsetX: 0,  
31 - textShadowOffsetY: 1,  
32 - },  
33 - color: [{  
34 - type: 'linear',  
35 - x: 0,  
36 - y: 0,  
37 - x2: 1,  
38 - y2: 1,  
39 - colorStops: [{  
40 - offset: 0,  
41 - color: ['#324791'], // 这里设置水球波动 0% 处的颜色  
42 - }, {  
43 - offset: 1,  
44 - color: ['#449090'], // 这里设置水球波动 100% 处的颜色  
45 - }],  
46 - global: false,  
47 - }],  
48 - outline: {  
49 - show: true,  
50 - borderDistance: 1, 1 +import { FormFieldsEnum, defaultFlowmetmerColorConfig } from '../CircularFlowMeter/form.config'
  2 +import { isLightboxMode } from '@/utils/env'
  3 +import type { FlowMeterColorItemType } from '@/api/node/model'
  4 +
  5 +export function getSetValue(value: number) {
  6 + return [
  7 + value / 100,
  8 + (value - 10) / 100,
  9 + (value - 20) / 100,
  10 + ]
  11 +}
  12 +export const setOption = (value: number = 40, circularFlowMeterOption: FlowMeterColorItemType[] = defaultFlowmetmerColorConfig) => {
  13 + const colorMap = (isLightboxMode() ? circularFlowMeterOption : defaultFlowmetmerColorConfig).reduce((prev, next) => ({ ...prev, [next.key]: next.value }), {} as Record<FormFieldsEnum, string>)
  14 + return {
  15 + series: [
  16 + {
  17 + type: 'liquidFill',
  18 + radius: '90%',
  19 + shape: 'rect', // 设置水球图形状
  20 + data: getSetValue(value),
  21 + color: [colorMap[FormFieldsEnum.COLOR_FIRST], colorMap[FormFieldsEnum.COLOR_SECOND], colorMap[FormFieldsEnum.COLOR_THIRD]],
51 itemStyle: { 22 itemStyle: {
52 - borderWidth: 0,  
53 - color: {  
54 - type: 'linear',  
55 - x: 0,  
56 - y: 0,  
57 - x2: 1,  
58 - y2: 0,  
59 - colorStops: [{  
60 - offset: 0, color: '#0b2355', // 这里设置水球外边框 0% 处的颜色  
61 - }, {  
62 - offset: 1, color: '#195b9d', // 这里设置水球外边框 100% 处的颜色  
63 - }],  
64 - global: false, 23 + opacity: 0.6,
  24 + },
  25 + backgroundStyle: {
  26 + borderWidth: 1,
  27 + color: colorMap[FormFieldsEnum.BACKGROUND], // 这里设置背景色
  28 + },
  29 + emphasis: {
  30 + itemStyle: {
  31 + opacity: 0.9,
  32 + },
  33 + },
  34 + label: {
  35 + color: '#fff',
  36 + insideColor: '#f7e8c1',
  37 + left: '50%',
  38 + top: '40%',
  39 + textAlign: 'center',
  40 + fontSize: 20,
  41 + fontWeight: 600,
  42 + textBorderColor: 'rgba(0, 0, 0, 0)',
  43 + textShadowColor: '#000',
  44 + textShadowBlur: 0,
  45 + textShadowOffsetX: 0,
  46 + textShadowOffsetY: 1,
  47 + },
  48 +
  49 + outline: {
  50 + show: true,
  51 + borderDistance: 1,
  52 + itemStyle: {
  53 + borderWidth: 0,
  54 + color: {
  55 + type: 'linear',
  56 + x: 0,
  57 + y: 0,
  58 + x2: 1,
  59 + y2: 0,
  60 + colorStops: [
  61 + {
  62 + offset: 0,
  63 + color: '#0b2355', // 这里设置水球外边框 0% 处的颜色
  64 + },
  65 + {
  66 + offset: 1,
  67 + color: '#195b9d', // 这里设置水球外边框 100% 处的颜色
  68 + },
  69 + ],
  70 + global: false,
  71 + },
65 }, 72 },
66 }, 73 },
67 }, 74 },
68 - },  
69 - ], 75 + ],
  76 + }
70 } 77 }
@@ -2,17 +2,22 @@ @@ -2,17 +2,22 @@
2 import { computed, onMounted, onUnmounted, ref, unref } from 'vue' 2 import { computed, onMounted, onUnmounted, ref, unref } from 'vue'
3 import type { ECharts, EChartsOption } from 'echarts' 3 import type { ECharts, EChartsOption } from 'echarts'
4 import { init } from 'echarts' 4 import { init } from 'echarts'
5 -import { defaultOption } from './index.config' 5 +import { getSetValue, setOption } from './index.config'
6 import type { CreateComponentType, RenderComponentExposeType } from '@/core/Library/types' 6 import type { CreateComponentType, RenderComponentExposeType } from '@/core/Library/types'
7 import 'echarts-liquidfill' // 水球图插件 7 import 'echarts-liquidfill' // 水球图插件
8 -import type { NodeDataDataSourceJsonType } from '@/api/node/model'  
9 import { useOnMessage } from '@/core/Library/hook/useOnMessage' 8 import { useOnMessage } from '@/core/Library/hook/useOnMessage'
  9 +import type { NodeDataDataSourceJsonType } from '@/api/node/model'
10 import { useLatestMessageValue } from '@/core/Library/hook/useLatestMessageValue' 10 import { useLatestMessageValue } from '@/core/Library/hook/useLatestMessageValue'
  11 +import { useContentDataStore } from '@/store/modules/contentData'
11 12
12 const props = defineProps<{ 13 const props = defineProps<{
13 config: CreateComponentType 14 config: CreateComponentType
14 }>() 15 }>()
15 16
  17 +const contentDataStore = useContentDataStore()
  18 +
  19 +const getCurrentNodeData = computed(() => contentDataStore.contentData.find(item => item.id === props.config.cellInfo?.id))
  20 +
16 const getCellBounds = computed(() => props.config.cellBounds || { width: 300, height: 300, x: 0, y: 0 }) 21 const getCellBounds = computed(() => props.config.cellBounds || { width: 300, height: 300, x: 0, y: 0 })
17 22
18 const chartElRef = ref<Nullable<HTMLDivElement>>() 23 const chartElRef = ref<Nullable<HTMLDivElement>>()
@@ -20,8 +25,10 @@ const chartElRef = ref<Nullable<HTMLDivElement>>() @@ -20,8 +25,10 @@ const chartElRef = ref<Nullable<HTMLDivElement>>()
20 const chartInstance = ref<Nullable<ECharts>>() 25 const chartInstance = ref<Nullable<ECharts>>()
21 26
22 function initChartInstance() { 27 function initChartInstance() {
  28 + const { dataSourceJson } = unref(getCurrentNodeData) || {}
  29 + const { rectFlowMeterOption } = dataSourceJson || {}
23 chartInstance.value = init(unref(chartElRef)) 30 chartInstance.value = init(unref(chartElRef))
24 - chartInstance.value.setOption(defaultOption) 31 + chartInstance.value.setOption(setOption(40, rectFlowMeterOption))
25 } 32 }
26 33
27 const { onMessage } = useOnMessage({ 34 const { onMessage } = useOnMessage({
@@ -31,13 +38,7 @@ const { onMessage } = useOnMessage({ @@ -31,13 +38,7 @@ const { onMessage } = useOnMessage({
31 const { latestValue } = useLatestMessageValue(message.data, attr) 38 const { latestValue } = useLatestMessageValue(message.data, attr)
32 unref(chartInstance)?.setOption({ 39 unref(chartInstance)?.setOption({
33 series: [{ 40 series: [{
34 - data: [  
35 - Number(latestValue) / 100,  
36 - {  
37 - value: (Number(latestValue) - 10) / 100,  
38 - direction: 'left',  
39 - },  
40 - ], 41 + data: getSetValue(Number(latestValue)),
41 }], 42 }],
42 } as EChartsOption) 43 } as EChartsOption)
43 }, 44 },
@@ -5,7 +5,6 @@ import { DataSourceForm } from '@/core/Library/components/PublicForm/components/ @@ -5,7 +5,6 @@ import { DataSourceForm } from '@/core/Library/components/PublicForm/components/
5 import { useNodeData } from '@/core/Library/hook/useNodeData' 5 import { useNodeData } from '@/core/Library/hook/useNodeData'
6 import { useMessage } from '@/hooks/web/useMessage' 6 import { useMessage } from '@/hooks/web/useMessage'
7 import type { ConfigComponentProps } from '@/core/Library/types' 7 import type { ConfigComponentProps } from '@/core/Library/types'
8 -import type { NodeDataDataSourceJsonType } from '@/api/node/model'  
9 import { useSavePageContent } from '@/core/Library/hook/useSavePageContent' 8 import { useSavePageContent } from '@/core/Library/hook/useSavePageContent'
10 9
11 const props = defineProps<ConfigComponentProps>() 10 const props = defineProps<ConfigComponentProps>()
@@ -16,7 +15,7 @@ const loading = ref(false) @@ -16,7 +15,7 @@ const loading = ref(false)
16 15
17 const dataSourceFormRef = ref<Nullable<InstanceType<typeof DataSourceForm>>>(null) 16 const dataSourceFormRef = ref<Nullable<InstanceType<typeof DataSourceForm>>>(null)
18 17
19 -const nodeDataActinType = useNodeData({ cell: props.cell!, immediate: true }) 18 +const nodeDataActinType = useNodeData({ cell: props.cell!, immediate: false })
20 19
21 const { getNodeAllData, saveNodeAllData, getNodeData } = nodeDataActinType 20 const { getNodeAllData, saveNodeAllData, getNodeData } = nodeDataActinType
22 21
@@ -38,11 +37,9 @@ const handleSubmit = async () => { @@ -38,11 +37,9 @@ const handleSubmit = async () => {
38 37
39 onMounted(async () => { 38 onMounted(async () => {
40 await getNodeAllData() 39 await getNodeAllData()
41 - if (unref(getNodeData)?.dataSourceJson) {  
42 - const { thermometerOption } = unref(getNodeData)?.dataSourceJson as NodeDataDataSourceJsonType  
43 - if (!thermometerOption) return  
44 - dataSourceFormRef.value?.setFieldsValue(thermometerOption)  
45 - } 40 + const { dataSourceJson } = unref(getNodeData) || {}
  41 + if (dataSourceJson)
  42 + dataSourceFormRef.value?.setFieldsValue(dataSourceJson)
46 }) 43 })
47 </script> 44 </script>
48 45
@@ -40,7 +40,7 @@ export class MessageHandler { @@ -40,7 +40,7 @@ export class MessageHandler {
40 if (!cell) return 40 if (!cell) return
41 const instanceId = getAppInstanceId(cell) 41 const instanceId = getAppInstanceId(cell)
42 const instance = window?.VueInstanceMap?.[instanceId] as App 42 const instance = window?.VueInstanceMap?.[instanceId] as App
43 - if (instance) 43 + if (instance && (instance._instance?.exposed as RenderComponentExposeType)?.onMessage)
44 (instance._instance?.exposed as RenderComponentExposeType)?.onMessage?.(commandSource, message) 44 (instance._instance?.exposed as RenderComponentExposeType)?.onMessage?.(commandSource, message)
45 else 45 else
46 this.defaultHandler(commandSource, message) 46 this.defaultHandler(commandSource, message)